1 // SPDX-License-Identifier: GPL-2.0-only
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
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>
28 #include <net/inet_connection_sock.h>
34 static int nl80211_crypto_settings(struct cfg80211_registered_device
*rdev
,
35 struct genl_info
*info
,
36 struct cfg80211_crypto_settings
*settings
,
39 /* the netlink family */
40 static struct genl_family nl80211_fam
;
42 /* multicast groups */
43 enum nl80211_multicast_groups
{
46 NL80211_MCGRP_REGULATORY
,
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
}
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
];
77 if (!have_ifidx
&& !have_wdev_id
)
78 return ERR_PTR(-EINVAL
);
81 ifidx
= nla_get_u32(attrs
[NL80211_ATTR_IFINDEX
]);
83 wdev_id
= nla_get_u64(attrs
[NL80211_ATTR_WDEV
]);
84 wiphy_idx
= wdev_id
>> 32;
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
) {
98 if (have_wdev_id
&& wdev
->identifier
== (u32
)wdev_id
) {
104 return result
?: ERR_PTR(-ENODEV
);
109 for_each_rdev(rdev
) {
110 struct wireless_dev
*wdev
;
112 if (wiphy_net(&rdev
->wiphy
) != netns
)
115 if (have_wdev_id
&& rdev
->wiphy_idx
!= wiphy_idx
)
118 list_for_each_entry(wdev
, &rdev
->wiphy
.wdev_list
, list
) {
119 if (have_ifidx
&& wdev
->netdev
&&
120 wdev
->netdev
->ifindex
== ifidx
) {
124 if (have_wdev_id
&& wdev
->identifier
== (u32
)wdev_id
) {
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
;
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
;
161 tmp
= cfg80211_rdev_by_wiphy_idx(wdev_id
>> 32);
163 /* make sure wdev exists */
164 list_for_each_entry(wdev
, &tmp
->wiphy
.wdev_list
, list
) {
165 if (wdev
->identifier
!= (u32
)wdev_id
)
174 if (rdev
&& tmp
!= rdev
)
175 return ERR_PTR(-EINVAL
);
180 if (attrs
[NL80211_ATTR_IFINDEX
]) {
181 int ifindex
= nla_get_u32(attrs
[NL80211_ATTR_IFINDEX
]);
183 netdev
= __dev_get_by_index(netns
, ifindex
);
185 if (netdev
->ieee80211_ptr
)
187 netdev
->ieee80211_ptr
->wiphy
);
191 /* not wireless device -- return error */
193 return ERR_PTR(-EINVAL
);
195 /* mismatch -- return error */
196 if (rdev
&& tmp
!= rdev
)
197 return ERR_PTR(-EINVAL
);
204 return ERR_PTR(-ENODEV
);
206 if (netns
!= wiphy_net(&rdev
->wiphy
))
207 return ERR_PTR(-ENODEV
);
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
;
235 if (len
< offsetofend(typeof(*mgmt
), frame_control
))
238 s1g_bcn
= ieee80211_is_s1g_beacon(mgmt
->frame_control
);
240 fixedlen
= offsetof(struct ieee80211_ext
,
241 u
.s1g_beacon
.variable
);
242 hdrlen
= offsetof(struct ieee80211_ext
, u
.s1g_beacon
);
244 fixedlen
= offsetof(struct ieee80211_mgmt
,
246 hdrlen
= offsetof(struct ieee80211_mgmt
, u
.beacon
);
252 if (ieee80211_hdrlen(mgmt
->frame_control
) != hdrlen
)
258 for_each_element(elem
, data
, len
) {
262 if (for_each_element_completed(elem
, data
, len
))
266 NL_SET_ERR_MSG_ATTR(extack
, attr
, "malformed beacon head");
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
) {
281 if (for_each_element_completed(elem
, data
, len
))
284 NL_SET_ERR_MSG_ATTR(extack
, attr
, "malformed information elements");
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
)))
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
,
305 [NL80211_FTM_RESP_ATTR_CIVICLOC
] = { .type
= NLA_BINARY
,
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
= {
470 static const struct netlink_range_validation q_range
= {
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
,
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
,
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
,
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
,
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
},
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
] = {
907 .len
= NL80211_KEK_EXT_LEN
909 [NL80211_REKEY_DATA_KCK
] = {
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
)
990 struct nlattr
**attrbuf_free
= NULL
;
993 attrbuf
= kcalloc(NUM_NL80211_ATTR
, sizeof(*attrbuf
),
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
);
1005 kfree(attrbuf_free
);
1010 *wdev
= __cfg80211_wdev_from_attrs(NULL
, sock_net(cb
->skb
->sk
),
1012 kfree(attrbuf_free
);
1013 if (IS_ERR(*wdev
)) {
1015 return PTR_ERR(*wdev
);
1017 *rdev
= wiphy_to_rdev((*wdev
)->wiphy
);
1018 mutex_lock(&(*rdev
)->wiphy
.mtx
);
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
;
1024 /* subtract the 1 again here */
1025 struct wiphy
*wiphy
;
1026 struct wireless_dev
*tmp
;
1029 wiphy
= wiphy_idx_to_wiphy(cb
->args
[0] - 1);
1034 *rdev
= wiphy_to_rdev(wiphy
);
1037 list_for_each_entry(tmp
, &(*rdev
)->wiphy
.wdev_list
, list
) {
1038 if (tmp
->identifier
== cb
->args
[1]) {
1048 mutex_lock(&(*rdev
)->wiphy
.mtx
);
1055 /* message building helper */
1056 void *nl80211hdr_put(struct sk_buff
*skb
, u32 portid
, u32 seq
,
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
)
1067 struct nlattr
*nl_wmm_rules
=
1068 nla_nest_start_noflag(msg
, NL80211_FREQUENCY_ATTR_WMM
);
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
);
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
);
1099 static int nl80211_msg_put_channel(struct sk_buff
*msg
, struct wiphy
*wiphy
,
1100 struct ieee80211_channel
*chan
,
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
))
1109 if (!large
&& chan
->freq_offset
)
1112 if (nla_put_u32(msg
, NL80211_FREQUENCY_ATTR_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
;
1138 time
= elapsed_jiffies_msecs(chan
->dfs_state_entered
);
1140 if (nla_put_u32(msg
, NL80211_FREQUENCY_ATTR_DFS_STATE
,
1142 goto nla_put_failure
;
1143 if (nla_put_u32(msg
, NL80211_FREQUENCY_ATTR_DFS_TIME
,
1145 goto nla_put_failure
;
1146 if (nla_put_u32(msg
,
1147 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME
,
1149 goto nla_put_failure
;
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
;
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
;
1239 static bool nl80211_put_txq_stats(struct sk_buff
*msg
,
1240 struct cfg80211_txq_stats
*txqstats
,
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)) \
1251 txqattr
= nla_nest_start_noflag(msg
, attrtype
);
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
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
];
1299 return nla_get_u8(linkid
);
1303 struct key_params p
;
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
,
1320 k
->def
= !!tb
[NL80211_KEY_DEFAULT
];
1321 k
->defmgmt
= !!tb
[NL80211_KEY_DEFAULT_MGMT
];
1322 k
->defbeacon
= !!tb
[NL80211_KEY_DEFAULT_BEACON
];
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
,
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
]);
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
];
1394 k
->def_multi
= true;
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
,
1412 k
->def_uni
= kdt
[NL80211_KEY_DEFAULT_TYPE_UNICAST
];
1413 k
->def_multi
= kdt
[NL80211_KEY_DEFAULT_TYPE_MULTICAST
];
1419 static int nl80211_parse_key(struct genl_info
*info
, struct key_parse
*k
)
1423 memset(k
, 0, sizeof(*k
));
1427 if (info
->attrs
[NL80211_ATTR_KEY
])
1428 err
= nl80211_parse_key_new(info
, info
->attrs
[NL80211_ATTR_KEY
], k
);
1430 err
= nl80211_parse_key_old(info
, k
);
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");
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");
1452 if (k
->idx
< 4 || k
->idx
> 5) {
1453 GENL_SET_ERR_MSG(info
,
1454 "defmgmt key idx not 4 or 5");
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");
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");
1469 if (k
->idx
< 0 || k
->idx
> 7) {
1470 GENL_SET_ERR_MSG(info
, "key idx not 0-7");
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
;
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
) {
1498 result
= kzalloc(sizeof(*result
), GFP_KERNEL
);
1500 return ERR_PTR(-ENOMEM
);
1504 nla_for_each_nested(key
, keys
, rem
) {
1505 memset(&parse
, 0, sizeof(parse
));
1508 err
= nl80211_parse_key_new(info
, key
, &parse
);
1514 if (parse
.idx
< 0 || parse
.idx
> 3) {
1515 GENL_SET_ERR_MSG(info
, "key index out of range [0-3]");
1520 GENL_SET_ERR_MSG(info
,
1521 "only one key can be default");
1525 result
->def
= parse
.idx
;
1526 if (!parse
.def_uni
|| !parse
.def_multi
)
1528 } else if (parse
.defmgmt
)
1530 err
= cfg80211_validate_key_settings(rdev
, &parse
.p
,
1531 parse
.idx
, false, NULL
);
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");
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 */
1550 if (result
->def
< 0) {
1552 GENL_SET_ERR_MSG(info
, "need a default/TX key");
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
:
1572 case NL80211_IFTYPE_ADHOC
:
1573 if (wdev
->u
.ibss
.current_bss
)
1576 case NL80211_IFTYPE_STATION
:
1577 case NL80211_IFTYPE_P2P_CLIENT
:
1578 if (wdev
->connected
)
1581 case NL80211_IFTYPE_NAN
:
1582 if (wiphy_ext_feature_isset(wdev
->wiphy
,
1583 NL80211_EXT_FEATURE_SECURE_NAN
))
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
:
1598 static struct ieee80211_channel
*nl80211_get_valid_chan(struct wiphy
*wiphy
,
1601 struct ieee80211_channel
*chan
;
1603 chan
= ieee80211_get_channel_khz(wiphy
, freq
);
1604 if (!chan
|| chan
->flags
& IEEE80211_CHAN_DISABLED
)
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
);
1615 goto nla_put_failure
;
1619 if ((ifmodes
& 1) && nla_put_flag(msg
, i
))
1620 goto nla_put_failure
;
1625 nla_nest_end(msg
, nl_modes
);
1632 static int nl80211_put_ifcomb_data(struct sk_buff
*msg
, bool large
, int idx
,
1633 const struct ieee80211_iface_combination
*c
,
1636 struct nlattr
*nl_combi
, *nl_limits
;
1639 nl_combi
= nla_nest_start_noflag(msg
, idx
| nested
);
1641 goto nla_put_failure
;
1643 nl_limits
= nla_nest_start_noflag(msg
, NL80211_IFACE_COMB_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);
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
,
1671 goto nla_put_failure
;
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
);
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
;
1699 nl_combis
= nla_nest_start_noflag(msg
, attr
| nested
);
1701 goto nla_put_failure
;
1704 c
= wiphy
->radio
[0].iface_combinations
;
1705 n
= wiphy
->radio
[0].n_iface_combinations
;
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
);
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
;
1731 nl_tcp
= nla_nest_start_noflag(msg
,
1732 NL80211_WOWLAN_TRIG_TCP_CONNECTION
);
1736 if (nla_put_u32(msg
, NL80211_WOWLAN_TCP_DATA_PAYLOAD
,
1737 tcp
->data_payload_max
))
1740 if (nla_put_u32(msg
, NL80211_WOWLAN_TCP_DATA_PAYLOAD
,
1741 tcp
->data_payload_max
))
1744 if (tcp
->seq
&& nla_put_flag(msg
, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ
))
1747 if (tcp
->tok
&& nla_put(msg
, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN
,
1748 sizeof(*tcp
->tok
), tcp
->tok
))
1751 if (nla_put_u32(msg
, NL80211_WOWLAN_TCP_DATA_INTERVAL
,
1752 tcp
->data_interval_max
))
1755 if (nla_put_u32(msg
, NL80211_WOWLAN_TCP_WAKE_PAYLOAD
,
1756 tcp
->wake_payload_max
))
1759 nla_nest_end(msg
, nl_tcp
);
1763 static int nl80211_send_wowlan(struct sk_buff
*msg
,
1764 struct cfg80211_registered_device
*rdev
,
1767 struct nlattr
*nl_wowlan
;
1769 if (!rdev
->wiphy
.wowlan
)
1772 nl_wowlan
= nla_nest_start_noflag(msg
,
1773 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED
);
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
)))
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
,
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
))
1813 if (large
&& nl80211_send_wowlan_tcp_caps(rdev
, msg
))
1816 nla_nest_end(msg
, nl_wowlan
);
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
)
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
))
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
))
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
))
1870 if (eht_cap
->has_eht
&& he_cap
->has_he
) {
1871 u8 mcs_nss_size
, ppe_thresh_size
;
1875 is_ap
= iftdata
->types_mask
& BIT(NL80211_IFTYPE_AP
) ||
1876 iftdata
->types_mask
& BIT(NL80211_IFTYPE_P2P_GO
);
1879 ieee80211_eht_mcs_nss_size(&he_cap
->he_cap_elem
,
1880 &eht_cap
->eht_cap_elem
,
1883 ppe_thres_hdr
= get_unaligned_le16(&eht_cap
->eht_ppe_thres
[0]);
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
))
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
))
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
))
1915 static int nl80211_send_band_rateinfo(struct sk_buff
*msg
,
1916 struct ieee80211_supported_band
*sband
,
1919 struct nlattr
*nl_rates
, *nl_rate
;
1920 struct ieee80211_rate
*rate
;
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
)))
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
)))
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
;
1952 if (!nl_iftype_data
)
1955 for_each_sband_iftype_data(sband
, i
, iftd
) {
1956 struct nlattr
*iftdata
;
1958 iftdata
= nla_nest_start_noflag(msg
, i
+ 1);
1962 err
= nl80211_send_iftype_data(msg
, sband
, iftd
);
1966 nla_nest_end(msg
, iftdata
);
1969 nla_nest_end(msg
, nl_iftype_data
);
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
)))
1982 nl_rates
= nla_nest_start_noflag(msg
, NL80211_BAND_ATTR_RATES
);
1986 for (i
= 0; i
< sband
->n_bitrates
; i
++) {
1987 nl_rate
= nla_nest_start_noflag(msg
, i
);
1991 rate
= &sband
->bitrates
[i
];
1992 if (nla_put_u32(msg
, NL80211_BITRATE_ATTR_RATE
,
1995 if ((rate
->flags
& IEEE80211_RATE_SHORT_PREAMBLE
) &&
1997 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE
))
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
)))
2019 nl80211_send_mgmt_stypes(struct sk_buff
*msg
,
2020 const struct ieee80211_txrx_stypes
*mgmt_stypes
)
2023 struct nlattr
*nl_ftypes
, *nl_ifs
;
2024 enum nl80211_iftype ift
;
2030 nl_ifs
= nla_nest_start_noflag(msg
, NL80211_ATTR_TX_FRAME_TYPES
);
2034 for (ift
= 0; ift
< NUM_NL80211_IFTYPES
; ift
++) {
2035 nl_ftypes
= nla_nest_start_noflag(msg
, ift
);
2039 stypes
= mgmt_stypes
[ift
].tx
;
2042 nla_put_u16(msg
, NL80211_ATTR_FRAME_TYPE
,
2043 (i
<< 4) | IEEE80211_FTYPE_MGMT
))
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
);
2057 for (ift
= 0; ift
< NUM_NL80211_IFTYPES
; ift
++) {
2058 nl_ftypes
= nla_nest_start_noflag(msg
, ift
);
2062 stypes
= mgmt_stypes
[ift
].rx
;
2065 nla_put_u16(msg
, NL80211_ATTR_FRAME_TYPE
,
2066 (i
<< 4) | IEEE80211_FTYPE_MGMT
))
2071 nla_nest_end(msg
, nl_ftypes
);
2073 nla_nest_end(msg
, nl_ifs
);
2078 #define CMD(op, n) \
2080 if (rdev->ops->op) { \
2082 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
2083 goto nla_put_failure; \
2087 static int nl80211_add_commands_unsplit(struct cfg80211_registered_device
*rdev
,
2088 struct sk_buff
*msg
)
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
) {
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
) {
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
) {
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
);
2149 if (rdev
->ops
->connect
|| rdev
->ops
->auth
) {
2151 if (nla_put_u32(msg
, i
, NL80211_CMD_CONNECT
))
2152 goto nla_put_failure
;
2155 if (rdev
->ops
->disconnect
|| rdev
->ops
->deauth
) {
2157 if (nla_put_u32(msg
, i
, NL80211_CMD_DISCONNECT
))
2158 goto nla_put_failure
;
2167 nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities
*cap
,
2168 struct sk_buff
*msg
)
2172 if (!cap
->ftm
.supported
)
2175 ftm
= nla_nest_start_noflag(msg
, NL80211_PMSR_TYPE_FTM
);
2179 if (cap
->ftm
.asap
&& nla_put_flag(msg
, NL80211_PMSR_FTM_CAPA_ATTR_ASAP
))
2181 if (cap
->ftm
.non_asap
&&
2182 nla_put_flag(msg
, NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP
))
2184 if (cap
->ftm
.request_lci
&&
2185 nla_put_flag(msg
, NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI
))
2187 if (cap
->ftm
.request_civicloc
&&
2188 nla_put_flag(msg
, NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC
))
2190 if (nla_put_u32(msg
, NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES
,
2191 cap
->ftm
.preambles
))
2193 if (nla_put_u32(msg
, NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS
,
2194 cap
->ftm
.bandwidths
))
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
))
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
))
2204 if (cap
->ftm
.trigger_based
&&
2205 nla_put_flag(msg
, NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED
))
2207 if (cap
->ftm
.non_trigger_based
&&
2208 nla_put_flag(msg
, NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED
))
2211 nla_nest_end(msg
, ftm
);
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
;
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
);
2233 if (nla_put_u32(msg
, NL80211_PMSR_ATTR_MAX_PEERS
, cap
->max_peers
))
2236 if (cap
->report_ap_tsf
&&
2237 nla_put_flag(msg
, NL80211_PMSR_ATTR_REPORT_AP_TSF
))
2240 if (cap
->randomize_mac_addr
&&
2241 nla_put_flag(msg
, NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR
))
2244 caps
= nla_nest_start_noflag(msg
, NL80211_PMSR_ATTR_TYPE_CAPA
);
2248 if (nl80211_send_pmsr_ftm_capa(cap
, msg
))
2251 nla_nest_end(msg
, caps
);
2252 nla_nest_end(msg
, pmsr
);
2258 nl80211_put_iftype_akm_suites(struct cfg80211_registered_device
*rdev
,
2259 struct sk_buff
*msg
)
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
)
2269 nested
= nla_nest_start(msg
, NL80211_ATTR_IFTYPE_AKM_SUITES
);
2273 for (i
= 0; i
< rdev
->wiphy
.num_iftype_akm_suites
; i
++) {
2274 nested_akms
= nla_nest_start(msg
, i
+ 1);
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
))
2284 if (nla_put(msg
, NL80211_IFTYPE_AKM_ATTR_SUITES
,
2285 sizeof(u32
) * iftype_akms
->n_akm_suites
,
2286 iftype_akms
->akm_suites
)) {
2289 nla_nest_end(msg
, nested_akms
);
2292 nla_nest_end(msg
, nested
);
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
)
2307 supp
= nla_nest_start(msg
, NL80211_ATTR_TID_CONFIG
);
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
))
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
))
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
))
2327 if (nla_put_u8(msg
, NL80211_TID_CONFIG_ATTR_RETRY_LONG
,
2328 rdev
->wiphy
.tid_config_support
.max_retry
))
2331 nla_nest_end(msg
, supp
);
2335 nla_nest_cancel(msg
, supp
);
2340 nl80211_put_sar_specs(struct cfg80211_registered_device
*rdev
,
2341 struct sk_buff
*msg
)
2343 struct nlattr
*sar_capa
, *specs
, *sub_freq_range
;
2347 if (!rdev
->wiphy
.sar_capa
)
2350 num_freq_ranges
= rdev
->wiphy
.sar_capa
->num_freq_ranges
;
2352 sar_capa
= nla_nest_start(msg
, NL80211_ATTR_SAR_SPEC
);
2356 if (nla_put_u32(msg
, NL80211_SAR_ATTR_TYPE
, rdev
->wiphy
.sar_capa
->type
))
2359 specs
= nla_nest_start(msg
, NL80211_SAR_ATTR_SPECS
);
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
)
2369 if (nla_put_u32(msg
, NL80211_SAR_ATTR_SPECS_START_FREQ
,
2370 rdev
->wiphy
.sar_capa
->freq_ranges
[i
].start_freq
))
2373 if (nla_put_u32(msg
, NL80211_SAR_ATTR_SPECS_END_FREQ
,
2374 rdev
->wiphy
.sar_capa
->freq_ranges
[i
].end_freq
))
2377 nla_nest_end(msg
, sub_freq_range
);
2380 nla_nest_end(msg
, specs
);
2381 nla_nest_end(msg
, sar_capa
);
2385 nla_nest_cancel(msg
, sar_capa
);
2389 static int nl80211_put_mbssid_support(struct wiphy
*wiphy
, struct sk_buff
*msg
)
2391 struct nlattr
*config
;
2393 if (!wiphy
->mbssid_max_interfaces
)
2396 config
= nla_nest_start(msg
, NL80211_ATTR_MBSSID_CONFIG
);
2400 if (nla_put_u8(msg
, NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES
,
2401 wiphy
->mbssid_max_interfaces
))
2404 if (wiphy
->ema_max_profile_periodicity
&&
2406 NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY
,
2407 wiphy
->ema_max_profile_periodicity
))
2410 nla_nest_end(msg
, config
);
2414 nla_nest_cancel(msg
, config
);
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
;
2424 radio
= nla_nest_start(msg
, idx
);
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
,
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
);
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
,
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
],
2457 goto nla_put_failure
;
2459 nla_nest_end(msg
, radio
);
2467 static int nl80211_put_radios(struct wiphy
*wiphy
, struct sk_buff
*msg
)
2469 struct nlattr
*radios
;
2472 if (!wiphy
->n_radio
)
2475 radios
= nla_nest_start(msg
, NL80211_ATTR_WIPHY_RADIOS
);
2479 for (i
= 0; i
< wiphy
->n_radio
; i
++)
2480 if (nl80211_put_radio(wiphy
, msg
, i
))
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
))
2493 nla_nest_cancel(msg
, radios
);
2497 struct nl80211_dump_wiphy_state
{
2500 long split_start
, band_start
, chan_start
, capa_start
;
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
)
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
;
2516 const struct ieee80211_txrx_stypes
*mgmt_stypes
=
2517 rdev
->wiphy
.mgmt_stypes
;
2520 hdr
= nl80211hdr_put(msg
, portid
, seq
, flags
, cmd
);
2524 if (WARN_ON(!state
))
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
)
2537 switch (state
->split_start
) {
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
++;
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;
2614 res
= rdev_get_antenna(rdev
, &tx_ant
, &rx_ant
);
2616 if (nla_put_u32(msg
,
2617 NL80211_ATTR_WIPHY_ANTENNA_TX
,
2620 NL80211_ATTR_WIPHY_ANTENNA_RX
,
2622 goto nla_put_failure
;
2626 state
->split_start
++;
2631 if (nl80211_put_iftypes(msg
, NL80211_ATTR_SUPPORTED_IFTYPES
,
2632 rdev
->wiphy
.interface_modes
))
2633 goto nla_put_failure
;
2634 state
->split_start
++;
2639 nl_bands
= nla_nest_start_noflag(msg
,
2640 NL80211_ATTR_WIPHY_BANDS
);
2642 goto nla_put_failure
;
2644 for (band
= state
->band_start
;
2645 band
< (state
->split
?
2647 NL80211_BAND_60GHZ
+ 1);
2649 struct ieee80211_supported_band
*sband
;
2651 /* omit higher bands for ancient software */
2652 if (band
> NL80211_BAND_5GHZ
&& !state
->split
)
2655 sband
= rdev
->wiphy
.bands
[band
];
2660 nl_band
= nla_nest_start_noflag(msg
, band
);
2662 goto nla_put_failure
;
2664 switch (state
->chan_start
) {
2666 if (nl80211_send_band_rateinfo(msg
, sband
,
2668 goto nla_put_failure
;
2669 state
->chan_start
++;
2674 /* add frequencies */
2675 nl_freqs
= nla_nest_start_noflag(msg
,
2676 NL80211_BAND_ATTR_FREQS
);
2678 goto nla_put_failure
;
2680 for (i
= state
->chan_start
- 1;
2681 i
< sband
->n_channels
;
2683 nl_freq
= nla_nest_start_noflag(msg
,
2686 goto nla_put_failure
;
2688 chan
= &sband
->channels
[i
];
2690 if (nl80211_msg_put_channel(
2691 msg
, &rdev
->wiphy
, chan
,
2693 goto nla_put_failure
;
2695 nla_nest_end(msg
, nl_freq
);
2699 if (i
< sband
->n_channels
)
2700 state
->chan_start
= i
+ 2;
2702 state
->chan_start
= 0;
2703 nla_nest_end(msg
, nl_freqs
);
2706 nla_nest_end(msg
, nl_band
);
2709 /* start again here */
2710 if (state
->chan_start
)
2715 nla_nest_end(msg
, nl_bands
);
2717 if (band
< NUM_NL80211_BANDS
)
2718 state
->band_start
= band
+ 1;
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
++;
2729 nl_cmds
= nla_nest_start_noflag(msg
,
2730 NL80211_ATTR_SUPPORTED_COMMANDS
);
2732 goto nla_put_failure
;
2734 i
= nl80211_add_commands_unsplit(rdev
, msg
);
2736 goto nla_put_failure
;
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
);
2754 nla_nest_end(msg
, nl_cmds
);
2755 state
->split_start
++;
2760 if (rdev
->ops
->remain_on_channel
&&
2761 (rdev
->wiphy
.flags
& WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
) &&
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
++;
2777 if (nl80211_send_wowlan(msg
, rdev
, state
->split
))
2778 goto nla_put_failure
;
2779 state
->split_start
++;
2783 state
->split_start
++;
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,
2795 goto nla_put_failure
;
2797 state
->split_start
++;
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.
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.
2841 state
->split_start
++;
2843 state
->split_start
= 0;
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) {
2884 attr
= nla_nest_start(msg
, NL80211_ATTR_MAC_ADDRS
);
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
++;
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
++;
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
);
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
);
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
++;
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
);
2977 goto nla_put_failure
;
2980 while (bss_select_support
) {
2981 if ((bss_select_support
& 1) &&
2982 nla_put_flag(msg
, i
))
2983 goto nla_put_failure
;
2985 bss_select_support
>>= 1;
2987 nla_nest_end(msg
, nested
);
2990 state
->split_start
++;
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
);
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
,
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
&&
3023 NL80211_ATTR_EML_CAPABILITY
,
3024 capab
->eml_capabilities
) ||
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
);
3034 nla_nest_end(msg
, nested
);
3035 if (i
< rdev
->wiphy
.num_iftype_ext_capab
) {
3036 state
->capa_start
= i
+ 1;
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
= {};
3050 res
= rdev_get_txq_stats(rdev
, NULL
, &txqstats
);
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
++;
3070 if (nl80211_send_pmsr_capa(rdev
, msg
))
3071 goto nla_put_failure
;
3073 state
->split_start
++;
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
++;
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
++;
3111 if (nl80211_put_radios(&rdev
->wiphy
, msg
))
3112 goto nla_put_failure
;
3115 state
->split_start
= 0;
3119 genlmsg_end(msg
, hdr
);
3123 genlmsg_cancel(msg
, hdr
);
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
);
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 */
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
);
3162 if (netdev
->ieee80211_ptr
) {
3163 rdev
= wiphy_to_rdev(
3164 netdev
->ieee80211_ptr
->wiphy
);
3165 state
->filter_wiphy
= rdev
->wiphy_idx
;
3175 static int nl80211_dump_wiphy(struct sk_buff
*skb
, struct netlink_callback
*cb
)
3178 struct nl80211_dump_wiphy_state
*state
= (void *)cb
->args
[0];
3179 struct cfg80211_registered_device
*rdev
;
3183 state
= kzalloc(sizeof(*state
), GFP_KERNEL
);
3188 state
->filter_wiphy
= -1;
3189 ret
= nl80211_dump_wiphy_parse(skb
, cb
, state
);
3195 cb
->args
[0] = (long)state
;
3198 for_each_rdev(rdev
) {
3199 if (!net_eq(wiphy_net(&rdev
->wiphy
), sock_net(skb
->sk
)))
3201 if (++idx
<= state
->start
)
3203 if (state
->filter_wiphy
!= -1 &&
3204 state
->filter_wiphy
!= rdev
->wiphy_idx
)
3206 wiphy_lock(&rdev
->wiphy
);
3207 /* attempt to fit multiple wiphy data chunks into the skb */
3209 ret
= nl80211_send_wiphy(rdev
, NL80211_CMD_NEW_WIPHY
,
3211 NETLINK_CB(cb
->skb
).portid
,
3213 NLM_F_MULTI
, state
);
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
);
3240 } while (state
->split_start
> 0);
3241 wiphy_unlock(&rdev
->wiphy
);
3251 static int nl80211_dump_wiphy_done(struct netlink_callback
*cb
)
3253 kfree((void *)cb
->args
[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
);
3267 if (nl80211_send_wiphy(rdev
, NL80211_CMD_NEW_WIPHY
, msg
,
3268 info
->snd_portid
, info
->snd_seq
, 0,
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
)
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
])
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
)
3303 txq_params
->ac
= array_index_nospec(ac
, NL80211_NUM_ACS
);
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.
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
;
3339 if (!attrs
[NL80211_ATTR_WIPHY_FREQ
]) {
3340 NL_SET_ERR_MSG_ATTR(extack
, attrs
[NL80211_ATTR_WIPHY_FREQ
],
3341 "Frequency is missing");
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
])
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
],
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
]);
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
,
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");
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");
3394 NL_SET_ERR_MSG_ATTR(extack
,
3395 attrs
[NL80211_ATTR_WIPHY_CHANNEL_TYPE
],
3396 "invalid channel type");
3399 } else if (attrs
[NL80211_ATTR_CHANNEL_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");
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
]);
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");
3448 if (!cfg80211_chandef_valid(chandef
)) {
3449 NL_SET_ERR_MSG(extack
, "invalid channel definition");
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");
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");
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
,
3482 struct cfg80211_chan_def chandef
;
3484 enum nl80211_iftype iftype
= NL80211_IFTYPE_MONITOR
;
3485 struct wireless_dev
*wdev
= NULL
;
3486 int link_id
= _link_id
;
3489 wdev
= dev
->ieee80211_ptr
;
3490 if (!nl80211_can_set_dev_channel(wdev
))
3493 iftype
= wdev
->iftype
;
3496 if (wdev
&& wdev
->valid_links
)
3501 result
= _nl80211_parse_chandef(rdev
, info
,
3502 iftype
== NL80211_IFTYPE_MONITOR
,
3508 case NL80211_IFTYPE_AP
:
3509 case NL80211_IFTYPE_P2P_GO
:
3510 if (!cfg80211_reg_can_beacon_relax(&rdev
->wiphy
, &chandef
,
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
))
3521 /* Only allow dynamic channel width changes */
3522 cur_chan
= wdev
->links
[link_id
].ap
.chandef
.chan
;
3523 if (chandef
.chan
!= cur_chan
)
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
:
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
:
3553 result
= rdev_set_ap_chanwidth(rdev
, dev
, link_id
,
3557 wdev
->links
[link_id
].ap
.chandef
= chandef
;
3559 wdev
->u
.ap
.preset_chandef
= chandef
;
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
);
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
;
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;
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
);
3617 rdev
= __cfg80211_rdev_from_attrs(genl_info_net(info
),
3621 return PTR_ERR(rdev
);
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
]));
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
;
3658 if (netdev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_AP
&&
3659 netdev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_P2P_GO
) {
3664 if (!netif_running(netdev
)) {
3669 nla_for_each_nested(nl_txq_params
,
3670 info
->attrs
[NL80211_ATTR_WIPHY_TXQ_PARAMS
],
3672 result
= nla_parse_nested_deprecated(tb
,
3673 NL80211_TXQ_ATTR_MAX
,
3679 result
= parse_txq_params(tb
, &txq_params
);
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
)))
3690 else if (txq_params
.link_id
>= 0 &&
3691 !netdev
->ieee80211_ptr
->valid_links
)
3694 result
= rdev_set_txq_params(rdev
, netdev
,
3701 if (info
->attrs
[NL80211_ATTR_WIPHY_FREQ
]) {
3702 int link_id
= nl80211_link_id_or_invalid(info
->attrs
);
3705 result
= __nl80211_set_channel(
3707 nl80211_can_set_dev_channel(wdev
) ? netdev
: NULL
,
3710 result
= __nl80211_set_channel(rdev
, netdev
, info
, link_id
);
3717 if (info
->attrs
[NL80211_ATTR_WIPHY_TX_POWER_SETTING
]) {
3718 struct wireless_dev
*txp_wdev
= wdev
;
3719 enum nl80211_tx_power_setting type
;
3722 if (!(rdev
->wiphy
.features
& NL80211_FEATURE_VIF_TXPOWER
))
3725 if (!rdev
->ops
->set_tx_power
) {
3726 result
= -EOPNOTSUPP
;
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
)) {
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
);
3749 if (info
->attrs
[NL80211_ATTR_WIPHY_ANTENNA_TX
] &&
3750 info
->attrs
[NL80211_ATTR_WIPHY_ANTENNA_RX
]) {
3753 if ((!rdev
->wiphy
.available_antennas_tx
&&
3754 !rdev
->wiphy
.available_antennas_rx
) ||
3755 !rdev
->ops
->set_antenna
) {
3756 result
= -EOPNOTSUPP
;
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
))) {
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
);
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) {
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
]) {
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
;
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
;
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
;
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
;
3869 txq_quantum
= nla_get_u32(
3870 info
->attrs
[NL80211_ATTR_TXQ_QUANTUM
]);
3871 changed
|= WIPHY_PARAM_TXQ_QUANTUM
;
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
;
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
);
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
;
3928 wiphy_unlock(&rdev
->wiphy
);
3932 int nl80211_send_chandef(struct sk_buff
*msg
, const struct cfg80211_chan_def
*chandef
)
3934 if (WARN_ON(!cfg80211_chandef_valid(chandef
)))
3937 if (nla_put_u32(msg
, NL80211_ATTR_WIPHY_FREQ
,
3938 chandef
->chan
->center_freq
))
3940 if (nla_put_u32(msg
, NL80211_ATTR_WIPHY_FREQ_OFFSET
,
3941 chandef
->chan
->freq_offset
))
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
)))
3954 if (nla_put_u32(msg
, NL80211_ATTR_CHANNEL_WIDTH
, chandef
->width
))
3956 if (nla_put_u32(msg
, NL80211_ATTR_CENTER_FREQ1
, chandef
->center_freq1
))
3958 if (chandef
->center_freq2
&&
3959 nla_put_u32(msg
, NL80211_ATTR_CENTER_FREQ2
, chandef
->center_freq2
))
3961 if (chandef
->punctured
&&
3962 nla_put_u32(msg
, NL80211_ATTR_PUNCT_BITMAP
, chandef
->punctured
))
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
;
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
);
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
= {};
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
) {
4016 ret
= rdev_get_tx_power(rdev
, wdev
, &dbm
);
4018 nla_put_u32(msg
, NL80211_ATTR_WIPHY_TX_POWER_LEVEL
,
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
,
4029 goto nla_put_failure
;
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
;
4038 case NL80211_IFTYPE_ADHOC
:
4039 if (wdev
->u
.ibss
.ssid_len
&&
4040 nla_put(msg
, NL80211_ATTR_SSID
, wdev
->u
.ibss
.ssid_len
,
4042 goto nla_put_failure
;
4049 if (rdev
->ops
->get_txq_stats
) {
4050 struct cfg80211_txq_stats txqstats
= {};
4051 int ret
= rdev_get_txq_stats(rdev
, wdev
, &txqstats
);
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
);
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
= {};
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
);
4095 genlmsg_cancel(msg
, hdr
);
4099 static int nl80211_dump_interface(struct sk_buff
*skb
, struct netlink_callback
*cb
)
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
;
4112 struct nl80211_dump_wiphy_state state
= {
4116 ret
= nl80211_dump_wiphy_parse(skb
, cb
, &state
);
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;
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
)))
4137 if (wp_idx
< wp_start
) {
4142 if (filter_wiphy
>= 0 && filter_wiphy
!= rdev
->wiphy_idx
)
4147 wiphy_lock(&rdev
->wiphy
);
4148 list_for_each_entry(wdev
, &rdev
->wiphy
.wdev_list
, list
) {
4149 if (if_idx
< if_start
) {
4153 if (nl80211_send_iface(skb
, NETLINK_CB(cb
->skb
).portid
,
4154 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
4156 NL80211_CMD_NEW_INTERFACE
) < 0) {
4157 wiphy_unlock(&rdev
->wiphy
);
4162 wiphy_unlock(&rdev
->wiphy
);
4168 cb
->args
[0] = wp_idx
;
4169 cb
->args
[1] = if_idx
;
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
);
4188 if (nl80211_send_iface(msg
, info
->snd_portid
, info
->snd_seq
, 0,
4189 rdev
, wdev
, NL80211_CMD_NEW_INTERFACE
) < 0) {
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];
4217 if (nla_parse_nested_deprecated(flags
, NL80211_MNTR_FLAG_MAX
, nla
, mntr_flags_policy
, NULL
))
4220 for (flag
= 1; flag
<= NL80211_MNTR_FLAG_MAX
; flag
++)
4222 *mntrflags
|= (1<<flag
);
4224 *mntrflags
|= MONITOR_FLAG_CHANGED
;
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;
4237 if (info
->attrs
[NL80211_ATTR_MNTR_FLAGS
]) {
4238 if (type
!= NL80211_IFTYPE_MONITOR
)
4241 err
= parse_monitor_flags(info
->attrs
[NL80211_ATTR_MNTR_FLAGS
],
4249 if (params
->flags
& MONITOR_FLAG_ACTIVE
&&
4250 !(rdev
->wiphy
.features
& NL80211_FEATURE_ACTIVE_MONITOR
))
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
)
4260 if (!wiphy_ext_feature_isset(&rdev
->wiphy
, cap_flag
))
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)))
4271 params
->vht_mumimo_groups
= mumimo_groups
;
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
)
4281 if (!wiphy_ext_feature_isset(&rdev
->wiphy
, cap_flag
))
4284 params
->vht_mumimo_follow_addr
=
4285 nla_data(info
->attrs
[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR
]);
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
)
4297 if (netdev
&& netif_is_bridge_port(netdev
))
4303 case NL80211_IFTYPE_AP_VLAN
:
4304 if (rdev
->wiphy
.flags
& WIPHY_FLAG_4ADDR_AP
)
4307 case NL80211_IFTYPE_STATION
:
4308 if (rdev
->wiphy
.flags
& WIPHY_FLAG_4ADDR_STATION
)
4318 static int nl80211_parse_vif_radio_mask(struct genl_info
*info
,
4321 struct cfg80211_registered_device
*rdev
= info
->user_ptr
[0];
4322 struct nlattr
*attr
= info
->attrs
[NL80211_ATTR_VIF_RADIO_MASK
];
4330 allowed
= BIT(rdev
->wiphy
.n_radio
) - 1;
4331 mask
= nla_get_u32(attr
);
4332 if (mask
& ~allowed
)
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
;
4346 enum nl80211_iftype otype
, ntype
;
4347 struct net_device
*dev
= info
->user_ptr
[1];
4348 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
4350 bool change
= false;
4352 memset(¶ms
, 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
]);
4362 if (info
->attrs
[NL80211_ATTR_MESH_ID
]) {
4363 if (ntype
!= NL80211_IFTYPE_MESH_POINT
)
4365 if (otype
!= NL80211_IFTYPE_MESH_POINT
)
4367 if (netif_running(dev
))
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
]);
4380 err
= nl80211_valid_4addr(rdev
, dev
, params
.use_4addr
, ntype
);
4384 params
.use_4addr
= -1;
4387 err
= nl80211_parse_mon_options(rdev
, ntype
, info
, ¶ms
);
4393 err
= nl80211_parse_vif_radio_mask(info
, &radio_mask
);
4396 if (err
&& netif_running(dev
))
4400 err
= cfg80211_change_iface(rdev
, dev
, ntype
, ¶ms
);
4404 if (!err
&& params
.use_4addr
!= -1)
4405 dev
->ieee80211_ptr
->use_4addr
= params
.use_4addr
;
4408 wdev
->radio_mask
= radio_mask
;
4411 nl80211_notify_iface(rdev
, wdev
, NL80211_CMD_SET_INTERFACE
);
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
;
4424 enum nl80211_iftype type
= NL80211_IFTYPE_UNSPECIFIED
;
4426 memset(¶ms
, 0, sizeof(params
));
4428 if (!info
->attrs
[NL80211_ATTR_IFNAME
])
4431 if (info
->attrs
[NL80211_ATTR_IFTYPE
])
4432 type
= nla_get_u32(info
->attrs
[NL80211_ATTR_IFTYPE
]);
4434 if (!rdev
->ops
->add_virtual_intf
)
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
],
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
);
4453 if (!cfg80211_iftype_allowed(&rdev
->wiphy
, type
, params
.use_4addr
, 0))
4456 err
= nl80211_parse_mon_options(rdev
, type
, info
, ¶ms
);
4460 err
= nl80211_parse_vif_radio_mask(info
, &radio_mask
);
4464 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4468 wdev
= rdev_add_virtual_intf(rdev
,
4469 nla_data(info
->attrs
[NL80211_ATTR_IFNAME
]),
4470 NET_NAME_USER
, type
, ¶ms
);
4471 if (WARN_ON(!wdev
)) {
4474 } else if (IS_ERR(wdev
)) {
4476 return PTR_ERR(wdev
);
4479 if (info
->attrs
[NL80211_ATTR_SOCKET_OWNER
])
4480 wdev
->owner_nlportid
= info
->snd_portid
;
4483 case NL80211_IFTYPE_MESH_POINT
:
4484 if (!info
->attrs
[NL80211_ATTR_MESH_ID
])
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
);
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
);
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) {
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];
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
);
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
)
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.
4559 info
->user_ptr
[1] = NULL
;
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];
4574 if (!info
->attrs
[NL80211_ATTR_NOACK_MAP
])
4577 if (!rdev
->ops
->set_noack_map
)
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
)
4590 if (link_id
!= -1) {
4591 GENL_SET_ERR_MSG(info
,
4592 "link ID not allowed for pairwise key");
4599 if (wdev
->valid_links
) {
4600 if (link_id
== -1) {
4601 GENL_SET_ERR_MSG(info
,
4602 "link ID must for MLO group key");
4605 if (!(wdev
->valid_links
& BIT(link_id
))) {
4606 GENL_SET_ERR_MSG(info
, "invalid link ID for MLO group key");
4609 } else if (link_id
!= -1) {
4610 GENL_SET_ERR_MSG(info
, "link ID not allowed for non-MLO group key");
4617 struct get_key_cookie
{
4618 struct sk_buff
*msg
;
4623 static void get_key_callback(void *c
, struct key_params
*params
)
4626 struct get_key_cookie
*cookie
= c
;
4629 nla_put(cookie
->msg
, NL80211_ATTR_KEY_SEQ
,
4630 params
->seq_len
, params
->seq
)) ||
4632 nla_put_u32(cookie
->msg
, NL80211_ATTR_KEY_CIPHER
,
4634 goto nla_put_failure
;
4636 key
= nla_nest_start_noflag(cookie
->msg
, NL80211_ATTR_KEY
);
4638 goto nla_put_failure
;
4641 nla_put(cookie
->msg
, NL80211_KEY_SEQ
,
4642 params
->seq_len
, params
->seq
)) ||
4644 nla_put_u32(cookie
->msg
, NL80211_KEY_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
);
4658 static int nl80211_get_key(struct sk_buff
*skb
, struct genl_info
*info
)
4660 struct cfg80211_registered_device
*rdev
= info
->user_ptr
[0];
4662 struct net_device
*dev
= info
->user_ptr
[1];
4664 const u8
*mac_addr
= NULL
;
4666 struct get_key_cookie cookie
= {
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");
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
)
4704 pairwise
= kt
== NL80211_KEYTYPE_PAIRWISE
;
4707 if (!rdev
->ops
->get_key
)
4710 if (!pairwise
&& mac_addr
&& !(rdev
->wiphy
.flags
& WIPHY_FLAG_IBSS_RSN
))
4713 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
4717 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
4718 NL80211_CMD_NEW_KEY
);
4720 goto nla_put_failure
;
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
;
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
);
4736 err
= rdev_get_key(rdev
, dev
, link_id
, key_idx
, pairwise
, mac_addr
,
4737 &cookie
, get_key_callback
);
4743 goto nla_put_failure
;
4745 genlmsg_end(msg
, hdr
);
4746 return genlmsg_reply(msg
, info
);
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
;
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
);
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
))
4779 if (!rdev
->ops
->set_default_key
)
4782 err
= nl80211_key_allowed(wdev
);
4786 err
= nl80211_validate_key_link_id(info
, wdev
, link_id
, false);
4790 err
= rdev_set_default_key(rdev
, dev
, link_id
, key
.idx
,
4791 key
.def_uni
, key
.def_multi
);
4796 #ifdef CONFIG_CFG80211_WEXT
4797 wdev
->wext
.default_key
= key
.idx
;
4800 } else if (key
.defmgmt
) {
4801 if (key
.def_uni
|| !key
.def_multi
)
4804 if (!rdev
->ops
->set_default_mgmt_key
)
4807 err
= nl80211_key_allowed(wdev
);
4811 err
= nl80211_validate_key_link_id(info
, wdev
, link_id
, false);
4815 err
= rdev_set_default_mgmt_key(rdev
, dev
, link_id
, key
.idx
);
4819 #ifdef CONFIG_CFG80211_WEXT
4820 wdev
->wext
.default_mgmt_key
= key
.idx
;
4823 } else if (key
.defbeacon
) {
4824 if (key
.def_uni
|| !key
.def_multi
)
4827 if (!rdev
->ops
->set_default_beacon_key
)
4830 err
= nl80211_key_allowed(wdev
);
4834 err
= nl80211_validate_key_link_id(info
, wdev
, link_id
, false);
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)
4850 err
= nl80211_validate_key_link_id(info
, wdev
, link_id
, true);
4854 return rdev_add_key(rdev
, dev
, link_id
, key
.idx
,
4855 NL80211_KEYTYPE_PAIRWISE
,
4862 static int nl80211_new_key(struct sk_buff
*skb
, struct genl_info
*info
)
4864 struct cfg80211_registered_device
*rdev
= info
->user_ptr
[0];
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
);
4877 GENL_SET_ERR_MSG(info
, "no key");
4881 if (info
->attrs
[NL80211_ATTR_MAC
])
4882 mac_addr
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
4884 if (key
.type
== -1) {
4886 key
.type
= NL80211_KEYTYPE_PAIRWISE
;
4888 key
.type
= NL80211_KEYTYPE_GROUP
;
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");
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
)
4905 if (cfg80211_validate_key_settings(rdev
, &key
.p
, key
.idx
,
4906 key
.type
== NL80211_KEYTYPE_PAIRWISE
,
4908 GENL_SET_ERR_MSG(info
, "key setting validation failed");
4912 err
= nl80211_key_allowed(wdev
);
4914 GENL_SET_ERR_MSG(info
, "key not allowed");
4917 err
= nl80211_validate_key_link_id(info
, wdev
, link_id
,
4918 key
.type
== NL80211_KEYTYPE_PAIRWISE
);
4921 err
= rdev_add_key(rdev
, dev
, link_id
, key
.idx
,
4922 key
.type
== NL80211_KEYTYPE_PAIRWISE
,
4925 GENL_SET_ERR_MSG(info
, "key addition failed");
4931 static int nl80211_del_key(struct sk_buff
*skb
, struct genl_info
*info
)
4933 struct cfg80211_registered_device
*rdev
= info
->user_ptr
[0];
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
);
4945 if (info
->attrs
[NL80211_ATTR_MAC
])
4946 mac_addr
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
4948 if (key
.type
== -1) {
4950 key
.type
= NL80211_KEYTYPE_PAIRWISE
;
4952 key
.type
= NL80211_KEYTYPE_GROUP
;
4956 if (key
.type
!= NL80211_KEYTYPE_PAIRWISE
&&
4957 key
.type
!= NL80211_KEYTYPE_GROUP
)
4960 if (!cfg80211_valid_key_idx(rdev
, key
.idx
,
4961 key
.type
== NL80211_KEYTYPE_PAIRWISE
))
4964 if (!rdev
->ops
->del_key
)
4967 err
= nl80211_key_allowed(wdev
);
4969 if (key
.type
== NL80211_KEYTYPE_GROUP
&& mac_addr
&&
4970 !(rdev
->wiphy
.flags
& WIPHY_FLAG_IBSS_RSN
))
4974 err
= nl80211_validate_key_link_id(info
, wdev
, link_id
,
4975 key
.type
== NL80211_KEYTYPE_PAIRWISE
);
4978 err
= rdev_del_key(rdev
, dev
, link_id
, key
.idx
,
4979 key
.type
== NL80211_KEYTYPE_PAIRWISE
,
4982 #ifdef CONFIG_CFG80211_WEXT
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;
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
)
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
]);
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
);
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
);
5053 acl
->acl_policy
= acl_policy
;
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
;
5065 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_AP
&&
5066 dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_P2P_GO
)
5069 if (!dev
->ieee80211_ptr
->links
[0].ap
.beacon_interval
)
5072 acl
= parse_acl_data(&rdev
->wiphy
, info
);
5074 return PTR_ERR(acl
);
5076 err
= rdev_set_mac_acl(rdev
, dev
, acl
);
5083 static u32
rateset_to_mask(struct ieee80211_supported_band
*sband
,
5084 u8
*rates
, u8 rates_len
)
5089 for (i
= 0; i
< rates_len
; i
++) {
5090 int rate
= (rates
[i
] & 0x7f) * 5;
5093 for (ridx
= 0; ridx
< sband
->n_bitrates
; ridx
++) {
5094 struct ieee80211_rate
*srate
=
5095 &sband
->bitrates
[ridx
];
5096 if (rate
== srate
->bitrate
) {
5101 if (ridx
== sband
->n_bitrates
)
5102 return 0; /* rate not found */
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
])
5114 memset(mcs
, 0, IEEE80211_HT_MCS_MASK_LEN
);
5116 for (i
= 0; i
< rates_len
; i
++) {
5119 ridx
= rates
[i
] / 8;
5120 rbit
= BIT(rates
[i
] % 8);
5122 /* check validity */
5123 if ((ridx
< 0) || (ridx
>= IEEE80211_HT_MCS_MASK_LEN
))
5126 /* check availability */
5127 ridx
= array_index_nospec(ridx
, IEEE80211_HT_MCS_MASK_LEN
);
5128 if (sband
->ht_cap
.mcs
.rx_mask
[ridx
] & rbit
)
5137 static u16
vht_mcs_map_to_mcs_mask(u8 vht_mcs_map
)
5141 switch (vht_mcs_map
) {
5142 case IEEE80211_VHT_MCS_NOT_SUPPORTED
:
5144 case IEEE80211_VHT_MCS_SUPPORT_0_7
:
5147 case IEEE80211_VHT_MCS_SUPPORT_0_8
:
5150 case IEEE80211_VHT_MCS_SUPPORT_0_9
:
5160 static void vht_build_mcs_mask(u16 vht_mcs_map
,
5161 u16 vht_mcs_mask
[NL80211_VHT_NSS_MAX
])
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);
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
] = {};
5179 if (!sband
->vht_cap
.vht_supported
)
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
];
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
:
5202 case IEEE80211_HE_MCS_SUPPORT_0_7
:
5204 case IEEE80211_HE_MCS_SUPPORT_0_9
:
5206 case IEEE80211_HE_MCS_SUPPORT_0_11
:
5214 static void he_build_mcs_mask(u16 he_mcs_map
,
5215 u16 he_mcs_mask
[NL80211_HE_NSS_MAX
])
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);
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
;
5233 chandef
= wdev_chandef(wdev
, link_id
);
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
;
5246 case NL80211_CHAN_WIDTH_160
:
5247 tx_mcs
= he_cap
->he_mcs_nss_supp
.tx_mcs_160
;
5250 tx_mcs
= he_cap
->he_mcs_nss_supp
.tx_mcs_80
;
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
] = {};
5269 he_cap
= ieee80211_get_he_iftype_cap(sband
, wdev
->iftype
);
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
];
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
;
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
)
5314 sband
= rdev
->wiphy
.bands
[i
];
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
);
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 */
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
);
5352 if (band
< 0 || band
>= NUM_NL80211_BANDS
)
5354 sband
= rdev
->wiphy
.bands
[band
];
5357 err
= nla_parse_nested_deprecated(tb
, NL80211_TXRATE_MAX
,
5359 nl80211_txattr_policy
,
5363 if (tb
[NL80211_TXRATE_LEGACY
]) {
5364 mask
->control
[band
].legacy
= rateset_to_mask(
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
]))
5372 if (tb
[NL80211_TXRATE_HT
]) {
5373 if (!ht_rateset_to_mask(
5375 nla_data(tb
[NL80211_TXRATE_HT
]),
5376 nla_len(tb
[NL80211_TXRATE_HT
]),
5377 mask
->control
[band
].ht_mcs
))
5381 if (tb
[NL80211_TXRATE_VHT
]) {
5382 if (!vht_set_mcs_mask(
5384 nla_data(tb
[NL80211_TXRATE_VHT
]),
5385 mask
->control
[band
].vht_mcs
))
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
)
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
,
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
)))
5418 for (i
= 0; i
< IEEE80211_HT_MCS_MASK_LEN
; i
++)
5419 if (mask
->control
[band
].ht_mcs
[i
])
5422 for (i
= 0; i
< NL80211_VHT_NSS_MAX
; i
++)
5423 if (mask
->control
[band
].vht_mcs
[i
])
5426 for (i
= 0; i
< NL80211_HE_NSS_MAX
; i
++)
5427 if (mask
->control
[band
].he_mcs
[i
])
5430 /* legacy and mcs rates may not be both empty */
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)
5451 for (i
= 0; i
< IEEE80211_HT_MCS_MASK_LEN
; i
++) {
5452 if (hweight8(beacon_rate
->control
[band
].ht_mcs
[i
]) > 1) {
5454 } else if (beacon_rate
->control
[band
].ht_mcs
[i
]) {
5459 if (count_ht
&& rate
)
5464 for (i
= 0; i
< NL80211_VHT_NSS_MAX
; i
++) {
5465 if (hweight16(beacon_rate
->control
[band
].vht_mcs
[i
]) > 1) {
5467 } else if (beacon_rate
->control
[band
].vht_mcs
[i
]) {
5472 if (count_vht
&& rate
)
5477 for (i
= 0; i
< NL80211_HE_NSS_MAX
; i
++) {
5478 if (hweight16(beacon_rate
->control
[band
].he_mcs
[i
]) > 1) {
5480 } else if (beacon_rate
->control
[band
].he_mcs
[i
]) {
5485 if (count_he
&& rate
)
5489 if ((count_ht
&& count_vht
&& count_he
) ||
5490 (!rate
&& !count_ht
&& !count_vht
&& !count_he
))
5494 !wiphy_ext_feature_isset(&rdev
->wiphy
,
5495 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY
))
5498 !wiphy_ext_feature_isset(&rdev
->wiphy
,
5499 NL80211_EXT_FEATURE_BEACON_RATE_HT
))
5502 !wiphy_ext_feature_isset(&rdev
->wiphy
,
5503 NL80211_EXT_FEATURE_BEACON_RATE_VHT
))
5506 !wiphy_ext_feature_isset(&rdev
->wiphy
,
5507 NL80211_EXT_FEATURE_BEACON_RATE_HE
))
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
,
5519 struct nlattr
*tb
[NL80211_MBSSID_CONFIG_ATTR_MAX
+ 1];
5521 if (!wiphy
->mbssid_max_interfaces
)
5524 if (nla_parse_nested(tb
, NL80211_MBSSID_CONFIG_ATTR_MAX
, attrs
, NULL
,
5526 !tb
[NL80211_MBSSID_CONFIG_ATTR_INDEX
])
5529 config
->ema
= nla_get_flag(tb
[NL80211_MBSSID_CONFIG_ATTR_EMA
]);
5531 if (!wiphy
->ema_max_profile_periodicity
)
5534 if (num_elems
> wiphy
->ema_max_profile_periodicity
)
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
))
5543 if (tb
[NL80211_MBSSID_CONFIG_ATTR_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
))
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
) {
5563 config
->tx_wdev
= tx_netdev
->ieee80211_ptr
;
5565 config
->tx_wdev
= dev
->ieee80211_ptr
;
5567 } else if (!config
->index
) {
5568 config
->tx_wdev
= dev
->ieee80211_ptr
;
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
;
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
);
5593 elems
= kzalloc(struct_size(elems
, elem
, num_elems
), GFP_KERNEL
);
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
);
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
;
5613 u8 i
= 0, num_elems
= 0;
5615 nla_for_each_nested(nl_elems
, attrs
, rem_elems
) {
5618 ret
= validate_ie_attr(nl_elems
, extack
);
5620 return ERR_PTR(ret
);
5625 elems
= kzalloc(struct_size(elems
, elem
, num_elems
), GFP_KERNEL
);
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
);
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];
5644 err
= nla_parse_nested(tb
, NL80211_HE_BSS_COLOR_ATTR_MAX
, attrs
,
5645 he_bss_color_policy
, NULL
);
5649 if (!tb
[NL80211_HE_BSS_COLOR_ATTR_COLOR
])
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
]);
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;
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
]);
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
]);
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
],
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;
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
]);
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
);
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
]);
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
],
5770 return PTR_ERR(rnr
);
5772 if (rnr
&& rnr
->cnt
< bcn
->mbssid_ies
->cnt
)
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];
5788 err
= nla_parse_nested(tb
, NL80211_HE_OBSS_PD_ATTR_MAX
, attrs
,
5789 he_obss_pd_policy
, NULL
);
5793 if (!tb
[NL80211_HE_OBSS_PD_ATTR_SR_CTRL
])
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
)
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;
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];
5833 if (!wiphy_ext_feature_isset(&rdev
->wiphy
,
5834 NL80211_EXT_FEATURE_FILS_DISCOVERY
))
5837 ret
= nla_parse_nested(tb
, NL80211_FILS_DISCOVERY_ATTR_MAX
, attrs
,
5842 if (!tb
[NL80211_FILS_DISCOVERY_ATTR_INT_MIN
] &&
5843 !tb
[NL80211_FILS_DISCOVERY_ATTR_INT_MAX
] &&
5844 !tb
[NL80211_FILS_DISCOVERY_ATTR_TMPL
]) {
5849 if (!tb
[NL80211_FILS_DISCOVERY_ATTR_INT_MIN
] ||
5850 !tb
[NL80211_FILS_DISCOVERY_ATTR_INT_MAX
] ||
5851 !tb
[NL80211_FILS_DISCOVERY_ATTR_TMPL
])
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
]);
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];
5870 if (!wiphy_ext_feature_isset(&rdev
->wiphy
,
5871 NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP
))
5874 ret
= nla_parse_nested(tb
, NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX
,
5879 if (!tb
[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT
] &&
5880 !tb
[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL
]) {
5881 presp
->update
= true;
5885 if (!tb
[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT
] ||
5886 !tb
[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL
])
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;
5896 static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings
*params
,
5897 const struct element
*rates
)
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
= ¶ms
->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
);
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))
5957 cap
= cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_OPERATION
, ies
, ies_len
);
5961 params
->eht_oper
= (void *)(cap
->data
+ 1);
5962 if (!ieee80211_eht_oper_size_ok((const u8
*)params
->eht_oper
,
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
)
5979 if (!wdev
->u
.ap
.preset_chandef
.chan
)
5982 params
->chandef
= wdev
->u
.ap
.preset_chandef
;
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
)
5997 case NL80211_CMD_AUTHENTICATE
:
5998 if (!(rdev
->wiphy
.features
& NL80211_FEATURE_SAE
) &&
5999 auth_type
== NL80211_AUTHTYPE_SAE
)
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
))
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
)
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
)
6019 if (!wiphy_ext_feature_isset(
6021 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD
) &&
6022 auth_type
== NL80211_AUTHTYPE_FILS_SK
)
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
)
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
)
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
;
6049 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
6053 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_START_AP
);
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
)))
6068 genlmsg_end(msg
, hdr
);
6070 genlmsg_multicast_netns(&nl80211_fam
, wiphy_net(wiphy
), msg
, 0,
6071 NL80211_MCGRP_MLME
, GFP_KERNEL
);
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
))
6085 if ((params
->eht_cap
|| params
->eht_oper
) &&
6086 (channel
->flags
& IEEE80211_CHAN_NO_EHT
))
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
;
6102 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_AP
&&
6103 dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_P2P_GO
)
6106 if (!rdev
->ops
->start_ap
)
6109 if (wdev
->links
[link_id
].cac_started
)
6112 if (wdev
->links
[link_id
].ap
.beacon_interval
)
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
])
6121 if (info
->attrs
[NL80211_ATTR_SMPS_MODE
] &&
6122 nla_get_u8(info
->attrs
[NL80211_ATTR_SMPS_MODE
]) != NL80211_SMPS_OFF
)
6125 params
= kzalloc(sizeof(*params
), GFP_KERNEL
);
6129 err
= nl80211_parse_beacon(rdev
, info
->attrs
, ¶ms
->beacon
,
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
);
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
]);
6154 nla_len(info
->attrs
[NL80211_ATTR_SSID
]);
6155 if (params
->ssid_len
== 0) {
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 */
6167 } else if (wdev
->valid_links
) {
6168 /* require SSID for MLO */
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
)) {
6188 params
->auth_type
= NL80211_AUTHTYPE_AUTOMATIC
;
6190 err
= nl80211_crypto_settings(rdev
, info
, ¶ms
->crypto
,
6191 NL80211_MAX_NR_CIPHER_SUITES
);
6195 if (info
->attrs
[NL80211_ATTR_INACTIVITY_TIMEOUT
]) {
6196 if (!(rdev
->wiphy
.features
& NL80211_FEATURE_INACTIVITY_TIMER
)) {
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
) {
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
)) {
6218 if (info
->attrs
[NL80211_ATTR_P2P_OPPPS
]) {
6221 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_P2P_GO
) {
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
)) {
6234 if (info
->attrs
[NL80211_ATTR_WIPHY_FREQ
]) {
6235 err
= nl80211_parse_chandef(rdev
, info
, ¶ms
->chandef
);
6238 } else if (wdev
->valid_links
) {
6239 /* with MLD need to specify the channel configuration */
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
)) {
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
, ¶ms
->chandef
,
6260 if (info
->attrs
[NL80211_ATTR_TX_RATES
]) {
6261 err
= nl80211_parse_tx_bitrate_mask(info
, info
->attrs
,
6262 NL80211_ATTR_TX_RATES
,
6263 ¶ms
->beacon_rate
,
6264 dev
, false, link_id
);
6268 err
= validate_beacon_tx_rate(rdev
, params
->chandef
.chan
->band
,
6269 ¶ms
->beacon_rate
);
6274 params
->pbss
= nla_get_flag(info
->attrs
[NL80211_ATTR_PBSS
]);
6275 if (params
->pbss
&& !rdev
->wiphy
.bands
[NL80211_BAND_60GHZ
]) {
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
);
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 ¶ms
->he_obss_pd
);
6300 if (info
->attrs
[NL80211_ATTR_FILS_DISCOVERY
]) {
6301 err
= nl80211_parse_fils_discovery(rdev
,
6302 info
->attrs
[NL80211_ATTR_FILS_DISCOVERY
],
6303 ¶ms
->fils_discovery
);
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 ¶ms
->unsol_bcast_probe_resp
);
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 ¶ms
->mbssid_config
,
6320 params
->beacon
.mbssid_ies
?
6321 params
->beacon
.mbssid_ies
->cnt
:
6327 if (!params
->mbssid_config
.ema
&& params
->beacon
.rnr_ies
) {
6332 err
= nl80211_calculate_ap_params(params
);
6336 err
= nl80211_validate_ap_phy_operation(params
);
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
) {
6353 /* FIXME: validate MLO/link-id against driver capabilities */
6355 err
= rdev_start_ap(rdev
, dev
, params
);
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
,
6363 if (info
->attrs
[NL80211_ATTR_SOCKET_OWNER
])
6364 wdev
->conn_owner_nlportid
= info
->snd_portid
;
6366 nl80211_send_ap_started(wdev
, link_id
);
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
);
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
;
6392 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_AP
&&
6393 dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_P2P_GO
)
6396 if (!rdev
->ops
->change_beacon
)
6399 if (!wdev
->links
[link_id
].ap
.beacon_interval
)
6402 params
= kzalloc(sizeof(*params
), GFP_KERNEL
);
6406 err
= nl80211_parse_beacon(rdev
, info
->attrs
, ¶ms
->beacon
,
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
,
6424 attr
= info
->attrs
[NL80211_ATTR_FILS_DISCOVERY
];
6426 err
= nl80211_parse_fils_discovery(rdev
, attr
,
6427 ¶ms
->fils_discovery
);
6432 attr
= info
->attrs
[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP
];
6434 err
= nl80211_parse_unsol_bcast_probe_resp(rdev
, attr
,
6435 ¶ms
->unsol_bcast_probe_resp
);
6440 err
= rdev_change_beacon(rdev
, dev
, params
);
6443 kfree(params
->beacon
.mbssid_ies
);
6444 kfree(params
->beacon
.rnr_ies
);
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];
6476 * Try parsing the new attribute first so userspace
6477 * can specify both for older kernels.
6479 nla
= info
->attrs
[NL80211_ATTR_STA_FLAGS2
];
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
))
6493 /* if present, parse the old attribute */
6495 nla
= info
->attrs
[NL80211_ATTR_STA_FLAGS
];
6499 if (nla_parse_nested_deprecated(flags
, NL80211_STA_FLAG_MAX
, nla
, sta_flags_policy
, info
->extack
))
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.
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
);
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
);
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
);
6531 for (flag
= 1; flag
<= NL80211_STA_FLAG_MAX
; 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
)
6544 bool nl80211_put_sta_rate(struct sk_buff
*msg
, struct rate_info
*info
, int attr
)
6546 struct nlattr
*rate
;
6549 enum nl80211_rate_info rate_flg
;
6551 rate
= nla_nest_start_noflag(msg
, attr
);
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;
6560 nla_put_u32(msg
, NL80211_RATE_INFO_BITRATE32
, bitrate
))
6562 if (bitrate_compat
> 0 &&
6563 nla_put_u16(msg
, NL80211_RATE_INFO_BITRATE
, bitrate_compat
))
6567 case RATE_INFO_BW_1
:
6568 rate_flg
= NL80211_RATE_INFO_1_MHZ_WIDTH
;
6570 case RATE_INFO_BW_2
:
6571 rate_flg
= NL80211_RATE_INFO_2_MHZ_WIDTH
;
6573 case RATE_INFO_BW_4
:
6574 rate_flg
= NL80211_RATE_INFO_4_MHZ_WIDTH
;
6576 case RATE_INFO_BW_5
:
6577 rate_flg
= NL80211_RATE_INFO_5_MHZ_WIDTH
;
6579 case RATE_INFO_BW_8
:
6580 rate_flg
= NL80211_RATE_INFO_8_MHZ_WIDTH
;
6582 case RATE_INFO_BW_10
:
6583 rate_flg
= NL80211_RATE_INFO_10_MHZ_WIDTH
;
6585 case RATE_INFO_BW_16
:
6586 rate_flg
= NL80211_RATE_INFO_16_MHZ_WIDTH
;
6591 case RATE_INFO_BW_20
:
6594 case RATE_INFO_BW_40
:
6595 rate_flg
= NL80211_RATE_INFO_40_MHZ_WIDTH
;
6597 case RATE_INFO_BW_80
:
6598 rate_flg
= NL80211_RATE_INFO_80_MHZ_WIDTH
;
6600 case RATE_INFO_BW_160
:
6601 rate_flg
= NL80211_RATE_INFO_160_MHZ_WIDTH
;
6603 case RATE_INFO_BW_HE_RU
:
6605 WARN_ON(!(info
->flags
& RATE_INFO_FLAGS_HE_MCS
));
6607 case RATE_INFO_BW_320
:
6608 rate_flg
= NL80211_RATE_INFO_320_MHZ_WIDTH
;
6610 case RATE_INFO_BW_EHT_RU
:
6612 WARN_ON(!(info
->flags
& RATE_INFO_FLAGS_EHT_MCS
));
6616 if (rate_flg
&& nla_put_flag(msg
, rate_flg
))
6619 if (info
->flags
& RATE_INFO_FLAGS_MCS
) {
6620 if (nla_put_u8(msg
, NL80211_RATE_INFO_MCS
, info
->mcs
))
6622 if (info
->flags
& RATE_INFO_FLAGS_SHORT_GI
&&
6623 nla_put_flag(msg
, NL80211_RATE_INFO_SHORT_GI
))
6625 } else if (info
->flags
& RATE_INFO_FLAGS_VHT_MCS
) {
6626 if (nla_put_u8(msg
, NL80211_RATE_INFO_VHT_MCS
, info
->mcs
))
6628 if (nla_put_u8(msg
, NL80211_RATE_INFO_VHT_NSS
, info
->nss
))
6630 if (info
->flags
& RATE_INFO_FLAGS_SHORT_GI
&&
6631 nla_put_flag(msg
, NL80211_RATE_INFO_SHORT_GI
))
6633 } else if (info
->flags
& RATE_INFO_FLAGS_HE_MCS
) {
6634 if (nla_put_u8(msg
, NL80211_RATE_INFO_HE_MCS
, info
->mcs
))
6636 if (nla_put_u8(msg
, NL80211_RATE_INFO_HE_NSS
, info
->nss
))
6638 if (nla_put_u8(msg
, NL80211_RATE_INFO_HE_GI
, info
->he_gi
))
6640 if (nla_put_u8(msg
, NL80211_RATE_INFO_HE_DCM
, info
->he_dcm
))
6642 if (info
->bw
== RATE_INFO_BW_HE_RU
&&
6643 nla_put_u8(msg
, NL80211_RATE_INFO_HE_RU_ALLOC
,
6646 } else if (info
->flags
& RATE_INFO_FLAGS_S1G_MCS
) {
6647 if (nla_put_u8(msg
, NL80211_RATE_INFO_S1G_MCS
, info
->mcs
))
6649 if (nla_put_u8(msg
, NL80211_RATE_INFO_S1G_NSS
, info
->nss
))
6651 if (info
->flags
& RATE_INFO_FLAGS_SHORT_GI
&&
6652 nla_put_flag(msg
, NL80211_RATE_INFO_SHORT_GI
))
6654 } else if (info
->flags
& RATE_INFO_FLAGS_EHT_MCS
) {
6655 if (nla_put_u8(msg
, NL80211_RATE_INFO_EHT_MCS
, info
->mcs
))
6657 if (nla_put_u8(msg
, NL80211_RATE_INFO_EHT_NSS
, info
->nss
))
6659 if (nla_put_u8(msg
, NL80211_RATE_INFO_EHT_GI
, info
->eht_gi
))
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
))
6667 nla_nest_end(msg
, rate
);
6671 static bool nl80211_put_signal(struct sk_buff
*msg
, u8 mask
, s8
*signal
,
6680 attr
= nla_nest_start_noflag(msg
, id
);
6684 for (i
= 0; i
< IEEE80211_MAX_CHAINS
; i
++) {
6685 if (!(mask
& BIT(i
)))
6688 if (nla_put_u8(msg
, i
, signal
[i
]))
6692 nla_nest_end(msg
, attr
);
6697 static int nl80211_send_station(struct sk_buff
*msg
, u32 cmd
, u32 portid
,
6699 struct cfg80211_registered_device
*rdev
,
6700 struct net_device
*dev
,
6701 const u8
*mac_addr
, struct station_info
*sinfo
)
6704 struct nlattr
*sinfoattr
, *bss_param
;
6706 hdr
= nl80211hdr_put(msg
, portid
, seq
, flags
, cmd
);
6708 cfg80211_sinfo_release_content(sinfo
);
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
);
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, \
6726 goto nla_put_failure; \
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; \
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
);
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
);
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
),
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
);
6846 #undef PUT_SINFO_U64
6848 if (sinfo
->pertid
) {
6849 struct nlattr
*tidsattr
;
6852 tidsattr
= nla_nest_start_noflag(msg
,
6853 NL80211_STA_INFO_TID_STATS
);
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
)
6866 tidattr
= nla_nest_start_noflag(msg
, tid
+ 1);
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; \
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
,
6915 goto nla_put_failure
;
6918 cfg80211_sinfo_release_content(sinfo
);
6919 genlmsg_end(msg
, hdr
);
6923 cfg80211_sinfo_release_content(sinfo
);
6924 genlmsg_cancel(msg
, hdr
);
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];
6938 err
= nl80211_prepare_wdev_dump(cb
, &rdev
, &wdev
, NULL
);
6941 /* nl80211_prepare_wdev_dump acquired it in the successful case */
6942 __acquire(&rdev
->wiphy
.mtx
);
6944 if (!wdev
->netdev
) {
6949 if (!rdev
->ops
->dump_station
) {
6955 memset(&sinfo
, 0, sizeof(sinfo
));
6956 err
= rdev_dump_station(rdev
, wdev
->netdev
, sta_idx
,
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
,
6974 cb
->args
[2] = sta_idx
;
6977 wiphy_unlock(&rdev
->wiphy
);
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
;
6991 memset(&sinfo
, 0, sizeof(sinfo
));
6993 if (!info
->attrs
[NL80211_ATTR_MAC
])
6996 mac_addr
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
6998 if (!rdev
->ops
->get_station
)
7001 err
= rdev_get_station(rdev
, dev
, mac_addr
, &sinfo
);
7005 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
7007 cfg80211_sinfo_release_content(&sinfo
);
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) {
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
)
7029 if (params
->support_p2p_ps
!= -1 &&
7030 statype
!= CFG80211_STA_AP_CLIENT_UNASSOC
)
7034 !(params
->sta_flags_set
& BIT(NL80211_STA_FLAG_TDLS_PEER
)) &&
7035 statype
!= CFG80211_STA_AP_CLIENT_UNASSOC
)
7038 /* When you run into this, adjust the code below for the new flag */
7039 BUILD_BUG_ON(NL80211_STA_FLAG_MAX
!= 8);
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
7049 if (params
->sta_flags_mask
&
7050 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED
) |
7051 BIT(NL80211_STA_FLAG_MFP
) |
7052 BIT(NL80211_STA_FLAG_AUTHORIZED
)))
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
)))
7059 /* ignore since it can't change */
7060 params
->sta_flags_mask
&= ~BIT(NL80211_STA_FLAG_TDLS_PEER
);
7063 /* disallow mesh-specific things */
7064 if (params
->plink_action
!= NL80211_PLINK_ACTION_NO_ACTION
)
7066 if (params
->local_pm
)
7068 if (params
->sta_modify_mask
& STATION_PARAM_APPLY_PLINK_STATE
)
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
))
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
)
7090 if (params
->sta_modify_mask
& STATION_PARAM_APPLY_CAPABILITY
)
7092 if (params
->link_sta_params
.supported_rates
)
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
)
7099 if (params
->sta_flags_mask
& BIT(NL80211_STA_FLAG_SPP_AMSDU
))
7103 if (statype
!= CFG80211_STA_AP_CLIENT
&&
7104 statype
!= CFG80211_STA_AP_CLIENT_UNASSOC
) {
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
)))
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
)))
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
)))
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
))
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
)))
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
)
7151 case CFG80211_STA_TDLS_PEER_ACTIVE
:
7152 /* reject any changes */
7154 case CFG80211_STA_MESH_PEER_KERNEL
:
7155 if (params
->sta_modify_mask
& STATION_PARAM_APPLY_PLINK_STATE
)
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
)
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;
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
;
7191 v
= dev_get_by_index(genl_info_net(info
), nla_get_u32(vlanattr
));
7193 return ERR_PTR(-ENODEV
);
7195 if (!v
->ieee80211_ptr
|| v
->ieee80211_ptr
->wiphy
!= &rdev
->wiphy
) {
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
) {
7207 if (!netif_running(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];
7225 /* parse WME attributes if present */
7226 if (!info
->attrs
[NL80211_ATTR_STA_WME
])
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
,
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
)
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
)
7248 params
->sta_modify_mask
|= STATION_PARAM_APPLY_UAPSD
;
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)
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
]);
7279 static int nl80211_set_station_tdls(struct genl_info
*info
,
7280 struct station_parameters
*params
)
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
,
7312 err
= nl80211_parse_sta_channel_info(info
, params
);
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
,
7323 struct cfg80211_registered_device
*rdev
= info
->user_ptr
[0];
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
))
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
]);
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
;
7360 memset(¶ms
, 0, sizeof(params
));
7362 if (!rdev
->ops
->change_station
)
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
]);
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
]);
7386 params
.support_p2p_ps
= -1;
7388 if (!info
->attrs
[NL80211_ATTR_MAC
])
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)
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
))
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
]) {
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
]) {
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
, ¶ms
))
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
))
7473 err
= nl80211_parse_sta_txpower_setting(info
,
7474 ¶ms
.link_sta_params
.txpwr
,
7475 ¶ms
.link_sta_params
.txpwr_set
);
7479 /* Include parameters for TDLS peer (will check later) */
7480 err
= nl80211_set_station_tdls(info
, ¶ms
);
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
:
7502 /* driver will call cfg80211_check_station_change() */
7503 err
= rdev_change_station(rdev
, dev
, mac_addr
, ¶ms
);
7506 dev_put(params
.vlan
);
7511 static int nl80211_new_station(struct sk_buff
*skb
, struct genl_info
*info
)
7513 struct cfg80211_registered_device
*rdev
= info
->user_ptr
[0];
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(¶ms
, 0, sizeof(params
));
7524 if (!rdev
->ops
->add_station
)
7527 if (!info
->attrs
[NL80211_ATTR_MAC
])
7530 if (!info
->attrs
[NL80211_ATTR_STA_LISTEN_INTERVAL
])
7533 if (!info
->attrs
[NL80211_ATTR_STA_SUPPORTED_RATES
])
7536 if (!info
->attrs
[NL80211_ATTR_STA_AID
] &&
7537 !info
->attrs
[NL80211_ATTR_PEER_AID
])
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
))
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
]);
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
]);
7579 params
.aid
= nla_get_u16(info
->attrs
[NL80211_ATTR_STA_AID
]);
7581 if (info
->attrs
[NL80211_ATTR_STA_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
]) {
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
,
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
))
7645 err
= nl80211_parse_sta_txpower_setting(info
,
7646 ¶ms
.link_sta_params
.txpwr
,
7647 ¶ms
.link_sta_params
.txpwr_set
);
7651 err
= nl80211_parse_sta_channel_info(info
, ¶ms
);
7655 err
= nl80211_parse_sta_wme(info
, ¶ms
);
7659 if (parse_station_flags(info
, dev
->ieee80211_ptr
->iftype
, ¶ms
))
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
)
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
))
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
])
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
)
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
))
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
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
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
);
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
))
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
])
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
)))
7755 /* Only TDLS peers can be added */
7756 if (!(params
.sta_flags_set
& BIT(NL80211_STA_FLAG_TDLS_PEER
)))
7758 /* Can only add if TDLS ... */
7759 if (!(rdev
->wiphy
.flags
& WIPHY_FLAG_SUPPORTS_TDLS
))
7761 /* ... with external setup is supported */
7762 if (!(rdev
->wiphy
.flags
& WIPHY_FLAG_TDLS_EXTERNAL_SETUP
))
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
);
7774 /* be aware of params.vlan when changing code here */
7776 if (wdev
->valid_links
) {
7777 if (params
.link_sta_params
.link_id
< 0) {
7781 if (!(wdev
->valid_links
& BIT(params
.link_sta_params
.link_id
))) {
7786 if (params
.link_sta_params
.link_id
>= 0) {
7791 err
= rdev_add_station(rdev
, dev
, mac_addr
, ¶ms
);
7793 dev_put(params
.vlan
);
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(¶ms
, 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 */
7817 case NL80211_IFTYPE_ADHOC
:
7818 /* conditionally accept */
7819 if (wiphy_ext_feature_isset(&rdev
->wiphy
,
7820 NL80211_EXT_FEATURE_DEL_IBSS_STA
))
7827 if (!rdev
->ops
->del_station
)
7830 if (info
->attrs
[NL80211_ATTR_MGMT_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)
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 */
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)
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
)))
7860 params
.link_id
= link_id
;
7862 return rdev_del_station(rdev
, dev
, ¶ms
);
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
)
7871 struct nlattr
*pinfoattr
;
7873 hdr
= nl80211hdr_put(msg
, portid
, seq
, flags
, NL80211_CMD_NEW_MPATH
);
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
);
7885 goto nla_put_failure
;
7886 if ((pinfo
->filled
& MPATH_INFO_FRAME_QLEN
) &&
7887 nla_put_u32(msg
, NL80211_MPATH_INFO_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
,
7895 ((pinfo
->filled
& MPATH_INFO_EXPTIME
) &&
7896 nla_put_u32(msg
, NL80211_MPATH_INFO_EXPTIME
,
7898 ((pinfo
->filled
& MPATH_INFO_FLAGS
) &&
7899 nla_put_u8(msg
, NL80211_MPATH_INFO_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
);
7921 genlmsg_cancel(msg
, hdr
);
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
;
7932 u8 next_hop
[ETH_ALEN
];
7933 int path_idx
= cb
->args
[2];
7936 err
= nl80211_prepare_wdev_dump(cb
, &rdev
, &wdev
, NULL
);
7939 /* nl80211_prepare_wdev_dump acquired it in the successful case */
7940 __acquire(&rdev
->wiphy
.mtx
);
7942 if (!rdev
->ops
->dump_mpath
) {
7947 if (wdev
->iftype
!= NL80211_IFTYPE_MESH_POINT
) {
7953 err
= rdev_dump_mpath(rdev
, wdev
->netdev
, path_idx
, dst
,
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
,
7970 cb
->args
[2] = path_idx
;
7973 wiphy_unlock(&rdev
->wiphy
);
7977 static int nl80211_get_mpath(struct sk_buff
*skb
, struct genl_info
*info
)
7979 struct cfg80211_registered_device
*rdev
= info
->user_ptr
[0];
7981 struct net_device
*dev
= info
->user_ptr
[1];
7982 struct mpath_info pinfo
;
7983 struct sk_buff
*msg
;
7985 u8 next_hop
[ETH_ALEN
];
7987 memset(&pinfo
, 0, sizeof(pinfo
));
7989 if (!info
->attrs
[NL80211_ATTR_MAC
])
7992 dst
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
7994 if (!rdev
->ops
->get_mpath
)
7997 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_MESH_POINT
)
8000 err
= rdev_get_mpath(rdev
, dev
, dst
, next_hop
, &pinfo
);
8004 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8008 if (nl80211_send_mpath(msg
, info
->snd_portid
, info
->snd_seq
, 0,
8009 dev
, dst
, next_hop
, &pinfo
) < 0) {
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];
8022 u8
*next_hop
= NULL
;
8024 if (!info
->attrs
[NL80211_ATTR_MAC
])
8027 if (!info
->attrs
[NL80211_ATTR_MPATH_NEXT_HOP
])
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
)
8036 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_MESH_POINT
)
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];
8047 u8
*next_hop
= NULL
;
8049 if (!info
->attrs
[NL80211_ATTR_MAC
])
8052 if (!info
->attrs
[NL80211_ATTR_MPATH_NEXT_HOP
])
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
)
8061 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_MESH_POINT
)
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];
8073 if (info
->attrs
[NL80211_ATTR_MAC
])
8074 dst
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
8076 if (!rdev
->ops
->del_mpath
)
8079 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_MESH_POINT
)
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];
8089 struct net_device
*dev
= info
->user_ptr
[1];
8090 struct mpath_info pinfo
;
8091 struct sk_buff
*msg
;
8095 memset(&pinfo
, 0, sizeof(pinfo
));
8097 if (!info
->attrs
[NL80211_ATTR_MAC
])
8100 dst
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
8102 if (!rdev
->ops
->get_mpp
)
8105 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_MESH_POINT
)
8108 err
= rdev_get_mpp(rdev
, dev
, dst
, mpp
, &pinfo
);
8112 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8116 if (nl80211_send_mpath(msg
, info
->snd_portid
, info
->snd_seq
, 0,
8117 dev
, dst
, mpp
, &pinfo
) < 0) {
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
;
8133 int path_idx
= cb
->args
[2];
8136 err
= nl80211_prepare_wdev_dump(cb
, &rdev
, &wdev
, NULL
);
8139 /* nl80211_prepare_wdev_dump acquired it in the successful case */
8140 __acquire(&rdev
->wiphy
.mtx
);
8142 if (!rdev
->ops
->dump_mpp
) {
8147 if (wdev
->iftype
!= NL80211_IFTYPE_MESH_POINT
) {
8153 err
= rdev_dump_mpp(rdev
, wdev
->netdev
, path_idx
, dst
,
8160 if (nl80211_send_mpath(skb
, NETLINK_CB(cb
->skb
).portid
,
8161 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
8162 wdev
->netdev
, dst
, mpp
,
8170 cb
->args
[2] = path_idx
;
8173 wiphy_unlock(&rdev
->wiphy
);
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(¶ms
, 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
])
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
)
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
))
8225 if (info
->attrs
[NL80211_ATTR_P2P_OPPPS
]) {
8228 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_P2P_GO
)
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
))
8237 if (!rdev
->ops
->change_bss
)
8240 if (dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_AP
&&
8241 dev
->ieee80211_ptr
->iftype
!= NL80211_IFTYPE_P2P_GO
)
8244 return rdev_change_bss(rdev
, dev
, ¶ms
);
8247 static int nl80211_req_set_reg(struct sk_buff
*skb
, struct genl_info
*info
)
8251 enum nl80211_user_reg_hint_type user_reg_hint_type
;
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
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
])
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
];
8284 regulatory_hint_indoor(is_indoor
, owner_nlportid
);
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
;
8305 struct nlattr
*pinfoattr
;
8306 struct sk_buff
*msg
;
8308 if (wdev
->iftype
!= NL80211_IFTYPE_MESH_POINT
)
8311 if (!rdev
->ops
->get_mesh_config
)
8314 /* If not connected, get default parameters */
8315 if (!wdev
->u
.mesh
.id_len
)
8316 memcpy(&cur_params
, &default_mesh_config
, sizeof(cur_params
));
8318 err
= rdev_get_mesh_config(rdev
, dev
, &cur_params
);
8323 /* Draw up a netlink message to send back */
8324 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8327 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
8328 NL80211_CMD_GET_MESH_CONFIG
);
8331 pinfoattr
= nla_nest_start_noflag(msg
, NL80211_ATTR_MESH_CONFIG
);
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
);
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
,
8476 struct nlattr
*tb
[NL80211_MESHCONF_ATTR_MAX
+ 1];
8480 #define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, mask, attr, fn) \
8483 cfg->param = fn(tb[attr]); \
8484 mask |= BIT((attr) - 1); \
8488 if (!info
->attrs
[NL80211_ATTR_MESH_CONFIG
])
8490 if (nla_parse_nested_deprecated(tb
, NL80211_MESHCONF_ATTR_MAX
, info
->attrs
[NL80211_ATTR_MESH_CONFIG
], nl80211_meshconf_params_policy
, info
->extack
))
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
,
8503 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshHoldingTimeout
, mask
,
8504 NL80211_MESHCONF_HOLDING_TIMEOUT
,
8506 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshMaxPeerLinks
, mask
,
8507 NL80211_MESHCONF_MAX_PEER_LINKS
,
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
,
8518 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshNbrOffsetMaxNeighbor
,
8520 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR
,
8522 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshHWMPmaxPREQretries
, mask
,
8523 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES
,
8525 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, path_refresh_time
, mask
,
8526 NL80211_MESHCONF_PATH_REFRESH_TIME
,
8528 if (mask
& BIT(NL80211_MESHCONF_PATH_REFRESH_TIME
) &&
8529 (cfg
->path_refresh_time
< 1 || cfg
->path_refresh_time
> 65535))
8531 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, min_discovery_timeout
, mask
,
8532 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT
,
8534 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshHWMPactivePathTimeout
,
8536 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT
,
8538 if (mask
& BIT(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT
) &&
8539 (cfg
->dot11MeshHWMPactivePathTimeout
< 1 ||
8540 cfg
->dot11MeshHWMPactivePathTimeout
> 65535))
8542 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshHWMPpreqMinInterval
, mask
,
8543 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL
,
8545 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshHWMPperrMinInterval
, mask
,
8546 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL
,
8548 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
,
8549 dot11MeshHWMPnetDiameterTraversalTime
, mask
,
8550 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME
,
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
,
8557 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshGateAnnouncementProtocol
,
8558 mask
, NL80211_MESHCONF_GATE_ANNOUNCEMENTS
,
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
,
8565 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshConnectedToMeshGate
, mask
,
8566 NL80211_MESHCONF_CONNECTED_TO_GATE
,
8568 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshConnectedToAuthServer
, mask
,
8569 NL80211_MESHCONF_CONNECTED_TO_AS
,
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
))
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
,
8593 if (mask
& BIT(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT
) &&
8594 (cfg
->dot11MeshHWMPactivePathToRootTimeout
< 1 ||
8595 cfg
->dot11MeshHWMPactivePathToRootTimeout
> 65535))
8597 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshHWMProotInterval
, mask
,
8598 NL80211_MESHCONF_HWMP_ROOT_INTERVAL
,
8600 FILL_IN_MESH_PARAM_IF_SET(tb
, cfg
, dot11MeshHWMPconfirmationInterval
,
8602 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL
,
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
);
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
])
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
))
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
))
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
)
8668 nla_get_u8(tb
[NL80211_MESH_SETUP_AUTH_PROTOCOL
]);
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
= {};
8684 if (wdev
->iftype
!= NL80211_IFTYPE_MESH_POINT
)
8687 if (!rdev
->ops
->update_mesh_config
)
8690 err
= nl80211_parse_mesh_config(info
, &cfg
, &mask
);
8694 if (!wdev
->u
.mesh
.id_len
)
8698 err
= rdev_update_mesh_config(rdev
, dev
, mask
, &cfg
);
8703 static int nl80211_put_regdom(const struct ieee80211_regdomain
*regdom
,
8704 struct sk_buff
*msg
)
8706 struct nlattr
*nl_reg_rules
;
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
);
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
= ®dom
->reg_rules
[i
];
8726 freq_range
= ®_rule
->freq_range
;
8727 power_rule
= ®_rule
->power_rule
;
8729 nl_reg_rule
= nla_nest_start_noflag(msg
, i
);
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
,
8738 if (nla_put_u32(msg
, NL80211_ATTR_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
,
8757 goto nla_put_failure
;
8759 nla_nest_end(msg
, nl_reg_rule
);
8762 nla_nest_end(msg
, nl_reg_rules
);
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
;
8778 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
8782 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
8783 NL80211_CMD_GET_REG
);
8789 if (info
->attrs
[NL80211_ATTR_WIPHY
]) {
8792 rdev
= cfg80211_get_dev_from_info(genl_info_net(info
), info
);
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
;
8804 regdom
= get_wiphy_regdom(wiphy
);
8806 /* a self-managed-reg device must have a private regdom */
8807 if (WARN_ON(!regdom
&& self_managed
)) {
8809 goto nla_put_failure_rcu
;
8813 nla_put_u32(msg
, NL80211_ATTR_WIPHY
, get_wiphy_idx(wiphy
)))
8814 goto nla_put_failure_rcu
;
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
;
8825 regdom
= rcu_dereference(cfg80211_regdomain
);
8827 if (nl80211_put_regdom(regdom
, msg
))
8828 goto nla_put_failure_rcu
;
8832 genlmsg_end(msg
, hdr
);
8834 return genlmsg_reply(msg
, info
);
8836 nla_put_failure_rcu
:
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
);
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
;
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
);
8877 genlmsg_cancel(msg
, hdr
);
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];
8890 if (cfg80211_regdomain
&& start
== 0) {
8891 err
= nl80211_send_regdom(skb
, cb
, cb
->nlh
->nlmsg_seq
,
8893 rcu_dereference(cfg80211_regdomain
));
8898 /* the global regdom is idx 0 */
8900 list_for_each_entry_rcu(rdev
, &cfg80211_rdev_list
, list
) {
8901 regdom
= get_wiphy_regdom(&rdev
->wiphy
);
8905 if (++reg_idx
<= start
)
8908 err
= nl80211_send_regdom(skb
, cb
, cb
->nlh
->nlmsg_seq
,
8909 NLM_F_MULTI
, &rdev
->wiphy
, regdom
);
8916 cb
->args
[2] = reg_idx
;
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
= ®_rule
->freq_range
;
8938 struct ieee80211_power_rule
*power_rule
= ®_rule
->power_rule
;
8940 if (!tb
[NL80211_ATTR_REG_RULE_FLAGS
])
8942 if (!tb
[NL80211_ATTR_FREQ_RANGE_START
])
8944 if (!tb
[NL80211_ATTR_FREQ_RANGE_END
])
8946 if (!tb
[NL80211_ATTR_FREQ_RANGE_MAX_BW
])
8948 if (!tb
[NL80211_ATTR_POWER_RULE_MAX_EIRP
])
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
]);
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
;
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
])
8987 if (!info
->attrs
[NL80211_ATTR_REG_RULES
])
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
],
8998 if (num_rules
> NL80211_MAX_SUPP_REG_RULES
)
9003 if (!reg_is_valid_request(alpha2
)) {
9008 rd
= kzalloc(struct_size(rd
, reg_rules
, num_rules
), GFP_KERNEL
);
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
],
9027 r
= nla_parse_nested_deprecated(tb
, NL80211_REG_RULE_ATTR_MAX
,
9028 nl_reg_rule
, reg_rule_policy
,
9032 r
= parse_reg_rule(tb
, &rd
->reg_rules
[rule_idx
]);
9038 if (rule_idx
> NL80211_MAX_SUPP_REG_RULES
) {
9044 r
= set_regdom(rd
, REGD_SOURCE_CRDA
);
9045 /* set_regdom takes ownership of rd */
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
))
9064 nla_for_each_nested(attr1
, freqs
, tmp1
) {
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
))
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
;
9098 /* only process one nested attribute */
9099 nest
= nla_data(nla
);
9100 if (!nla_ok(nest
, nla_len(nest
)))
9103 err
= nla_parse_nested_deprecated(attr
, NL80211_BSS_SELECT_ATTR_MAX
,
9104 nest
, nl80211_bss_select_policy
,
9109 /* only one attribute may be given */
9110 for (i
= 0; i
<= NL80211_BSS_SELECT_ATTR_MAX
; i
++) {
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
))
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
))
9142 /* user-space did not provide behaviour attribute */
9143 if (bss_select
->behaviour
== __NL80211_BSS_SELECT_ATTR_INVALID
)
9146 if (!(wiphy
->bss_select_support
& BIT(bss_select
->behaviour
)))
9152 int nl80211_parse_random_mac(struct nlattr
**attrs
,
9153 u8
*mac_addr
, u8
*mac_addr_mask
)
9157 if (!attrs
[NL80211_ATTR_MAC
] && !attrs
[NL80211_ATTR_MAC_MASK
]) {
9158 eth_zero_addr(mac_addr
);
9159 eth_zero_addr(mac_addr_mask
);
9161 mac_addr_mask
[0] = 0x3;
9166 /* need both or none */
9167 if (!attrs
[NL80211_ATTR_MAC
] || !attrs
[NL80211_ATTR_MAC_MASK
])
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
))
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
9183 for (i
= 0; i
< ETH_ALEN
; i
++)
9184 mac_addr
[i
] &= mac_addr_mask
[i
];
9189 static bool cfg80211_off_channel_oper_allowed(struct wireless_dev
*wdev
,
9190 struct ieee80211_channel
*chan
)
9192 unsigned int link_id
;
9195 lockdep_assert_wiphy(wdev
->wiphy
);
9197 if (!cfg80211_wdev_channel_allowed(wdev
, chan
))
9200 if (!cfg80211_beaconing_iface_active(wdev
))
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
)
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
)
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
))
9240 if (wiphy_ext_feature_isset(wiphy
, feat
))
9246 nl80211_check_scan_flags(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
9247 void *request
, struct nlattr
**attrs
,
9250 u8
*mac_addr
, *mac_addr_mask
;
9252 enum nl80211_feature_flags randomness_flag
;
9254 if (!attrs
[NL80211_ATTR_SCAN_FLAGS
])
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
;
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
))
9308 if (*flags
& NL80211_SCAN_FLAG_RANDOM_ADDR
) {
9311 if (!(wiphy
->features
& randomness_flag
) ||
9312 (wdev
&& wdev
->connected
))
9315 err
= nl80211_parse_random_mac(attrs
, mac_addr
, mac_addr_mask
);
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
)
9341 if (!rdev
->ops
->scan
)
9344 if (rdev
->scan_req
|| rdev
->scan_msg
)
9347 if (info
->attrs
[NL80211_ATTR_SCAN_FREQ_KHZ
]) {
9348 if (!wiphy_ext_feature_isset(wiphy
,
9349 NL80211_EXT_FEATURE_SCAN_FREQ_KHZ
))
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
];
9357 n_channels
= validate_scan_freqs(scan_freqs
);
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
)
9368 if (n_ssids
> wiphy
->max_scan_ssids
)
9371 if (info
->attrs
[NL80211_ATTR_IE
])
9372 ie_len
= nla_len(info
->attrs
[NL80211_ATTR_IE
]);
9376 if (ie_len
> wiphy
->max_scan_ie_len
)
9379 size
= struct_size(request
, channels
, n_channels
);
9380 ssids_offset
= size
;
9381 size
= size_add(size
, array_size(sizeof(*request
->ssids
), n_ssids
));
9383 size
= size_add(size
, ie_len
);
9384 request
= kzalloc(size
, GFP_KERNEL
);
9387 request
->n_channels
= n_channels
;
9390 request
->ssids
= (void *)request
+ ssids_offset
;
9391 request
->n_ssids
= n_ssids
;
9393 request
->ie
= (void *)request
+ ie_offset
;
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
);
9411 /* ignore disabled channels */
9412 if (chan
->flags
& IEEE80211_CHAN_DISABLED
||
9413 !cfg80211_wdev_channel_allowed(wdev
, chan
))
9416 request
->channels
[i
] = chan
;
9420 enum nl80211_band band
;
9423 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
9426 if (!wiphy
->bands
[band
])
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
))
9437 request
->channels
[i
] = chan
;
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
))
9457 if (!cfg80211_wdev_on_sub_chan(wdev
, chan
, true)) {
9465 nla_for_each_nested(attr
, info
->attrs
[NL80211_ATTR_SCAN_SSIDS
], tmp
) {
9466 if (nla_len(attr
) > IEEE80211_MAX_SSID_LEN
) {
9470 request
->ssids
[i
].ssid_len
= nla_len(attr
);
9471 memcpy(request
->ssids
[i
].ssid
, nla_data(attr
), nla_len(attr
));
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
]),
9483 for (i
= 0; i
< NUM_NL80211_BANDS
; i
++)
9484 if (wiphy
->bands
[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
],
9492 enum nl80211_band band
= nla_type(attr
);
9494 if (band
< 0 || band
>= NUM_NL80211_BANDS
) {
9499 if (!wiphy
->bands
[band
])
9502 err
= ieee80211_get_ratemask(wiphy
->bands
[band
],
9505 &request
->rates
[band
]);
9511 if (info
->attrs
[NL80211_ATTR_MEASUREMENT_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
,
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
]),
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
);
9556 nl80211_send_scan_start(rdev
, wdev
);
9557 dev_hold(wdev
->netdev
);
9562 rdev
->scan_req
= NULL
;
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
)
9579 if (!rdev
->scan_req
)
9582 rdev_abort_scan(rdev
, wdev
);
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
]) {
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
]);
9607 request
->scan_plans
[0].interval
=
9608 DIV_ROUND_UP(interval
, MSEC_PER_SEC
);
9609 if (!request
->scan_plans
[0].interval
)
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
;
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
))
9626 err
= nla_parse_nested_deprecated(plan
,
9627 NL80211_SCHED_SCAN_PLAN_MAX
,
9628 attr
, nl80211_plan_policy
,
9633 if (!plan
[NL80211_SCHED_SCAN_PLAN_INTERVAL
])
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
)
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
))
9650 } else if (i
< n_plans
- 1) {
9652 * All scan plans but the last one must specify
9653 * a finite number of iterations
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
)
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
]);
9687 return ERR_PTR(-EINVAL
);
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
],
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
],
9713 struct nlattr
*rssi
;
9715 err
= nla_parse_nested_deprecated(tb
,
9716 NL80211_SCHED_SCAN_MATCH_ATTR_MAX
,
9718 nl80211_match_policy
,
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
]) {
9734 rssi
= tb
[NL80211_SCHED_SCAN_MATCH_ATTR_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
)
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
]);
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
)
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
);
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
),
9792 size
= size_add(size
, array_size(sizeof(*request
->scan_plans
),
9794 size
= size_add(size
, ie_len
);
9795 request
= kzalloc(size
, GFP_KERNEL
);
9797 return ERR_PTR(-ENOMEM
);
9798 request
->n_channels
= n_channels
;
9801 request
->ssids
= (void *)request
+
9802 struct_size(request
, channels
, n_channels
);
9803 request
->n_ssids
= n_ssids
;
9806 request
->ie
= (void *)(request
->ssids
+ n_ssids
);
9808 request
->ie
= (void *)(request
->channels
+ n_channels
);
9813 request
->match_sets
= (void *)(request
->ie
+ ie_len
);
9815 request
->match_sets
=
9816 (void *)(request
->ssids
+ n_ssids
);
9818 request
->match_sets
=
9819 (void *)(request
->channels
+ n_channels
);
9821 request
->n_match_sets
= n_match_sets
;
9824 request
->scan_plans
= (void *)(request
->match_sets
+
9826 else if (request
->ie
)
9827 request
->scan_plans
= (void *)(request
->ie
+ ie_len
);
9829 request
->scan_plans
= (void *)(request
->ssids
+ n_ssids
);
9831 request
->scan_plans
= (void *)(request
->channels
+ n_channels
);
9833 request
->n_scan_plans
= n_plans
;
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
],
9841 struct ieee80211_channel
*chan
;
9843 chan
= ieee80211_get_channel(wiphy
, nla_get_u32(attr
));
9850 /* ignore disabled channels */
9851 if (chan
->flags
& IEEE80211_CHAN_DISABLED
)
9854 request
->channels
[i
] = chan
;
9859 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
9862 if (!wiphy
->bands
[band
])
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
)
9872 request
->channels
[i
] = chan
;
9883 request
->n_channels
= i
;
9887 nla_for_each_nested(attr
, attrs
[NL80211_ATTR_SCAN_SSIDS
],
9889 if (nla_len(attr
) > IEEE80211_MAX_SSID_LEN
) {
9893 request
->ssids
[i
].ssid_len
= nla_len(attr
);
9894 memcpy(request
->ssids
[i
].ssid
, nla_data(attr
),
9901 if (attrs
[NL80211_ATTR_SCHED_SCAN_MATCH
]) {
9902 nla_for_each_nested(attr
,
9903 attrs
[NL80211_ATTR_SCHED_SCAN_MATCH
],
9905 struct nlattr
*ssid
, *bssid
, *rssi
;
9907 err
= nla_parse_nested_deprecated(tb
,
9908 NL80211_SCHED_SCAN_MATCH_ATTR_MAX
,
9910 nl80211_match_policy
,
9914 ssid
= tb
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID
];
9915 bssid
= tb
[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID
];
9917 if (!ssid
&& !bssid
) {
9922 if (WARN_ON(i
>= n_match_sets
)) {
9923 /* this indicates a programming error,
9924 * the loop above should have verified
9932 memcpy(request
->match_sets
[i
].ssid
.ssid
,
9933 nla_data(ssid
), nla_len(ssid
));
9934 request
->match_sets
[i
].ssid
.ssid_len
=
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
];
9945 request
->match_sets
[i
].rssi_thold
=
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
);
9960 request
->min_rssi_thold
= NL80211_SCAN_RSSI_THOLD_OFF
;
9964 request
->ie_len
= ie_len
;
9965 memcpy((void *)request
->ie
,
9966 nla_data(attrs
[NL80211_ATTR_IE
]),
9970 err
= nl80211_check_scan_flags(wiphy
, wdev
, request
, attrs
, true);
9974 if (attrs
[NL80211_ATTR_SCHED_SCAN_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
)) {
9998 err
= nl80211_parse_sched_scan_plans(wiphy
, n_plans
, request
, attrs
);
10002 request
->scan_start
= jiffies
;
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
;
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
);
10029 sched_scan_req
= nl80211_parse_sched_scan(&rdev
->wiphy
, wdev
,
10031 rdev
->wiphy
.max_match_sets
);
10033 err
= PTR_ERR_OR_ZERO(sched_scan_req
);
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
);
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
);
10059 kfree(sched_scan_req
);
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];
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
,
10082 if (!req
|| req
->reqid
||
10083 (req
->owner_nlportid
&&
10084 req
->owner_nlportid
!= info
->snd_portid
))
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
;
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
:
10112 /* caution - see cfg80211_beaconing_iface_active() below */
10118 dfs_region
= reg_get_dfs_region(wiphy
);
10119 if (dfs_region
== NL80211_DFS_UNSET
)
10122 err
= nl80211_parse_chandef(rdev
, info
, &chandef
);
10126 err
= cfg80211_chandef_dfs_required(wiphy
, &chandef
, wdev
->iftype
);
10135 if (!cfg80211_chandef_dfs_usable(wiphy
, &chandef
)) {
10140 if (nla_get_flag(info
->attrs
[NL80211_ATTR_RADAR_BACKGROUND
])) {
10141 err
= cfg80211_start_background_radar_detection(rdev
, wdev
,
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
) {
10159 if (wdev
->links
[link_id
].cac_started
) {
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
)) {
10170 if (!rdev
->ops
->start_radar_detection
) {
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
,
10182 switch (wdev
->iftype
) {
10183 case NL80211_IFTYPE_AP
:
10184 case NL80211_IFTYPE_P2P_GO
:
10185 wdev
->links
[0].ap
.chandef
= chandef
;
10187 case NL80211_IFTYPE_ADHOC
:
10188 wdev
->u
.ibss
.chandef
= chandef
;
10190 case NL80211_IFTYPE_MESH_POINT
:
10191 wdev
->u
.mesh
.chandef
= chandef
;
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
;
10201 wiphy_unlock(wiphy
);
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
;
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");
10224 err
= nl80211_parse_chandef(rdev
, info
, &chandef
);
10226 GENL_SET_ERR_MSG(info
, "Unable to extract chandef info");
10230 err
= cfg80211_chandef_dfs_required(wiphy
, &chandef
, wdev
->iftype
);
10232 GENL_SET_ERR_MSG(info
, "chandef is invalid");
10237 GENL_SET_ERR_MSG(info
,
10238 "Unexpected Radar indication for chandef/iftype");
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
)
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
);
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
)
10272 if (!nla_len(attr
) || (nla_len(attr
) % sizeof(u16
)))
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
))
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
)
10289 if (first_count
!= -1 && data
[offset
] != first_count
)
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
;
10305 bool need_new_beacon
= false;
10306 bool need_handle_dfs_flag
= true;
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
)
10328 case NL80211_IFTYPE_ADHOC
:
10329 if (!wdev
->u
.ibss
.ssid_len
)
10332 case NL80211_IFTYPE_MESH_POINT
:
10333 if (!wdev
->u
.mesh
.id_len
)
10337 return -EOPNOTSUPP
;
10340 memset(¶ms
, 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
])
10347 /* only important for AP, IBSS and mesh create IEs internally */
10348 if (need_new_beacon
&& !info
->attrs
[NL80211_ATTR_CSA_IES
])
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)
10358 params
.count
= cs_count
;
10360 if (!need_new_beacon
)
10363 err
= nl80211_parse_beacon(rdev
, info
->attrs
, ¶ms
.beacon_after
,
10368 csa_attrs
= kcalloc(NL80211_ATTR_MAX
+ 1, sizeof(*csa_attrs
),
10375 err
= nla_parse_nested_deprecated(csa_attrs
, NL80211_ATTR_MAX
,
10376 info
->attrs
[NL80211_ATTR_CSA_IES
],
10377 nl80211_policy
, info
->extack
);
10381 err
= nl80211_parse_beacon(rdev
, csa_attrs
, ¶ms
.beacon_csa
,
10386 if (!csa_attrs
[NL80211_ATTR_CNTDWN_OFFS_BEACON
]) {
10391 err
= nl80211_parse_counter_offsets(rdev
, params
.beacon_csa
.tail
,
10392 params
.beacon_csa
.tail_len
,
10394 csa_attrs
[NL80211_ATTR_CNTDWN_OFFS_BEACON
],
10395 ¶ms
.counter_offsets_beacon
,
10396 ¶ms
.n_counter_offsets_beacon
);
10400 err
= nl80211_parse_counter_offsets(rdev
, params
.beacon_csa
.probe_resp
,
10401 params
.beacon_csa
.probe_resp_len
,
10403 csa_attrs
[NL80211_ATTR_CNTDWN_OFFS_PRESP
],
10404 ¶ms
.counter_offsets_presp
,
10405 ¶ms
.n_counter_offsets_presp
);
10410 err
= nl80211_parse_chandef(rdev
, info
, ¶ms
.chandef
);
10414 if (!cfg80211_reg_can_beacon_relax(&rdev
->wiphy
, ¶ms
.chandef
,
10420 err
= cfg80211_chandef_dfs_required(wdev
->wiphy
,
10427 params
.radar_required
= true;
10428 if (need_handle_dfs_flag
&&
10429 !nla_get_flag(info
->attrs
[NL80211_ATTR_HANDLE_DFS
])) {
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
, ¶ms
);
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
);
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
;
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
);
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
),
10478 goto nla_put_failure
;
10480 bss
= nla_nest_start_noflag(msg
, NL80211_ATTR_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
;
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
);
10498 if (nla_put_u64_64bit(msg
, NL80211_BSS_TSF
, ies
->tsf
,
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
,
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
;
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
,
10551 goto nla_put_failure
;
10553 case CFG80211_SIGNAL_TYPE_UNSPEC
:
10554 if (nla_put_u8(msg
, NL80211_BSS_SIGNAL_UNSPEC
,
10556 goto nla_put_failure
;
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
,
10573 nla_put(msg
, NL80211_BSS_MLD_ADDR
, ETH_ALEN
,
10574 wdev
->u
.client
.connected_addr
)))))
10575 goto nla_put_failure
;
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
;
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
,
10595 goto nla_put_failure
;
10597 nla_nest_end(msg
, bss
);
10599 genlmsg_end(msg
, hdr
);
10605 genlmsg_cancel(msg
, hdr
);
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
;
10619 attrbuf
= kcalloc(NUM_NL80211_ATTR
, sizeof(*attrbuf
), GFP_KERNEL
);
10623 err
= nl80211_prepare_wdev_dump(cb
, &rdev
, &wdev
, attrbuf
);
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
];
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.
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
)
10651 if (!dump_include_use_data
&&
10652 !(scan
->pub
.use_for
& NL80211_BSS_USE_FOR_NORMAL
))
10654 if (nl80211_send_bss(skb
, cb
,
10655 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
10656 rdev
, wdev
, scan
) < 0) {
10662 spin_unlock_bh(&rdev
->bss_lock
);
10665 wiphy_unlock(&rdev
->wiphy
);
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
)
10676 struct nlattr
*infoattr
;
10678 /* skip radio stats if userspace didn't request them */
10679 if (!survey
->channel
&& !allow_radio_stats
)
10682 hdr
= nl80211hdr_put(msg
, portid
, seq
, flags
,
10683 NL80211_CMD_NEW_SURVEY_RESULTS
);
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
);
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
);
10745 genlmsg_cancel(msg
, hdr
);
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];
10759 attrbuf
= kcalloc(NUM_NL80211_ATTR
, sizeof(*attrbuf
), GFP_KERNEL
);
10763 res
= nl80211_prepare_wdev_dump(cb
, &rdev
, &wdev
, attrbuf
);
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
) {
10779 if (!rdev
->ops
->dump_survey
) {
10785 res
= rdev_dump_survey(rdev
, wdev
->netdev
, survey_idx
, &survey
);
10786 if (res
== -ENOENT
)
10791 /* don't send disabled channels, but do send non-channel data */
10792 if (survey
.channel
&&
10793 survey
.channel
->flags
& IEEE80211_CHAN_DISABLED
) {
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)
10807 cb
->args
[2] = survey_idx
;
10811 wiphy_unlock(&rdev
->wiphy
);
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
;
10822 enum nl80211_auth_type auth_type
;
10823 struct key_parse key
;
10824 bool local_state_change
;
10825 struct cfg80211_auth_request req
= {};
10828 if (!info
->attrs
[NL80211_ATTR_MAC
])
10831 if (!info
->attrs
[NL80211_ATTR_AUTH_TYPE
])
10834 if (!info
->attrs
[NL80211_ATTR_SSID
])
10837 if (!info
->attrs
[NL80211_ATTR_WIPHY_FREQ
])
10840 err
= nl80211_parse_key(info
, &key
);
10844 if (key
.idx
>= 0) {
10845 if (key
.type
!= -1 && key
.type
!= NL80211_KEYTYPE_GROUP
)
10847 if (!key
.p
.key
|| !key
.p
.key_len
)
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
))
10861 if (key
.idx
>= 0) {
10865 for (i
= 0; i
< rdev
->wiphy
.n_cipher_suites
; i
++) {
10866 if (key
.p
.cipher
== rdev
->wiphy
.cipher_suites
[i
]) {
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
])
10886 nla_get_u32(info
->attrs
[NL80211_ATTR_WIPHY_FREQ_OFFSET
]);
10888 chan
= nl80211_get_valid_chan(&rdev
->wiphy
, freq
);
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
))
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
])
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
)
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
)
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
))
10938 if (!info
->attrs
[NL80211_ATTR_MLD_ADDR
])
10940 req
.ap_mld_addr
= nla_data(info
->attrs
[NL80211_ATTR_MLD_ADDR
]);
10941 if (!is_valid_ether_addr(req
.ap_mld_addr
))
10945 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
10946 IEEE80211_BSS_TYPE_ESS
,
10947 IEEE80211_PRIVACY_ANY
);
10951 err
= cfg80211_mlme_auth(rdev
, dev
, &req
);
10953 cfg80211_put_bss(&rdev
->wiphy
, req
.bss
);
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");
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
;
10974 static int nl80211_crypto_settings(struct cfg80211_registered_device
*rdev
,
10975 struct genl_info
*info
,
10976 struct cfg80211_crypto_settings
*settings
,
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
]) {
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
)
10992 if (info
->attrs
[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT
])
10993 settings
->control_port_no_encrypt
= true;
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
);
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
]) {
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
))
11020 if (settings
->n_ciphers_pairwise
> cipher_limit
)
11023 memcpy(settings
->ciphers_pairwise
, data
, len
);
11025 for (i
= 0; i
< settings
->n_ciphers_pairwise
; i
++)
11026 if (!cfg80211_supported_cipher_suite(
11028 settings
->ciphers_pairwise
[i
]))
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
))
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
]) {
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
))
11055 if (settings
->n_akm_suites
> rdev
->wiphy
.max_num_akm_suites
)
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
)
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
))
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
))
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
);
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
;
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
);
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
,
11121 IEEE80211_BSS_TYPE_ESS
,
11122 IEEE80211_PRIVACY_ANY
,
11125 return ERR_PTR(-ENOENT
);
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
;
11140 if (dev
->ieee80211_ptr
->conn_owner_nlportid
&&
11141 dev
->ieee80211_ptr
->conn_owner_nlportid
!= info
->snd_portid
)
11144 if (!info
->attrs
[NL80211_ATTR_SSID
])
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");
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
)
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
])
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
])
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
))
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
])
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
])
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
])
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");
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
;
11271 if (req
.link_id
< 0)
11274 if (!(rdev
->wiphy
.flags
& WIPHY_FLAG_SUPPORTS_MLO
))
11277 if (info
->attrs
[NL80211_ATTR_MAC
] ||
11278 info
->attrs
[NL80211_ATTR_WIPHY_FREQ
] ||
11279 !info
->attrs
[NL80211_ATTR_MLD_ADDR
])
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
);
11289 nla_for_each_nested(link
,
11290 info
->attrs
[NL80211_ATTR_MLO_LINKS
],
11292 memset(attrs
, 0, attrsize
);
11294 nla_parse_nested(attrs
, NL80211_ATTR_MAX
,
11297 if (!attrs
[NL80211_ATTR_MLO_LINK_ID
]) {
11299 NL_SET_BAD_ATTR(info
->extack
, link
);
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
) {
11307 NL_SET_BAD_ATTR(info
->extack
, link
);
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");
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");
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");
11348 req
.links
[link_id
].disabled
=
11349 nla_get_flag(attrs
[NL80211_ATTR_MLO_LINK_DISABLED
]);
11352 if (!req
.links
[req
.link_id
].bss
) {
11357 if (req
.links
[req
.link_id
].elems_len
) {
11358 GENL_SET_ERR_MSG(info
,
11359 "cannot have per-link elems on assoc link");
11364 if (req
.links
[req
.link_id
].disabled
) {
11365 GENL_SET_ERR_MSG(info
,
11366 "cannot have assoc link disabled");
11374 if (req
.link_id
>= 0)
11377 req
.bss
= nl80211_assoc_bss(rdev
, ssid
, ssid_len
, info
->attrs
,
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);
11386 struct nlattr
*link
;
11389 err
= cfg80211_mlme_assoc(rdev
, dev
, &req
,
11392 if (!err
&& info
->attrs
[NL80211_ATTR_SOCKET_OWNER
]) {
11393 dev
->ieee80211_ptr
->conn_owner_nlportid
=
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
],
11404 struct nlattr
*link_id_attr
=
11405 nla_find_nested(link
, NL80211_ATTR_MLO_LINK_ID
);
11410 link_id
= nla_get_u8(link_id_attr
);
11412 if (link_id
== req
.link_id
)
11415 if (!req
.links
[link_id
].error
||
11416 WARN_ON(req
.links
[link_id
].error
> 0))
11421 NL_SET_BAD_ATTR(info
->extack
, link
);
11422 err
= req
.links
[link_id
].error
;
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
);
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
;
11444 bool local_state_change
;
11446 if (dev
->ieee80211_ptr
->conn_owner_nlportid
&&
11447 dev
->ieee80211_ptr
->conn_owner_nlportid
!= info
->snd_portid
)
11450 if (!info
->attrs
[NL80211_ATTR_MAC
])
11453 if (!info
->attrs
[NL80211_ATTR_REASON_CODE
])
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 */
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
;
11489 bool local_state_change
;
11491 if (dev
->ieee80211_ptr
->conn_owner_nlportid
&&
11492 dev
->ieee80211_ptr
->conn_owner_nlportid
!= info
->snd_portid
)
11495 if (!info
->attrs
[NL80211_ATTR_MAC
])
11498 if (!info
->attrs
[NL80211_ATTR_REASON_CODE
])
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 */
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
);
11528 nl80211_parse_mcast_rate(struct cfg80211_registered_device
*rdev
,
11529 int mcast_rate
[NUM_NL80211_BANDS
],
11532 struct wiphy
*wiphy
= &rdev
->wiphy
;
11533 bool found
= false;
11536 for (band
= 0; band
< NUM_NL80211_BANDS
; band
++) {
11537 struct ieee80211_supported_band
*sband
;
11539 sband
= wiphy
->bands
[band
];
11543 for (i
= 0; i
< sband
->n_bitrates
; i
++) {
11544 if (sband
->bitrates
[i
].bitrate
== rateval
) {
11545 mcast_rate
[band
] = i
+ 1;
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
;
11564 memset(&ibss
, 0, sizeof(ibss
));
11566 if (!info
->attrs
[NL80211_ATTR_SSID
] ||
11567 !nla_len(info
->attrs
[NL80211_ATTR_SSID
]))
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
);
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
))
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
);
11607 if (!cfg80211_reg_can_beacon(&rdev
->wiphy
, &ibss
.chandef
,
11608 NL80211_IFTYPE_ADHOC
))
11611 switch (ibss
.chandef
.width
) {
11612 case NL80211_CHAN_WIDTH_5
:
11613 case NL80211_CHAN_WIDTH_10
:
11614 case NL80211_CHAN_WIDTH_20_NOHT
:
11616 case NL80211_CHAN_WIDTH_20
:
11617 case NL80211_CHAN_WIDTH_40
:
11618 if (!(rdev
->wiphy
.features
& NL80211_FEATURE_HT_IBSS
))
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
))
11626 if (!wiphy_ext_feature_isset(&rdev
->wiphy
,
11627 NL80211_EXT_FEATURE_VHT_IBSS
))
11630 case NL80211_CHAN_WIDTH_320
:
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
]) {
11641 nla_data(info
->attrs
[NL80211_ATTR_BSS_BASIC_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
);
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
])
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
])))
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
) &&
11680 kfree_sensitive(connkeys
);
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
);
11692 kfree_sensitive(connkeys
);
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
);
11704 kfree_sensitive(connkeys
);
11705 else if (info
->attrs
[NL80211_ATTR_SOCKET_OWNER
])
11706 dev
->ieee80211_ptr
->conn_owner_nlportid
= info
->snd_portid
;
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
];
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
])
11745 nla_rate
= nla_get_u32(info
->attrs
[NL80211_ATTR_MCAST_RATE
]);
11746 if (!nl80211_parse_mcast_rate(rdev
, mcast_rate
, nla_rate
))
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
,
11760 struct sk_buff
*skb
;
11762 struct nlattr
*data
;
11764 skb
= nlmsg_new(approxlen
+ 100, gfp
);
11768 hdr
= nl80211hdr_put(skb
, portid
, seq
, 0, cmd
);
11774 if (nla_put_u32(skb
, NL80211_ATTR_WIPHY
, rdev
->wiphy_idx
))
11775 goto nla_put_failure
;
11778 if (nla_put_u32(skb
, NL80211_ATTR_VENDOR_ID
,
11780 goto nla_put_failure
;
11781 if (nla_put_u32(skb
, NL80211_ATTR_VENDOR_SUBCMD
,
11783 goto nla_put_failure
;
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
);
11798 goto nla_put_failure
;
11800 ((void **)skb
->cb
)[0] = rdev
;
11801 ((void **)skb
->cb
)[1] = hdr
;
11802 ((void **)skb
->cb
)[2] = data
;
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
;
11823 case NL80211_CMD_TESTMODE
:
11824 if (WARN_ON(vendor_event_idx
!= -1))
11828 case NL80211_CMD_VENDOR
:
11829 if (WARN_ON(vendor_event_idx
< 0 ||
11830 vendor_event_idx
>= wiphy
->n_vendor_events
))
11832 info
= &wiphy
->vendor_events
[vendor_event_idx
];
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
,
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
;
11878 lockdep_assert_held(&rdev
->wiphy
.mtx
);
11880 wdev
= __cfg80211_wdev_from_attrs(rdev
, genl_info_net(info
),
11883 if (!rdev
->ops
->testmode_cmd
)
11884 return -EOPNOTSUPP
;
11886 if (IS_ERR(wdev
)) {
11887 err
= PTR_ERR(wdev
);
11888 if (err
!= -EINVAL
)
11891 } else if (wdev
->wiphy
!= &rdev
->wiphy
) {
11895 if (!info
->attrs
[NL80211_ATTR_TESTDATA
])
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
;
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
;
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
);
11932 attrbuf
= kcalloc(NUM_NL80211_ATTR
, sizeof(*attrbuf
),
11939 err
= nlmsg_parse_deprecated(cb
->nlh
,
11940 GENL_HDRLEN
+ nl80211_fam
.hdrsize
,
11941 attrbuf
, nl80211_fam
.maxattr
,
11942 nl80211_policy
, NULL
);
11946 rdev
= __cfg80211_rdev_from_attrs(sock_net(skb
->sk
), attrbuf
);
11947 if (IS_ERR(rdev
)) {
11948 err
= PTR_ERR(rdev
);
11951 phy_idx
= rdev
->wiphy_idx
;
11953 if (attrbuf
[NL80211_ATTR_TESTDATA
])
11954 cb
->args
[1] = (long)attrbuf
[NL80211_ATTR_TESTDATA
];
11958 data
= nla_data((void *)cb
->args
[1]);
11959 data_len
= nla_len((void *)cb
->args
[1]);
11962 if (!rdev
->ops
->testmode_dump
) {
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
;
11976 if (nla_put_u32(skb
, NL80211_ATTR_WIPHY
, phy_idx
)) {
11977 genlmsg_cancel(skb
, hdr
);
11981 tmdata
= nla_nest_start_noflag(skb
, NL80211_ATTR_TESTDATA
);
11983 genlmsg_cancel(skb
, hdr
);
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
);
11993 genlmsg_cancel(skb
, hdr
);
11997 genlmsg_end(skb
, hdr
);
12002 cb
->args
[0] = phy_idx
+ 1;
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
;
12020 memset(&connect
, 0, sizeof(connect
));
12022 if (!info
->attrs
[NL80211_ATTR_SSID
] ||
12023 !nla_len(info
->attrs
[NL80211_ATTR_SSID
]))
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
))
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
))
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
);
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
;
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
])
12093 nla_get_u32(info
->attrs
[NL80211_ATTR_WIPHY_FREQ_OFFSET
]);
12096 connect
.channel
= nl80211_get_valid_chan(wiphy
, freq
);
12097 if (!connect
.channel
)
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
)
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
);
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
);
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
);
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
);
12189 err
= parse_bss_select(info
->attrs
[NL80211_ATTR_BSS_SELECT
],
12190 wiphy
, &connect
.bss_select
);
12192 kfree_sensitive(connkeys
);
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
=
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
);
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");
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
);
12242 kfree_sensitive(connkeys
);
12244 if (!err
&& info
->attrs
[NL80211_ATTR_SOCKET_OWNER
]) {
12245 dev
->ieee80211_ptr
->conn_owner_nlportid
= info
->snd_portid
;
12247 memcpy(dev
->ieee80211_ptr
->disconnect_bssid
,
12248 connect
.bssid
, ETH_ALEN
);
12250 eth_zero_addr(dev
->ieee80211_ptr
->disconnect_bssid
);
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
;
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
=
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
]) {
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
))
12318 if (auth_type
== NL80211_AUTHTYPE_FILS_SK
&&
12319 fils_sk_offload
&& !(changed
& UPDATE_FILS_ERP_INFO
))
12322 connect
.auth_type
= auth_type
;
12323 changed
|= UPDATE_AUTH_TYPE
;
12326 if (!wdev
->connected
)
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];
12338 if (dev
->ieee80211_ptr
->conn_owner_nlportid
&&
12339 dev
->ieee80211_ptr
->conn_owner_nlportid
!= info
->snd_portid
)
12342 reason
= nla_get_u16_default(info
->attrs
[NL80211_ATTR_REASON_CODE
],
12343 WLAN_REASON_DEAUTH_LEAVING
);
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];
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
);
12374 return PTR_ERR(net
);
12378 /* check if anything to do */
12379 if (!net_eq(wiphy_net(&rdev
->wiphy
), net
))
12380 err
= cfg80211_switch_netns(rdev
, net
);
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
])
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
]);
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
) {
12474 pmksa
.ssid
= nla_data(info
->attrs
[NL80211_ATTR_SSID
]);
12475 pmksa
.ssid_len
= nla_len(info
->attrs
[NL80211_ATTR_SSID
]);
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;
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
])
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
])
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
,
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
;
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
])
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
;
12581 if (!info
->attrs
[NL80211_ATTR_WIPHY_FREQ
] ||
12582 !info
->attrs
[NL80211_ATTR_DURATION
])
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
)
12599 err
= nl80211_parse_chandef(rdev
, info
, &chandef
);
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 */
12614 /* note: returns first one if identical chandefs */
12615 compat_chandef
= cfg80211_chandef_compatible(&chandef
,
12618 if (compat_chandef
!= &chandef
)
12622 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
12626 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
12627 NL80211_CMD_REMAIN_ON_CHANNEL
);
12633 err
= rdev_remain_on_channel(rdev
, wdev
, chandef
.chan
,
12634 duration
, &cookie
);
12639 if (nla_put_u64_64bit(msg
, NL80211_ATTR_COOKIE
, cookie
,
12641 goto nla_put_failure
;
12643 genlmsg_end(msg
, hdr
);
12645 return genlmsg_reply(msg
, info
);
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];
12661 if (!info
->attrs
[NL80211_ATTR_COOKIE
])
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];
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
);
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
])
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
:
12715 case NL80211_IFTYPE_NAN
:
12716 if (!wiphy_ext_feature_isset(wdev
->wiphy
,
12717 NL80211_EXT_FEATURE_SECURE_NAN
))
12718 return -EOPNOTSUPP
;
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
],
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
;
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
])
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
])
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
:
12776 case NL80211_IFTYPE_NAN
:
12777 if (!wiphy_ext_feature_isset(wdev
->wiphy
,
12778 NL80211_EXT_FEATURE_SECURE_NAN
))
12779 return -EOPNOTSUPP
;
12782 return -EOPNOTSUPP
;
12785 if (info
->attrs
[NL80211_ATTR_DURATION
]) {
12786 if (!(rdev
->wiphy
.flags
& WIPHY_FLAG_OFFCHAN_TX
))
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
)
12799 params
.offchan
= info
->attrs
[NL80211_ATTR_OFFCHANNEL_TX_OK
];
12801 if (params
.offchan
&& !(rdev
->wiphy
.flags
& WIPHY_FLAG_OFFCHAN_TX
))
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
);
12816 if (!chandef
.chan
&& params
.offchan
)
12819 if (params
.offchan
&&
12820 !cfg80211_off_channel_oper_allowed(wdev
, chandef
.chan
))
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
12829 if (params
.link_id
>= 0 &&
12830 !(wdev
->valid_links
& BIT(params
.link_id
)))
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 ¶ms
.csa_offsets
,
12839 ¶ms
.n_csa_offsets
);
12843 if (!params
.dont_wait_for_ack
) {
12844 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
12848 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
12849 NL80211_CMD_FRAME
);
12856 params
.chan
= chandef
.chan
;
12857 err
= cfg80211_mlme_mgmt_tx(rdev
, wdev
, ¶ms
, &cookie
);
12862 if (nla_put_u64_64bit(msg
, NL80211_ATTR_COOKIE
, cookie
,
12864 goto nla_put_failure
;
12866 genlmsg_end(msg
, hdr
);
12867 return genlmsg_reply(msg
, info
);
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];
12885 if (!info
->attrs
[NL80211_ATTR_COOKIE
])
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
:
12900 case NL80211_IFTYPE_NAN
:
12901 if (!wiphy_ext_feature_isset(wdev
->wiphy
,
12902 NL80211_EXT_FEATURE_SECURE_NAN
))
12903 return -EOPNOTSUPP
;
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];
12923 if (!info
->attrs
[NL80211_ATTR_PS_STATE
])
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
)
12938 err
= rdev_set_power_mgmt(rdev
, dev
, state
, wdev
->ps_timeout
);
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
;
12954 wdev
= dev
->ieee80211_ptr
;
12956 if (!rdev
->ops
->set_power_mgmt
)
12957 return -EOPNOTSUPP
;
12959 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
12963 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
12964 NL80211_CMD_GET_POWER_SAVE
);
12971 ps_state
= NL80211_PS_ENABLED
;
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
);
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
)
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
;
13026 int i
, n
, low_index
;
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
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
= {};
13041 mac_addr
= wdev
->links
[0].client
.current_bss
->pub
.bssid
;
13043 err
= rdev_get_station(rdev
, dev
, mac_addr
, &sinfo
);
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
])
13064 if (low_index
>= 0) {
13065 low_index
= array_index_nospec(low_index
, n
);
13066 low
= cqm_config
->rssi_thresholds
[low_index
] - hyst
;
13071 i
= array_index_nospec(i
, n
);
13072 high
= cqm_config
->rssi_thresholds
[i
] + hyst
- 1;
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
,
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
;
13091 /* Check all values negative and sorted */
13092 for (i
= 0; i
< n_thresholds
; i
++) {
13093 if (thresholds
[i
] > 0 || thresholds
[i
] <= prev
)
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 */
13106 old
= wiphy_dereference(wdev
->wiphy
, wdev
->cqm_config
);
13108 /* if already disabled just succeed */
13109 if (!n_thresholds
&& !old
)
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
;
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
,
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
,
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
);
13142 err
= rdev_set_cqm_rssi_config(rdev
, dev
,
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);
13151 err
= rdev_set_cqm_rssi_config(rdev
, dev
, 0, 0);
13155 rcu_assign_pointer(wdev
->cqm_config
, old
);
13156 kfree_rcu(cqm_config
, rcu_head
);
13158 kfree_rcu(old
, rcu_head
);
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
;
13170 cqm
= info
->attrs
[NL80211_ATTR_CQM
];
13174 err
= nla_parse_nested_deprecated(attrs
, NL80211_ATTR_CQM_MAX
, cqm
,
13175 nl80211_attr_cqm_policy
,
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
]);
13190 return nl80211_set_cqm_rssi(info
, thresholds
, len
/ 4,
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
);
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
= {};
13214 err
= nl80211_parse_chandef(rdev
, info
, &setup
.chandef
);
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
;
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
);
13248 if (!info
->attrs
[NL80211_ATTR_MESH_ID
] ||
13249 !nla_len(info
->attrs
[NL80211_ATTR_MESH_ID
]))
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
])))
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
);
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)
13278 if (info
->attrs
[NL80211_ATTR_MESH_SETUP
]) {
13279 /* parse additional setup parameters if given */
13280 err
= nl80211_parse_mesh_setup(info
, &setup
);
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
);
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
]);
13300 nla_len(info
->attrs
[NL80211_ATTR_BSS_BASIC_RATES
]);
13301 struct ieee80211_supported_band
*sband
;
13303 if (!setup
.chandef
.chan
)
13306 sband
= rdev
->wiphy
.bands
[setup
.chandef
.chan
->band
];
13308 err
= ieee80211_get_ratemask(sband
, rates
, n_rates
,
13309 &setup
.basic_rates
);
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
,
13322 if (!setup
.chandef
.chan
)
13325 err
= validate_beacon_tx_rate(rdev
, setup
.chandef
.chan
->band
,
13326 &setup
.beacon_rate
);
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
);
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
;
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
);
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
;
13366 if (!wowlan
->n_patterns
)
13369 nl_pats
= nla_nest_start_noflag(msg
, NL80211_WOWLAN_TRIG_PKT_PATTERN
);
13373 for (i
= 0; i
< wowlan
->n_patterns
; i
++) {
13374 nl_pat
= nla_nest_start_noflag(msg
, i
+ 1);
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
))
13385 nla_nest_end(msg
, nl_pat
);
13387 nla_nest_end(msg
, nl_pats
);
13392 static int nl80211_send_wowlan_tcp(struct sk_buff
*msg
,
13393 struct cfg80211_wowlan_tcp
*tcp
)
13395 struct nlattr
*nl_tcp
;
13400 nl_tcp
= nla_nest_start_noflag(msg
,
13401 NL80211_WOWLAN_TRIG_TCP_CONNECTION
);
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
))
13420 if (tcp
->payload_seq
.len
&&
13421 nla_put(msg
, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ
,
13422 sizeof(tcp
->payload_seq
), &tcp
->payload_seq
))
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
))
13431 nla_nest_end(msg
, nl_tcp
);
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
;
13445 nd
= nla_nest_start_noflag(msg
, NL80211_WOWLAN_TRIG_NET_DETECT
);
13449 if (req
->n_scan_plans
== 1 &&
13450 nla_put_u32(msg
, NL80211_ATTR_SCHED_SCAN_INTERVAL
,
13451 req
->scan_plans
[0].interval
* 1000))
13454 if (nla_put_u32(msg
, NL80211_ATTR_SCHED_SCAN_DELAY
, req
->delay
))
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
))
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
))
13471 freqs
= nla_nest_start_noflag(msg
, NL80211_ATTR_SCAN_FREQUENCIES
);
13475 for (i
= 0; i
< req
->n_channels
; i
++) {
13476 if (nla_put_u32(msg
, i
, req
->channels
[i
]->center_freq
))
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
);
13488 for (i
= 0; i
< req
->n_match_sets
; i
++) {
13489 match
= nla_nest_start_noflag(msg
, i
);
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
))
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
);
13506 for (i
= 0; i
< req
->n_scan_plans
; i
++) {
13507 scan_plan
= nla_nest_start_noflag(msg
, i
+ 1);
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
)))
13517 nla_nest_end(msg
, scan_plan
);
13519 nla_nest_end(msg
, scan_plans
);
13521 nla_nest_end(msg
, nd
);
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
;
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
);
13548 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
13549 NL80211_CMD_GET_WOWLAN
);
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
);
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(
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
);
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
;
13609 u32 data_size
, wake_size
, tokens_size
= 0, wake_mask_size
;
13612 if (!rdev
->wiphy
.wowlan
->tcp
)
13615 err
= nla_parse_nested_deprecated(tb
, MAX_NL80211_WOWLAN_TCP
, attr
,
13616 nl80211_wowlan_tcp_policy
, NULL
);
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
])
13630 data_size
= nla_len(tb
[NL80211_WOWLAN_TCP_DATA_PAYLOAD
]);
13631 if (data_size
> rdev
->wiphy
.wowlan
->tcp
->data_payload_max
)
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)
13639 wake_size
= nla_len(tb
[NL80211_WOWLAN_TCP_WAKE_PAYLOAD
]);
13640 if (wake_size
> rdev
->wiphy
.wowlan
->tcp
->wake_payload_max
)
13643 wake_mask_size
= nla_len(tb
[NL80211_WOWLAN_TCP_WAKE_MASK
]);
13644 if (wake_mask_size
!= DIV_ROUND_UP(wake_size
, 8))
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
)
13655 if (!rdev
->wiphy
.wowlan
->tcp
->tok
)
13657 if (tok
->len
> rdev
->wiphy
.wowlan
->tcp
->tok
->max_len
)
13659 if (tok
->len
< rdev
->wiphy
.wowlan
->tcp
->tok
->min_len
)
13661 if (tokens_size
> rdev
->wiphy
.wowlan
->tcp
->tok
->bufsize
)
13663 if (tok
->offset
+ tok
->len
> data_size
)
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
)
13671 if (seq
->len
== 0 || seq
->len
> 4)
13673 if (seq
->len
+ seq
->offset
> data_size
)
13677 size
= sizeof(*cfg
);
13679 size
+= wake_size
+ wake_mask_size
;
13680 size
+= tokens_size
;
13682 cfg
= kzalloc(size
, GFP_KERNEL
);
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
]),
13689 port
= nla_get_u16_default(tb
[NL80211_WOWLAN_TCP_SRC_PORT
], 0);
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);
13698 if (inet_csk_get_port(cfg
->sock
->sk
, port
)) {
13699 sock_release(cfg
->sock
);
13701 return -EADDRINUSE
;
13703 cfg
->src_port
= inet_sk(cfg
->sock
->sk
)->inet_num
;
13709 cfg
->src_port
= port
;
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
]),
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
]),
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
]),
13732 cfg
->tokens_size
= tokens_size
;
13733 cfg
->payload_tok
= *tok
;
13734 memcpy(cfg
->payload_tok
.token_stream
, tok
->token_stream
,
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
;
13751 tb
= kcalloc(NUM_NL80211_ATTR
, sizeof(*tb
), GFP_KERNEL
);
13755 if (!(wowlan
->flags
& WIPHY_WOWLAN_NET_DETECT
)) {
13760 err
= nla_parse_nested_deprecated(tb
, NL80211_ATTR_MAX
, attr
,
13761 nl80211_policy
, NULL
);
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
);
13769 trig
->nd_config
= NULL
;
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
;
13784 bool prev_enabled
= rdev
->wiphy
.wowlan_config
;
13785 bool regular
= false;
13788 return -EOPNOTSUPP
;
13790 if (!info
->attrs
[NL80211_ATTR_WOWLAN_TRIGGERS
]) {
13791 cfg80211_rdev_free_wowlan(rdev
);
13792 rdev
->wiphy
.wowlan_config
= NULL
;
13796 err
= nla_parse_nested_deprecated(tb
, MAX_NL80211_WOWLAN_TRIG
,
13797 info
->attrs
[NL80211_ATTR_WOWLAN_TRIGGERS
],
13798 nl80211_wowlan_policy
, info
->extack
);
13802 if (tb
[NL80211_WOWLAN_TRIG_ANY
]) {
13803 if (!(wowlan
->flags
& WIPHY_WOWLAN_ANY
))
13805 new_triggers
.any
= true;
13808 if (tb
[NL80211_WOWLAN_TRIG_DISCONNECT
]) {
13809 if (!(wowlan
->flags
& WIPHY_WOWLAN_DISCONNECT
))
13811 new_triggers
.disconnect
= true;
13815 if (tb
[NL80211_WOWLAN_TRIG_MAGIC_PKT
]) {
13816 if (!(wowlan
->flags
& WIPHY_WOWLAN_MAGIC_PKT
))
13818 new_triggers
.magic_pkt
= true;
13822 if (tb
[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED
])
13825 if (tb
[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE
]) {
13826 if (!(wowlan
->flags
& WIPHY_WOWLAN_GTK_REKEY_FAILURE
))
13828 new_triggers
.gtk_rekey_failure
= true;
13832 if (tb
[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST
]) {
13833 if (!(wowlan
->flags
& WIPHY_WOWLAN_EAP_IDENTITY_REQ
))
13835 new_triggers
.eap_identity_req
= true;
13839 if (tb
[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE
]) {
13840 if (!(wowlan
->flags
& WIPHY_WOWLAN_4WAY_HANDSHAKE
))
13842 new_triggers
.four_way_handshake
= true;
13846 if (tb
[NL80211_WOWLAN_TRIG_RFKILL_RELEASE
]) {
13847 if (!(wowlan
->flags
& WIPHY_WOWLAN_RFKILL_RELEASE
))
13849 new_triggers
.rfkill_release
= 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
];
13861 nla_for_each_nested(pat
, tb
[NL80211_WOWLAN_TRIG_PKT_PATTERN
],
13864 if (n_patterns
> wowlan
->n_patterns
)
13867 new_triggers
.patterns
= kcalloc(n_patterns
,
13868 sizeof(new_triggers
.patterns
[0]),
13870 if (!new_triggers
.patterns
)
13873 new_triggers
.n_patterns
= n_patterns
;
13876 nla_for_each_nested(pat
, tb
[NL80211_WOWLAN_TRIG_PKT_PATTERN
],
13880 err
= nla_parse_nested_deprecated(pat_tb
,
13881 MAX_NL80211_PKTPAT
,
13883 nl80211_packet_pattern_policy
,
13889 if (!pat_tb
[NL80211_PKTPAT_MASK
] ||
13890 !pat_tb
[NL80211_PKTPAT_PATTERN
])
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
)
13896 if (pat_len
> wowlan
->pattern_max_len
||
13897 pat_len
< wowlan
->pattern_min_len
)
13901 nla_get_u32_default(pat_tb
[NL80211_PKTPAT_OFFSET
],
13903 if (pkt_offset
> wowlan
->max_pkt_offset
)
13905 new_triggers
.patterns
[i
].pkt_offset
= pkt_offset
;
13907 mask_pat
= kmalloc(mask_len
+ pat_len
, GFP_KERNEL
);
13912 new_triggers
.patterns
[i
].mask
= mask_pat
;
13913 memcpy(mask_pat
, nla_data(pat_tb
[NL80211_PKTPAT_MASK
]),
13915 mask_pat
+= mask_len
;
13916 new_triggers
.patterns
[i
].pattern
= mask_pat
;
13917 new_triggers
.patterns
[i
].pattern_len
= pat_len
;
13919 nla_data(pat_tb
[NL80211_PKTPAT_PATTERN
]),
13925 if (tb
[NL80211_WOWLAN_TRIG_TCP_CONNECTION
]) {
13927 err
= nl80211_parse_wowlan_tcp(
13928 rdev
, tb
[NL80211_WOWLAN_TRIG_TCP_CONNECTION
],
13934 if (tb
[NL80211_WOWLAN_TRIG_NET_DETECT
]) {
13936 err
= nl80211_parse_wowlan_nd(
13937 rdev
, wowlan
, tb
[NL80211_WOWLAN_TRIG_NET_DETECT
],
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
) {
13954 ntrig
= kmemdup(&new_triggers
, sizeof(new_triggers
), GFP_KERNEL
);
13959 cfg80211_rdev_free_wowlan(rdev
);
13960 rdev
->wiphy
.wowlan_config
= ntrig
;
13963 if (rdev
->ops
->set_wakeup
&&
13964 prev_enabled
!= !!rdev
->wiphy
.wowlan_config
)
13965 rdev_set_wakeup(rdev
, rdev
->wiphy
.wowlan_config
);
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
);
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
;
13985 struct cfg80211_coalesce_rules
*rule
;
13987 if (!rdev
->coalesce
->n_rules
)
13990 nl_rules
= nla_nest_start_noflag(msg
, NL80211_ATTR_COALESCE_RULE
);
13994 for (i
= 0; i
< rdev
->coalesce
->n_rules
; i
++) {
13995 nl_rule
= nla_nest_start_noflag(msg
, i
+ 1);
13999 rule
= &rdev
->coalesce
->rules
[i
];
14000 if (nla_put_u32(msg
, NL80211_ATTR_COALESCE_RULE_DELAY
,
14004 if (nla_put_u32(msg
, NL80211_ATTR_COALESCE_RULE_CONDITION
,
14008 nl_pats
= nla_nest_start_noflag(msg
,
14009 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN
);
14013 for (j
= 0; j
< rule
->n_patterns
; j
++) {
14014 nl_pat
= nla_nest_start_noflag(msg
, j
+ 1);
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
))
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
);
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
;
14042 if (!rdev
->wiphy
.coalesce
)
14043 return -EOPNOTSUPP
;
14045 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
14049 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
14050 NL80211_CMD_GET_COALESCE
);
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
);
14065 void cfg80211_free_coalesce(struct cfg80211_coalesce
*coalesce
)
14068 struct cfg80211_coalesce_rules
*rule
;
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
);
14082 static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device
*rdev
,
14083 struct nlattr
*rule
,
14084 struct cfg80211_coalesce_rules
*new_rule
)
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
);
14097 if (tb
[NL80211_ATTR_COALESCE_RULE_DELAY
])
14099 nla_get_u32(tb
[NL80211_ATTR_COALESCE_RULE_DELAY
]);
14100 if (new_rule
->delay
> coalesce
->max_delay
)
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
])
14110 nla_for_each_nested(pat
, tb
[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN
],
14113 if (n_patterns
> coalesce
->n_patterns
)
14116 new_rule
->patterns
= kcalloc(n_patterns
, sizeof(new_rule
->patterns
[0]),
14118 if (!new_rule
->patterns
)
14121 new_rule
->n_patterns
= n_patterns
;
14124 nla_for_each_nested(pat
, tb
[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN
],
14128 err
= nla_parse_nested_deprecated(pat_tb
, MAX_NL80211_PKTPAT
,
14130 nl80211_packet_pattern_policy
,
14135 if (!pat_tb
[NL80211_PKTPAT_MASK
] ||
14136 !pat_tb
[NL80211_PKTPAT_PATTERN
])
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
)
14142 if (pat_len
> coalesce
->pattern_max_len
||
14143 pat_len
< coalesce
->pattern_min_len
)
14146 pkt_offset
= nla_get_u32_default(pat_tb
[NL80211_PKTPAT_OFFSET
],
14148 if (pkt_offset
> coalesce
->max_pkt_offset
)
14150 new_rule
->patterns
[i
].pkt_offset
= pkt_offset
;
14152 mask_pat
= kmalloc(mask_len
+ pat_len
, GFP_KERNEL
);
14156 new_rule
->patterns
[i
].mask
= mask_pat
;
14157 memcpy(mask_pat
, nla_data(pat_tb
[NL80211_PKTPAT_MASK
]),
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
]),
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
);
14189 nla_for_each_nested(rule
, info
->attrs
[NL80211_ATTR_COALESCE_RULE
],
14192 if (n_rules
> coalesce
->n_rules
)
14195 new_coalesce
= kzalloc(struct_size(new_coalesce
, rules
, n_rules
),
14200 new_coalesce
->n_rules
= n_rules
;
14203 nla_for_each_nested(rule
, info
->attrs
[NL80211_ATTR_COALESCE_RULE
],
14205 err
= nl80211_parse_coalesce_rule(rdev
, rule
,
14206 &new_coalesce
->rules
[i
]);
14213 err
= rdev_set_coalesce(rdev
, new_coalesce
);
14217 cfg80211_free_coalesce(rdev
->coalesce
);
14218 rdev
->coalesce
= new_coalesce
;
14222 cfg80211_free_coalesce(new_coalesce
);
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
= {};
14236 if (!info
->attrs
[NL80211_ATTR_REKEY_DATA
])
14239 err
= nla_parse_nested_deprecated(tb
, MAX_NL80211_REKEY_DATA
,
14240 info
->attrs
[NL80211_ATTR_REKEY_DATA
],
14241 nl80211_rekey_policy
, info
->extack
);
14245 if (!tb
[NL80211_REKEY_DATA_REPLAY_CTR
] || !tb
[NL80211_REKEY_DATA_KEK
] ||
14246 !tb
[NL80211_REKEY_DATA_KCK
])
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
))
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
))
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
)
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
)
14286 if (wdev
->ap_unexpected_nlportid
)
14289 wdev
->ap_unexpected_nlportid
= info
->snd_portid
;
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
;
14305 if (wdev
->iftype
!= NL80211_IFTYPE_AP
&&
14306 wdev
->iftype
!= NL80211_IFTYPE_P2P_GO
)
14307 return -EOPNOTSUPP
;
14309 if (!info
->attrs
[NL80211_ATTR_MAC
])
14312 if (!rdev
->ops
->probe_client
)
14313 return -EOPNOTSUPP
;
14315 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
14319 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
14320 NL80211_CMD_PROBE_CLIENT
);
14326 addr
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
14328 err
= rdev_probe_client(rdev
, dev
, addr
, &cookie
);
14332 if (nla_put_u64_64bit(msg
, NL80211_ATTR_COOKIE
, cookie
,
14334 goto nla_put_failure
;
14336 genlmsg_end(msg
, hdr
);
14338 return genlmsg_reply(msg
, info
);
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
;
14353 if (!(rdev
->wiphy
.flags
& WIPHY_FLAG_REPORTS_OBSS
))
14354 return -EOPNOTSUPP
;
14356 nreg
= kzalloc(sizeof(*nreg
), GFP_KERNEL
);
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
) {
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
);
14376 spin_unlock_bh(&rdev
->beacon_registrations_lock
);
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];
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
))
14396 if (rfkill_blocked(rdev
->wiphy
.rfkill
))
14399 err
= rdev_start_p2p_device(rdev
, wdev
);
14403 wdev
->is_running
= true;
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
);
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
= {};
14432 if (wdev
->iftype
!= NL80211_IFTYPE_NAN
)
14433 return -EOPNOTSUPP
;
14435 if (wdev_running(wdev
))
14438 if (rfkill_blocked(rdev
->wiphy
.rfkill
))
14441 if (!info
->attrs
[NL80211_ATTR_NAN_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
)))
14456 conf
.bands
= bands
;
14459 err
= rdev_start_nan(rdev
, wdev
, &conf
);
14463 wdev
->is_running
= true;
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
);
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
);
14498 static int handle_nan_filter(struct nlattr
*attr_filter
,
14499 struct cfg80211_nan_func
*func
,
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
);
14510 BUILD_BUG_ON(sizeof(*func
->rx_filters
) != sizeof(*func
->tx_filters
));
14512 filter
= kcalloc(n_entries
, sizeof(*func
->rx_filters
), GFP_KERNEL
);
14517 nla_for_each_nested(attr
, attr_filter
, rem
) {
14518 filter
[i
].filter
= nla_memdup(attr
, GFP_KERNEL
);
14519 if (!filter
[i
].filter
)
14522 filter
[i
].len
= nla_len(attr
);
14526 func
->num_tx_filters
= n_entries
;
14527 func
->tx_filters
= filter
;
14529 func
->num_rx_filters
= n_entries
;
14530 func
->rx_filters
= filter
;
14537 nla_for_each_nested(attr
, attr_filter
, rem
) {
14538 kfree(filter
[i
].filter
);
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
;
14556 if (wdev
->iftype
!= NL80211_IFTYPE_NAN
)
14557 return -EOPNOTSUPP
;
14559 if (!wdev_running(wdev
))
14562 if (!info
->attrs
[NL80211_ATTR_NAN_FUNC
])
14565 err
= nla_parse_nested_deprecated(tb
, NL80211_NAN_FUNC_ATTR_MAX
,
14566 info
->attrs
[NL80211_ATTR_NAN_FUNC
],
14567 nl80211_nan_func_policy
,
14572 func
= kzalloc(sizeof(*func
), GFP_KERNEL
);
14576 func
->cookie
= cfg80211_assign_cookie(rdev
);
14578 if (!tb
[NL80211_NAN_FUNC_TYPE
]) {
14584 func
->type
= nla_get_u8(tb
[NL80211_NAN_FUNC_TYPE
]);
14586 if (!tb
[NL80211_NAN_FUNC_SERVICE_ID
]) {
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
,
14604 if (!func
->serv_spec_info
) {
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
]) {
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
) {
14631 case NL80211_NAN_FUNC_SUBSCRIBE
:
14632 func
->subscribe_active
=
14633 nla_get_flag(tb
[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE
]);
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
]) {
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
));
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
,
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
]) {
14682 nla_len(srf_tb
[NL80211_NAN_SRF_BF
]);
14684 kmemdup(nla_data(srf_tb
[NL80211_NAN_SRF_BF
]),
14685 func
->srf_bf_len
, GFP_KERNEL
);
14686 if (!func
->srf_bf
) {
14692 nla_get_u8(srf_tb
[NL80211_NAN_SRF_BF_IDX
]);
14694 struct nlattr
*attr
, *mac_attr
=
14695 srf_tb
[NL80211_NAN_SRF_MAC_ADDRS
];
14696 int n_entries
, rem
, i
= 0;
14703 n_entries
= validate_acl_mac_addrs(mac_attr
);
14704 if (n_entries
<= 0) {
14709 func
->srf_num_macs
= n_entries
;
14711 kcalloc(n_entries
, sizeof(*func
->srf_macs
),
14713 if (!func
->srf_macs
) {
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
],
14731 if (tb
[NL80211_NAN_FUNC_RX_MATCH_FILTER
]) {
14732 err
= handle_nan_filter(tb
[NL80211_NAN_FUNC_RX_MATCH_FILTER
],
14738 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
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
)) {
14752 err
= rdev_add_nan_func(rdev
, wdev
, func
);
14755 cfg80211_free_nan_func(func
);
14760 /* propagate the instance id and cookie to userspace */
14761 if (nla_put_u64_64bit(msg
, NL80211_ATTR_COOKIE
, func
->cookie
,
14763 goto nla_put_failure
;
14765 func_attr
= nla_nest_start_noflag(msg
, NL80211_ATTR_NAN_FUNC
);
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
);
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];
14790 if (wdev
->iftype
!= NL80211_IFTYPE_NAN
)
14791 return -EOPNOTSUPP
;
14793 if (!wdev_running(wdev
))
14796 if (!info
->attrs
[NL80211_ATTR_COOKIE
])
14799 cookie
= nla_get_u64(info
->attrs
[NL80211_ATTR_COOKIE
]);
14801 rdev_del_nan_func(rdev
, wdev
, cookie
);
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
= {};
14814 if (wdev
->iftype
!= NL80211_IFTYPE_NAN
)
14815 return -EOPNOTSUPP
;
14817 if (!wdev_running(wdev
))
14820 if (info
->attrs
[NL80211_ATTR_NAN_MASTER_PREF
]) {
14822 nla_get_u8(info
->attrs
[NL80211_ATTR_NAN_MASTER_PREF
]);
14823 if (conf
.master_pref
<= 1 || conf
.master_pref
== 255)
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
)))
14838 conf
.bands
= bands
;
14839 changed
|= CFG80211_NAN_CONF_CHANGED_BANDS
;
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
;
14857 if (WARN_ON(!match
->inst_id
|| !match
->peer_inst_id
|| !match
->addr
))
14860 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
14864 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_NAN_MATCH
);
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
),
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
);
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
,
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
);
14918 genlmsg_unicast(wiphy_net(&rdev
->wiphy
), msg
,
14919 wdev
->owner_nlportid
);
14926 EXPORT_SYMBOL(cfg80211_nan_match
);
14928 void cfg80211_nan_func_terminated(struct wireless_dev
*wdev
,
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
;
14939 if (WARN_ON(!inst_id
))
14942 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
14946 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION
);
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
),
14957 goto nla_put_failure
;
14959 if (nla_put_u64_64bit(msg
, NL80211_ATTR_COOKIE
, cookie
,
14961 goto nla_put_failure
;
14963 func_attr
= nla_nest_start_noflag(msg
, NL80211_ATTR_NAN_FUNC
);
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
);
14978 genlmsg_unicast(wiphy_net(&rdev
->wiphy
), msg
,
14979 wdev
->owner_nlportid
);
14986 EXPORT_SYMBOL(cfg80211_nan_func_terminated
);
14988 static int nl80211_get_protocol_features(struct sk_buff
*skb
,
14989 struct genl_info
*info
)
14992 struct sk_buff
*msg
;
14994 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
14998 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
14999 NL80211_CMD_GET_PROTOCOL_FEATURES
);
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
);
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
])
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
;
15045 if (!rdev
->ops
->crit_proto_start
)
15046 return -EOPNOTSUPP
;
15048 if (WARN_ON(!rdev
->ops
->crit_proto_stop
))
15051 if (rdev
->crit_proto_nlportid
)
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
)
15061 /* timeout must be provided */
15062 if (!info
->attrs
[NL80211_ATTR_MAX_CRIT_PROT_DURATION
])
15066 nla_get_u16(info
->attrs
[NL80211_ATTR_MAX_CRIT_PROT_DURATION
]);
15068 ret
= rdev_crit_proto_start(rdev
, wdev
, proto
, duration
);
15070 rdev
->crit_proto_nlportid
= info
->snd_portid
;
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
);
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");
15105 if (!(attr
->nla_type
& NLA_F_NESTED
)) {
15106 NL_SET_ERR_MSG_ATTR(extack
, attr
, "expected nested data");
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
),
15122 if (!rdev
->wiphy
.vendor_commands
)
15123 return -EOPNOTSUPP
;
15125 if (IS_ERR(wdev
)) {
15126 err
= PTR_ERR(wdev
);
15127 if (err
!= -EINVAL
)
15130 } else if (wdev
->wiphy
!= &rdev
->wiphy
) {
15134 if (!info
->attrs
[NL80211_ATTR_VENDOR_ID
] ||
15135 !info
->attrs
[NL80211_ATTR_VENDOR_SUBCMD
])
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
;
15145 vcmd
= &rdev
->wiphy
.vendor_commands
[i
];
15147 if (vcmd
->info
.vendor_id
!= vid
|| vcmd
->info
.subcmd
!= subcmd
)
15150 if (vcmd
->flags
& (WIPHY_VENDOR_CMD_NEED_WDEV
|
15151 WIPHY_VENDOR_CMD_NEED_NETDEV
)) {
15154 if (vcmd
->flags
& WIPHY_VENDOR_CMD_NEED_NETDEV
&&
15158 if (vcmd
->flags
& WIPHY_VENDOR_CMD_NEED_RUNNING
) {
15159 if (!wdev_running(wdev
))
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
],
15180 rdev
->cur_cmd_info
= info
;
15181 err
= vcmd
->doit(&rdev
->wiphy
, wdev
, data
, len
);
15182 rdev
->cur_cmd_info
= NULL
;
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
;
15200 unsigned int data_len
= 0;
15203 /* subtract the 1 again here */
15204 struct wiphy
*wiphy
= wiphy_idx_to_wiphy(cb
->args
[0] - 1);
15205 struct wireless_dev
*tmp
;
15209 *rdev
= wiphy_to_rdev(wiphy
);
15213 list_for_each_entry(tmp
, &wiphy
->wdev_list
, list
) {
15214 if (tmp
->identifier
== cb
->args
[1] - 1) {
15221 /* keep rtnl locked in successful case */
15225 attrbuf
= kcalloc(NUM_NL80211_ATTR
, sizeof(*attrbuf
), GFP_KERNEL
);
15229 err
= nlmsg_parse_deprecated(cb
->nlh
,
15230 GENL_HDRLEN
+ nl80211_fam
.hdrsize
,
15231 attrbuf
, nl80211_fam
.maxattr
,
15232 nl80211_policy
, NULL
);
15236 if (!attrbuf
[NL80211_ATTR_VENDOR_ID
] ||
15237 !attrbuf
[NL80211_ATTR_VENDOR_SUBCMD
]) {
15242 *wdev
= __cfg80211_wdev_from_attrs(NULL
, sock_net(skb
->sk
), attrbuf
);
15246 *rdev
= __cfg80211_rdev_from_attrs(sock_net(skb
->sk
), attrbuf
);
15247 if (IS_ERR(*rdev
)) {
15248 err
= PTR_ERR(*rdev
);
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
)
15263 if (!vcmd
->dumpit
) {
15272 if (vcmd_idx
< 0) {
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
],
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 */
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
;
15314 struct nlattr
*vendor_data
;
15317 err
= nl80211_prepare_vendor_dump(skb
, cb
, &rdev
, &wdev
);
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
)) {
15332 if (vcmd
->flags
& WIPHY_VENDOR_CMD_NEED_NETDEV
&&
15338 if (vcmd
->flags
& WIPHY_VENDOR_CMD_NEED_RUNNING
) {
15339 if (!wdev_running(wdev
)) {
15347 void *hdr
= nl80211hdr_put(skb
, NETLINK_CB(cb
->skb
).portid
,
15348 cb
->nlh
->nlmsg_seq
, NLM_F_MULTI
,
15349 NL80211_CMD_VENDOR
);
15353 if (nla_put_u32(skb
, NL80211_ATTR_WIPHY
, rdev
->wiphy_idx
) ||
15354 (wdev
&& nla_put_u64_64bit(skb
, NL80211_ATTR_WDEV
,
15356 NL80211_ATTR_PAD
))) {
15357 genlmsg_cancel(skb
, hdr
);
15361 vendor_data
= nla_nest_start_noflag(skb
,
15362 NL80211_ATTR_VENDOR_DATA
);
15363 if (!vendor_data
) {
15364 genlmsg_cancel(skb
, hdr
);
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
);
15375 } else if (err
<= 0) {
15376 genlmsg_cancel(skb
, hdr
);
15380 genlmsg_end(skb
, hdr
);
15389 struct sk_buff
*__cfg80211_alloc_reply_skb(struct wiphy
*wiphy
,
15390 enum nl80211_commands cmd
,
15391 enum nl80211_attrs attr
,
15394 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
15396 if (WARN_ON(!rdev
->cur_cmd_info
))
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
)) {
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
))
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
;
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
]);
15456 qos_map
= kzalloc(sizeof(struct cfg80211_qos_map
), GFP_KERNEL
);
15460 num_des
= (len
- IEEE80211_QOS_MAP_LEN_MIN
) >> 1;
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) {
15474 memcpy(qos_map
->up
, pos
, IEEE80211_QOS_MAP_LEN_MIN
);
15477 ret
= nl80211_key_allowed(dev
->ieee80211_ptr
);
15479 ret
= rdev_set_qos_map(rdev
, dev
, qos_map
);
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
;
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
])
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
15513 peer
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
15515 if (info
->attrs
[NL80211_ATTR_ADMITTED_TIME
]) {
15517 nla_get_u16(info
->attrs
[NL80211_ATTR_ADMITTED_TIME
]);
15518 if (!admitted_time
)
15522 switch (wdev
->iftype
) {
15523 case NL80211_IFTYPE_STATION
:
15524 case NL80211_IFTYPE_P2P_CLIENT
:
15525 if (wdev
->connected
)
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];
15542 if (!info
->attrs
[NL80211_ATTR_TSID
] || !info
->attrs
[NL80211_ATTR_MAC
])
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
= {};
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
:
15571 return -EOPNOTSUPP
;
15574 if (!info
->attrs
[NL80211_ATTR_MAC
] ||
15575 !info
->attrs
[NL80211_ATTR_OPER_CLASS
])
15578 err
= nl80211_parse_chandef(rdev
, info
, &chandef
);
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
)
15592 /* we will be active on the TDLS link */
15593 if (!cfg80211_reg_can_beacon_relax(&rdev
->wiphy
, &chandef
,
15597 /* don't allow switching to DFS channels */
15598 if (cfg80211_chandef_dfs_required(wdev
->wiphy
, &chandef
, wdev
->iftype
))
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];
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
:
15624 return -EOPNOTSUPP
;
15627 if (!info
->attrs
[NL80211_ATTR_MAC
])
15630 addr
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
15632 rdev_tdls_cancel_channel_switch(rdev
, dev
, addr
);
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
;
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
])
15677 if (!wdev
->connected
)
15680 pmk_conf
.aa
= nla_data(info
->attrs
[NL80211_ATTR_MAC
]);
15681 if (memcmp(pmk_conf
.aa
, wdev
->u
.client
.connected_addr
, ETH_ALEN
))
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
)
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
;
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
])
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
)
15733 if (!info
->attrs
[NL80211_ATTR_BSSID
])
15736 if (!info
->attrs
[NL80211_ATTR_STATUS_CODE
])
15739 memset(¶ms
, 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)
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
]),
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
, ¶ms
);
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
;
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");
15790 switch (wdev
->iftype
) {
15791 case NL80211_IFTYPE_AP
:
15792 case NL80211_IFTYPE_P2P_GO
:
15793 case NL80211_IFTYPE_MESH_POINT
:
15795 case NL80211_IFTYPE_ADHOC
:
15796 if (wdev
->u
.ibss
.current_bss
)
15799 case NL80211_IFTYPE_STATION
:
15800 case NL80211_IFTYPE_P2P_CLIENT
:
15801 if (wdev
->connected
)
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
]);
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
);
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
;
15835 struct nlattr
*ftm_stats_attr
;
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
);
15846 if (!ftm_stats
.filled
)
15849 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
15853 hdr
= nl80211hdr_put(msg
, info
->snd_portid
, info
->snd_seq
, 0,
15854 NL80211_CMD_GET_FTM_RESPONDER_STATS
);
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
);
15888 nla_nest_end(msg
, ftm_stats_attr
);
15890 genlmsg_end(msg
, hdr
);
15891 return genlmsg_reply(msg
, info
);
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
])
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
= {};
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");
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
))
15953 if (!ether_addr_equal(buf
, dest
) || is_multicast_ether_addr(buf
) ||
15954 !ether_addr_equal(buf
+ ETH_ALEN
, dev
->dev_addr
))
15957 err
= rdev_get_station(rdev
, dev
, dest
, &sinfo
);
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
;
15976 if (!attrs
[NL80211_TID_CONFIG_ATTR_TIDS
])
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
,
15994 if (attrs
[NL80211_TID_CONFIG_ATTR_NOACK
]) {
15995 tid_conf
->mask
|= BIT(NL80211_TID_CONFIG_ATTR_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
)
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
)
16018 if (attrs
[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL
]) {
16019 tid_conf
->mask
|= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL
);
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
);
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
);
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
,
16049 tid_conf
->mask
|= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE
);
16051 tid_conf
->mask
|= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE
);
16055 mask
= rdev
->wiphy
.tid_config_support
.peer
;
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
;
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
;
16080 if (!info
->attrs
[NL80211_ATTR_TID_CONFIG
])
16083 if (!rdev
->ops
->set_tid_config
)
16084 return -EOPNOTSUPP
;
16086 nla_for_each_nested(tid
, info
->attrs
[NL80211_ATTR_TID_CONFIG
],
16090 tid_config
= kzalloc(struct_size(tid_config
, tid_conf
, num_conf
),
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
],
16102 ret
= nla_parse_nested(attrs
, NL80211_TID_CONFIG_ATTR_MAX
,
16108 ret
= parse_tid_conf(rdev
, attrs
, dev
,
16109 &tid_config
->tid_conf
[conf_idx
],
16110 info
, tid_config
->peer
, link_id
);
16117 ret
= rdev_set_tid_config(rdev
, dev
, tid_config
);
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
;
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
])
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
, ¶ms
.beacon_next
,
16157 tb
= kcalloc(NL80211_ATTR_MAX
+ 1, sizeof(*tb
), GFP_KERNEL
);
16161 err
= nla_parse_nested(tb
, NL80211_ATTR_MAX
,
16162 info
->attrs
[NL80211_ATTR_COLOR_CHANGE_ELEMS
],
16163 nl80211_policy
, info
->extack
);
16167 err
= nl80211_parse_beacon(rdev
, tb
, ¶ms
.beacon_color_change
,
16172 if (!tb
[NL80211_ATTR_CNTDWN_OFFS_BEACON
]) {
16177 if (nla_len(tb
[NL80211_ATTR_CNTDWN_OFFS_BEACON
]) != sizeof(u16
)) {
16182 offset
= nla_get_u16(tb
[NL80211_ATTR_CNTDWN_OFFS_BEACON
]);
16183 if (offset
>= params
.beacon_color_change
.tail_len
) {
16188 if (params
.beacon_color_change
.tail
[offset
] != params
.count
) {
16193 params
.counter_offset_beacon
= offset
;
16195 if (tb
[NL80211_ATTR_CNTDWN_OFFS_PRESP
]) {
16196 if (nla_len(tb
[NL80211_ATTR_CNTDWN_OFFS_PRESP
]) !=
16202 offset
= nla_get_u16(tb
[NL80211_ATTR_CNTDWN_OFFS_PRESP
]);
16203 if (offset
>= params
.beacon_color_change
.probe_resp_len
) {
16208 if (params
.beacon_color_change
.probe_resp
[offset
] !=
16214 params
.counter_offset_presp
= offset
;
16217 params
.link_id
= nl80211_link_id(info
->attrs
);
16218 err
= rdev_color_change(rdev
, dev
, ¶ms
);
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
);
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
= {};
16237 if (!info
->attrs
[NL80211_ATTR_MAC
] ||
16238 !info
->attrs
[NL80211_ATTR_FILS_KEK
] ||
16239 !info
->attrs
[NL80211_ATTR_FILS_NONCES
])
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
;
16260 if (!(wdev
->wiphy
->flags
& WIPHY_FLAG_SUPPORTS_MLO
))
16263 switch (wdev
->iftype
) {
16264 case NL80211_IFTYPE_AP
:
16270 if (!info
->attrs
[NL80211_ATTR_MAC
] ||
16271 !is_valid_ether_addr(nla_data(info
->attrs
[NL80211_ATTR_MAC
])))
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
);
16280 wdev
->valid_links
&= ~BIT(link_id
);
16281 eth_zero_addr(wdev
->links
[link_id
].addr
);
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
])
16297 switch (wdev
->iftype
) {
16298 case NL80211_IFTYPE_AP
:
16304 cfg80211_remove_link(wdev
, link_id
);
16310 nl80211_add_mod_link_station(struct sk_buff
*skb
, struct genl_info
*info
,
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];
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
])
16325 if (!info
->attrs
[NL80211_ATTR_MLD_ADDR
])
16328 if (add
&& !info
->attrs
[NL80211_ATTR_STA_SUPPORTED_RATES
])
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
))
16339 if (!info
->attrs
[NL80211_ATTR_MLO_LINK_ID
])
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
])
16353 nla_data(info
->attrs
[NL80211_ATTR_HT_CAPABILITY
]);
16355 if (info
->attrs
[NL80211_ATTR_VHT_CAPABILITY
])
16357 nla_data(info
->attrs
[NL80211_ATTR_VHT_CAPABILITY
]);
16359 if (info
->attrs
[NL80211_ATTR_HE_CAPABILITY
]) {
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
]) {
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
,
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
, ¶ms
.txpwr
,
16390 ¶ms
.txpwr_set
);
16395 return rdev_add_link_station(rdev
, dev
, ¶ms
);
16397 return rdev_mod_link_station(rdev
, dev
, ¶ms
);
16401 nl80211_add_link_station(struct sk_buff
*skb
, struct genl_info
*info
)
16403 return nl80211_add_mod_link_station(skb
, info
, true);
16407 nl80211_modify_link_station(struct sk_buff
*skb
, struct genl_info
*info
)
16409 return nl80211_add_mod_link_station(skb
, info
, false);
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
])
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
, ¶ms
);
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
]);
16450 nla_get_flag(info
->attrs
[NL80211_ATTR_HW_TIMESTAMP_ENABLED
]);
16452 return rdev_set_hw_timestamp(rdev
, dev
, &hwts
);
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
)
16470 if (!info
->attrs
[NL80211_ATTR_MLO_TTLM_DLINK
] ||
16471 !info
->attrs
[NL80211_ATTR_MLO_TTLM_ULINK
])
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
, ¶ms
);
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(_
)
16566 static u32 nl80211_internal_flags
[] = {
16567 #define SELECTOR(_, name, value) [NL80211_IFL_SEL_##name] = value,
16568 INTERNAL_FLAG_SELECTORS(_
)
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
;
16582 if (WARN_ON(ops
->internal_flags
>= ARRAY_SIZE(nl80211_internal_flags
)))
16585 internal_flags
= nl80211_internal_flags
[ops
->internal_flags
];
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
);
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
),
16599 if (IS_ERR(wdev
)) {
16600 err
= PTR_ERR(wdev
);
16604 dev
= wdev
->netdev
;
16606 rdev
= wiphy_to_rdev(wdev
->wiphy
);
16608 if (internal_flags
& NL80211_FLAG_NEED_NETDEV
) {
16614 info
->user_ptr
[1] = dev
;
16616 info
->user_ptr
[1] = wdev
;
16619 if (internal_flags
& NL80211_FLAG_CHECK_NETDEV_UP
&&
16620 !wdev_running(wdev
)) {
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
];
16636 /* MLO -> require valid link ID */
16637 if (wdev
->valid_links
&&
16639 !(wdev
->valid_links
& BIT(nla_get_u8(link_id
))))) {
16644 /* non-MLO -> no link ID attribute accepted */
16645 if (!wdev
->valid_links
&& link_id
) {
16651 if (internal_flags
& NL80211_FLAG_MLO_UNSUPPORTED
) {
16652 if (info
->attrs
[NL80211_ATTR_MLO_LINK_ID
] ||
16653 (wdev
&& wdev
->valid_links
)) {
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
))
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
);
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
)
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
)
16723 if (!spec
[NL80211_SAR_ATTR_SPECS_POWER
] ||
16724 !spec
[NL80211_SAR_ATTR_SPECS_RANGE_INDEX
])
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
)
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
)
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
;
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
;
16758 if (!rdev
->wiphy
.sar_capa
|| !rdev
->ops
->set_sar_specs
)
16759 return -EOPNOTSUPP
;
16761 if (!info
->attrs
[NL80211_ATTR_SAR_SPEC
])
16764 nla_parse_nested(tb
, NL80211_SAR_ATTR_MAX
,
16765 info
->attrs
[NL80211_ATTR_SAR_SPEC
],
16768 if (!tb
[NL80211_SAR_ATTR_TYPE
] || !tb
[NL80211_SAR_ATTR_SPECS
])
16771 type
= nla_get_u32(tb
[NL80211_SAR_ATTR_TYPE
]);
16772 if (type
!= rdev
->wiphy
.sar_capa
->type
)
16776 nla_for_each_nested(spec_list
, tb
[NL80211_SAR_ATTR_SPECS
], rem
)
16779 if (specs
> rdev
->wiphy
.sar_capa
->num_freq_ranges
)
16782 sar_spec
= kzalloc(struct_size(sar_spec
, sub_specs
, specs
), GFP_KERNEL
);
16786 sar_spec
->type
= type
;
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
);
16793 case NL80211_SAR_TYPE_POWER
:
16794 if (nl80211_set_sar_sub_specs(rdev
, sar_spec
,
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
;
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
,
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
,
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
),
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
),
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
),
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
,
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
);
17713 if (nl80211_send_wiphy(rdev
, cmd
, msg
, 0, 0, 0, &state
) < 0) {
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
);
17732 if (nl80211_send_iface(msg
, 0, 0, 0, rdev
, wdev
, cmd
) < 0) {
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
;
17747 struct cfg80211_scan_info
*info
;
17752 nest
= nla_nest_start_noflag(msg
, NL80211_ATTR_SCAN_SSIDS
);
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
);
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
);
17772 nest
= nla_nest_start_noflag(msg
,
17773 NL80211_ATTR_SCAN_FREQUENCIES
);
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
);
17784 nla_put(msg
, NL80211_ATTR_IE
, req
->ie_len
, req
->ie
))
17785 goto nla_put_failure
;
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
,
17798 goto nla_put_failure
;
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
,
17813 hdr
= nl80211hdr_put(msg
, portid
, seq
, flags
, cmd
);
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
),
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
);
17831 genlmsg_cancel(msg
, hdr
);
17836 nl80211_prep_sched_scan_msg(struct sk_buff
*msg
,
17837 struct cfg80211_sched_scan_request
*req
, u32 cmd
)
17841 hdr
= nl80211hdr_put(msg
, 0, 0, 0, cmd
);
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
,
17850 goto nla_put_failure
;
17852 genlmsg_end(msg
, hdr
);
17856 genlmsg_cancel(msg
, hdr
);
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
);
17869 if (nl80211_prep_scan_msg(msg
, rdev
, wdev
, 0, 0, 0,
17870 NL80211_CMD_TRIGGER_SCAN
) < 0) {
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
);
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) {
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
)
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
);
17917 if (nl80211_prep_sched_scan_msg(msg
, req
, cmd
) < 0) {
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
;
17947 if (nla_put_u8(msg
, NL80211_ATTR_REG_TYPE
,
17948 NL80211_REGDOM_TYPE_COUNTRY
) ||
17949 nla_put_string(msg
, NL80211_ATTR_REG_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
);
17958 nla_put_u32(msg
, NL80211_ATTR_WIPHY
, request
->wiphy_idx
))
17959 goto nla_put_failure
;
17962 wiphy
->regulatory_flags
& REGULATORY_WIPHY_SELF_MANAGED
&&
17963 nla_put_flag(msg
, NL80211_ATTR_WIPHY_SELF_MANAGED_REG
))
17964 goto nla_put_failure
;
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
;
17983 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
17987 hdr
= nl80211hdr_put(msg
, 0, 0, 0, cmd_id
);
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
);
18005 struct nl80211_mlme_event
{
18006 enum nl80211_commands cmd
;
18011 size_t req_ies_len
;
18015 static void nl80211_send_mlme_event(struct cfg80211_registered_device
*rdev
,
18016 struct net_device
*netdev
,
18017 const struct nl80211_mlme_event
*event
,
18020 struct sk_buff
*msg
;
18023 msg
= nlmsg_new(100 + event
->buf_len
+ event
->req_ies_len
, gfp
);
18027 hdr
= nl80211hdr_put(msg
, 0, 0, 0, event
->cmd
);
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
) ||
18037 nla_put(msg
, NL80211_ATTR_REQ_IE
, event
->req_ies_len
,
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
);
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
);
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
,
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
,
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
,
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
,
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
,
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
= {
18138 .uapsd_queues
= -1,
18141 if (WARN_ON(len
< 2))
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)
18152 event
.cmd
= NL80211_CMD_UNPROT_BEACON
;
18153 wdev
->unprot_beacon_reported
= jiffies
;
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
;
18170 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
18174 hdr
= nl80211hdr_put(msg
, 0, 0, 0, cmd
);
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
);
18196 void nl80211_send_auth_timeout(struct cfg80211_registered_device
*rdev
,
18197 struct net_device
*netdev
, const u8
*addr
,
18200 nl80211_send_mlme_timeout(rdev
, netdev
, NL80211_CMD_AUTHENTICATE
,
18204 void nl80211_send_assoc_timeout(struct cfg80211_registered_device
*rdev
,
18205 struct net_device
*netdev
, const u8
*addr
,
18208 nl80211_send_mlme_timeout(rdev
, netdev
, NL80211_CMD_ASSOCIATE
,
18212 void nl80211_send_connect_result(struct cfg80211_registered_device
*rdev
,
18213 struct net_device
*netdev
,
18214 struct cfg80211_connect_resp_params
*cr
,
18217 struct sk_buff
*msg
;
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
;
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
,
18246 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_CONNECT
);
18252 if (nla_put_u32(msg
, NL80211_ATTR_WIPHY
, rdev
->wiphy_idx
) ||
18253 nla_put_u32(msg
, NL80211_ATTR_IFINDEX
, netdev
->ifindex
) ||
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
:
18260 (nla_put_flag(msg
, NL80211_ATTR_TIMED_OUT
) ||
18261 nla_put_u32(msg
, NL80211_ATTR_TIMEOUT_REASON
,
18262 cr
->timeout_reason
))) ||
18264 nla_put(msg
, NL80211_ATTR_REQ_IE
, cr
->req_ie_len
, cr
->req_ie
)) ||
18266 nla_put(msg
, NL80211_ATTR_RESP_IE
, cr
->resp_ie_len
,
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
&&
18273 nla_put(msg
, NL80211_ATTR_FILS_KEK
, cr
->fils
.kek_len
,
18276 nla_put(msg
, NL80211_ATTR_PMK
, cr
->fils
.pmk_len
, cr
->fils
.pmk
)) ||
18278 nla_put(msg
, NL80211_ATTR_PMKID
, WLAN_PMKID_LEN
, cr
->fils
.pmkid
)))))
18279 goto nla_put_failure
;
18281 if (cr
->valid_links
) {
18283 struct nlattr
*nested
;
18285 nested
= nla_nest_start(msg
, NL80211_ATTR_MLO_LINKS
);
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
) ||
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
);
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
);
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
;
18331 size_t link_info_size
= 0;
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
;
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
);
18360 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_ROAM
);
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
) ||
18370 nla_put(msg
, NL80211_ATTR_REQ_IE
, info
->req_ie_len
,
18373 nla_put(msg
, NL80211_ATTR_RESP_IE
, info
->resp_ie_len
,
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
)) ||
18379 nla_put(msg
, NL80211_ATTR_FILS_KEK
, info
->fils
.kek_len
,
18380 info
->fils
.kek
)) ||
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
) {
18389 struct nlattr
*nested
;
18391 nested
= nla_nest_start(msg
, NL80211_ATTR_MLO_LINKS
);
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
) ||
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
);
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
);
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
;
18436 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
18440 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED
);
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
);
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
;
18473 msg
= nlmsg_new(100 + ie_len
, GFP_KERNEL
);
18477 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_DISCONNECT
);
18483 if (nla_put_u32(msg
, NL80211_ATTR_WIPHY
, rdev
->wiphy_idx
) ||
18484 nla_put_u32(msg
, NL80211_ATTR_IFINDEX
, netdev
->ifindex
) ||
18486 nla_put_u16(msg
, NL80211_ATTR_REASON_CODE
, reason
)) ||
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
);
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
;
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
))
18518 if (WARN_ON(!wdev
->valid_links
|| !link_mask
||
18519 (wdev
->valid_links
& link_mask
) != link_mask
||
18520 wdev
->valid_links
== link_mask
))
18523 cfg80211_wdev_release_link_bsses(wdev
, link_mask
);
18524 wdev
->valid_links
&= ~link_mask
;
18526 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
18530 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_LINKS_REMOVED
);
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
);
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);
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
);
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
,
18576 struct sk_buff
*msg
;
18579 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
18583 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_JOIN_IBSS
);
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
);
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
;
18613 if (WARN_ON(wdev
->iftype
!= NL80211_IFTYPE_MESH_POINT
))
18616 trace_cfg80211_notify_new_peer_candidate(dev
, addr
);
18618 msg
= nlmsg_new(100 + ie_len
, gfp
);
18622 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE
);
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
) ||
18632 nla_put(msg
, NL80211_ATTR_IE
, ie_len
, ie
)) ||
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
);
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
;
18656 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
18660 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE
);
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
) ||
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
);
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
;
18691 struct nlattr
*nl_freq
;
18693 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_ATOMIC
);
18697 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT
);
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
;
18711 nl_freq
= nla_nest_start_noflag(msg
, NL80211_ATTR_FREQ_BEFORE
);
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
);
18720 nl_freq
= nla_nest_start_noflag(msg
, NL80211_ATTR_FREQ_AFTER
);
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
);
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
;
18748 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
18752 hdr
= nl80211hdr_put(msg
, 0, 0, 0, cmd
);
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
,
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
);
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
;
18793 trace_cfg80211_assoc_comeback(wdev
, ap_addr
, timeout
);
18795 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
18799 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_ASSOC_COMEBACK
);
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
);
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
,
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
,
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
,
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
);
18875 if (nl80211_send_station(msg
, NL80211_CMD_NEW_STATION
, 0, 0, 0,
18876 rdev
, dev
, mac_addr
, sinfo
) < 0) {
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
= {};
18895 sinfo
= &empty_sinfo
;
18897 trace_cfg80211_del_sta(dev
, mac_addr
);
18899 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
18901 cfg80211_sinfo_release_content(sinfo
);
18905 if (nl80211_send_station(msg
, NL80211_CMD_DEL_STATION
, 0, 0, 0,
18906 rdev
, dev
, mac_addr
, sinfo
) < 0) {
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
,
18920 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
18921 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
18922 struct sk_buff
*msg
;
18925 msg
= nlmsg_new(NLMSG_GOODSIZE
, gfp
);
18929 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_CONN_FAILED
);
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
);
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
;
18958 u32 nlportid
= READ_ONCE(wdev
->ap_unexpected_nlportid
);
18963 msg
= nlmsg_new(100, gfp
);
18967 hdr
= nl80211hdr_put(msg
, 0, 0, 0, cmd
);
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
);
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
;
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);
19000 ret
= __nl80211_unexpected_frame(dev
, NL80211_CMD_UNEXPECTED_FRAME
,
19002 trace_cfg80211_return_bool(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
;
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);
19021 ret
= __nl80211_unexpected_frame(dev
,
19022 NL80211_CMD_UNEXPECTED_4ADDR_FRAME
,
19024 trace_cfg80211_return_bool(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
;
19037 msg
= nlmsg_new(100 + info
->len
, gfp
);
19041 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_FRAME
);
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) ||
19057 nla_put_u32(msg
, NL80211_ATTR_RX_SIGNAL_DBM
, info
->sig_dbm
)) ||
19058 nla_put(msg
, NL80211_ATTR_FRAME
, info
->len
, info
->buf
) ||
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
,
19064 NL80211_ATTR_PAD
)) ||
19065 (info
->ack_tstamp
&& nla_put_u64_64bit(msg
,
19066 NL80211_ATTR_TX_HW_TIMESTAMP
,
19068 NL80211_ATTR_PAD
)))
19069 goto nla_put_failure
;
19071 genlmsg_end(msg
, hdr
);
19073 return genlmsg_unicast(wiphy_net(&rdev
->wiphy
), msg
, nlportid
);
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
;
19090 if (command
== NL80211_CMD_FRAME_TX_STATUS
)
19091 trace_cfg80211_mgmt_tx_status(wdev
, status
->cookie
,
19094 trace_cfg80211_control_port_tx_status(wdev
, status
->cookie
,
19097 msg
= nlmsg_new(100 + status
->len
, gfp
);
19101 hdr
= nl80211hdr_put(msg
, 0, 0, 0, command
);
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
);
19134 void cfg80211_control_port_tx_status(struct wireless_dev
*wdev
, u64 cookie
,
19135 const u8
*buf
, size_t len
, bool ack
,
19138 struct cfg80211_tx_status status
= {
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
,
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
;
19170 struct nlattr
*frame
;
19172 u32 nlportid
= READ_ONCE(wdev
->conn_owner_nlportid
);
19177 msg
= nlmsg_new(100 + skb
->len
, gfp
);
19181 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME
);
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
) ||
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
);
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
);
19213 bool cfg80211_rx_control_port(struct net_device
*dev
, struct sk_buff
*skb
,
19214 bool unencrypted
, int link_id
)
19218 trace_cfg80211_rx_control_port(dev
, skb
, unencrypted
, link_id
);
19219 ret
= __nl80211_rx_control_port(dev
, skb
, unencrypted
, link_id
,
19221 trace_cfg80211_return_bool(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
);
19237 cb
= (void **)msg
->cb
;
19239 cb
[0] = nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_NOTIFY_CQM
);
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
);
19254 goto nla_put_failure
;
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
))
19292 cqm_config
= rcu_dereference(wdev
->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
);
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
,
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
;
19312 cqm_config
= wiphy_dereference(wdev
->wiphy
, wdev
->cqm_config
);
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
);
19326 if (nla_put_u32(msg
, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT
,
19328 goto nla_put_failure
;
19330 if (rssi_level
&& nla_put_s32(msg
, NL80211_ATTR_CQM_RSSI_LEVEL
,
19332 goto nla_put_failure
;
19334 cfg80211_send_cqm(msg
, GFP_KERNEL
);
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
);
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
);
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
);
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
);
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
);
19399 if (nla_put_flag(msg
, NL80211_ATTR_CQM_BEACON_LOSS_EVENT
))
19400 goto nla_put_failure
;
19402 cfg80211_send_cqm(msg
, gfp
);
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
;
19418 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
19422 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD
);
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
);
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
);
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
);
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
;
19474 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
19478 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE
);
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
);
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
) ||
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
);
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
,
19527 enum nl80211_commands notif
,
19528 u8 count
, bool quiet
)
19530 struct wireless_dev
*wdev
= netdev
->ieee80211_ptr
;
19531 struct sk_buff
*msg
;
19534 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
19538 hdr
= nl80211hdr_put(msg
, 0, 0, 0, notif
);
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
;
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
);
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
,
19592 case NL80211_IFTYPE_MESH_POINT
:
19593 wdev
->u
.mesh
.chandef
= *chandef
;
19594 wdev
->u
.mesh
.preset_chandef
= *chandef
;
19596 case NL80211_IFTYPE_AP
:
19597 case NL80211_IFTYPE_P2P_GO
:
19598 wdev
->links
[link_id
].ap
.chandef
= *chandef
;
19600 case NL80211_IFTYPE_ADHOC
:
19601 wdev
->u
.ibss
.chandef
= *chandef
;
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
,
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
,
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
;
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
);
19655 hdr
= nl80211hdr_put(msg
, 0, 0, 0, cmd
);
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
);
19684 EXPORT_SYMBOL(cfg80211_bss_color_notify
);
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
;
19695 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
19699 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_RADAR_DETECT
);
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 */
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
),
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
);
19734 void cfg80211_sta_opmode_change_notify(struct net_device
*dev
, const u8
*mac
,
19735 struct sta_opmode_info
*sta_opmode
,
19738 struct sk_buff
*msg
;
19739 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
19740 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
19746 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
19750 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED
);
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
);
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
;
19798 trace_cfg80211_probe_status(dev
, addr
, cookie
, acked
);
19800 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
19805 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_PROBE_CLIENT
);
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
,
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
);
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
;
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
);
19846 spin_unlock_bh(&rdev
->beacon_registrations_lock
);
19850 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_FRAME
);
19852 goto nla_put_failure
;
19854 if (nla_put_u32(msg
, NL80211_ATTR_WIPHY
, rdev
->wiphy_idx
) ||
19856 (nla_put_u32(msg
, NL80211_ATTR_WIPHY_FREQ
,
19857 KHZ_TO_MHZ(freq
)) ||
19858 nla_put_u32(msg
, NL80211_ATTR_WIPHY_FREQ_OFFSET
,
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
);
19873 spin_unlock_bh(&rdev
->beacon_registrations_lock
);
19876 EXPORT_SYMBOL(cfg80211_report_obss_beacon_khz
);
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
;
19886 nl_results
= nla_nest_start_noflag(msg
,
19887 NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS
);
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
);
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
);
19911 if (match
->n_channels
) {
19912 nl_freqs
= nla_nest_start_noflag(msg
,
19913 NL80211_ATTR_SCAN_FREQUENCIES
);
19915 nla_nest_cancel(msg
, nl_match
);
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
);
19927 nla_nest_end(msg
, nl_freqs
);
19930 nla_nest_end(msg
, nl_match
);
19934 nla_nest_end(msg
, nl_results
);
19938 void cfg80211_report_wowlan_wakeup(struct wireless_dev
*wdev
,
19939 struct cfg80211_wowlan_wakeup
*wakeup
,
19942 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
19943 struct sk_buff
*msg
;
19947 trace_cfg80211_report_wowlan_wakeup(wdev
->wiphy
, wdev
, wakeup
);
19950 size
+= wakeup
->packet_present_len
;
19952 msg
= nlmsg_new(size
, gfp
);
19956 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_SET_WOWLAN
);
19960 if (nla_put_u32(msg
, NL80211_ATTR_WIPHY
, rdev
->wiphy_idx
) ||
19961 nla_put_u64_64bit(msg
, NL80211_ATTR_WDEV
, wdev_id(wdev
),
19965 if (wdev
->netdev
&& nla_put_u32(msg
, NL80211_ATTR_IFINDEX
,
19966 wdev
->netdev
->ifindex
))
19970 struct nlattr
*reasons
;
19972 reasons
= nla_nest_start_noflag(msg
,
19973 NL80211_ATTR_WOWLAN_TRIGGERS
);
19977 if (wakeup
->disconnect
&&
19978 nla_put_flag(msg
, NL80211_WOWLAN_TRIG_DISCONNECT
))
19980 if (wakeup
->magic_pkt
&&
19981 nla_put_flag(msg
, NL80211_WOWLAN_TRIG_MAGIC_PKT
))
19983 if (wakeup
->gtk_rekey_failure
&&
19984 nla_put_flag(msg
, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE
))
19986 if (wakeup
->eap_identity_req
&&
19987 nla_put_flag(msg
, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST
))
19989 if (wakeup
->four_way_handshake
&&
19990 nla_put_flag(msg
, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE
))
19992 if (wakeup
->rfkill_release
&&
19993 nla_put_flag(msg
, NL80211_WOWLAN_TRIG_RFKILL_RELEASE
))
19996 if (wakeup
->pattern_idx
>= 0 &&
19997 nla_put_u32(msg
, NL80211_WOWLAN_TRIG_PKT_PATTERN
,
19998 wakeup
->pattern_idx
))
20001 if (wakeup
->tcp_match
&&
20002 nla_put_flag(msg
, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH
))
20005 if (wakeup
->tcp_connlost
&&
20006 nla_put_flag(msg
, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST
))
20009 if (wakeup
->tcp_nomoretokens
&&
20011 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS
))
20014 if (wakeup
->unprot_deauth_disassoc
&&
20016 NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC
))
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
) {
20025 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023
;
20027 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN
;
20030 if (wakeup
->packet_len
&&
20031 nla_put_u32(msg
, len_attr
, wakeup
->packet_len
))
20034 if (nla_put(msg
, pkt_attr
, wakeup
->packet_present_len
,
20039 if (wakeup
->net_detect
&&
20040 cfg80211_net_detect_results(msg
, wakeup
))
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
);
20055 EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup
);
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
;
20067 trace_cfg80211_tdls_oper_request(wdev
->wiphy
, dev
, peer
, oper
,
20070 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
20074 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_TDLS_OPER
);
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
);
20097 EXPORT_SYMBOL(cfg80211_tdls_oper_request
);
20099 static int nl80211_netlink_notify(struct notifier_block
* nb
,
20100 unsigned long state
,
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
;
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
,
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
,
20142 if (reg
->nlportid
== notify
->portid
) {
20143 list_del(®
->list
);
20148 spin_unlock_bh(&rdev
->beacon_registrations_lock
);
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
);
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
;
20173 trace_cfg80211_ft_event(wiphy
, netdev
, ft_event
);
20175 if (!ft_event
->target_ap
)
20178 msg
= nlmsg_new(100 + ft_event
->ies_len
+ ft_event
->ric_ies_len
,
20183 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_FT_EVENT
);
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
))
20192 if (ft_event
->ies
&&
20193 nla_put(msg
, NL80211_ATTR_IE
, ft_event
->ies_len
, ft_event
->ies
))
20195 if (ft_event
->ric_ies
&&
20196 nla_put(msg
, NL80211_ATTR_IE_RIC
, ft_event
->ric_ies_len
,
20197 ft_event
->ric_ies
))
20200 genlmsg_end(msg
, hdr
);
20202 genlmsg_multicast_netns(&nl80211_fam
, wiphy_net(&rdev
->wiphy
), msg
, 0,
20203 NL80211_MCGRP_MLME
, GFP_KERNEL
);
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
;
20217 rdev
= wiphy_to_rdev(wdev
->wiphy
);
20218 if (!rdev
->crit_proto_nlportid
)
20221 nlportid
= rdev
->crit_proto_nlportid
;
20222 rdev
->crit_proto_nlportid
= 0;
20224 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
20228 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP
);
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
),
20235 goto nla_put_failure
;
20237 genlmsg_end(msg
, hdr
);
20239 genlmsg_unicast(wiphy_net(&rdev
->wiphy
), msg
, nlportid
);
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
;
20254 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
20258 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_STOP_AP
);
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
)))
20270 genlmsg_end(msg
, hdr
);
20272 genlmsg_multicast_netns(&nl80211_fam
, wiphy_net(wiphy
), msg
, 0,
20273 NL80211_MCGRP_MLME
, GFP_KERNEL
);
20279 int cfg80211_external_auth_request(struct net_device
*dev
,
20280 struct cfg80211_external_auth_params
*params
,
20283 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
20284 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
20285 struct sk_buff
*msg
;
20288 if (!wdev
->conn_owner_nlportid
)
20291 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
20295 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH
);
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
;
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
,
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
);
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
,
20343 struct wiphy
*wiphy
= netdev
->ieee80211_ptr
->wiphy
;
20344 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
20345 struct sk_buff
*msg
;
20348 trace_cfg80211_update_owe_info_event(wiphy
, netdev
, owe_info
);
20350 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, gfp
);
20354 hdr
= nl80211hdr_put(msg
, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO
);
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
);
20385 genlmsg_cancel(msg
, hdr
);
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)
20410 err
= genl_register_family(&nl80211_fam
);
20414 err
= netlink_register_notifier(&nl80211_netlink_notifier
);
20420 genl_unregister_family(&nl80211_fam
);
20424 void nl80211_exit(void)
20426 netlink_unregister_notifier(&nl80211_netlink_notifier
);
20427 genl_unregister_family(&nl80211_fam
);