lib80211: don't use skcipher
[linux-block.git] / net / wireless / nl80211.c
CommitLineData
55682965
JB
1/*
2 * This is the new netlink-based wireless configuration interface.
3 *
026331c4 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
2740f0cf 5 * Copyright 2013-2014 Intel Mobile Communications GmbH
66cd794e 6 * Copyright 2015-2017 Intel Deutschland GmbH
50f32718 7 * Copyright (C) 2018 Intel Corporation
55682965
JB
8 */
9
10#include <linux/if.h>
11#include <linux/module.h>
12#include <linux/err.h>
5a0e3ad6 13#include <linux/slab.h>
55682965
JB
14#include <linux/list.h>
15#include <linux/if_ether.h>
16#include <linux/ieee80211.h>
17#include <linux/nl80211.h>
18#include <linux/rtnetlink.h>
19#include <linux/netlink.h>
259d8c1e 20#include <linux/nospec.h>
2a519311 21#include <linux/etherdevice.h>
463d0183 22#include <net/net_namespace.h>
55682965
JB
23#include <net/genetlink.h>
24#include <net/cfg80211.h>
463d0183 25#include <net/sock.h>
2a0e047e 26#include <net/inet_connection_sock.h>
55682965
JB
27#include "core.h"
28#include "nl80211.h"
b2e1b302 29#include "reg.h"
e35e4d28 30#include "rdev-ops.h"
55682965 31
5fb628e9
JM
32static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
33 struct genl_info *info,
34 struct cfg80211_crypto_settings *settings,
35 int cipher_limit);
36
55682965 37/* the netlink family */
489111e5 38static struct genl_family nl80211_fam;
55682965 39
2a94fe48
JB
40/* multicast groups */
41enum nl80211_multicast_groups {
42 NL80211_MCGRP_CONFIG,
43 NL80211_MCGRP_SCAN,
44 NL80211_MCGRP_REGULATORY,
45 NL80211_MCGRP_MLME,
567ffc35 46 NL80211_MCGRP_VENDOR,
50bcd31d 47 NL80211_MCGRP_NAN,
2a94fe48
JB
48 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
49};
50
51static const struct genl_multicast_group nl80211_mcgrps[] = {
71b836ec
JB
52 [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
53 [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
54 [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
55 [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
56 [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
50bcd31d 57 [NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
2a94fe48 58#ifdef CONFIG_NL80211_TESTMODE
71b836ec 59 [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
2a94fe48
JB
60#endif
61};
62
89a54e48
JB
63/* returns ERR_PTR values */
64static struct wireless_dev *
65__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
55682965 66{
89a54e48
JB
67 struct cfg80211_registered_device *rdev;
68 struct wireless_dev *result = NULL;
69 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
70 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
71 u64 wdev_id;
72 int wiphy_idx = -1;
73 int ifidx = -1;
55682965 74
5fe231e8 75 ASSERT_RTNL();
55682965 76
89a54e48
JB
77 if (!have_ifidx && !have_wdev_id)
78 return ERR_PTR(-EINVAL);
55682965 79
89a54e48
JB
80 if (have_ifidx)
81 ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
82 if (have_wdev_id) {
83 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
84 wiphy_idx = wdev_id >> 32;
55682965
JB
85 }
86
89a54e48
JB
87 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
88 struct wireless_dev *wdev;
89
90 if (wiphy_net(&rdev->wiphy) != netns)
91 continue;
92
93 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
94 continue;
95
53873f13 96 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
89a54e48
JB
97 if (have_ifidx && wdev->netdev &&
98 wdev->netdev->ifindex == ifidx) {
99 result = wdev;
100 break;
101 }
102 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
103 result = wdev;
104 break;
105 }
106 }
89a54e48
JB
107
108 if (result)
109 break;
110 }
111
112 if (result)
113 return result;
114 return ERR_PTR(-ENODEV);
55682965
JB
115}
116
a9455408 117static struct cfg80211_registered_device *
878d9ec7 118__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
a9455408 119{
7fee4778
JB
120 struct cfg80211_registered_device *rdev = NULL, *tmp;
121 struct net_device *netdev;
a9455408 122
5fe231e8 123 ASSERT_RTNL();
a9455408 124
878d9ec7 125 if (!attrs[NL80211_ATTR_WIPHY] &&
89a54e48
JB
126 !attrs[NL80211_ATTR_IFINDEX] &&
127 !attrs[NL80211_ATTR_WDEV])
7fee4778
JB
128 return ERR_PTR(-EINVAL);
129
878d9ec7 130 if (attrs[NL80211_ATTR_WIPHY])
7fee4778 131 rdev = cfg80211_rdev_by_wiphy_idx(
878d9ec7 132 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
a9455408 133
89a54e48
JB
134 if (attrs[NL80211_ATTR_WDEV]) {
135 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
136 struct wireless_dev *wdev;
137 bool found = false;
138
139 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
140 if (tmp) {
141 /* make sure wdev exists */
53873f13 142 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
89a54e48
JB
143 if (wdev->identifier != (u32)wdev_id)
144 continue;
145 found = true;
146 break;
147 }
89a54e48
JB
148
149 if (!found)
150 tmp = NULL;
151
152 if (rdev && tmp != rdev)
153 return ERR_PTR(-EINVAL);
154 rdev = tmp;
155 }
156 }
157
878d9ec7
JB
158 if (attrs[NL80211_ATTR_IFINDEX]) {
159 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
7a087e74 160
7f2b8562 161 netdev = __dev_get_by_index(netns, ifindex);
7fee4778
JB
162 if (netdev) {
163 if (netdev->ieee80211_ptr)
f26cbf40
ZG
164 tmp = wiphy_to_rdev(
165 netdev->ieee80211_ptr->wiphy);
7fee4778
JB
166 else
167 tmp = NULL;
168
7fee4778
JB
169 /* not wireless device -- return error */
170 if (!tmp)
171 return ERR_PTR(-EINVAL);
172
173 /* mismatch -- return error */
174 if (rdev && tmp != rdev)
175 return ERR_PTR(-EINVAL);
176
177 rdev = tmp;
a9455408 178 }
a9455408 179 }
a9455408 180
4f7eff10
JB
181 if (!rdev)
182 return ERR_PTR(-ENODEV);
a9455408 183
4f7eff10
JB
184 if (netns != wiphy_net(&rdev->wiphy))
185 return ERR_PTR(-ENODEV);
186
187 return rdev;
a9455408
JB
188}
189
190/*
191 * This function returns a pointer to the driver
192 * that the genl_info item that is passed refers to.
a9455408
JB
193 *
194 * The result of this can be a PTR_ERR and hence must
195 * be checked with IS_ERR() for errors.
196 */
197static struct cfg80211_registered_device *
4f7eff10 198cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
a9455408 199{
5fe231e8 200 return __cfg80211_rdev_from_attrs(netns, info->attrs);
a9455408
JB
201}
202
55682965 203/* policy for the attributes */
81e54d08
PKC
204static const struct nla_policy
205nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
206 [NL80211_FTM_RESP_ATTR_ENABLED] = { .type = NLA_FLAG, },
207 [NL80211_FTM_RESP_ATTR_LCI] = { .type = NLA_BINARY,
208 .len = U8_MAX },
209 [NL80211_FTM_RESP_ATTR_CIVICLOC] = { .type = NLA_BINARY,
210 .len = U8_MAX },
211};
212
8cd4d456 213static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
55682965
JB
214 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
215 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 216 .len = 20-1 },
31888487 217 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 218
72bdcf34 219 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 220 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
3d9d1d66
JB
221 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
222 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
223 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
224
b9a5f8ca
JM
225 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
226 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
227 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
228 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 229 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
3057dbfd 230 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
55682965
JB
231
232 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
233 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
234 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 235
e007b857
EP
236 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
237 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
41ade00f 238
b9454e83 239 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
240 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
241 .len = WLAN_MAX_KEY_LEN },
242 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
243 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
244 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 245 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
e31b8213 246 [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
ed1b6cc7
JB
247
248 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
249 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
250 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
251 .len = IEEE80211_MAX_DATA_LEN },
252 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
253 .len = IEEE80211_MAX_DATA_LEN },
5727ef1b
JB
254 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
255 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
256 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
257 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
258 .len = NL80211_MAX_SUPP_RATES },
2ec600d6 259 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
5727ef1b 260 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 261 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 262 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 263 .len = IEEE80211_MAX_MESH_ID_LEN },
2ec600d6 264 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
9f1ba906 265
b2e1b302
LR
266 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
267 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
268
9f1ba906
JM
269 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
270 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
271 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
272 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
273 .len = NL80211_MAX_SUPP_RATES },
50b12f59 274 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 275
24bdd9f4 276 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 277 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 278
6c739419 279 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
9aed3cc1
JM
280
281 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
282 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
283 .len = IEEE80211_MAX_DATA_LEN },
2a519311
JB
284 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
285 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
286
287 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
288 .len = IEEE80211_MAX_SSID_LEN },
289 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
290 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 291 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 292 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
dc6382ce 293 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
eccb8e8f
JB
294 [NL80211_ATTR_STA_FLAGS2] = {
295 .len = sizeof(struct nl80211_sta_flag_update),
296 },
3f77316c 297 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
298 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
299 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
64bf3d4b 300 [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
b23aa676
SO
301 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
302 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
303 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 304 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 305 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
9361df14 306 [NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN },
9588bbd5
JM
307 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
308 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 309 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
310 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
311 .len = IEEE80211_MAX_DATA_LEN },
312 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ffb9eb3d 313 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
d6dc1a38 314 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 315 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 316 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
317 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
318 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 319 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
320 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
321 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 322 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 323 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 324 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 325 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
9c3990aa 326 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
bbe6ad6d 327 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 328 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 329 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
32e9de84 330 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
9946ecfb
JM
331 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
332 .len = IEEE80211_MAX_DATA_LEN },
333 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
334 .len = IEEE80211_MAX_DATA_LEN },
f4b34b55 335 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 336 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 337 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
338 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
339 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
340 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
341 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
342 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 343 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 344 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
345 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
346 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 347 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
348 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
349 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
350 .len = NL80211_HT_CAPABILITY_LEN
351 },
1d9d9213 352 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 353 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 354 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 355 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 356 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
11b6b5a4 357 [NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, },
f461be3e 358 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
ed473771 359 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
53cabad7
JB
360 [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
361 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
8feb69c7 362 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] = {. type = NLA_U32 },
77765eaf
VT
363 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
364 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
365 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
366 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 367 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
368 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
369 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
370 .len = NL80211_VHT_CAPABILITY_LEN,
371 },
355199e0
JM
372 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
373 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
374 .len = IEEE80211_MAX_DATA_LEN },
5e4b6f56 375 [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
16ef1fe2
SW
376 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
377 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
378 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
9a774c78
AO
379 [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY },
380 [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY },
c01fc9ad
SD
381 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
382 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
5336fa88 383 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 384 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
385 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
386 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
387 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
fa9ffc74
KP
388 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
389 .len = IEEE80211_QOS_MAP_LEN_MAX },
1df4a510
JM
390 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
391 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
df942e7b 392 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
18e5ca65 393 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
34d22ce2 394 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
bab5ab7d 395 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
960d01ac
JB
396 [NL80211_ATTR_TSID] = { .type = NLA_U8 },
397 [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
398 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
18998c38 399 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
ad2b26ab 400 [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
1bdd716c 401 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
4b681c82 402 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
9c748934 403 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
05050753 404 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
34d50519 405 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
38de03d2 406 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
17b94247 407 [NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 },
c6e6a0c8
AE
408 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
409 .len = VHT_MUMIMO_GROUPS_DATA_LEN
410 },
411 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
cb3b7d87 412 [NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 },
8585989d 413 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
a442b761 414 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
348bd456
JM
415 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
416 .len = FILS_MAX_KEK_LEN },
417 [NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
ce0ce13a 418 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
2fa436b3 419 [NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
bf95ecdb 420 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
421 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
422 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
423 },
3093ebbe 424 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
a3caf744
VK
425 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
426 .len = FILS_ERP_MAX_USERNAME_LEN },
427 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
428 .len = FILS_ERP_MAX_REALM_LEN },
429 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
430 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
431 .len = FILS_ERP_MAX_RRK_LEN },
432 [NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
433 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
ca986ad9 434 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
40cbfa90 435 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
52539ca8
THJ
436
437 [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
438 [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
439 [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
c4cbaf79
LC
440 [NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
441 .len = NL80211_HE_MAX_CAPABILITY_LEN },
81e54d08
PKC
442
443 [NL80211_ATTR_FTM_RESPONDER] = {
444 .type = NLA_NESTED,
445 .validation_data = nl80211_ftm_responder_policy,
446 },
55682965
JB
447};
448
e31b8213 449/* policy for the key attributes */
b54452b0 450static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 451 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
452 [NL80211_KEY_IDX] = { .type = NLA_U8 },
453 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 454 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
455 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
456 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
e31b8213 457 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
dbd2fd65
JB
458 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
459};
460
461/* policy for the key default flags */
462static const struct nla_policy
463nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
464 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
465 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
466};
467
f83ace3b 468#ifdef CONFIG_PM
ff1b6e69
JB
469/* policy for WoWLAN attributes */
470static const struct nla_policy
471nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
472 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
473 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
474 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
475 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
476 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
477 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
478 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
479 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 480 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 481 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
482};
483
484static const struct nla_policy
485nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
486 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
487 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
488 [NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
489 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
490 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
491 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
492 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
493 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
494 },
495 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
496 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
497 },
498 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
499 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
500 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
ff1b6e69 501};
f83ace3b 502#endif /* CONFIG_PM */
ff1b6e69 503
be29b99a
AK
504/* policy for coalesce rule attributes */
505static const struct nla_policy
506nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
507 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
508 [NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U32 },
509 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
510};
511
e5497d76
JB
512/* policy for GTK rekey offload attributes */
513static const struct nla_policy
514nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
515 [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
516 [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
517 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
518};
519
a1f1c21c
LC
520static const struct nla_policy
521nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 522 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 523 .len = IEEE80211_MAX_SSID_LEN },
3007e352 524 [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
88e920b4 525 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
a1f1c21c
LC
526};
527
3b06d277
AS
528static const struct nla_policy
529nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
530 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
531 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
532};
533
38de03d2
AS
534static const struct nla_policy
535nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
536 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
537 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
538 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
539 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
540 },
541};
542
a442b761
AB
543/* policy for NAN function attributes */
544static const struct nla_policy
545nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
546 [NL80211_NAN_FUNC_TYPE] = { .type = NLA_U8 },
0a27844c 547 [NL80211_NAN_FUNC_SERVICE_ID] = {
a442b761
AB
548 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
549 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
550 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
551 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
552 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
553 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
554 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = { .len = ETH_ALEN },
555 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
556 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
557 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
558 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
559 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
560 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
561 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
562 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
563 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
564};
565
566/* policy for Service Response Filter attributes */
567static const struct nla_policy
568nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
569 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
570 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
571 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
572 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
573 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
574};
575
ad670233
PX
576/* policy for packet pattern attributes */
577static const struct nla_policy
578nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
579 [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
580 [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
581 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
582};
583
5297c65c 584static int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
97990a06
JB
585 struct cfg80211_registered_device **rdev,
586 struct wireless_dev **wdev)
a043897a 587{
97990a06 588 int err;
a043897a 589
97990a06
JB
590 if (!cb->args[0]) {
591 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
c90c39da 592 genl_family_attrbuf(&nl80211_fam),
fceb6435 593 nl80211_fam.maxattr, nl80211_policy, NULL);
97990a06 594 if (err)
ea90e0dc 595 return err;
67748893 596
c90c39da 597 *wdev = __cfg80211_wdev_from_attrs(
5297c65c 598 sock_net(cb->skb->sk),
c90c39da 599 genl_family_attrbuf(&nl80211_fam));
ea90e0dc
JB
600 if (IS_ERR(*wdev))
601 return PTR_ERR(*wdev);
f26cbf40 602 *rdev = wiphy_to_rdev((*wdev)->wiphy);
c319d50b
JB
603 /* 0 is the first index - add 1 to parse only once */
604 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
605 cb->args[1] = (*wdev)->identifier;
606 } else {
c319d50b
JB
607 /* subtract the 1 again here */
608 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
97990a06 609 struct wireless_dev *tmp;
67748893 610
ea90e0dc
JB
611 if (!wiphy)
612 return -ENODEV;
f26cbf40 613 *rdev = wiphy_to_rdev(wiphy);
97990a06 614 *wdev = NULL;
67748893 615
53873f13 616 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
617 if (tmp->identifier == cb->args[1]) {
618 *wdev = tmp;
619 break;
620 }
621 }
67748893 622
ea90e0dc
JB
623 if (!*wdev)
624 return -ENODEV;
67748893
JB
625 }
626
67748893 627 return 0;
67748893
JB
628}
629
f4a11bb0
JB
630/* IE validation */
631static bool is_valid_ie_attr(const struct nlattr *attr)
632{
633 const u8 *pos;
634 int len;
635
636 if (!attr)
637 return true;
638
639 pos = nla_data(attr);
640 len = nla_len(attr);
641
642 while (len) {
643 u8 elemlen;
644
645 if (len < 2)
646 return false;
647 len -= 2;
648
649 elemlen = pos[1];
650 if (elemlen > len)
651 return false;
652
653 len -= elemlen;
654 pos += 2 + elemlen;
655 }
656
657 return true;
658}
659
55682965 660/* message building helper */
15e47304 661static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
55682965
JB
662 int flags, u8 cmd)
663{
664 /* since there is no private header just add the generic one */
15e47304 665 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
666}
667
50f32718
HD
668static int nl80211_msg_put_wmm_rules(struct sk_buff *msg,
669 const struct ieee80211_reg_rule *rule)
670{
671 int j;
672 struct nlattr *nl_wmm_rules =
673 nla_nest_start(msg, NL80211_FREQUENCY_ATTR_WMM);
674
675 if (!nl_wmm_rules)
676 goto nla_put_failure;
677
678 for (j = 0; j < IEEE80211_NUM_ACS; j++) {
679 struct nlattr *nl_wmm_rule = nla_nest_start(msg, j);
680
681 if (!nl_wmm_rule)
682 goto nla_put_failure;
683
684 if (nla_put_u16(msg, NL80211_WMMR_CW_MIN,
38cb87ee 685 rule->wmm_rule.client[j].cw_min) ||
50f32718 686 nla_put_u16(msg, NL80211_WMMR_CW_MAX,
38cb87ee 687 rule->wmm_rule.client[j].cw_max) ||
50f32718 688 nla_put_u8(msg, NL80211_WMMR_AIFSN,
38cb87ee 689 rule->wmm_rule.client[j].aifsn) ||
d3c89bbc
HD
690 nla_put_u16(msg, NL80211_WMMR_TXOP,
691 rule->wmm_rule.client[j].cot))
50f32718
HD
692 goto nla_put_failure;
693
694 nla_nest_end(msg, nl_wmm_rule);
695 }
696 nla_nest_end(msg, nl_wmm_rules);
697
698 return 0;
699
700nla_put_failure:
701 return -ENOBUFS;
702}
703
704static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
cdc89b97
JB
705 struct ieee80211_channel *chan,
706 bool large)
5dab3b8a 707{
ea077c1c
RL
708 /* Some channels must be completely excluded from the
709 * list to protect old user-space tools from breaking
710 */
711 if (!large && chan->flags &
712 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
713 return 0;
714
9360ffd1
DM
715 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
716 chan->center_freq))
717 goto nla_put_failure;
5dab3b8a 718
9360ffd1
DM
719 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
720 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
721 goto nla_put_failure;
8fe02e16
LR
722 if (chan->flags & IEEE80211_CHAN_NO_IR) {
723 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
724 goto nla_put_failure;
725 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
726 goto nla_put_failure;
727 }
cdc89b97
JB
728 if (chan->flags & IEEE80211_CHAN_RADAR) {
729 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
730 goto nla_put_failure;
731 if (large) {
732 u32 time;
733
734 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
735
736 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
737 chan->dfs_state))
738 goto nla_put_failure;
739 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
740 time))
741 goto nla_put_failure;
089027e5
JD
742 if (nla_put_u32(msg,
743 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
744 chan->dfs_cac_ms))
745 goto nla_put_failure;
cdc89b97
JB
746 }
747 }
5dab3b8a 748
fe1abafd
JB
749 if (large) {
750 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
751 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
752 goto nla_put_failure;
753 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
754 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
755 goto nla_put_failure;
756 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
757 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
758 goto nla_put_failure;
759 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
760 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
761 goto nla_put_failure;
570dbde1
DS
762 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
763 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
764 goto nla_put_failure;
06f207fc
AN
765 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
766 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 767 goto nla_put_failure;
ea077c1c
RL
768 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
769 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
770 goto nla_put_failure;
771 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
772 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
773 goto nla_put_failure;
fe1abafd
JB
774 }
775
9360ffd1
DM
776 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
777 DBM_TO_MBM(chan->max_power)))
778 goto nla_put_failure;
5dab3b8a 779
50f32718
HD
780 if (large) {
781 const struct ieee80211_reg_rule *rule =
b88d26d9 782 freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
50f32718 783
38cb87ee 784 if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) {
50f32718
HD
785 if (nl80211_msg_put_wmm_rules(msg, rule))
786 goto nla_put_failure;
787 }
788 }
789
5dab3b8a
LR
790 return 0;
791
792 nla_put_failure:
793 return -ENOBUFS;
794}
795
52539ca8
THJ
796static bool nl80211_put_txq_stats(struct sk_buff *msg,
797 struct cfg80211_txq_stats *txqstats,
798 int attrtype)
799{
800 struct nlattr *txqattr;
801
802#define PUT_TXQVAL_U32(attr, memb) do { \
803 if (txqstats->filled & BIT(NL80211_TXQ_STATS_ ## attr) && \
804 nla_put_u32(msg, NL80211_TXQ_STATS_ ## attr, txqstats->memb)) \
805 return false; \
806 } while (0)
807
808 txqattr = nla_nest_start(msg, attrtype);
809 if (!txqattr)
810 return false;
811
812 PUT_TXQVAL_U32(BACKLOG_BYTES, backlog_bytes);
813 PUT_TXQVAL_U32(BACKLOG_PACKETS, backlog_packets);
814 PUT_TXQVAL_U32(FLOWS, flows);
815 PUT_TXQVAL_U32(DROPS, drops);
816 PUT_TXQVAL_U32(ECN_MARKS, ecn_marks);
817 PUT_TXQVAL_U32(OVERLIMIT, overlimit);
818 PUT_TXQVAL_U32(OVERMEMORY, overmemory);
819 PUT_TXQVAL_U32(COLLISIONS, collisions);
820 PUT_TXQVAL_U32(TX_BYTES, tx_bytes);
821 PUT_TXQVAL_U32(TX_PACKETS, tx_packets);
822 PUT_TXQVAL_U32(MAX_FLOWS, max_flows);
823 nla_nest_end(msg, txqattr);
824
825#undef PUT_TXQVAL_U32
826 return true;
827}
828
55682965
JB
829/* netlink command implementations */
830
b9454e83
JB
831struct key_parse {
832 struct key_params p;
833 int idx;
e31b8213 834 int type;
b9454e83 835 bool def, defmgmt;
dbd2fd65 836 bool def_uni, def_multi;
b9454e83
JB
837};
838
768075eb
JB
839static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
840 struct key_parse *k)
b9454e83
JB
841{
842 struct nlattr *tb[NL80211_KEY_MAX + 1];
843 int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
768075eb 844 nl80211_key_policy, info->extack);
b9454e83
JB
845 if (err)
846 return err;
847
848 k->def = !!tb[NL80211_KEY_DEFAULT];
849 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
850
dbd2fd65
JB
851 if (k->def) {
852 k->def_uni = true;
853 k->def_multi = true;
854 }
855 if (k->defmgmt)
856 k->def_multi = true;
857
b9454e83
JB
858 if (tb[NL80211_KEY_IDX])
859 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
860
861 if (tb[NL80211_KEY_DATA]) {
862 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
863 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
864 }
865
866 if (tb[NL80211_KEY_SEQ]) {
867 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
868 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
869 }
870
871 if (tb[NL80211_KEY_CIPHER])
872 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
873
e31b8213
JB
874 if (tb[NL80211_KEY_TYPE]) {
875 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
876 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
768075eb
JB
877 return genl_err_attr(info, -EINVAL,
878 tb[NL80211_KEY_TYPE]);
e31b8213
JB
879 }
880
dbd2fd65
JB
881 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
882 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 883
2da8f419
JB
884 err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
885 tb[NL80211_KEY_DEFAULT_TYPES],
768075eb
JB
886 nl80211_key_default_policy,
887 info->extack);
dbd2fd65
JB
888 if (err)
889 return err;
890
891 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
892 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
893 }
894
b9454e83
JB
895 return 0;
896}
897
898static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
899{
900 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
901 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
902 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
903 }
904
905 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
906 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
907 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
908 }
909
910 if (info->attrs[NL80211_ATTR_KEY_IDX])
911 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
912
913 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
914 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
915
916 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
917 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
918
dbd2fd65
JB
919 if (k->def) {
920 k->def_uni = true;
921 k->def_multi = true;
922 }
923 if (k->defmgmt)
924 k->def_multi = true;
925
e31b8213
JB
926 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
927 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
768075eb
JB
928 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) {
929 GENL_SET_ERR_MSG(info, "key type out of range");
e31b8213 930 return -EINVAL;
768075eb 931 }
e31b8213
JB
932 }
933
dbd2fd65
JB
934 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
935 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
fceb6435
JB
936 int err = nla_parse_nested(kdt,
937 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
938 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
fe52145f
JB
939 nl80211_key_default_policy,
940 info->extack);
dbd2fd65
JB
941 if (err)
942 return err;
943
944 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
945 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
946 }
947
b9454e83
JB
948 return 0;
949}
950
951static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
952{
953 int err;
954
955 memset(k, 0, sizeof(*k));
956 k->idx = -1;
e31b8213 957 k->type = -1;
b9454e83
JB
958
959 if (info->attrs[NL80211_ATTR_KEY])
768075eb 960 err = nl80211_parse_key_new(info, info->attrs[NL80211_ATTR_KEY], k);
b9454e83
JB
961 else
962 err = nl80211_parse_key_old(info, k);
963
964 if (err)
965 return err;
966
768075eb
JB
967 if (k->def && k->defmgmt) {
968 GENL_SET_ERR_MSG(info, "key with def && defmgmt is invalid");
b9454e83 969 return -EINVAL;
768075eb 970 }
b9454e83 971
dbd2fd65 972 if (k->defmgmt) {
768075eb
JB
973 if (k->def_uni || !k->def_multi) {
974 GENL_SET_ERR_MSG(info, "defmgmt key must be mcast");
dbd2fd65 975 return -EINVAL;
768075eb 976 }
dbd2fd65
JB
977 }
978
b9454e83
JB
979 if (k->idx != -1) {
980 if (k->defmgmt) {
768075eb
JB
981 if (k->idx < 4 || k->idx > 5) {
982 GENL_SET_ERR_MSG(info,
983 "defmgmt key idx not 4 or 5");
b9454e83 984 return -EINVAL;
768075eb 985 }
b9454e83 986 } else if (k->def) {
768075eb
JB
987 if (k->idx < 0 || k->idx > 3) {
988 GENL_SET_ERR_MSG(info, "def key idx not 0-3");
b9454e83 989 return -EINVAL;
768075eb 990 }
b9454e83 991 } else {
768075eb
JB
992 if (k->idx < 0 || k->idx > 5) {
993 GENL_SET_ERR_MSG(info, "key idx not 0-5");
b9454e83 994 return -EINVAL;
768075eb 995 }
b9454e83
JB
996 }
997 }
998
999 return 0;
1000}
1001
fffd0934
JB
1002static struct cfg80211_cached_keys *
1003nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
768075eb 1004 struct genl_info *info, bool *no_ht)
fffd0934 1005{
768075eb 1006 struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
fffd0934
JB
1007 struct key_parse parse;
1008 struct nlattr *key;
1009 struct cfg80211_cached_keys *result;
1010 int rem, err, def = 0;
f1c1f17a
JB
1011 bool have_key = false;
1012
1013 nla_for_each_nested(key, keys, rem) {
1014 have_key = true;
1015 break;
1016 }
1017
1018 if (!have_key)
1019 return NULL;
fffd0934
JB
1020
1021 result = kzalloc(sizeof(*result), GFP_KERNEL);
1022 if (!result)
1023 return ERR_PTR(-ENOMEM);
1024
1025 result->def = -1;
fffd0934
JB
1026
1027 nla_for_each_nested(key, keys, rem) {
1028 memset(&parse, 0, sizeof(parse));
1029 parse.idx = -1;
1030
768075eb 1031 err = nl80211_parse_key_new(info, key, &parse);
fffd0934
JB
1032 if (err)
1033 goto error;
1034 err = -EINVAL;
1035 if (!parse.p.key)
1036 goto error;
768075eb
JB
1037 if (parse.idx < 0 || parse.idx > 3) {
1038 GENL_SET_ERR_MSG(info, "key index out of range [0-3]");
fffd0934 1039 goto error;
768075eb 1040 }
fffd0934 1041 if (parse.def) {
768075eb
JB
1042 if (def) {
1043 GENL_SET_ERR_MSG(info,
1044 "only one key can be default");
fffd0934 1045 goto error;
768075eb 1046 }
fffd0934
JB
1047 def = 1;
1048 result->def = parse.idx;
dbd2fd65
JB
1049 if (!parse.def_uni || !parse.def_multi)
1050 goto error;
fffd0934
JB
1051 } else if (parse.defmgmt)
1052 goto error;
1053 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 1054 parse.idx, false, NULL);
fffd0934
JB
1055 if (err)
1056 goto error;
386b1f27
JB
1057 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
1058 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
768075eb 1059 GENL_SET_ERR_MSG(info, "connect key must be WEP");
386b1f27
JB
1060 err = -EINVAL;
1061 goto error;
1062 }
fffd0934
JB
1063 result->params[parse.idx].cipher = parse.p.cipher;
1064 result->params[parse.idx].key_len = parse.p.key_len;
1065 result->params[parse.idx].key = result->data[parse.idx];
1066 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 1067
386b1f27
JB
1068 /* must be WEP key if we got here */
1069 if (no_ht)
1070 *no_ht = true;
fffd0934
JB
1071 }
1072
f1c1f17a
JB
1073 if (result->def < 0) {
1074 err = -EINVAL;
768075eb 1075 GENL_SET_ERR_MSG(info, "need a default/TX key");
f1c1f17a
JB
1076 goto error;
1077 }
1078
fffd0934
JB
1079 return result;
1080 error:
1081 kfree(result);
1082 return ERR_PTR(err);
1083}
1084
1085static int nl80211_key_allowed(struct wireless_dev *wdev)
1086{
1087 ASSERT_WDEV_LOCK(wdev);
1088
fffd0934
JB
1089 switch (wdev->iftype) {
1090 case NL80211_IFTYPE_AP:
1091 case NL80211_IFTYPE_AP_VLAN:
074ac8df 1092 case NL80211_IFTYPE_P2P_GO:
ff973af7 1093 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
1094 break;
1095 case NL80211_IFTYPE_ADHOC:
fffd0934 1096 case NL80211_IFTYPE_STATION:
074ac8df 1097 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 1098 if (!wdev->current_bss)
fffd0934
JB
1099 return -ENOLINK;
1100 break;
de4fcbad 1101 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 1102 case NL80211_IFTYPE_OCB:
de4fcbad 1103 case NL80211_IFTYPE_MONITOR:
cb3b7d87 1104 case NL80211_IFTYPE_NAN:
de4fcbad
JB
1105 case NL80211_IFTYPE_P2P_DEVICE:
1106 case NL80211_IFTYPE_WDS:
1107 case NUM_NL80211_IFTYPES:
fffd0934
JB
1108 return -EINVAL;
1109 }
1110
1111 return 0;
1112}
1113
664834de
JM
1114static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
1115 struct nlattr *tb)
1116{
1117 struct ieee80211_channel *chan;
1118
1119 if (tb == NULL)
1120 return NULL;
1121 chan = ieee80211_get_channel(wiphy, nla_get_u32(tb));
1122 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
1123 return NULL;
1124 return chan;
1125}
1126
7527a782
JB
1127static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
1128{
1129 struct nlattr *nl_modes = nla_nest_start(msg, attr);
1130 int i;
1131
1132 if (!nl_modes)
1133 goto nla_put_failure;
1134
1135 i = 0;
1136 while (ifmodes) {
9360ffd1
DM
1137 if ((ifmodes & 1) && nla_put_flag(msg, i))
1138 goto nla_put_failure;
7527a782
JB
1139 ifmodes >>= 1;
1140 i++;
1141 }
1142
1143 nla_nest_end(msg, nl_modes);
1144 return 0;
1145
1146nla_put_failure:
1147 return -ENOBUFS;
1148}
1149
1150static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1151 struct sk_buff *msg,
1152 bool large)
7527a782
JB
1153{
1154 struct nlattr *nl_combis;
1155 int i, j;
1156
1157 nl_combis = nla_nest_start(msg,
1158 NL80211_ATTR_INTERFACE_COMBINATIONS);
1159 if (!nl_combis)
1160 goto nla_put_failure;
1161
1162 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1163 const struct ieee80211_iface_combination *c;
1164 struct nlattr *nl_combi, *nl_limits;
1165
1166 c = &wiphy->iface_combinations[i];
1167
1168 nl_combi = nla_nest_start(msg, i + 1);
1169 if (!nl_combi)
1170 goto nla_put_failure;
1171
1172 nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
1173 if (!nl_limits)
1174 goto nla_put_failure;
1175
1176 for (j = 0; j < c->n_limits; j++) {
1177 struct nlattr *nl_limit;
1178
1179 nl_limit = nla_nest_start(msg, j + 1);
1180 if (!nl_limit)
1181 goto nla_put_failure;
9360ffd1
DM
1182 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1183 c->limits[j].max))
1184 goto nla_put_failure;
7527a782
JB
1185 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1186 c->limits[j].types))
1187 goto nla_put_failure;
1188 nla_nest_end(msg, nl_limit);
1189 }
1190
1191 nla_nest_end(msg, nl_limits);
1192
9360ffd1
DM
1193 if (c->beacon_int_infra_match &&
1194 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1195 goto nla_put_failure;
1196 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1197 c->num_different_channels) ||
1198 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1199 c->max_interfaces))
1200 goto nla_put_failure;
cdc89b97 1201 if (large &&
8c48b50a
FF
1202 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1203 c->radar_detect_widths) ||
1204 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1205 c->radar_detect_regions)))
cdc89b97 1206 goto nla_put_failure;
0c317a02
PK
1207 if (c->beacon_int_min_gcd &&
1208 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1209 c->beacon_int_min_gcd))
1210 goto nla_put_failure;
7527a782
JB
1211
1212 nla_nest_end(msg, nl_combi);
1213 }
1214
1215 nla_nest_end(msg, nl_combis);
1216
1217 return 0;
1218nla_put_failure:
1219 return -ENOBUFS;
1220}
1221
3713b4e3 1222#ifdef CONFIG_PM
b56cf720
JB
1223static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1224 struct sk_buff *msg)
1225{
964dc9e2 1226 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1227 struct nlattr *nl_tcp;
1228
1229 if (!tcp)
1230 return 0;
1231
1232 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
1233 if (!nl_tcp)
1234 return -ENOBUFS;
1235
1236 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1237 tcp->data_payload_max))
1238 return -ENOBUFS;
1239
1240 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1241 tcp->data_payload_max))
1242 return -ENOBUFS;
1243
1244 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1245 return -ENOBUFS;
1246
1247 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1248 sizeof(*tcp->tok), tcp->tok))
1249 return -ENOBUFS;
1250
1251 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1252 tcp->data_interval_max))
1253 return -ENOBUFS;
1254
1255 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1256 tcp->wake_payload_max))
1257 return -ENOBUFS;
1258
1259 nla_nest_end(msg, nl_tcp);
1260 return 0;
1261}
1262
3713b4e3 1263static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1264 struct cfg80211_registered_device *rdev,
b56cf720 1265 bool large)
55682965 1266{
3713b4e3 1267 struct nlattr *nl_wowlan;
55682965 1268
1b8ec87a 1269 if (!rdev->wiphy.wowlan)
3713b4e3 1270 return 0;
55682965 1271
3713b4e3
JB
1272 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
1273 if (!nl_wowlan)
1274 return -ENOBUFS;
9360ffd1 1275
1b8ec87a 1276 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1277 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1278 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1279 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1280 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1281 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1282 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1283 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1284 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1285 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1286 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1287 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1288 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1289 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1290 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1291 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1292 return -ENOBUFS;
9360ffd1 1293
1b8ec87a 1294 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1295 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1296 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1297 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1298 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1299 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1300 };
9360ffd1 1301
3713b4e3
JB
1302 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1303 sizeof(pat), &pat))
1304 return -ENOBUFS;
1305 }
9360ffd1 1306
75453ccb
LC
1307 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1308 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1309 rdev->wiphy.wowlan->max_nd_match_sets))
1310 return -ENOBUFS;
1311
1b8ec87a 1312 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1313 return -ENOBUFS;
1314
3713b4e3 1315 nla_nest_end(msg, nl_wowlan);
9360ffd1 1316
3713b4e3
JB
1317 return 0;
1318}
1319#endif
9360ffd1 1320
be29b99a 1321static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1322 struct cfg80211_registered_device *rdev)
be29b99a
AK
1323{
1324 struct nl80211_coalesce_rule_support rule;
1325
1b8ec87a 1326 if (!rdev->wiphy.coalesce)
be29b99a
AK
1327 return 0;
1328
1b8ec87a
ZG
1329 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1330 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1331 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1332 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1333 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1334 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1335
1336 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1337 return -ENOBUFS;
1338
1339 return 0;
1340}
1341
c4cbaf79
LC
1342static int
1343nl80211_send_iftype_data(struct sk_buff *msg,
1344 const struct ieee80211_sband_iftype_data *iftdata)
1345{
1346 const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
1347
1348 if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
1349 iftdata->types_mask))
1350 return -ENOBUFS;
1351
1352 if (he_cap->has_he) {
1353 if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
1354 sizeof(he_cap->he_cap_elem.mac_cap_info),
1355 he_cap->he_cap_elem.mac_cap_info) ||
1356 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
1357 sizeof(he_cap->he_cap_elem.phy_cap_info),
1358 he_cap->he_cap_elem.phy_cap_info) ||
1359 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
1360 sizeof(he_cap->he_mcs_nss_supp),
1361 &he_cap->he_mcs_nss_supp) ||
1362 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
1363 sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
1364 return -ENOBUFS;
1365 }
1366
1367 return 0;
1368}
1369
3713b4e3
JB
1370static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1371 struct ieee80211_supported_band *sband)
1372{
1373 struct nlattr *nl_rates, *nl_rate;
1374 struct ieee80211_rate *rate;
1375 int i;
87bbbe22 1376
3713b4e3
JB
1377 /* add HT info */
1378 if (sband->ht_cap.ht_supported &&
1379 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1380 sizeof(sband->ht_cap.mcs),
1381 &sband->ht_cap.mcs) ||
1382 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1383 sband->ht_cap.cap) ||
1384 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1385 sband->ht_cap.ampdu_factor) ||
1386 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1387 sband->ht_cap.ampdu_density)))
1388 return -ENOBUFS;
afe0cbf8 1389
3713b4e3
JB
1390 /* add VHT info */
1391 if (sband->vht_cap.vht_supported &&
1392 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1393 sizeof(sband->vht_cap.vht_mcs),
1394 &sband->vht_cap.vht_mcs) ||
1395 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1396 sband->vht_cap.cap)))
1397 return -ENOBUFS;
f59ac048 1398
c4cbaf79
LC
1399 if (sband->n_iftype_data) {
1400 struct nlattr *nl_iftype_data =
1401 nla_nest_start(msg, NL80211_BAND_ATTR_IFTYPE_DATA);
1402 int err;
1403
1404 if (!nl_iftype_data)
1405 return -ENOBUFS;
1406
1407 for (i = 0; i < sband->n_iftype_data; i++) {
1408 struct nlattr *iftdata;
1409
1410 iftdata = nla_nest_start(msg, i + 1);
1411 if (!iftdata)
1412 return -ENOBUFS;
1413
1414 err = nl80211_send_iftype_data(msg,
1415 &sband->iftype_data[i]);
1416 if (err)
1417 return err;
1418
1419 nla_nest_end(msg, iftdata);
1420 }
1421
1422 nla_nest_end(msg, nl_iftype_data);
1423 }
1424
3713b4e3
JB
1425 /* add bitrates */
1426 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
1427 if (!nl_rates)
1428 return -ENOBUFS;
ee688b00 1429
3713b4e3
JB
1430 for (i = 0; i < sband->n_bitrates; i++) {
1431 nl_rate = nla_nest_start(msg, i);
1432 if (!nl_rate)
1433 return -ENOBUFS;
ee688b00 1434
3713b4e3
JB
1435 rate = &sband->bitrates[i];
1436 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1437 rate->bitrate))
1438 return -ENOBUFS;
1439 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1440 nla_put_flag(msg,
1441 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1442 return -ENOBUFS;
ee688b00 1443
3713b4e3
JB
1444 nla_nest_end(msg, nl_rate);
1445 }
d51626df 1446
3713b4e3 1447 nla_nest_end(msg, nl_rates);
bf0c111e 1448
3713b4e3
JB
1449 return 0;
1450}
ee688b00 1451
3713b4e3
JB
1452static int
1453nl80211_send_mgmt_stypes(struct sk_buff *msg,
1454 const struct ieee80211_txrx_stypes *mgmt_stypes)
1455{
1456 u16 stypes;
1457 struct nlattr *nl_ftypes, *nl_ifs;
1458 enum nl80211_iftype ift;
1459 int i;
ee688b00 1460
3713b4e3
JB
1461 if (!mgmt_stypes)
1462 return 0;
5dab3b8a 1463
3713b4e3
JB
1464 nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES);
1465 if (!nl_ifs)
1466 return -ENOBUFS;
e2f367f2 1467
3713b4e3
JB
1468 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1469 nl_ftypes = nla_nest_start(msg, ift);
1470 if (!nl_ftypes)
1471 return -ENOBUFS;
1472 i = 0;
1473 stypes = mgmt_stypes[ift].tx;
1474 while (stypes) {
1475 if ((stypes & 1) &&
1476 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1477 (i << 4) | IEEE80211_FTYPE_MGMT))
1478 return -ENOBUFS;
1479 stypes >>= 1;
1480 i++;
ee688b00 1481 }
3713b4e3
JB
1482 nla_nest_end(msg, nl_ftypes);
1483 }
ee688b00 1484
3713b4e3 1485 nla_nest_end(msg, nl_ifs);
ee688b00 1486
3713b4e3
JB
1487 nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES);
1488 if (!nl_ifs)
1489 return -ENOBUFS;
ee688b00 1490
3713b4e3
JB
1491 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1492 nl_ftypes = nla_nest_start(msg, ift);
1493 if (!nl_ftypes)
1494 return -ENOBUFS;
1495 i = 0;
1496 stypes = mgmt_stypes[ift].rx;
1497 while (stypes) {
1498 if ((stypes & 1) &&
1499 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1500 (i << 4) | IEEE80211_FTYPE_MGMT))
1501 return -ENOBUFS;
1502 stypes >>= 1;
1503 i++;
1504 }
1505 nla_nest_end(msg, nl_ftypes);
1506 }
1507 nla_nest_end(msg, nl_ifs);
ee688b00 1508
3713b4e3
JB
1509 return 0;
1510}
ee688b00 1511
1794899e
JB
1512#define CMD(op, n) \
1513 do { \
1514 if (rdev->ops->op) { \
1515 i++; \
1516 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1517 goto nla_put_failure; \
1518 } \
1519 } while (0)
1520
1521static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
1522 struct sk_buff *msg)
1523{
1524 int i = 0;
1525
1526 /*
1527 * do *NOT* add anything into this function, new things need to be
1528 * advertised only to new versions of userspace that can deal with
1529 * the split (and they can't possibly care about new features...
1530 */
1531 CMD(add_virtual_intf, NEW_INTERFACE);
1532 CMD(change_virtual_intf, SET_INTERFACE);
1533 CMD(add_key, NEW_KEY);
1534 CMD(start_ap, START_AP);
1535 CMD(add_station, NEW_STATION);
1536 CMD(add_mpath, NEW_MPATH);
1537 CMD(update_mesh_config, SET_MESH_CONFIG);
1538 CMD(change_bss, SET_BSS);
1539 CMD(auth, AUTHENTICATE);
1540 CMD(assoc, ASSOCIATE);
1541 CMD(deauth, DEAUTHENTICATE);
1542 CMD(disassoc, DISASSOCIATE);
1543 CMD(join_ibss, JOIN_IBSS);
1544 CMD(join_mesh, JOIN_MESH);
1545 CMD(set_pmksa, SET_PMKSA);
1546 CMD(del_pmksa, DEL_PMKSA);
1547 CMD(flush_pmksa, FLUSH_PMKSA);
1548 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1549 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1550 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1551 CMD(mgmt_tx, FRAME);
1552 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1553 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1554 i++;
1555 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1556 goto nla_put_failure;
1557 }
1558 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
1559 rdev->ops->join_mesh) {
1560 i++;
1561 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1562 goto nla_put_failure;
1563 }
1564 CMD(set_wds_peer, SET_WDS_PEER);
1565 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1566 CMD(tdls_mgmt, TDLS_MGMT);
1567 CMD(tdls_oper, TDLS_OPER);
1568 }
ca986ad9 1569 if (rdev->wiphy.max_sched_scan_reqs)
1794899e
JB
1570 CMD(sched_scan_start, START_SCHED_SCAN);
1571 CMD(probe_client, PROBE_CLIENT);
1572 CMD(set_noack_map, SET_NOACK_MAP);
1573 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1574 i++;
1575 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1576 goto nla_put_failure;
1577 }
1578 CMD(start_p2p_device, START_P2P_DEVICE);
1579 CMD(set_mcast_rate, SET_MCAST_RATE);
1580#ifdef CONFIG_NL80211_TESTMODE
1581 CMD(testmode_cmd, TESTMODE);
1582#endif
1583
1584 if (rdev->ops->connect || rdev->ops->auth) {
1585 i++;
1586 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1587 goto nla_put_failure;
1588 }
1589
1590 if (rdev->ops->disconnect || rdev->ops->deauth) {
1591 i++;
1592 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1593 goto nla_put_failure;
1594 }
1595
1596 return i;
1597 nla_put_failure:
1598 return -ENOBUFS;
1599}
1600
86e8cf98
JB
1601struct nl80211_dump_wiphy_state {
1602 s64 filter_wiphy;
1603 long start;
019ae3a9 1604 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
1605 bool split;
1606};
1607
1b8ec87a 1608static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 1609 enum nl80211_commands cmd,
3713b4e3 1610 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 1611 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
1612{
1613 void *hdr;
1614 struct nlattr *nl_bands, *nl_band;
1615 struct nlattr *nl_freqs, *nl_freq;
1616 struct nlattr *nl_cmds;
57fbcce3 1617 enum nl80211_band band;
3713b4e3
JB
1618 struct ieee80211_channel *chan;
1619 int i;
1620 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 1621 rdev->wiphy.mgmt_stypes;
fe1abafd 1622 u32 features;
ee688b00 1623
3bb20556 1624 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
1625 if (!hdr)
1626 return -ENOBUFS;
ee688b00 1627
86e8cf98
JB
1628 if (WARN_ON(!state))
1629 return -EINVAL;
ee688b00 1630
1b8ec87a 1631 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 1632 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 1633 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
1634 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1635 cfg80211_rdev_list_generation))
8fdc621d
JB
1636 goto nla_put_failure;
1637
3bb20556
JB
1638 if (cmd != NL80211_CMD_NEW_WIPHY)
1639 goto finish;
1640
86e8cf98 1641 switch (state->split_start) {
3713b4e3
JB
1642 case 0:
1643 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 1644 rdev->wiphy.retry_short) ||
3713b4e3 1645 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 1646 rdev->wiphy.retry_long) ||
3713b4e3 1647 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 1648 rdev->wiphy.frag_threshold) ||
3713b4e3 1649 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 1650 rdev->wiphy.rts_threshold) ||
3713b4e3 1651 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 1652 rdev->wiphy.coverage_class) ||
3713b4e3 1653 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 1654 rdev->wiphy.max_scan_ssids) ||
3713b4e3 1655 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 1656 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 1657 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 1658 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 1659 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 1660 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 1661 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
3b06d277
AS
1662 rdev->wiphy.max_match_sets) ||
1663 nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
1664 rdev->wiphy.max_sched_scan_plans) ||
1665 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
1666 rdev->wiphy.max_sched_scan_plan_interval) ||
1667 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
1668 rdev->wiphy.max_sched_scan_plan_iterations))
9360ffd1 1669 goto nla_put_failure;
3713b4e3 1670
1b8ec87a 1671 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 1672 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 1673 goto nla_put_failure;
1b8ec87a 1674 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
1675 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
1676 goto nla_put_failure;
1b8ec87a 1677 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
1678 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
1679 goto nla_put_failure;
1b8ec87a 1680 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
1681 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
1682 goto nla_put_failure;
1b8ec87a 1683 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
1684 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
1685 goto nla_put_failure;
1b8ec87a 1686 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 1687 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 1688 goto nla_put_failure;
86e8cf98
JB
1689 state->split_start++;
1690 if (state->split)
3713b4e3
JB
1691 break;
1692 case 1:
1693 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
1694 sizeof(u32) * rdev->wiphy.n_cipher_suites,
1695 rdev->wiphy.cipher_suites))
3713b4e3 1696 goto nla_put_failure;
4745fc09 1697
3713b4e3 1698 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 1699 rdev->wiphy.max_num_pmkids))
3713b4e3 1700 goto nla_put_failure;
b23aa676 1701
1b8ec87a 1702 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 1703 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 1704 goto nla_put_failure;
b23aa676 1705
3713b4e3 1706 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 1707 rdev->wiphy.available_antennas_tx) ||
3713b4e3 1708 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 1709 rdev->wiphy.available_antennas_rx))
9360ffd1 1710 goto nla_put_failure;
b23aa676 1711
1b8ec87a 1712 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 1713 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 1714 rdev->wiphy.probe_resp_offload))
3713b4e3 1715 goto nla_put_failure;
8fdc621d 1716
1b8ec87a
ZG
1717 if ((rdev->wiphy.available_antennas_tx ||
1718 rdev->wiphy.available_antennas_rx) &&
1719 rdev->ops->get_antenna) {
3713b4e3
JB
1720 u32 tx_ant = 0, rx_ant = 0;
1721 int res;
7a087e74 1722
1b8ec87a 1723 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
1724 if (!res) {
1725 if (nla_put_u32(msg,
1726 NL80211_ATTR_WIPHY_ANTENNA_TX,
1727 tx_ant) ||
1728 nla_put_u32(msg,
1729 NL80211_ATTR_WIPHY_ANTENNA_RX,
1730 rx_ant))
1731 goto nla_put_failure;
1732 }
1733 }
a293911d 1734
86e8cf98
JB
1735 state->split_start++;
1736 if (state->split)
3713b4e3
JB
1737 break;
1738 case 2:
1739 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 1740 rdev->wiphy.interface_modes))
3713b4e3 1741 goto nla_put_failure;
86e8cf98
JB
1742 state->split_start++;
1743 if (state->split)
3713b4e3
JB
1744 break;
1745 case 3:
1746 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1747 if (!nl_bands)
1748 goto nla_put_failure;
f7ca38df 1749
86e8cf98 1750 for (band = state->band_start;
57fbcce3 1751 band < NUM_NL80211_BANDS; band++) {
3713b4e3 1752 struct ieee80211_supported_band *sband;
2e161f78 1753
1b8ec87a 1754 sband = rdev->wiphy.bands[band];
2e161f78 1755
3713b4e3
JB
1756 if (!sband)
1757 continue;
1758
1759 nl_band = nla_nest_start(msg, band);
1760 if (!nl_band)
2e161f78 1761 goto nla_put_failure;
3713b4e3 1762
86e8cf98 1763 switch (state->chan_start) {
3713b4e3
JB
1764 case 0:
1765 if (nl80211_send_band_rateinfo(msg, sband))
9360ffd1 1766 goto nla_put_failure;
86e8cf98
JB
1767 state->chan_start++;
1768 if (state->split)
3713b4e3
JB
1769 break;
1770 default:
1771 /* add frequencies */
1772 nl_freqs = nla_nest_start(
1773 msg, NL80211_BAND_ATTR_FREQS);
1774 if (!nl_freqs)
1775 goto nla_put_failure;
1776
86e8cf98 1777 for (i = state->chan_start - 1;
3713b4e3
JB
1778 i < sband->n_channels;
1779 i++) {
1780 nl_freq = nla_nest_start(msg, i);
1781 if (!nl_freq)
1782 goto nla_put_failure;
1783
1784 chan = &sband->channels[i];
1785
86e8cf98 1786 if (nl80211_msg_put_channel(
50f32718 1787 msg, &rdev->wiphy, chan,
86e8cf98 1788 state->split))
3713b4e3
JB
1789 goto nla_put_failure;
1790
1791 nla_nest_end(msg, nl_freq);
86e8cf98 1792 if (state->split)
3713b4e3
JB
1793 break;
1794 }
1795 if (i < sband->n_channels)
86e8cf98 1796 state->chan_start = i + 2;
3713b4e3 1797 else
86e8cf98 1798 state->chan_start = 0;
3713b4e3
JB
1799 nla_nest_end(msg, nl_freqs);
1800 }
1801
1802 nla_nest_end(msg, nl_band);
1803
86e8cf98 1804 if (state->split) {
3713b4e3 1805 /* start again here */
86e8cf98 1806 if (state->chan_start)
3713b4e3
JB
1807 band--;
1808 break;
2e161f78 1809 }
2e161f78 1810 }
3713b4e3 1811 nla_nest_end(msg, nl_bands);
2e161f78 1812
57fbcce3 1813 if (band < NUM_NL80211_BANDS)
86e8cf98 1814 state->band_start = band + 1;
3713b4e3 1815 else
86e8cf98 1816 state->band_start = 0;
74b70a4e 1817
3713b4e3 1818 /* if bands & channels are done, continue outside */
86e8cf98
JB
1819 if (state->band_start == 0 && state->chan_start == 0)
1820 state->split_start++;
1821 if (state->split)
3713b4e3
JB
1822 break;
1823 case 4:
1824 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
1825 if (!nl_cmds)
2e161f78
JB
1826 goto nla_put_failure;
1827
1794899e
JB
1828 i = nl80211_add_commands_unsplit(rdev, msg);
1829 if (i < 0)
1830 goto nla_put_failure;
86e8cf98 1831 if (state->split) {
5de17984
AS
1832 CMD(crit_proto_start, CRIT_PROTOCOL_START);
1833 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 1834 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 1835 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 1836 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
1837 if (rdev->wiphy.features &
1838 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 1839 CMD(add_tx_ts, ADD_TX_TS);
ce0ce13a 1840 CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
088e8df8 1841 CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
5de17984 1842 }
3713b4e3 1843#undef CMD
ff1b6e69 1844
3713b4e3 1845 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
1846 state->split_start++;
1847 if (state->split)
3713b4e3
JB
1848 break;
1849 case 5:
1b8ec87a
ZG
1850 if (rdev->ops->remain_on_channel &&
1851 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
1852 nla_put_u32(msg,
1853 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 1854 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
1855 goto nla_put_failure;
1856
1b8ec87a 1857 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
1858 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
1859 goto nla_put_failure;
1860
1861 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
1862 goto nla_put_failure;
86e8cf98
JB
1863 state->split_start++;
1864 if (state->split)
3713b4e3
JB
1865 break;
1866 case 6:
1867#ifdef CONFIG_PM
1b8ec87a 1868 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 1869 goto nla_put_failure;
86e8cf98
JB
1870 state->split_start++;
1871 if (state->split)
3713b4e3
JB
1872 break;
1873#else
86e8cf98 1874 state->split_start++;
dfb89c56 1875#endif
3713b4e3
JB
1876 case 7:
1877 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 1878 rdev->wiphy.software_iftypes))
3713b4e3 1879 goto nla_put_failure;
ff1b6e69 1880
1b8ec87a 1881 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 1882 state->split))
3713b4e3 1883 goto nla_put_failure;
7527a782 1884
86e8cf98
JB
1885 state->split_start++;
1886 if (state->split)
3713b4e3
JB
1887 break;
1888 case 8:
1b8ec87a 1889 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 1890 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 1891 rdev->wiphy.ap_sme_capa))
3713b4e3 1892 goto nla_put_failure;
7527a782 1893
1b8ec87a 1894 features = rdev->wiphy.features;
fe1abafd
JB
1895 /*
1896 * We can only add the per-channel limit information if the
1897 * dump is split, otherwise it makes it too big. Therefore
1898 * only advertise it in that case.
1899 */
86e8cf98 1900 if (state->split)
fe1abafd
JB
1901 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
1902 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 1903 goto nla_put_failure;
562a7480 1904
1b8ec87a 1905 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 1906 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
1907 sizeof(*rdev->wiphy.ht_capa_mod_mask),
1908 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 1909 goto nla_put_failure;
1f074bd8 1910
1b8ec87a
ZG
1911 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
1912 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 1913 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 1914 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 1915 goto nla_put_failure;
7e7c8926 1916
3713b4e3
JB
1917 /*
1918 * Any information below this point is only available to
1919 * applications that can deal with it being split. This
1920 * helps ensure that newly added capabilities don't break
1921 * older tools by overrunning their buffers.
1922 *
1923 * We still increment split_start so that in the split
1924 * case we'll continue with more data in the next round,
1925 * but break unconditionally so unsplit data stops here.
1926 */
86e8cf98 1927 state->split_start++;
3713b4e3
JB
1928 break;
1929 case 9:
1b8ec87a 1930 if (rdev->wiphy.extended_capabilities &&
fe1abafd 1931 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
1932 rdev->wiphy.extended_capabilities_len,
1933 rdev->wiphy.extended_capabilities) ||
fe1abafd 1934 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
1935 rdev->wiphy.extended_capabilities_len,
1936 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 1937 goto nla_put_failure;
a50df0c4 1938
1b8ec87a 1939 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 1940 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
1941 sizeof(*rdev->wiphy.vht_capa_mod_mask),
1942 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
1943 goto nla_put_failure;
1944
be29b99a
AK
1945 state->split_start++;
1946 break;
1947 case 10:
1b8ec87a 1948 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
1949 goto nla_put_failure;
1950
1b8ec87a 1951 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
1952 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
1953 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
1954 goto nla_put_failure;
b43504cf 1955
1b8ec87a 1956 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 1957 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 1958 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
1959 goto nla_put_failure;
1960
ad7e718c
JB
1961 state->split_start++;
1962 break;
1963 case 11:
1b8ec87a 1964 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
1965 const struct nl80211_vendor_cmd_info *info;
1966 struct nlattr *nested;
1967
1968 nested = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1969 if (!nested)
1970 goto nla_put_failure;
1971
1b8ec87a
ZG
1972 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
1973 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
1974 if (nla_put(msg, i + 1, sizeof(*info), info))
1975 goto nla_put_failure;
1976 }
1977 nla_nest_end(msg, nested);
1978 }
1979
1b8ec87a 1980 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
1981 const struct nl80211_vendor_cmd_info *info;
1982 struct nlattr *nested;
ad7e718c 1983
567ffc35
JB
1984 nested = nla_nest_start(msg,
1985 NL80211_ATTR_VENDOR_EVENTS);
1986 if (!nested)
ad7e718c 1987 goto nla_put_failure;
567ffc35 1988
1b8ec87a
ZG
1989 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
1990 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
1991 if (nla_put(msg, i + 1, sizeof(*info), info))
1992 goto nla_put_failure;
1993 }
1994 nla_nest_end(msg, nested);
1995 }
9a774c78
AO
1996 state->split_start++;
1997 break;
1998 case 12:
1999 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
2000 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
2001 rdev->wiphy.max_num_csa_counters))
2002 goto nla_put_failure;
01e0daa4 2003
1bdd716c
AN
2004 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
2005 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
2006 goto nla_put_failure;
2007
ca986ad9
AVS
2008 if (rdev->wiphy.max_sched_scan_reqs &&
2009 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
2010 rdev->wiphy.max_sched_scan_reqs))
2011 goto nla_put_failure;
2012
d75bb06b
GKS
2013 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
2014 sizeof(rdev->wiphy.ext_features),
2015 rdev->wiphy.ext_features))
2016 goto nla_put_failure;
2017
38de03d2
AS
2018 if (rdev->wiphy.bss_select_support) {
2019 struct nlattr *nested;
2020 u32 bss_select_support = rdev->wiphy.bss_select_support;
2021
2022 nested = nla_nest_start(msg, NL80211_ATTR_BSS_SELECT);
2023 if (!nested)
2024 goto nla_put_failure;
2025
2026 i = 0;
2027 while (bss_select_support) {
2028 if ((bss_select_support & 1) &&
2029 nla_put_flag(msg, i))
2030 goto nla_put_failure;
2031 i++;
2032 bss_select_support >>= 1;
2033 }
2034 nla_nest_end(msg, nested);
2035 }
2036
019ae3a9
KV
2037 state->split_start++;
2038 break;
2039 case 13:
2040 if (rdev->wiphy.num_iftype_ext_capab &&
2041 rdev->wiphy.iftype_ext_capab) {
2042 struct nlattr *nested_ext_capab, *nested;
2043
2044 nested = nla_nest_start(msg,
2045 NL80211_ATTR_IFTYPE_EXT_CAPA);
2046 if (!nested)
2047 goto nla_put_failure;
2048
2049 for (i = state->capa_start;
2050 i < rdev->wiphy.num_iftype_ext_capab; i++) {
2051 const struct wiphy_iftype_ext_capab *capab;
2052
2053 capab = &rdev->wiphy.iftype_ext_capab[i];
2054
2055 nested_ext_capab = nla_nest_start(msg, i);
2056 if (!nested_ext_capab ||
2057 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
2058 capab->iftype) ||
2059 nla_put(msg, NL80211_ATTR_EXT_CAPA,
2060 capab->extended_capabilities_len,
2061 capab->extended_capabilities) ||
2062 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
2063 capab->extended_capabilities_len,
2064 capab->extended_capabilities_mask))
2065 goto nla_put_failure;
2066
2067 nla_nest_end(msg, nested_ext_capab);
2068 if (state->split)
2069 break;
2070 }
2071 nla_nest_end(msg, nested);
2072 if (i < rdev->wiphy.num_iftype_ext_capab) {
2073 state->capa_start = i + 1;
2074 break;
2075 }
2076 }
2077
8585989d
LC
2078 if (nla_put_u32(msg, NL80211_ATTR_BANDS,
2079 rdev->wiphy.nan_supported_bands))
2080 goto nla_put_failure;
2081
52539ca8
THJ
2082 if (wiphy_ext_feature_isset(&rdev->wiphy,
2083 NL80211_EXT_FEATURE_TXQS)) {
2084 struct cfg80211_txq_stats txqstats = {};
2085 int res;
2086
2087 res = rdev_get_txq_stats(rdev, NULL, &txqstats);
2088 if (!res &&
2089 !nl80211_put_txq_stats(msg, &txqstats,
2090 NL80211_ATTR_TXQ_STATS))
2091 goto nla_put_failure;
2092
2093 if (nla_put_u32(msg, NL80211_ATTR_TXQ_LIMIT,
2094 rdev->wiphy.txq_limit))
2095 goto nla_put_failure;
2096 if (nla_put_u32(msg, NL80211_ATTR_TXQ_MEMORY_LIMIT,
2097 rdev->wiphy.txq_memory_limit))
2098 goto nla_put_failure;
2099 if (nla_put_u32(msg, NL80211_ATTR_TXQ_QUANTUM,
2100 rdev->wiphy.txq_quantum))
2101 goto nla_put_failure;
2102 }
2103
3713b4e3 2104 /* done */
86e8cf98 2105 state->split_start = 0;
3713b4e3
JB
2106 break;
2107 }
3bb20556 2108 finish:
053c095a
JB
2109 genlmsg_end(msg, hdr);
2110 return 0;
55682965
JB
2111
2112 nla_put_failure:
bc3ed28c
TG
2113 genlmsg_cancel(msg, hdr);
2114 return -EMSGSIZE;
55682965
JB
2115}
2116
86e8cf98
JB
2117static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
2118 struct netlink_callback *cb,
2119 struct nl80211_dump_wiphy_state *state)
2120{
c90c39da 2121 struct nlattr **tb = genl_family_attrbuf(&nl80211_fam);
fceb6435
JB
2122 int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, tb,
2123 nl80211_fam.maxattr, nl80211_policy, NULL);
86e8cf98
JB
2124 /* ignore parse errors for backward compatibility */
2125 if (ret)
2126 return 0;
2127
2128 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
2129 if (tb[NL80211_ATTR_WIPHY])
2130 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2131 if (tb[NL80211_ATTR_WDEV])
2132 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
2133 if (tb[NL80211_ATTR_IFINDEX]) {
2134 struct net_device *netdev;
2135 struct cfg80211_registered_device *rdev;
2136 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
2137
7f2b8562 2138 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
86e8cf98
JB
2139 if (!netdev)
2140 return -ENODEV;
2141 if (netdev->ieee80211_ptr) {
f26cbf40 2142 rdev = wiphy_to_rdev(
86e8cf98
JB
2143 netdev->ieee80211_ptr->wiphy);
2144 state->filter_wiphy = rdev->wiphy_idx;
2145 }
86e8cf98
JB
2146 }
2147
2148 return 0;
2149}
2150
55682965
JB
2151static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
2152{
645e77de 2153 int idx = 0, ret;
86e8cf98 2154 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 2155 struct cfg80211_registered_device *rdev;
3a5a423b 2156
5fe231e8 2157 rtnl_lock();
86e8cf98
JB
2158 if (!state) {
2159 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
2160 if (!state) {
2161 rtnl_unlock();
86e8cf98 2162 return -ENOMEM;
3713b4e3 2163 }
86e8cf98
JB
2164 state->filter_wiphy = -1;
2165 ret = nl80211_dump_wiphy_parse(skb, cb, state);
2166 if (ret) {
2167 kfree(state);
2168 rtnl_unlock();
2169 return ret;
3713b4e3 2170 }
86e8cf98 2171 cb->args[0] = (long)state;
3713b4e3
JB
2172 }
2173
1b8ec87a
ZG
2174 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2175 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2176 continue;
86e8cf98 2177 if (++idx <= state->start)
55682965 2178 continue;
86e8cf98 2179 if (state->filter_wiphy != -1 &&
1b8ec87a 2180 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
2181 continue;
2182 /* attempt to fit multiple wiphy data chunks into the skb */
2183 do {
3bb20556
JB
2184 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
2185 skb,
3713b4e3
JB
2186 NETLINK_CB(cb->skb).portid,
2187 cb->nlh->nlmsg_seq,
86e8cf98 2188 NLM_F_MULTI, state);
3713b4e3
JB
2189 if (ret < 0) {
2190 /*
2191 * If sending the wiphy data didn't fit (ENOBUFS
2192 * or EMSGSIZE returned), this SKB is still
2193 * empty (so it's not too big because another
2194 * wiphy dataset is already in the skb) and
2195 * we've not tried to adjust the dump allocation
2196 * yet ... then adjust the alloc size to be
2197 * bigger, and return 1 but with the empty skb.
2198 * This results in an empty message being RX'ed
2199 * in userspace, but that is ignored.
2200 *
2201 * We can then retry with the larger buffer.
2202 */
2203 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 2204 !skb->len && !state->split &&
3713b4e3
JB
2205 cb->min_dump_alloc < 4096) {
2206 cb->min_dump_alloc = 4096;
f12cb289 2207 state->split_start = 0;
d98cae64 2208 rtnl_unlock();
3713b4e3
JB
2209 return 1;
2210 }
2211 idx--;
2212 break;
645e77de 2213 }
86e8cf98 2214 } while (state->split_start > 0);
3713b4e3 2215 break;
55682965 2216 }
5fe231e8 2217 rtnl_unlock();
55682965 2218
86e8cf98 2219 state->start = idx;
55682965
JB
2220
2221 return skb->len;
2222}
2223
86e8cf98
JB
2224static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
2225{
2226 kfree((void *)cb->args[0]);
2227 return 0;
2228}
2229
55682965
JB
2230static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
2231{
2232 struct sk_buff *msg;
1b8ec87a 2233 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 2234 struct nl80211_dump_wiphy_state state = {};
55682965 2235
645e77de 2236 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 2237 if (!msg)
4c476991 2238 return -ENOMEM;
55682965 2239
3bb20556
JB
2240 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
2241 info->snd_portid, info->snd_seq, 0,
86e8cf98 2242 &state) < 0) {
4c476991
JB
2243 nlmsg_free(msg);
2244 return -ENOBUFS;
2245 }
55682965 2246
134e6375 2247 return genlmsg_reply(msg, info);
55682965
JB
2248}
2249
31888487
JM
2250static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
2251 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
2252 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
2253 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
2254 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
2255 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
2256};
2257
2258static int parse_txq_params(struct nlattr *tb[],
2259 struct ieee80211_txq_params *txq_params)
2260{
259d8c1e
DW
2261 u8 ac;
2262
a3304b0a 2263 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
2264 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
2265 !tb[NL80211_TXQ_ATTR_AIFS])
2266 return -EINVAL;
2267
259d8c1e 2268 ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
2269 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
2270 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
2271 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
2272 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
2273
259d8c1e 2274 if (ac >= NL80211_NUM_ACS)
a3304b0a 2275 return -EINVAL;
259d8c1e 2276 txq_params->ac = array_index_nospec(ac, NL80211_NUM_ACS);
31888487
JM
2277 return 0;
2278}
2279
f444de05
JB
2280static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2281{
2282 /*
cc1d2806
JB
2283 * You can only set the channel explicitly for WDS interfaces,
2284 * all others have their channel managed via their respective
2285 * "establish a connection" command (connect, join, ...)
2286 *
2287 * For AP/GO and mesh mode, the channel can be set with the
2288 * channel userspace API, but is only stored and passed to the
2289 * low-level driver when the AP starts or the mesh is joined.
2290 * This is for backward compatibility, userspace can also give
2291 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
2292 *
2293 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
2294 * whatever else is going on, so they have their own special
2295 * operation to set the monitor channel if possible.
f444de05
JB
2296 */
2297 return !wdev ||
2298 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 2299 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
2300 wdev->iftype == NL80211_IFTYPE_MONITOR ||
2301 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
2302}
2303
683b6d3b
JB
2304static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2305 struct genl_info *info,
2306 struct cfg80211_chan_def *chandef)
2307{
49f9cf0e
JB
2308 struct netlink_ext_ack *extack = info->extack;
2309 struct nlattr **attrs = info->attrs;
dbeca2ea 2310 u32 control_freq;
683b6d3b 2311
49f9cf0e 2312 if (!attrs[NL80211_ATTR_WIPHY_FREQ])
683b6d3b
JB
2313 return -EINVAL;
2314
49f9cf0e 2315 control_freq = nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]);
683b6d3b
JB
2316
2317 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
3d9d1d66
JB
2318 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
2319 chandef->center_freq1 = control_freq;
2320 chandef->center_freq2 = 0;
683b6d3b
JB
2321
2322 /* Primary channel not allowed */
49f9cf0e
JB
2323 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED) {
2324 NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
2325 "Channel is disabled");
683b6d3b 2326 return -EINVAL;
49f9cf0e 2327 }
683b6d3b 2328
49f9cf0e 2329 if (attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
3d9d1d66
JB
2330 enum nl80211_channel_type chantype;
2331
49f9cf0e 2332 chantype = nla_get_u32(attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
3d9d1d66
JB
2333
2334 switch (chantype) {
2335 case NL80211_CHAN_NO_HT:
2336 case NL80211_CHAN_HT20:
2337 case NL80211_CHAN_HT40PLUS:
2338 case NL80211_CHAN_HT40MINUS:
2339 cfg80211_chandef_create(chandef, chandef->chan,
2340 chantype);
ffa4629e 2341 /* user input for center_freq is incorrect */
49f9cf0e
JB
2342 if (attrs[NL80211_ATTR_CENTER_FREQ1] &&
2343 chandef->center_freq1 != nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1])) {
2344 NL_SET_ERR_MSG_ATTR(extack,
2345 attrs[NL80211_ATTR_CENTER_FREQ1],
2346 "bad center frequency 1");
ffa4629e 2347 return -EINVAL;
49f9cf0e 2348 }
ffa4629e 2349 /* center_freq2 must be zero */
49f9cf0e
JB
2350 if (attrs[NL80211_ATTR_CENTER_FREQ2] &&
2351 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2])) {
2352 NL_SET_ERR_MSG_ATTR(extack,
2353 attrs[NL80211_ATTR_CENTER_FREQ2],
2354 "center frequency 2 can't be used");
ffa4629e 2355 return -EINVAL;
49f9cf0e 2356 }
3d9d1d66
JB
2357 break;
2358 default:
49f9cf0e
JB
2359 NL_SET_ERR_MSG_ATTR(extack,
2360 attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
2361 "invalid channel type");
3d9d1d66
JB
2362 return -EINVAL;
2363 }
49f9cf0e 2364 } else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
3d9d1d66 2365 chandef->width =
49f9cf0e
JB
2366 nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
2367 if (attrs[NL80211_ATTR_CENTER_FREQ1])
3d9d1d66 2368 chandef->center_freq1 =
49f9cf0e
JB
2369 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]);
2370 if (attrs[NL80211_ATTR_CENTER_FREQ2])
3d9d1d66 2371 chandef->center_freq2 =
49f9cf0e 2372 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
3d9d1d66
JB
2373 }
2374
49f9cf0e
JB
2375 if (!cfg80211_chandef_valid(chandef)) {
2376 NL_SET_ERR_MSG(extack, "invalid channel definition");
3d9d1d66 2377 return -EINVAL;
49f9cf0e 2378 }
3d9d1d66 2379
9f5e8f6e 2380 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
49f9cf0e
JB
2381 IEEE80211_CHAN_DISABLED)) {
2382 NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
3d9d1d66 2383 return -EINVAL;
49f9cf0e 2384 }
3d9d1d66 2385
2f301ab2
SW
2386 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
2387 chandef->width == NL80211_CHAN_WIDTH_10) &&
49f9cf0e
JB
2388 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ)) {
2389 NL_SET_ERR_MSG(extack, "5/10 MHz not supported");
2f301ab2 2390 return -EINVAL;
49f9cf0e 2391 }
2f301ab2 2392
683b6d3b
JB
2393 return 0;
2394}
2395
f444de05 2396static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 2397 struct net_device *dev,
f444de05
JB
2398 struct genl_info *info)
2399{
683b6d3b 2400 struct cfg80211_chan_def chandef;
f444de05 2401 int result;
e8c9bd5b 2402 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 2403 struct wireless_dev *wdev = NULL;
e8c9bd5b 2404
e16821bc
JM
2405 if (dev)
2406 wdev = dev->ieee80211_ptr;
f444de05
JB
2407 if (!nl80211_can_set_dev_channel(wdev))
2408 return -EOPNOTSUPP;
e16821bc
JM
2409 if (wdev)
2410 iftype = wdev->iftype;
f444de05 2411
683b6d3b
JB
2412 result = nl80211_parse_chandef(rdev, info, &chandef);
2413 if (result)
2414 return result;
f444de05 2415
e8c9bd5b 2416 switch (iftype) {
aa430da4
JB
2417 case NL80211_IFTYPE_AP:
2418 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
2419 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
2420 iftype)) {
aa430da4
JB
2421 result = -EINVAL;
2422 break;
2423 }
e16821bc
JM
2424 if (wdev->beacon_interval) {
2425 if (!dev || !rdev->ops->set_ap_chanwidth ||
2426 !(rdev->wiphy.features &
2427 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
2428 result = -EBUSY;
2429 break;
2430 }
2431
2432 /* Only allow dynamic channel width changes */
2433 if (chandef.chan != wdev->preset_chandef.chan) {
2434 result = -EBUSY;
2435 break;
2436 }
2437 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
2438 if (result)
2439 break;
2440 }
683b6d3b 2441 wdev->preset_chandef = chandef;
aa430da4
JB
2442 result = 0;
2443 break;
cc1d2806 2444 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 2445 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 2446 break;
e8c9bd5b 2447 case NL80211_IFTYPE_MONITOR:
683b6d3b 2448 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 2449 break;
aa430da4 2450 default:
e8c9bd5b 2451 result = -EINVAL;
f444de05 2452 }
f444de05
JB
2453
2454 return result;
2455}
2456
2457static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
2458{
4c476991
JB
2459 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2460 struct net_device *netdev = info->user_ptr[1];
f444de05 2461
e16821bc 2462 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
2463}
2464
e8347eba
BJ
2465static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
2466{
43b19952
JB
2467 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2468 struct net_device *dev = info->user_ptr[1];
2469 struct wireless_dev *wdev = dev->ieee80211_ptr;
388ac775 2470 const u8 *bssid;
e8347eba
BJ
2471
2472 if (!info->attrs[NL80211_ATTR_MAC])
2473 return -EINVAL;
2474
43b19952
JB
2475 if (netif_running(dev))
2476 return -EBUSY;
e8347eba 2477
43b19952
JB
2478 if (!rdev->ops->set_wds_peer)
2479 return -EOPNOTSUPP;
e8347eba 2480
43b19952
JB
2481 if (wdev->iftype != NL80211_IFTYPE_WDS)
2482 return -EOPNOTSUPP;
e8347eba
BJ
2483
2484 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
e35e4d28 2485 return rdev_set_wds_peer(rdev, dev, bssid);
e8347eba
BJ
2486}
2487
55682965
JB
2488static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2489{
2490 struct cfg80211_registered_device *rdev;
f444de05
JB
2491 struct net_device *netdev = NULL;
2492 struct wireless_dev *wdev;
a1e567c8 2493 int result = 0, rem_txq_params = 0;
31888487 2494 struct nlattr *nl_txq_params;
b9a5f8ca
JM
2495 u32 changed;
2496 u8 retry_short = 0, retry_long = 0;
2497 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 2498 u8 coverage_class = 0;
52539ca8 2499 u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
55682965 2500
5fe231e8
JB
2501 ASSERT_RTNL();
2502
f444de05
JB
2503 /*
2504 * Try to find the wiphy and netdev. Normally this
2505 * function shouldn't need the netdev, but this is
2506 * done for backward compatibility -- previously
2507 * setting the channel was done per wiphy, but now
2508 * it is per netdev. Previous userland like hostapd
2509 * also passed a netdev to set_wiphy, so that it is
2510 * possible to let that go to the right netdev!
2511 */
4bbf4d56 2512
f444de05
JB
2513 if (info->attrs[NL80211_ATTR_IFINDEX]) {
2514 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
2515
7f2b8562 2516 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 2517 if (netdev && netdev->ieee80211_ptr)
f26cbf40 2518 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 2519 else
f444de05 2520 netdev = NULL;
4bbf4d56
JB
2521 }
2522
f444de05 2523 if (!netdev) {
878d9ec7
JB
2524 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
2525 info->attrs);
5fe231e8 2526 if (IS_ERR(rdev))
4c476991 2527 return PTR_ERR(rdev);
f444de05
JB
2528 wdev = NULL;
2529 netdev = NULL;
2530 result = 0;
71fe96bf 2531 } else
f444de05 2532 wdev = netdev->ieee80211_ptr;
f444de05
JB
2533
2534 /*
2535 * end workaround code, by now the rdev is available
2536 * and locked, and wdev may or may not be NULL.
2537 */
4bbf4d56
JB
2538
2539 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
2540 result = cfg80211_dev_rename(
2541 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56 2542
4bbf4d56 2543 if (result)
7f2b8562 2544 return result;
31888487
JM
2545
2546 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
2547 struct ieee80211_txq_params txq_params;
2548 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
2549
7f2b8562
YX
2550 if (!rdev->ops->set_txq_params)
2551 return -EOPNOTSUPP;
31888487 2552
7f2b8562
YX
2553 if (!netdev)
2554 return -EINVAL;
f70f01c2 2555
133a3ff2 2556 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
7f2b8562
YX
2557 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2558 return -EINVAL;
133a3ff2 2559
7f2b8562
YX
2560 if (!netif_running(netdev))
2561 return -ENETDOWN;
2b5f8b0b 2562
31888487
JM
2563 nla_for_each_nested(nl_txq_params,
2564 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
2565 rem_txq_params) {
bfe2c7b1
JB
2566 result = nla_parse_nested(tb, NL80211_TXQ_ATTR_MAX,
2567 nl_txq_params,
fe52145f
JB
2568 txq_params_policy,
2569 info->extack);
ae811e21
JB
2570 if (result)
2571 return result;
31888487
JM
2572 result = parse_txq_params(tb, &txq_params);
2573 if (result)
7f2b8562 2574 return result;
31888487 2575
e35e4d28
HG
2576 result = rdev_set_txq_params(rdev, netdev,
2577 &txq_params);
31888487 2578 if (result)
7f2b8562 2579 return result;
31888487
JM
2580 }
2581 }
55682965 2582
72bdcf34 2583 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
2584 result = __nl80211_set_channel(
2585 rdev,
2586 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
2587 info);
72bdcf34 2588 if (result)
7f2b8562 2589 return result;
72bdcf34
JM
2590 }
2591
98d2ff8b 2592 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 2593 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
2594 enum nl80211_tx_power_setting type;
2595 int idx, mbm = 0;
2596
c8442118
JB
2597 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
2598 txp_wdev = NULL;
2599
7f2b8562
YX
2600 if (!rdev->ops->set_tx_power)
2601 return -EOPNOTSUPP;
98d2ff8b
JO
2602
2603 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
2604 type = nla_get_u32(info->attrs[idx]);
2605
2606 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
7f2b8562
YX
2607 (type != NL80211_TX_POWER_AUTOMATIC))
2608 return -EINVAL;
98d2ff8b
JO
2609
2610 if (type != NL80211_TX_POWER_AUTOMATIC) {
2611 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
2612 mbm = nla_get_u32(info->attrs[idx]);
2613 }
2614
c8442118 2615 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 2616 if (result)
7f2b8562 2617 return result;
98d2ff8b
JO
2618 }
2619
afe0cbf8
BR
2620 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
2621 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
2622 u32 tx_ant, rx_ant;
7a087e74 2623
7f531e03
BR
2624 if ((!rdev->wiphy.available_antennas_tx &&
2625 !rdev->wiphy.available_antennas_rx) ||
7f2b8562
YX
2626 !rdev->ops->set_antenna)
2627 return -EOPNOTSUPP;
afe0cbf8
BR
2628
2629 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
2630 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
2631
a7ffac95 2632 /* reject antenna configurations which don't match the
7f531e03
BR
2633 * available antenna masks, except for the "all" mask */
2634 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
7f2b8562
YX
2635 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
2636 return -EINVAL;
a7ffac95 2637
7f531e03
BR
2638 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
2639 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 2640
e35e4d28 2641 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 2642 if (result)
7f2b8562 2643 return result;
afe0cbf8
BR
2644 }
2645
b9a5f8ca
JM
2646 changed = 0;
2647
2648 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
2649 retry_short = nla_get_u8(
2650 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562
YX
2651 if (retry_short == 0)
2652 return -EINVAL;
2653
b9a5f8ca
JM
2654 changed |= WIPHY_PARAM_RETRY_SHORT;
2655 }
2656
2657 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
2658 retry_long = nla_get_u8(
2659 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562
YX
2660 if (retry_long == 0)
2661 return -EINVAL;
2662
b9a5f8ca
JM
2663 changed |= WIPHY_PARAM_RETRY_LONG;
2664 }
2665
2666 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
2667 frag_threshold = nla_get_u32(
2668 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
7f2b8562
YX
2669 if (frag_threshold < 256)
2670 return -EINVAL;
2671
b9a5f8ca
JM
2672 if (frag_threshold != (u32) -1) {
2673 /*
2674 * Fragments (apart from the last one) are required to
2675 * have even length. Make the fragmentation code
2676 * simpler by stripping LSB should someone try to use
2677 * odd threshold value.
2678 */
2679 frag_threshold &= ~0x1;
2680 }
2681 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
2682 }
2683
2684 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
2685 rts_threshold = nla_get_u32(
2686 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
2687 changed |= WIPHY_PARAM_RTS_THRESHOLD;
2688 }
2689
81077e82 2690 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
3057dbfd
LB
2691 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK])
2692 return -EINVAL;
2693
81077e82
LT
2694 coverage_class = nla_get_u8(
2695 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
2696 changed |= WIPHY_PARAM_COVERAGE_CLASS;
2697 }
2698
3057dbfd
LB
2699 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
2700 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION))
2701 return -EOPNOTSUPP;
2702
2703 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
2704 }
2705
52539ca8
THJ
2706 if (info->attrs[NL80211_ATTR_TXQ_LIMIT]) {
2707 if (!wiphy_ext_feature_isset(&rdev->wiphy,
2708 NL80211_EXT_FEATURE_TXQS))
2709 return -EOPNOTSUPP;
2710 txq_limit = nla_get_u32(
2711 info->attrs[NL80211_ATTR_TXQ_LIMIT]);
2712 changed |= WIPHY_PARAM_TXQ_LIMIT;
2713 }
2714
2715 if (info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]) {
2716 if (!wiphy_ext_feature_isset(&rdev->wiphy,
2717 NL80211_EXT_FEATURE_TXQS))
2718 return -EOPNOTSUPP;
2719 txq_memory_limit = nla_get_u32(
2720 info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);
2721 changed |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;
2722 }
2723
2724 if (info->attrs[NL80211_ATTR_TXQ_QUANTUM]) {
2725 if (!wiphy_ext_feature_isset(&rdev->wiphy,
2726 NL80211_EXT_FEATURE_TXQS))
2727 return -EOPNOTSUPP;
2728 txq_quantum = nla_get_u32(
2729 info->attrs[NL80211_ATTR_TXQ_QUANTUM]);
2730 changed |= WIPHY_PARAM_TXQ_QUANTUM;
2731 }
2732
b9a5f8ca
JM
2733 if (changed) {
2734 u8 old_retry_short, old_retry_long;
2735 u32 old_frag_threshold, old_rts_threshold;
81077e82 2736 u8 old_coverage_class;
52539ca8 2737 u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
b9a5f8ca 2738
7f2b8562
YX
2739 if (!rdev->ops->set_wiphy_params)
2740 return -EOPNOTSUPP;
b9a5f8ca
JM
2741
2742 old_retry_short = rdev->wiphy.retry_short;
2743 old_retry_long = rdev->wiphy.retry_long;
2744 old_frag_threshold = rdev->wiphy.frag_threshold;
2745 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 2746 old_coverage_class = rdev->wiphy.coverage_class;
52539ca8
THJ
2747 old_txq_limit = rdev->wiphy.txq_limit;
2748 old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
2749 old_txq_quantum = rdev->wiphy.txq_quantum;
b9a5f8ca
JM
2750
2751 if (changed & WIPHY_PARAM_RETRY_SHORT)
2752 rdev->wiphy.retry_short = retry_short;
2753 if (changed & WIPHY_PARAM_RETRY_LONG)
2754 rdev->wiphy.retry_long = retry_long;
2755 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
2756 rdev->wiphy.frag_threshold = frag_threshold;
2757 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
2758 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
2759 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
2760 rdev->wiphy.coverage_class = coverage_class;
52539ca8
THJ
2761 if (changed & WIPHY_PARAM_TXQ_LIMIT)
2762 rdev->wiphy.txq_limit = txq_limit;
2763 if (changed & WIPHY_PARAM_TXQ_MEMORY_LIMIT)
2764 rdev->wiphy.txq_memory_limit = txq_memory_limit;
2765 if (changed & WIPHY_PARAM_TXQ_QUANTUM)
2766 rdev->wiphy.txq_quantum = txq_quantum;
b9a5f8ca 2767
e35e4d28 2768 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
2769 if (result) {
2770 rdev->wiphy.retry_short = old_retry_short;
2771 rdev->wiphy.retry_long = old_retry_long;
2772 rdev->wiphy.frag_threshold = old_frag_threshold;
2773 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 2774 rdev->wiphy.coverage_class = old_coverage_class;
52539ca8
THJ
2775 rdev->wiphy.txq_limit = old_txq_limit;
2776 rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
2777 rdev->wiphy.txq_quantum = old_txq_quantum;
9189ee31 2778 return result;
b9a5f8ca
JM
2779 }
2780 }
7f2b8562 2781 return 0;
55682965
JB
2782}
2783
71bbc994
JB
2784static inline u64 wdev_id(struct wireless_dev *wdev)
2785{
2786 return (u64)wdev->identifier |
f26cbf40 2787 ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32);
71bbc994 2788}
55682965 2789
683b6d3b 2790static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 2791 const struct cfg80211_chan_def *chandef)
683b6d3b 2792{
601555cd
JB
2793 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
2794 return -EINVAL;
3d9d1d66 2795
683b6d3b
JB
2796 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
2797 chandef->chan->center_freq))
2798 return -ENOBUFS;
3d9d1d66
JB
2799 switch (chandef->width) {
2800 case NL80211_CHAN_WIDTH_20_NOHT:
2801 case NL80211_CHAN_WIDTH_20:
2802 case NL80211_CHAN_WIDTH_40:
2803 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2804 cfg80211_get_chandef_type(chandef)))
2805 return -ENOBUFS;
2806 break;
2807 default:
2808 break;
2809 }
2810 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
2811 return -ENOBUFS;
2812 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
2813 return -ENOBUFS;
2814 if (chandef->center_freq2 &&
2815 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
2816 return -ENOBUFS;
2817 return 0;
2818}
2819
15e47304 2820static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 2821 struct cfg80211_registered_device *rdev,
8f894be2 2822 struct wireless_dev *wdev, bool removal)
55682965 2823{
72fb2abc 2824 struct net_device *dev = wdev->netdev;
8f894be2 2825 u8 cmd = NL80211_CMD_NEW_INTERFACE;
55682965
JB
2826 void *hdr;
2827
8f894be2
TB
2828 if (removal)
2829 cmd = NL80211_CMD_DEL_INTERFACE;
2830
2831 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
2832 if (!hdr)
2833 return -1;
2834
72fb2abc
JB
2835 if (dev &&
2836 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 2837 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
2838 goto nla_put_failure;
2839
2840 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2841 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
2842 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
2843 NL80211_ATTR_PAD) ||
98104fde 2844 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
2845 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2846 rdev->devlist_generation ^
446faa15
AQ
2847 (cfg80211_rdev_list_generation << 2)) ||
2848 nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
9360ffd1 2849 goto nla_put_failure;
f5ea9120 2850
5b7ccaf3 2851 if (rdev->ops->get_channel) {
683b6d3b
JB
2852 int ret;
2853 struct cfg80211_chan_def chandef;
2854
2855 ret = rdev_get_channel(rdev, wdev, &chandef);
2856 if (ret == 0) {
2857 if (nl80211_send_chandef(msg, &chandef))
2858 goto nla_put_failure;
2859 }
d91df0e3
PF
2860 }
2861
d55d0d59
RM
2862 if (rdev->ops->get_tx_power) {
2863 int dbm, ret;
2864
2865 ret = rdev_get_tx_power(rdev, wdev, &dbm);
2866 if (ret == 0 &&
2867 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
2868 DBM_TO_MBM(dbm)))
2869 goto nla_put_failure;
2870 }
2871
44905265
JB
2872 wdev_lock(wdev);
2873 switch (wdev->iftype) {
2874 case NL80211_IFTYPE_AP:
2875 if (wdev->ssid_len &&
2876 nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
4564b187 2877 goto nla_put_failure_locked;
44905265
JB
2878 break;
2879 case NL80211_IFTYPE_STATION:
2880 case NL80211_IFTYPE_P2P_CLIENT:
2881 case NL80211_IFTYPE_ADHOC: {
2882 const u8 *ssid_ie;
2883 if (!wdev->current_bss)
2884 break;
7a94b8c2 2885 rcu_read_lock();
44905265
JB
2886 ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub,
2887 WLAN_EID_SSID);
7a94b8c2
DB
2888 if (ssid_ie &&
2889 nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2))
2890 goto nla_put_failure_rcu_locked;
2891 rcu_read_unlock();
44905265
JB
2892 break;
2893 }
2894 default:
2895 /* nothing */
2896 break;
b84e7a05 2897 }
44905265 2898 wdev_unlock(wdev);
b84e7a05 2899
52539ca8
THJ
2900 if (rdev->ops->get_txq_stats) {
2901 struct cfg80211_txq_stats txqstats = {};
2902 int ret = rdev_get_txq_stats(rdev, wdev, &txqstats);
2903
2904 if (ret == 0 &&
2905 !nl80211_put_txq_stats(msg, &txqstats,
2906 NL80211_ATTR_TXQ_STATS))
2907 goto nla_put_failure;
2908 }
2909
053c095a
JB
2910 genlmsg_end(msg, hdr);
2911 return 0;
55682965 2912
7a94b8c2
DB
2913 nla_put_failure_rcu_locked:
2914 rcu_read_unlock();
4564b187
JB
2915 nla_put_failure_locked:
2916 wdev_unlock(wdev);
55682965 2917 nla_put_failure:
bc3ed28c
TG
2918 genlmsg_cancel(msg, hdr);
2919 return -EMSGSIZE;
55682965
JB
2920}
2921
2922static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
2923{
2924 int wp_idx = 0;
2925 int if_idx = 0;
2926 int wp_start = cb->args[0];
2927 int if_start = cb->args[1];
b7fb44da 2928 int filter_wiphy = -1;
f5ea9120 2929 struct cfg80211_registered_device *rdev;
55682965 2930 struct wireless_dev *wdev;
ea90e0dc 2931 int ret;
55682965 2932
5fe231e8 2933 rtnl_lock();
b7fb44da
DK
2934 if (!cb->args[2]) {
2935 struct nl80211_dump_wiphy_state state = {
2936 .filter_wiphy = -1,
2937 };
b7fb44da
DK
2938
2939 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
2940 if (ret)
ea90e0dc 2941 goto out_unlock;
b7fb44da
DK
2942
2943 filter_wiphy = state.filter_wiphy;
2944
2945 /*
2946 * if filtering, set cb->args[2] to +1 since 0 is the default
2947 * value needed to determine that parsing is necessary.
2948 */
2949 if (filter_wiphy >= 0)
2950 cb->args[2] = filter_wiphy + 1;
2951 else
2952 cb->args[2] = -1;
2953 } else if (cb->args[2] > 0) {
2954 filter_wiphy = cb->args[2] - 1;
2955 }
2956
f5ea9120
JB
2957 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2958 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2959 continue;
bba95fef
JB
2960 if (wp_idx < wp_start) {
2961 wp_idx++;
55682965 2962 continue;
bba95fef 2963 }
b7fb44da
DK
2964
2965 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
2966 continue;
2967
55682965
JB
2968 if_idx = 0;
2969
53873f13 2970 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
2971 if (if_idx < if_start) {
2972 if_idx++;
55682965 2973 continue;
bba95fef 2974 }
15e47304 2975 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 2976 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8f894be2 2977 rdev, wdev, false) < 0) {
bba95fef
JB
2978 goto out;
2979 }
2980 if_idx++;
55682965 2981 }
bba95fef
JB
2982
2983 wp_idx++;
55682965 2984 }
bba95fef 2985 out:
55682965
JB
2986 cb->args[0] = wp_idx;
2987 cb->args[1] = if_idx;
2988
ea90e0dc
JB
2989 ret = skb->len;
2990 out_unlock:
2991 rtnl_unlock();
2992
2993 return ret;
55682965
JB
2994}
2995
2996static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
2997{
2998 struct sk_buff *msg;
1b8ec87a 2999 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 3000 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3001
fd2120ca 3002 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 3003 if (!msg)
4c476991 3004 return -ENOMEM;
55682965 3005
15e47304 3006 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 3007 rdev, wdev, false) < 0) {
4c476991
JB
3008 nlmsg_free(msg);
3009 return -ENOBUFS;
3010 }
55682965 3011
134e6375 3012 return genlmsg_reply(msg, info);
55682965
JB
3013}
3014
66f7ac50
MW
3015static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
3016 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
3017 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
3018 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
3019 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
3020 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 3021 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
3022};
3023
3024static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
3025{
3026 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
3027 int flag;
3028
3029 *mntrflags = 0;
3030
3031 if (!nla)
3032 return -EINVAL;
3033
fceb6435
JB
3034 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX, nla,
3035 mntr_flags_policy, NULL))
66f7ac50
MW
3036 return -EINVAL;
3037
3038 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
3039 if (flags[flag])
3040 *mntrflags |= (1<<flag);
3041
818a986e
JB
3042 *mntrflags |= MONITOR_FLAG_CHANGED;
3043
66f7ac50
MW
3044 return 0;
3045}
3046
1db77596
JB
3047static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
3048 enum nl80211_iftype type,
3049 struct genl_info *info,
3050 struct vif_params *params)
3051{
3052 bool change = false;
3053 int err;
3054
3055 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
3056 if (type != NL80211_IFTYPE_MONITOR)
3057 return -EINVAL;
3058
3059 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
3060 &params->flags);
3061 if (err)
3062 return err;
3063
3064 change = true;
3065 }
3066
3067 if (params->flags & MONITOR_FLAG_ACTIVE &&
3068 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
3069 return -EOPNOTSUPP;
3070
3071 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
3072 const u8 *mumimo_groups;
3073 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3074
3075 if (type != NL80211_IFTYPE_MONITOR)
3076 return -EINVAL;
3077
3078 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3079 return -EOPNOTSUPP;
3080
3081 mumimo_groups =
3082 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
3083
3084 /* bits 0 and 63 are reserved and must be zero */
4954601f
JB
3085 if ((mumimo_groups[0] & BIT(0)) ||
3086 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(7)))
1db77596
JB
3087 return -EINVAL;
3088
3089 params->vht_mumimo_groups = mumimo_groups;
3090 change = true;
3091 }
3092
3093 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
3094 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3095
3096 if (type != NL80211_IFTYPE_MONITOR)
3097 return -EINVAL;
3098
3099 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3100 return -EOPNOTSUPP;
3101
3102 params->vht_mumimo_follow_addr =
3103 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
3104 change = true;
3105 }
3106
3107 return change ? 1 : 0;
3108}
3109
9bc383de 3110static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
3111 struct net_device *netdev, u8 use_4addr,
3112 enum nl80211_iftype iftype)
9bc383de 3113{
ad4bb6f8 3114 if (!use_4addr) {
f350a0a8 3115 if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT))
ad4bb6f8 3116 return -EBUSY;
9bc383de 3117 return 0;
ad4bb6f8 3118 }
9bc383de
JB
3119
3120 switch (iftype) {
3121 case NL80211_IFTYPE_AP_VLAN:
3122 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
3123 return 0;
3124 break;
3125 case NL80211_IFTYPE_STATION:
3126 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
3127 return 0;
3128 break;
3129 default:
3130 break;
3131 }
3132
3133 return -EOPNOTSUPP;
3134}
3135
55682965
JB
3136static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
3137{
4c476991 3138 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3139 struct vif_params params;
e36d56b6 3140 int err;
04a773ad 3141 enum nl80211_iftype otype, ntype;
4c476991 3142 struct net_device *dev = info->user_ptr[1];
ac7f9cfa 3143 bool change = false;
55682965 3144
2ec600d6
LCC
3145 memset(&params, 0, sizeof(params));
3146
04a773ad 3147 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 3148
723b038d 3149 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 3150 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 3151 if (otype != ntype)
ac7f9cfa 3152 change = true;
4c476991
JB
3153 if (ntype > NL80211_IFTYPE_MAX)
3154 return -EINVAL;
723b038d
JB
3155 }
3156
92ffe055 3157 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
3158 struct wireless_dev *wdev = dev->ieee80211_ptr;
3159
4c476991
JB
3160 if (ntype != NL80211_IFTYPE_MESH_POINT)
3161 return -EINVAL;
29cbe68c
JB
3162 if (netif_running(dev))
3163 return -EBUSY;
3164
3165 wdev_lock(wdev);
3166 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
3167 IEEE80211_MAX_MESH_ID_LEN);
3168 wdev->mesh_id_up_len =
3169 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
3170 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
3171 wdev->mesh_id_up_len);
3172 wdev_unlock(wdev);
2ec600d6
LCC
3173 }
3174
8b787643
FF
3175 if (info->attrs[NL80211_ATTR_4ADDR]) {
3176 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
3177 change = true;
ad4bb6f8 3178 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 3179 if (err)
4c476991 3180 return err;
8b787643
FF
3181 } else {
3182 params.use_4addr = -1;
3183 }
3184
1db77596
JB
3185 err = nl80211_parse_mon_options(rdev, ntype, info, &params);
3186 if (err < 0)
3187 return err;
3188 if (err > 0)
c6e6a0c8 3189 change = true;
e057d3c3 3190
ac7f9cfa 3191 if (change)
818a986e 3192 err = cfg80211_change_iface(rdev, dev, ntype, &params);
ac7f9cfa
JB
3193 else
3194 err = 0;
60719ffd 3195
9bc383de
JB
3196 if (!err && params.use_4addr != -1)
3197 dev->ieee80211_ptr->use_4addr = params.use_4addr;
3198
55682965
JB
3199 return err;
3200}
3201
3202static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
3203{
4c476991 3204 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3205 struct vif_params params;
84efbb84 3206 struct wireless_dev *wdev;
896ff063 3207 struct sk_buff *msg;
55682965
JB
3208 int err;
3209 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
3210
78f22b6a
JB
3211 /* to avoid failing a new interface creation due to pending removal */
3212 cfg80211_destroy_ifaces(rdev);
3213
2ec600d6
LCC
3214 memset(&params, 0, sizeof(params));
3215
55682965
JB
3216 if (!info->attrs[NL80211_ATTR_IFNAME])
3217 return -EINVAL;
3218
3219 if (info->attrs[NL80211_ATTR_IFTYPE]) {
3220 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
3221 if (type > NL80211_IFTYPE_MAX)
3222 return -EINVAL;
3223 }
3224
79c97e97 3225 if (!rdev->ops->add_virtual_intf ||
4c476991
JB
3226 !(rdev->wiphy.interface_modes & (1 << type)))
3227 return -EOPNOTSUPP;
55682965 3228
cb3b7d87 3229 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
3230 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
3231 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
3232 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
3233 ETH_ALEN);
3234 if (!is_valid_ether_addr(params.macaddr))
3235 return -EADDRNOTAVAIL;
3236 }
3237
9bc383de 3238 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 3239 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 3240 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 3241 if (err)
4c476991 3242 return err;
9bc383de 3243 }
8b787643 3244
1db77596
JB
3245 err = nl80211_parse_mon_options(rdev, type, info, &params);
3246 if (err < 0)
3247 return err;
e057d3c3 3248
a18c7192
JB
3249 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3250 if (!msg)
3251 return -ENOMEM;
3252
e35e4d28
HG
3253 wdev = rdev_add_virtual_intf(rdev,
3254 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
818a986e 3255 NET_NAME_USER, type, &params);
d687cbb7
RM
3256 if (WARN_ON(!wdev)) {
3257 nlmsg_free(msg);
3258 return -EPROTO;
3259 } else if (IS_ERR(wdev)) {
1c90f9d4 3260 nlmsg_free(msg);
84efbb84 3261 return PTR_ERR(wdev);
1c90f9d4 3262 }
2ec600d6 3263
18e5ca65 3264 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
3265 wdev->owner_nlportid = info->snd_portid;
3266
98104fde
JB
3267 switch (type) {
3268 case NL80211_IFTYPE_MESH_POINT:
3269 if (!info->attrs[NL80211_ATTR_MESH_ID])
3270 break;
29cbe68c
JB
3271 wdev_lock(wdev);
3272 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
3273 IEEE80211_MAX_MESH_ID_LEN);
3274 wdev->mesh_id_up_len =
3275 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
3276 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
3277 wdev->mesh_id_up_len);
3278 wdev_unlock(wdev);
98104fde 3279 break;
cb3b7d87 3280 case NL80211_IFTYPE_NAN:
98104fde
JB
3281 case NL80211_IFTYPE_P2P_DEVICE:
3282 /*
cb3b7d87 3283 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
3284 * through the netdev notifier and must be added here
3285 */
e4d4216e 3286 cfg80211_init_wdev(rdev, wdev);
98104fde
JB
3287 break;
3288 default:
3289 break;
29cbe68c
JB
3290 }
3291
15e47304 3292 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 3293 rdev, wdev, false) < 0) {
1c90f9d4
JB
3294 nlmsg_free(msg);
3295 return -ENOBUFS;
3296 }
3297
3298 return genlmsg_reply(msg, info);
55682965
JB
3299}
3300
3301static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
3302{
4c476991 3303 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 3304 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3305
4c476991
JB
3306 if (!rdev->ops->del_virtual_intf)
3307 return -EOPNOTSUPP;
55682965 3308
84efbb84
JB
3309 /*
3310 * If we remove a wireless device without a netdev then clear
3311 * user_ptr[1] so that nl80211_post_doit won't dereference it
3312 * to check if it needs to do dev_put(). Otherwise it crashes
3313 * since the wdev has been freed, unlike with a netdev where
3314 * we need the dev_put() for the netdev to really be freed.
3315 */
3316 if (!wdev->netdev)
3317 info->user_ptr[1] = NULL;
3318
7f8ed01e 3319 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
3320}
3321
1d9d9213
SW
3322static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
3323{
3324 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3325 struct net_device *dev = info->user_ptr[1];
3326 u16 noack_map;
3327
3328 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
3329 return -EINVAL;
3330
3331 if (!rdev->ops->set_noack_map)
3332 return -EOPNOTSUPP;
3333
3334 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
3335
e35e4d28 3336 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
3337}
3338
41ade00f
JB
3339struct get_key_cookie {
3340 struct sk_buff *msg;
3341 int error;
b9454e83 3342 int idx;
41ade00f
JB
3343};
3344
3345static void get_key_callback(void *c, struct key_params *params)
3346{
b9454e83 3347 struct nlattr *key;
41ade00f
JB
3348 struct get_key_cookie *cookie = c;
3349
9360ffd1
DM
3350 if ((params->key &&
3351 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
3352 params->key_len, params->key)) ||
3353 (params->seq &&
3354 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
3355 params->seq_len, params->seq)) ||
3356 (params->cipher &&
3357 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
3358 params->cipher)))
3359 goto nla_put_failure;
41ade00f 3360
b9454e83
JB
3361 key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
3362 if (!key)
3363 goto nla_put_failure;
3364
9360ffd1
DM
3365 if ((params->key &&
3366 nla_put(cookie->msg, NL80211_KEY_DATA,
3367 params->key_len, params->key)) ||
3368 (params->seq &&
3369 nla_put(cookie->msg, NL80211_KEY_SEQ,
3370 params->seq_len, params->seq)) ||
3371 (params->cipher &&
3372 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
3373 params->cipher)))
3374 goto nla_put_failure;
b9454e83 3375
efdfce72 3376 if (nla_put_u8(cookie->msg, NL80211_KEY_IDX, cookie->idx))
9360ffd1 3377 goto nla_put_failure;
b9454e83
JB
3378
3379 nla_nest_end(cookie->msg, key);
3380
41ade00f
JB
3381 return;
3382 nla_put_failure:
3383 cookie->error = 1;
3384}
3385
3386static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
3387{
4c476991 3388 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3389 int err;
4c476991 3390 struct net_device *dev = info->user_ptr[1];
41ade00f 3391 u8 key_idx = 0;
e31b8213
JB
3392 const u8 *mac_addr = NULL;
3393 bool pairwise;
41ade00f
JB
3394 struct get_key_cookie cookie = {
3395 .error = 0,
3396 };
3397 void *hdr;
3398 struct sk_buff *msg;
3399
3400 if (info->attrs[NL80211_ATTR_KEY_IDX])
3401 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
3402
3cfcf6ac 3403 if (key_idx > 5)
41ade00f
JB
3404 return -EINVAL;
3405
3406 if (info->attrs[NL80211_ATTR_MAC])
3407 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3408
e31b8213
JB
3409 pairwise = !!mac_addr;
3410 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
3411 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 3412
e31b8213
JB
3413 if (kt >= NUM_NL80211_KEYTYPES)
3414 return -EINVAL;
3415 if (kt != NL80211_KEYTYPE_GROUP &&
3416 kt != NL80211_KEYTYPE_PAIRWISE)
3417 return -EINVAL;
3418 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
3419 }
3420
4c476991
JB
3421 if (!rdev->ops->get_key)
3422 return -EOPNOTSUPP;
41ade00f 3423
0fa7b391
JB
3424 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3425 return -ENOENT;
3426
fd2120ca 3427 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
3428 if (!msg)
3429 return -ENOMEM;
41ade00f 3430
15e47304 3431 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 3432 NL80211_CMD_NEW_KEY);
cb35fba3 3433 if (!hdr)
9fe271af 3434 goto nla_put_failure;
41ade00f
JB
3435
3436 cookie.msg = msg;
b9454e83 3437 cookie.idx = key_idx;
41ade00f 3438
9360ffd1
DM
3439 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3440 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
3441 goto nla_put_failure;
3442 if (mac_addr &&
3443 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
3444 goto nla_put_failure;
41ade00f 3445
e35e4d28
HG
3446 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
3447 get_key_callback);
41ade00f
JB
3448
3449 if (err)
6c95e2a2 3450 goto free_msg;
41ade00f
JB
3451
3452 if (cookie.error)
3453 goto nla_put_failure;
3454
3455 genlmsg_end(msg, hdr);
4c476991 3456 return genlmsg_reply(msg, info);
41ade00f
JB
3457
3458 nla_put_failure:
3459 err = -ENOBUFS;
6c95e2a2 3460 free_msg:
41ade00f 3461 nlmsg_free(msg);
41ade00f
JB
3462 return err;
3463}
3464
3465static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
3466{
4c476991 3467 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 3468 struct key_parse key;
41ade00f 3469 int err;
4c476991 3470 struct net_device *dev = info->user_ptr[1];
41ade00f 3471
b9454e83
JB
3472 err = nl80211_parse_key(info, &key);
3473 if (err)
3474 return err;
41ade00f 3475
b9454e83 3476 if (key.idx < 0)
41ade00f
JB
3477 return -EINVAL;
3478
b9454e83
JB
3479 /* only support setting default key */
3480 if (!key.def && !key.defmgmt)
41ade00f
JB
3481 return -EINVAL;
3482
dbd2fd65 3483 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 3484
dbd2fd65
JB
3485 if (key.def) {
3486 if (!rdev->ops->set_default_key) {
3487 err = -EOPNOTSUPP;
3488 goto out;
3489 }
41ade00f 3490
dbd2fd65
JB
3491 err = nl80211_key_allowed(dev->ieee80211_ptr);
3492 if (err)
3493 goto out;
3494
e35e4d28 3495 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
3496 key.def_uni, key.def_multi);
3497
3498 if (err)
3499 goto out;
fffd0934 3500
3d23e349 3501#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
3502 dev->ieee80211_ptr->wext.default_key = key.idx;
3503#endif
3504 } else {
3505 if (key.def_uni || !key.def_multi) {
3506 err = -EINVAL;
3507 goto out;
3508 }
3509
3510 if (!rdev->ops->set_default_mgmt_key) {
3511 err = -EOPNOTSUPP;
3512 goto out;
3513 }
3514
3515 err = nl80211_key_allowed(dev->ieee80211_ptr);
3516 if (err)
3517 goto out;
3518
e35e4d28 3519 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
3520 if (err)
3521 goto out;
3522
3523#ifdef CONFIG_CFG80211_WEXT
3524 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 3525#endif
dbd2fd65
JB
3526 }
3527
3528 out:
fffd0934 3529 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3530
41ade00f
JB
3531 return err;
3532}
3533
3534static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
3535{
4c476991 3536 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 3537 int err;
4c476991 3538 struct net_device *dev = info->user_ptr[1];
b9454e83 3539 struct key_parse key;
e31b8213 3540 const u8 *mac_addr = NULL;
41ade00f 3541
b9454e83
JB
3542 err = nl80211_parse_key(info, &key);
3543 if (err)
3544 return err;
41ade00f 3545
b9454e83 3546 if (!key.p.key)
41ade00f
JB
3547 return -EINVAL;
3548
41ade00f
JB
3549 if (info->attrs[NL80211_ATTR_MAC])
3550 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3551
e31b8213
JB
3552 if (key.type == -1) {
3553 if (mac_addr)
3554 key.type = NL80211_KEYTYPE_PAIRWISE;
3555 else
3556 key.type = NL80211_KEYTYPE_GROUP;
3557 }
3558
3559 /* for now */
3560 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3561 key.type != NL80211_KEYTYPE_GROUP)
3562 return -EINVAL;
3563
4c476991
JB
3564 if (!rdev->ops->add_key)
3565 return -EOPNOTSUPP;
25e47c18 3566
e31b8213
JB
3567 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
3568 key.type == NL80211_KEYTYPE_PAIRWISE,
3569 mac_addr))
4c476991 3570 return -EINVAL;
41ade00f 3571
fffd0934
JB
3572 wdev_lock(dev->ieee80211_ptr);
3573 err = nl80211_key_allowed(dev->ieee80211_ptr);
3574 if (!err)
e35e4d28
HG
3575 err = rdev_add_key(rdev, dev, key.idx,
3576 key.type == NL80211_KEYTYPE_PAIRWISE,
3577 mac_addr, &key.p);
fffd0934 3578 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3579
41ade00f
JB
3580 return err;
3581}
3582
3583static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
3584{
4c476991 3585 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3586 int err;
4c476991 3587 struct net_device *dev = info->user_ptr[1];
41ade00f 3588 u8 *mac_addr = NULL;
b9454e83 3589 struct key_parse key;
41ade00f 3590
b9454e83
JB
3591 err = nl80211_parse_key(info, &key);
3592 if (err)
3593 return err;
41ade00f
JB
3594
3595 if (info->attrs[NL80211_ATTR_MAC])
3596 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3597
e31b8213
JB
3598 if (key.type == -1) {
3599 if (mac_addr)
3600 key.type = NL80211_KEYTYPE_PAIRWISE;
3601 else
3602 key.type = NL80211_KEYTYPE_GROUP;
3603 }
3604
3605 /* for now */
3606 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3607 key.type != NL80211_KEYTYPE_GROUP)
3608 return -EINVAL;
3609
4c476991
JB
3610 if (!rdev->ops->del_key)
3611 return -EOPNOTSUPP;
41ade00f 3612
fffd0934
JB
3613 wdev_lock(dev->ieee80211_ptr);
3614 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 3615
0fa7b391 3616 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
3617 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3618 err = -ENOENT;
3619
fffd0934 3620 if (!err)
e35e4d28
HG
3621 err = rdev_del_key(rdev, dev, key.idx,
3622 key.type == NL80211_KEYTYPE_PAIRWISE,
3623 mac_addr);
41ade00f 3624
3d23e349 3625#ifdef CONFIG_CFG80211_WEXT
08645126 3626 if (!err) {
b9454e83 3627 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 3628 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 3629 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
3630 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
3631 }
3632#endif
fffd0934 3633 wdev_unlock(dev->ieee80211_ptr);
08645126 3634
41ade00f
JB
3635 return err;
3636}
3637
77765eaf
VT
3638/* This function returns an error or the number of nested attributes */
3639static int validate_acl_mac_addrs(struct nlattr *nl_attr)
3640{
3641 struct nlattr *attr;
3642 int n_entries = 0, tmp;
3643
3644 nla_for_each_nested(attr, nl_attr, tmp) {
3645 if (nla_len(attr) != ETH_ALEN)
3646 return -EINVAL;
3647
3648 n_entries++;
3649 }
3650
3651 return n_entries;
3652}
3653
3654/*
3655 * This function parses ACL information and allocates memory for ACL data.
3656 * On successful return, the calling function is responsible to free the
3657 * ACL buffer returned by this function.
3658 */
3659static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
3660 struct genl_info *info)
3661{
3662 enum nl80211_acl_policy acl_policy;
3663 struct nlattr *attr;
3664 struct cfg80211_acl_data *acl;
3665 int i = 0, n_entries, tmp;
3666
3667 if (!wiphy->max_acl_mac_addrs)
3668 return ERR_PTR(-EOPNOTSUPP);
3669
3670 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
3671 return ERR_PTR(-EINVAL);
3672
3673 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
3674 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
3675 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
3676 return ERR_PTR(-EINVAL);
3677
3678 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
3679 return ERR_PTR(-EINVAL);
3680
3681 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
3682 if (n_entries < 0)
3683 return ERR_PTR(n_entries);
3684
3685 if (n_entries > wiphy->max_acl_mac_addrs)
3686 return ERR_PTR(-ENOTSUPP);
3687
3688 acl = kzalloc(sizeof(*acl) + (sizeof(struct mac_address) * n_entries),
3689 GFP_KERNEL);
3690 if (!acl)
3691 return ERR_PTR(-ENOMEM);
3692
3693 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
3694 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
3695 i++;
3696 }
3697
3698 acl->n_acl_entries = n_entries;
3699 acl->acl_policy = acl_policy;
3700
3701 return acl;
3702}
3703
3704static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
3705{
3706 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3707 struct net_device *dev = info->user_ptr[1];
3708 struct cfg80211_acl_data *acl;
3709 int err;
3710
3711 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3712 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3713 return -EOPNOTSUPP;
3714
3715 if (!dev->ieee80211_ptr->beacon_interval)
3716 return -EINVAL;
3717
3718 acl = parse_acl_data(&rdev->wiphy, info);
3719 if (IS_ERR(acl))
3720 return PTR_ERR(acl);
3721
3722 err = rdev_set_mac_acl(rdev, dev, acl);
3723
3724 kfree(acl);
3725
3726 return err;
3727}
3728
a7c7fbff
PK
3729static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
3730 u8 *rates, u8 rates_len)
3731{
3732 u8 i;
3733 u32 mask = 0;
3734
3735 for (i = 0; i < rates_len; i++) {
3736 int rate = (rates[i] & 0x7f) * 5;
3737 int ridx;
3738
3739 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
3740 struct ieee80211_rate *srate =
3741 &sband->bitrates[ridx];
3742 if (rate == srate->bitrate) {
3743 mask |= 1 << ridx;
3744 break;
3745 }
3746 }
3747 if (ridx == sband->n_bitrates)
3748 return 0; /* rate not found */
3749 }
3750
3751 return mask;
3752}
3753
3754static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
3755 u8 *rates, u8 rates_len,
3756 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
3757{
3758 u8 i;
3759
3760 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
3761
3762 for (i = 0; i < rates_len; i++) {
3763 int ridx, rbit;
3764
3765 ridx = rates[i] / 8;
3766 rbit = BIT(rates[i] % 8);
3767
3768 /* check validity */
3769 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
3770 return false;
3771
3772 /* check availability */
30fe6d50 3773 ridx = array_index_nospec(ridx, IEEE80211_HT_MCS_MASK_LEN);
a7c7fbff
PK
3774 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
3775 mcs[ridx] |= rbit;
3776 else
3777 return false;
3778 }
3779
3780 return true;
3781}
3782
3783static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
3784{
3785 u16 mcs_mask = 0;
3786
3787 switch (vht_mcs_map) {
3788 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
3789 break;
3790 case IEEE80211_VHT_MCS_SUPPORT_0_7:
3791 mcs_mask = 0x00FF;
3792 break;
3793 case IEEE80211_VHT_MCS_SUPPORT_0_8:
3794 mcs_mask = 0x01FF;
3795 break;
3796 case IEEE80211_VHT_MCS_SUPPORT_0_9:
3797 mcs_mask = 0x03FF;
3798 break;
3799 default:
3800 break;
3801 }
3802
3803 return mcs_mask;
3804}
3805
3806static void vht_build_mcs_mask(u16 vht_mcs_map,
3807 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
3808{
3809 u8 nss;
3810
3811 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
3812 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
3813 vht_mcs_map >>= 2;
3814 }
3815}
3816
3817static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
3818 struct nl80211_txrate_vht *txrate,
3819 u16 mcs[NL80211_VHT_NSS_MAX])
3820{
3821 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3822 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
3823 u8 i;
3824
3825 if (!sband->vht_cap.vht_supported)
3826 return false;
3827
3828 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
3829
3830 /* Build vht_mcs_mask from VHT capabilities */
3831 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
3832
3833 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
3834 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
3835 mcs[i] = txrate->mcs[i];
3836 else
3837 return false;
3838 }
3839
3840 return true;
3841}
3842
3843static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
3844 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
3845 .len = NL80211_MAX_SUPP_RATES },
3846 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
3847 .len = NL80211_MAX_SUPP_HT_RATES },
3848 [NL80211_TXRATE_VHT] = { .len = sizeof(struct nl80211_txrate_vht)},
3849 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
3850};
3851
3852static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
3853 struct cfg80211_bitrate_mask *mask)
3854{
3855 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
3856 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3857 int rem, i;
3858 struct nlattr *tx_rates;
3859 struct ieee80211_supported_band *sband;
3860 u16 vht_tx_mcs_map;
3861
3862 memset(mask, 0, sizeof(*mask));
3863 /* Default to all rates enabled */
3864 for (i = 0; i < NUM_NL80211_BANDS; i++) {
3865 sband = rdev->wiphy.bands[i];
3866
3867 if (!sband)
3868 continue;
3869
3870 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
3871 memcpy(mask->control[i].ht_mcs,
3872 sband->ht_cap.mcs.rx_mask,
3873 sizeof(mask->control[i].ht_mcs));
3874
3875 if (!sband->vht_cap.vht_supported)
3876 continue;
3877
3878 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3879 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
3880 }
3881
3882 /* if no rates are given set it back to the defaults */
3883 if (!info->attrs[NL80211_ATTR_TX_RATES])
3884 goto out;
3885
3886 /* The nested attribute uses enum nl80211_band as the index. This maps
3887 * directly to the enum nl80211_band values used in cfg80211.
3888 */
3889 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
3890 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
3891 enum nl80211_band band = nla_type(tx_rates);
3892 int err;
3893
3894 if (band < 0 || band >= NUM_NL80211_BANDS)
3895 return -EINVAL;
3896 sband = rdev->wiphy.bands[band];
3897 if (sband == NULL)
3898 return -EINVAL;
bfe2c7b1 3899 err = nla_parse_nested(tb, NL80211_TXRATE_MAX, tx_rates,
fe52145f 3900 nl80211_txattr_policy, info->extack);
a7c7fbff
PK
3901 if (err)
3902 return err;
3903 if (tb[NL80211_TXRATE_LEGACY]) {
3904 mask->control[band].legacy = rateset_to_mask(
3905 sband,
3906 nla_data(tb[NL80211_TXRATE_LEGACY]),
3907 nla_len(tb[NL80211_TXRATE_LEGACY]));
3908 if ((mask->control[band].legacy == 0) &&
3909 nla_len(tb[NL80211_TXRATE_LEGACY]))
3910 return -EINVAL;
3911 }
3912 if (tb[NL80211_TXRATE_HT]) {
3913 if (!ht_rateset_to_mask(
3914 sband,
3915 nla_data(tb[NL80211_TXRATE_HT]),
3916 nla_len(tb[NL80211_TXRATE_HT]),
3917 mask->control[band].ht_mcs))
3918 return -EINVAL;
3919 }
3920 if (tb[NL80211_TXRATE_VHT]) {
3921 if (!vht_set_mcs_mask(
3922 sband,
3923 nla_data(tb[NL80211_TXRATE_VHT]),
3924 mask->control[band].vht_mcs))
3925 return -EINVAL;
3926 }
3927 if (tb[NL80211_TXRATE_GI]) {
3928 mask->control[band].gi =
3929 nla_get_u8(tb[NL80211_TXRATE_GI]);
3930 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
3931 return -EINVAL;
3932 }
3933
3934 if (mask->control[band].legacy == 0) {
3935 /* don't allow empty legacy rates if HT or VHT
3936 * are not even supported.
3937 */
3938 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
3939 rdev->wiphy.bands[band]->vht_cap.vht_supported))
3940 return -EINVAL;
3941
3942 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
3943 if (mask->control[band].ht_mcs[i])
3944 goto out;
3945
3946 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
3947 if (mask->control[band].vht_mcs[i])
3948 goto out;
3949
3950 /* legacy and mcs rates may not be both empty */
3951 return -EINVAL;
3952 }
3953 }
3954
3955out:
3956 return 0;
3957}
3958
8564e382
JB
3959static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
3960 enum nl80211_band band,
3961 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 3962{
8564e382
JB
3963 u32 count_ht, count_vht, i;
3964 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
3965
3966 /* Allow only one rate */
3967 if (hweight32(rate) > 1)
3968 return -EINVAL;
3969
3970 count_ht = 0;
3971 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 3972 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 3973 return -EINVAL;
8564e382 3974 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
3975 count_ht++;
3976 if (count_ht > 1)
3977 return -EINVAL;
3978 }
3979 if (count_ht && rate)
3980 return -EINVAL;
3981 }
3982
3983 count_vht = 0;
3984 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 3985 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 3986 return -EINVAL;
8564e382 3987 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
3988 count_vht++;
3989 if (count_vht > 1)
3990 return -EINVAL;
3991 }
3992 if (count_vht && rate)
3993 return -EINVAL;
3994 }
3995
3996 if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht))
3997 return -EINVAL;
3998
8564e382
JB
3999 if (rate &&
4000 !wiphy_ext_feature_isset(&rdev->wiphy,
4001 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
4002 return -EINVAL;
4003 if (count_ht &&
4004 !wiphy_ext_feature_isset(&rdev->wiphy,
4005 NL80211_EXT_FEATURE_BEACON_RATE_HT))
4006 return -EINVAL;
4007 if (count_vht &&
4008 !wiphy_ext_feature_isset(&rdev->wiphy,
4009 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
4010 return -EINVAL;
4011
a7c7fbff
PK
4012 return 0;
4013}
4014
81e54d08
PKC
4015static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
4016 struct nlattr *attrs[],
8860020e 4017 struct cfg80211_beacon_data *bcn)
ed1b6cc7 4018{
8860020e 4019 bool haveinfo = false;
81e54d08 4020 int err;
ed1b6cc7 4021
a1193be8
SW
4022 if (!is_valid_ie_attr(attrs[NL80211_ATTR_BEACON_TAIL]) ||
4023 !is_valid_ie_attr(attrs[NL80211_ATTR_IE]) ||
4024 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
4025 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_ASSOC_RESP]))
f4a11bb0
JB
4026 return -EINVAL;
4027
8860020e 4028 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 4029
a1193be8
SW
4030 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
4031 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
4032 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
4033 if (!bcn->head_len)
4034 return -EINVAL;
4035 haveinfo = true;
ed1b6cc7
JB
4036 }
4037
a1193be8
SW
4038 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
4039 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
4040 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 4041 haveinfo = true;
ed1b6cc7
JB
4042 }
4043
4c476991
JB
4044 if (!haveinfo)
4045 return -EINVAL;
3b85875a 4046
a1193be8
SW
4047 if (attrs[NL80211_ATTR_IE]) {
4048 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
4049 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
4050 }
4051
a1193be8 4052 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 4053 bcn->proberesp_ies =
a1193be8 4054 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 4055 bcn->proberesp_ies_len =
a1193be8 4056 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
4057 }
4058
a1193be8 4059 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 4060 bcn->assocresp_ies =
a1193be8 4061 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 4062 bcn->assocresp_ies_len =
a1193be8 4063 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
4064 }
4065
a1193be8
SW
4066 if (attrs[NL80211_ATTR_PROBE_RESP]) {
4067 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
4068 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
4069 }
4070
81e54d08
PKC
4071 if (attrs[NL80211_ATTR_FTM_RESPONDER]) {
4072 struct nlattr *tb[NL80211_FTM_RESP_ATTR_MAX + 1];
4073
4074 err = nla_parse_nested(tb, NL80211_FTM_RESP_ATTR_MAX,
4075 attrs[NL80211_ATTR_FTM_RESPONDER],
4076 NULL, NULL);
4077 if (err)
4078 return err;
4079
4080 if (tb[NL80211_FTM_RESP_ATTR_ENABLED] &&
4081 wiphy_ext_feature_isset(&rdev->wiphy,
4082 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
4083 bcn->ftm_responder = 1;
4084 else
4085 return -EOPNOTSUPP;
4086
4087 if (tb[NL80211_FTM_RESP_ATTR_LCI]) {
4088 bcn->lci = nla_data(tb[NL80211_FTM_RESP_ATTR_LCI]);
4089 bcn->lci_len = nla_len(tb[NL80211_FTM_RESP_ATTR_LCI]);
4090 }
4091
4092 if (tb[NL80211_FTM_RESP_ATTR_CIVICLOC]) {
4093 bcn->civicloc = nla_data(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
4094 bcn->civicloc_len = nla_len(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
4095 }
4096 } else {
4097 bcn->ftm_responder = -1;
4098 }
4099
8860020e
JB
4100 return 0;
4101}
4102
66cd794e
JB
4103static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
4104 const u8 *rates)
4105{
4106 int i;
4107
4108 if (!rates)
4109 return;
4110
4111 for (i = 0; i < rates[1]; i++) {
4112 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
4113 params->ht_required = true;
4114 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
4115 params->vht_required = true;
4116 }
4117}
4118
4119/*
4120 * Since the nl80211 API didn't include, from the beginning, attributes about
4121 * HT/VHT requirements/capabilities, we parse them out of the IEs for the
4122 * benefit of drivers that rebuild IEs in the firmware.
4123 */
4124static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
4125{
4126 const struct cfg80211_beacon_data *bcn = &params->beacon;
ba83bfb1
IM
4127 size_t ies_len = bcn->tail_len;
4128 const u8 *ies = bcn->tail;
66cd794e
JB
4129 const u8 *rates;
4130 const u8 *cap;
4131
4132 rates = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies, ies_len);
4133 nl80211_check_ap_rate_selectors(params, rates);
4134
4135 rates = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
4136 nl80211_check_ap_rate_selectors(params, rates);
4137
4138 cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
4139 if (cap && cap[1] >= sizeof(*params->ht_cap))
4140 params->ht_cap = (void *)(cap + 2);
4141 cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
4142 if (cap && cap[1] >= sizeof(*params->vht_cap))
4143 params->vht_cap = (void *)(cap + 2);
244eb9ae
ST
4144 cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
4145 if (cap && cap[1] >= sizeof(*params->he_cap) + 1)
4146 params->he_cap = (void *)(cap + 3);
66cd794e
JB
4147}
4148
46c1dd0c
FF
4149static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
4150 struct cfg80211_ap_settings *params)
4151{
4152 struct wireless_dev *wdev;
4153 bool ret = false;
4154
53873f13 4155 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
4156 if (wdev->iftype != NL80211_IFTYPE_AP &&
4157 wdev->iftype != NL80211_IFTYPE_P2P_GO)
4158 continue;
4159
683b6d3b 4160 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
4161 continue;
4162
683b6d3b 4163 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
4164 ret = true;
4165 break;
4166 }
4167
46c1dd0c
FF
4168 return ret;
4169}
4170
e39e5b5e
JM
4171static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
4172 enum nl80211_auth_type auth_type,
4173 enum nl80211_commands cmd)
4174{
4175 if (auth_type > NL80211_AUTHTYPE_MAX)
4176 return false;
4177
4178 switch (cmd) {
4179 case NL80211_CMD_AUTHENTICATE:
4180 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
4181 auth_type == NL80211_AUTHTYPE_SAE)
4182 return false;
63181060
JM
4183 if (!wiphy_ext_feature_isset(&rdev->wiphy,
4184 NL80211_EXT_FEATURE_FILS_STA) &&
4185 (auth_type == NL80211_AUTHTYPE_FILS_SK ||
4186 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
4187 auth_type == NL80211_AUTHTYPE_FILS_PK))
4188 return false;
e39e5b5e
JM
4189 return true;
4190 case NL80211_CMD_CONNECT:
10773a7c
SD
4191 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
4192 auth_type == NL80211_AUTHTYPE_SAE)
a3caf744 4193 return false;
10773a7c 4194
a3caf744
VK
4195 /* FILS with SK PFS or PK not supported yet */
4196 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
4197 auth_type == NL80211_AUTHTYPE_FILS_PK)
4198 return false;
4199 if (!wiphy_ext_feature_isset(
4200 &rdev->wiphy,
4201 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
4202 auth_type == NL80211_AUTHTYPE_FILS_SK)
4203 return false;
4204 return true;
e39e5b5e
JM
4205 case NL80211_CMD_START_AP:
4206 /* SAE not supported yet */
4207 if (auth_type == NL80211_AUTHTYPE_SAE)
4208 return false;
63181060
JM
4209 /* FILS not supported yet */
4210 if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
4211 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
4212 auth_type == NL80211_AUTHTYPE_FILS_PK)
4213 return false;
e39e5b5e
JM
4214 return true;
4215 default:
4216 return false;
4217 }
4218}
4219
8860020e
JB
4220static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
4221{
4222 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4223 struct net_device *dev = info->user_ptr[1];
4224 struct wireless_dev *wdev = dev->ieee80211_ptr;
4225 struct cfg80211_ap_settings params;
4226 int err;
4227
4228 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4229 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4230 return -EOPNOTSUPP;
4231
4232 if (!rdev->ops->start_ap)
4233 return -EOPNOTSUPP;
4234
4235 if (wdev->beacon_interval)
4236 return -EALREADY;
4237
4238 memset(&params, 0, sizeof(params));
4239
4240 /* these are required for START_AP */
4241 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
4242 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
4243 !info->attrs[NL80211_ATTR_BEACON_HEAD])
4244 return -EINVAL;
4245
81e54d08 4246 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon);
8860020e
JB
4247 if (err)
4248 return err;
4249
4250 params.beacon_interval =
4251 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
4252 params.dtim_period =
4253 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
4254
0c317a02
PK
4255 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
4256 params.beacon_interval);
8860020e
JB
4257 if (err)
4258 return err;
4259
4260 /*
4261 * In theory, some of these attributes should be required here
4262 * but since they were not used when the command was originally
4263 * added, keep them optional for old user space programs to let
4264 * them continue to work with drivers that do not need the
4265 * additional information -- drivers must check!
4266 */
4267 if (info->attrs[NL80211_ATTR_SSID]) {
4268 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
4269 params.ssid_len =
4270 nla_len(info->attrs[NL80211_ATTR_SSID]);
4271 if (params.ssid_len == 0 ||
4272 params.ssid_len > IEEE80211_MAX_SSID_LEN)
4273 return -EINVAL;
4274 }
4275
4276 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
4277 params.hidden_ssid = nla_get_u32(
4278 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
4279 if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
4280 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
4281 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
4282 return -EINVAL;
4283 }
4284
4285 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
4286
4287 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
4288 params.auth_type = nla_get_u32(
4289 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
4290 if (!nl80211_valid_auth_type(rdev, params.auth_type,
4291 NL80211_CMD_START_AP))
8860020e
JB
4292 return -EINVAL;
4293 } else
4294 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
4295
4296 err = nl80211_crypto_settings(rdev, info, &params.crypto,
4297 NL80211_MAX_NR_CIPHER_SUITES);
4298 if (err)
4299 return err;
4300
1b658f11
VT
4301 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
4302 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
4303 return -EOPNOTSUPP;
4304 params.inactivity_timeout = nla_get_u16(
4305 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
4306 }
4307
53cabad7
JB
4308 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
4309 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4310 return -EINVAL;
4311 params.p2p_ctwindow =
4312 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
4313 if (params.p2p_ctwindow > 127)
4314 return -EINVAL;
4315 if (params.p2p_ctwindow != 0 &&
4316 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
4317 return -EINVAL;
4318 }
4319
4320 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
4321 u8 tmp;
4322
4323 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4324 return -EINVAL;
4325 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
4326 if (tmp > 1)
4327 return -EINVAL;
4328 params.p2p_opp_ps = tmp;
4329 if (params.p2p_opp_ps != 0 &&
4330 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
4331 return -EINVAL;
4332 }
4333
aa430da4 4334 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
4335 err = nl80211_parse_chandef(rdev, info, &params.chandef);
4336 if (err)
4337 return err;
4338 } else if (wdev->preset_chandef.chan) {
4339 params.chandef = wdev->preset_chandef;
46c1dd0c 4340 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
4341 return -EINVAL;
4342
923b352f
AN
4343 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
4344 wdev->iftype))
aa430da4
JB
4345 return -EINVAL;
4346
a7c7fbff
PK
4347 if (info->attrs[NL80211_ATTR_TX_RATES]) {
4348 err = nl80211_parse_tx_bitrate_mask(info, &params.beacon_rate);
4349 if (err)
4350 return err;
4351
8564e382
JB
4352 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
4353 &params.beacon_rate);
a7c7fbff
PK
4354 if (err)
4355 return err;
4356 }
4357
18998c38
EP
4358 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
4359 params.smps_mode =
4360 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
4361 switch (params.smps_mode) {
4362 case NL80211_SMPS_OFF:
4363 break;
4364 case NL80211_SMPS_STATIC:
4365 if (!(rdev->wiphy.features &
4366 NL80211_FEATURE_STATIC_SMPS))
4367 return -EINVAL;
4368 break;
4369 case NL80211_SMPS_DYNAMIC:
4370 if (!(rdev->wiphy.features &
4371 NL80211_FEATURE_DYNAMIC_SMPS))
4372 return -EINVAL;
4373 break;
4374 default:
4375 return -EINVAL;
4376 }
4377 } else {
4378 params.smps_mode = NL80211_SMPS_OFF;
4379 }
4380
6e8ef842
PK
4381 params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
4382 if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
4383 return -EOPNOTSUPP;
4384
4baf6bea
OO
4385 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
4386 params.acl = parse_acl_data(&rdev->wiphy, info);
4387 if (IS_ERR(params.acl))
4388 return PTR_ERR(params.acl);
4389 }
4390
66cd794e
JB
4391 nl80211_calculate_ap_params(&params);
4392
c56589ed 4393 wdev_lock(wdev);
e35e4d28 4394 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 4395 if (!err) {
683b6d3b 4396 wdev->preset_chandef = params.chandef;
8860020e 4397 wdev->beacon_interval = params.beacon_interval;
9e0e2961 4398 wdev->chandef = params.chandef;
06e191e2
AQ
4399 wdev->ssid_len = params.ssid_len;
4400 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
466a3061
DK
4401
4402 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
4403 wdev->conn_owner_nlportid = info->snd_portid;
46c1dd0c 4404 }
c56589ed 4405 wdev_unlock(wdev);
77765eaf
VT
4406
4407 kfree(params.acl);
4408
56d1893d 4409 return err;
ed1b6cc7
JB
4410}
4411
8860020e
JB
4412static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
4413{
4414 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4415 struct net_device *dev = info->user_ptr[1];
4416 struct wireless_dev *wdev = dev->ieee80211_ptr;
4417 struct cfg80211_beacon_data params;
4418 int err;
4419
4420 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4421 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4422 return -EOPNOTSUPP;
4423
4424 if (!rdev->ops->change_beacon)
4425 return -EOPNOTSUPP;
4426
4427 if (!wdev->beacon_interval)
4428 return -EINVAL;
4429
81e54d08 4430 err = nl80211_parse_beacon(rdev, info->attrs, &params);
8860020e
JB
4431 if (err)
4432 return err;
4433
c56589ed
SW
4434 wdev_lock(wdev);
4435 err = rdev_change_beacon(rdev, dev, &params);
4436 wdev_unlock(wdev);
4437
4438 return err;
8860020e
JB
4439}
4440
4441static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 4442{
4c476991
JB
4443 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4444 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 4445
7c8d5e03 4446 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
4447}
4448
5727ef1b
JB
4449static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
4450 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
4451 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
4452 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 4453 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 4454 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 4455 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
4456};
4457
eccb8e8f 4458static int parse_station_flags(struct genl_info *info,
bdd3ae3d 4459 enum nl80211_iftype iftype,
eccb8e8f 4460 struct station_parameters *params)
5727ef1b
JB
4461{
4462 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 4463 struct nlattr *nla;
5727ef1b
JB
4464 int flag;
4465
eccb8e8f
JB
4466 /*
4467 * Try parsing the new attribute first so userspace
4468 * can specify both for older kernels.
4469 */
4470 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
4471 if (nla) {
4472 struct nl80211_sta_flag_update *sta_flags;
4473
4474 sta_flags = nla_data(nla);
4475 params->sta_flags_mask = sta_flags->mask;
4476 params->sta_flags_set = sta_flags->set;
77ee7c89 4477 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
4478 if ((params->sta_flags_mask |
4479 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
4480 return -EINVAL;
4481 return 0;
4482 }
4483
4484 /* if present, parse the old attribute */
5727ef1b 4485
eccb8e8f 4486 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
4487 if (!nla)
4488 return 0;
4489
fceb6435 4490 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX, nla,
fe52145f 4491 sta_flags_policy, info->extack))
5727ef1b
JB
4492 return -EINVAL;
4493
bdd3ae3d
JB
4494 /*
4495 * Only allow certain flags for interface types so that
4496 * other attributes are silently ignored. Remember that
4497 * this is backward compatibility code with old userspace
4498 * and shouldn't be hit in other cases anyway.
4499 */
4500 switch (iftype) {
4501 case NL80211_IFTYPE_AP:
4502 case NL80211_IFTYPE_AP_VLAN:
4503 case NL80211_IFTYPE_P2P_GO:
4504 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4505 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4506 BIT(NL80211_STA_FLAG_WME) |
4507 BIT(NL80211_STA_FLAG_MFP);
4508 break;
4509 case NL80211_IFTYPE_P2P_CLIENT:
4510 case NL80211_IFTYPE_STATION:
4511 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4512 BIT(NL80211_STA_FLAG_TDLS_PEER);
4513 break;
4514 case NL80211_IFTYPE_MESH_POINT:
4515 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4516 BIT(NL80211_STA_FLAG_MFP) |
4517 BIT(NL80211_STA_FLAG_AUTHORIZED);
5cf3006c 4518 break;
bdd3ae3d
JB
4519 default:
4520 return -EINVAL;
4521 }
5727ef1b 4522
3383b5a6
JB
4523 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
4524 if (flags[flag]) {
eccb8e8f 4525 params->sta_flags_set |= (1<<flag);
5727ef1b 4526
3383b5a6
JB
4527 /* no longer support new API additions in old API */
4528 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
4529 return -EINVAL;
4530 }
4531 }
4532
5727ef1b
JB
4533 return 0;
4534}
4535
c8dcfd8a
FF
4536static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
4537 int attr)
4538{
4539 struct nlattr *rate;
8eb41c8d
VK
4540 u32 bitrate;
4541 u16 bitrate_compat;
bbf67e45 4542 enum nl80211_rate_info rate_flg;
c8dcfd8a
FF
4543
4544 rate = nla_nest_start(msg, attr);
4545 if (!rate)
db9c64cf 4546 return false;
c8dcfd8a
FF
4547
4548 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
4549 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
4550 /* report 16-bit bitrate only if we can */
4551 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
4552 if (bitrate > 0 &&
4553 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
4554 return false;
4555 if (bitrate_compat > 0 &&
4556 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
4557 return false;
4558
b51f3bee
JB
4559 switch (info->bw) {
4560 case RATE_INFO_BW_5:
4561 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
4562 break;
4563 case RATE_INFO_BW_10:
4564 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
4565 break;
4566 default:
4567 WARN_ON(1);
4568 /* fall through */
4569 case RATE_INFO_BW_20:
4570 rate_flg = 0;
4571 break;
4572 case RATE_INFO_BW_40:
4573 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
4574 break;
4575 case RATE_INFO_BW_80:
4576 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
4577 break;
4578 case RATE_INFO_BW_160:
4579 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
4580 break;
c4cbaf79
LC
4581 case RATE_INFO_BW_HE_RU:
4582 rate_flg = 0;
4583 WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
b51f3bee
JB
4584 }
4585
4586 if (rate_flg && nla_put_flag(msg, rate_flg))
4587 return false;
4588
db9c64cf
JB
4589 if (info->flags & RATE_INFO_FLAGS_MCS) {
4590 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
4591 return false;
db9c64cf
JB
4592 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4593 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4594 return false;
4595 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
4596 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
4597 return false;
4598 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
4599 return false;
db9c64cf
JB
4600 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4601 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4602 return false;
c4cbaf79
LC
4603 } else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
4604 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
4605 return false;
4606 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
4607 return false;
4608 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
4609 return false;
4610 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
4611 return false;
4612 if (info->bw == RATE_INFO_BW_HE_RU &&
4613 nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
4614 info->he_ru_alloc))
4615 return false;
db9c64cf 4616 }
c8dcfd8a
FF
4617
4618 nla_nest_end(msg, rate);
4619 return true;
c8dcfd8a
FF
4620}
4621
119363c7
FF
4622static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
4623 int id)
4624{
4625 void *attr;
4626 int i = 0;
4627
4628 if (!mask)
4629 return true;
4630
4631 attr = nla_nest_start(msg, id);
4632 if (!attr)
4633 return false;
4634
4635 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
4636 if (!(mask & BIT(i)))
4637 continue;
4638
4639 if (nla_put_u8(msg, i, signal[i]))
4640 return false;
4641 }
4642
4643 nla_nest_end(msg, attr);
4644
4645 return true;
4646}
4647
cf5ead82
JB
4648static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
4649 u32 seq, int flags,
66266b3a
JL
4650 struct cfg80211_registered_device *rdev,
4651 struct net_device *dev,
98b62183 4652 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
4653{
4654 void *hdr;
f4263c98 4655 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 4656
cf5ead82 4657 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
fd5b74dc
JB
4658 if (!hdr)
4659 return -1;
4660
9360ffd1
DM
4661 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4662 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
4663 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
4664 goto nla_put_failure;
f5ea9120 4665
2ec600d6
LCC
4666 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
4667 if (!sinfoattr)
fd5b74dc 4668 goto nla_put_failure;
319090bf
JB
4669
4670#define PUT_SINFO(attr, memb, type) do { \
d686b920 4671 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
397c657a 4672 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
319090bf
JB
4673 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
4674 sinfo->memb)) \
4675 goto nla_put_failure; \
4676 } while (0)
d686b920 4677#define PUT_SINFO_U64(attr, memb) do { \
397c657a 4678 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
d686b920
JB
4679 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
4680 sinfo->memb, NL80211_STA_INFO_PAD)) \
4681 goto nla_put_failure; \
4682 } while (0)
319090bf
JB
4683
4684 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
4685 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
4686
397c657a
OE
4687 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
4688 BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 4689 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 4690 (u32)sinfo->rx_bytes))
9360ffd1 4691 goto nla_put_failure;
319090bf 4692
397c657a
OE
4693 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
4694 BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 4695 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
4696 (u32)sinfo->tx_bytes))
4697 goto nla_put_failure;
319090bf 4698
d686b920
JB
4699 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
4700 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
4701 PUT_SINFO(LLID, llid, u16);
4702 PUT_SINFO(PLID, plid, u16);
4703 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 4704 PUT_SINFO_U64(RX_DURATION, rx_duration);
319090bf 4705
66266b3a
JL
4706 switch (rdev->wiphy.signal_type) {
4707 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
4708 PUT_SINFO(SIGNAL, signal, u8);
4709 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
4710 break;
4711 default:
4712 break;
4713 }
397c657a 4714 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
4715 if (!nl80211_put_signal(msg, sinfo->chains,
4716 sinfo->chain_signal,
4717 NL80211_STA_INFO_CHAIN_SIGNAL))
4718 goto nla_put_failure;
4719 }
397c657a 4720 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
4721 if (!nl80211_put_signal(msg, sinfo->chains,
4722 sinfo->chain_signal_avg,
4723 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
4724 goto nla_put_failure;
4725 }
397c657a 4726 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
4727 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
4728 NL80211_STA_INFO_TX_BITRATE))
4729 goto nla_put_failure;
4730 }
397c657a 4731 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
4732 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
4733 NL80211_STA_INFO_RX_BITRATE))
420e7fab 4734 goto nla_put_failure;
420e7fab 4735 }
319090bf
JB
4736
4737 PUT_SINFO(RX_PACKETS, rx_packets, u32);
4738 PUT_SINFO(TX_PACKETS, tx_packets, u32);
4739 PUT_SINFO(TX_RETRIES, tx_retries, u32);
4740 PUT_SINFO(TX_FAILED, tx_failed, u32);
4741 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
4742 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
4743 PUT_SINFO(LOCAL_PM, local_pm, u32);
4744 PUT_SINFO(PEER_PM, peer_pm, u32);
4745 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
4746
397c657a 4747 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
f4263c98
PS
4748 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
4749 if (!bss_param)
4750 goto nla_put_failure;
4751
9360ffd1
DM
4752 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
4753 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
4754 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
4755 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
4756 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
4757 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
4758 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
4759 sinfo->bss_param.dtim_period) ||
4760 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
4761 sinfo->bss_param.beacon_interval))
4762 goto nla_put_failure;
f4263c98
PS
4763
4764 nla_nest_end(msg, bss_param);
4765 }
397c657a 4766 if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
4767 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
4768 sizeof(struct nl80211_sta_flag_update),
4769 &sinfo->sta_flags))
4770 goto nla_put_failure;
319090bf 4771
d686b920
JB
4772 PUT_SINFO_U64(T_OFFSET, t_offset);
4773 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
4774 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 4775 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
81d5439d 4776 if (wiphy_ext_feature_isset(&rdev->wiphy,
9c06602b
BP
4777 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
4778 PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
4779 PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8);
4780 }
319090bf
JB
4781
4782#undef PUT_SINFO
d686b920 4783#undef PUT_SINFO_U64
6de39808 4784
8689c051 4785 if (sinfo->pertid) {
6de39808
JB
4786 struct nlattr *tidsattr;
4787 int tid;
4788
4789 tidsattr = nla_nest_start(msg, NL80211_STA_INFO_TID_STATS);
4790 if (!tidsattr)
4791 goto nla_put_failure;
4792
4793 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
4794 struct cfg80211_tid_stats *tidstats;
4795 struct nlattr *tidattr;
4796
4797 tidstats = &sinfo->pertid[tid];
4798
4799 if (!tidstats->filled)
4800 continue;
4801
4802 tidattr = nla_nest_start(msg, tid + 1);
4803 if (!tidattr)
4804 goto nla_put_failure;
4805
d686b920 4806#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 4807 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
4808 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
4809 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
4810 goto nla_put_failure; \
4811 } while (0)
4812
d686b920
JB
4813 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
4814 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
4815 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
4816 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 4817
d686b920 4818#undef PUT_TIDVAL_U64
52539ca8
THJ
4819 if ((tidstats->filled &
4820 BIT(NL80211_TID_STATS_TXQ_STATS)) &&
4821 !nl80211_put_txq_stats(msg, &tidstats->txq_stats,
4822 NL80211_TID_STATS_TXQ_STATS))
4823 goto nla_put_failure;
4824
6de39808
JB
4825 nla_nest_end(msg, tidattr);
4826 }
4827
4828 nla_nest_end(msg, tidsattr);
4829 }
4830
2ec600d6 4831 nla_nest_end(msg, sinfoattr);
fd5b74dc 4832
319090bf 4833 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
4834 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
4835 sinfo->assoc_req_ies))
4836 goto nla_put_failure;
50d3dfb7 4837
7ea3e110 4838 cfg80211_sinfo_release_content(sinfo);
053c095a
JB
4839 genlmsg_end(msg, hdr);
4840 return 0;
fd5b74dc
JB
4841
4842 nla_put_failure:
7ea3e110 4843 cfg80211_sinfo_release_content(sinfo);
bc3ed28c
TG
4844 genlmsg_cancel(msg, hdr);
4845 return -EMSGSIZE;
fd5b74dc
JB
4846}
4847
2ec600d6 4848static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 4849 struct netlink_callback *cb)
2ec600d6 4850{
73887fd9 4851 struct station_info sinfo;
1b8ec87a 4852 struct cfg80211_registered_device *rdev;
97990a06 4853 struct wireless_dev *wdev;
2ec600d6 4854 u8 mac_addr[ETH_ALEN];
97990a06 4855 int sta_idx = cb->args[2];
2ec600d6 4856 int err;
2ec600d6 4857
ea90e0dc 4858 rtnl_lock();
5297c65c 4859 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 4860 if (err)
ea90e0dc 4861 goto out_err;
bba95fef 4862
97990a06
JB
4863 if (!wdev->netdev) {
4864 err = -EINVAL;
4865 goto out_err;
4866 }
4867
1b8ec87a 4868 if (!rdev->ops->dump_station) {
eec60b03 4869 err = -EOPNOTSUPP;
bba95fef
JB
4870 goto out_err;
4871 }
4872
bba95fef 4873 while (1) {
73887fd9 4874 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 4875 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
73887fd9 4876 mac_addr, &sinfo);
bba95fef
JB
4877 if (err == -ENOENT)
4878 break;
4879 if (err)
3b85875a 4880 goto out_err;
bba95fef 4881
cf5ead82 4882 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 4883 NETLINK_CB(cb->skb).portid,
bba95fef 4884 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 4885 rdev, wdev->netdev, mac_addr,
73887fd9 4886 &sinfo) < 0)
bba95fef
JB
4887 goto out;
4888
4889 sta_idx++;
4890 }
4891
bba95fef 4892 out:
97990a06 4893 cb->args[2] = sta_idx;
bba95fef 4894 err = skb->len;
bba95fef 4895 out_err:
ea90e0dc 4896 rtnl_unlock();
bba95fef
JB
4897
4898 return err;
2ec600d6 4899}
fd5b74dc 4900
5727ef1b
JB
4901static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
4902{
4c476991
JB
4903 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4904 struct net_device *dev = info->user_ptr[1];
73887fd9 4905 struct station_info sinfo;
fd5b74dc
JB
4906 struct sk_buff *msg;
4907 u8 *mac_addr = NULL;
4c476991 4908 int err;
fd5b74dc 4909
73887fd9 4910 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc 4911
73887fd9
JB
4912 if (!info->attrs[NL80211_ATTR_MAC])
4913 return -EINVAL;
fd5b74dc
JB
4914
4915 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4916
73887fd9
JB
4917 if (!rdev->ops->get_station)
4918 return -EOPNOTSUPP;
3b85875a 4919
73887fd9 4920 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 4921 if (err)
73887fd9 4922 return err;
2ec600d6 4923
fd2120ca 4924 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7ea3e110 4925 if (!msg) {
ba8f566a 4926 cfg80211_sinfo_release_content(&sinfo);
73887fd9 4927 return -ENOMEM;
7ea3e110 4928 }
fd5b74dc 4929
cf5ead82
JB
4930 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
4931 info->snd_portid, info->snd_seq, 0,
73887fd9 4932 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991 4933 nlmsg_free(msg);
73887fd9 4934 return -ENOBUFS;
4c476991 4935 }
3b85875a 4936
73887fd9 4937 return genlmsg_reply(msg, info);
5727ef1b
JB
4938}
4939
77ee7c89
JB
4940int cfg80211_check_station_change(struct wiphy *wiphy,
4941 struct station_parameters *params,
4942 enum cfg80211_station_type statype)
4943{
e4208427
AB
4944 if (params->listen_interval != -1 &&
4945 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 4946 return -EINVAL;
e4208427 4947
17b94247
AB
4948 if (params->support_p2p_ps != -1 &&
4949 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
4950 return -EINVAL;
4951
c72e1140 4952 if (params->aid &&
e4208427
AB
4953 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
4954 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
4955 return -EINVAL;
4956
4957 /* When you run into this, adjust the code below for the new flag */
4958 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
4959
4960 switch (statype) {
eef941e6
TP
4961 case CFG80211_STA_MESH_PEER_KERNEL:
4962 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
4963 /*
4964 * No ignoring the TDLS flag here -- the userspace mesh
4965 * code doesn't have the bug of including TDLS in the
4966 * mask everywhere.
4967 */
4968 if (params->sta_flags_mask &
4969 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4970 BIT(NL80211_STA_FLAG_MFP) |
4971 BIT(NL80211_STA_FLAG_AUTHORIZED)))
4972 return -EINVAL;
4973 break;
4974 case CFG80211_STA_TDLS_PEER_SETUP:
4975 case CFG80211_STA_TDLS_PEER_ACTIVE:
4976 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
4977 return -EINVAL;
4978 /* ignore since it can't change */
4979 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
4980 break;
4981 default:
4982 /* disallow mesh-specific things */
4983 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
4984 return -EINVAL;
4985 if (params->local_pm)
4986 return -EINVAL;
4987 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
4988 return -EINVAL;
4989 }
4990
4991 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
4992 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
4993 /* TDLS can't be set, ... */
4994 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
4995 return -EINVAL;
4996 /*
4997 * ... but don't bother the driver with it. This works around
4998 * a hostapd/wpa_supplicant issue -- it always includes the
4999 * TLDS_PEER flag in the mask even for AP mode.
5000 */
5001 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
5002 }
5003
47edb11b
AB
5004 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
5005 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
5006 /* reject other things that can't change */
5007 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
5008 return -EINVAL;
5009 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
5010 return -EINVAL;
5011 if (params->supported_rates)
5012 return -EINVAL;
c4cbaf79
LC
5013 if (params->ext_capab || params->ht_capa || params->vht_capa ||
5014 params->he_capa)
77ee7c89
JB
5015 return -EINVAL;
5016 }
5017
47edb11b
AB
5018 if (statype != CFG80211_STA_AP_CLIENT &&
5019 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
5020 if (params->vlan)
5021 return -EINVAL;
5022 }
5023
5024 switch (statype) {
5025 case CFG80211_STA_AP_MLME_CLIENT:
5026 /* Use this only for authorizing/unauthorizing a station */
5027 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
5028 return -EOPNOTSUPP;
5029 break;
5030 case CFG80211_STA_AP_CLIENT:
47edb11b 5031 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
5032 /* accept only the listed bits */
5033 if (params->sta_flags_mask &
5034 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
5035 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5036 BIT(NL80211_STA_FLAG_ASSOCIATED) |
5037 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
5038 BIT(NL80211_STA_FLAG_WME) |
5039 BIT(NL80211_STA_FLAG_MFP)))
5040 return -EINVAL;
5041
5042 /* but authenticated/associated only if driver handles it */
5043 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
5044 params->sta_flags_mask &
5045 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5046 BIT(NL80211_STA_FLAG_ASSOCIATED)))
5047 return -EINVAL;
5048 break;
5049 case CFG80211_STA_IBSS:
5050 case CFG80211_STA_AP_STA:
5051 /* reject any changes other than AUTHORIZED */
5052 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
5053 return -EINVAL;
5054 break;
5055 case CFG80211_STA_TDLS_PEER_SETUP:
5056 /* reject any changes other than AUTHORIZED or WME */
5057 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
5058 BIT(NL80211_STA_FLAG_WME)))
5059 return -EINVAL;
5060 /* force (at least) rates when authorizing */
5061 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
5062 !params->supported_rates)
5063 return -EINVAL;
5064 break;
5065 case CFG80211_STA_TDLS_PEER_ACTIVE:
5066 /* reject any changes */
5067 return -EINVAL;
eef941e6 5068 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
5069 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5070 return -EINVAL;
5071 break;
eef941e6 5072 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
5073 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
5074 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
5075 return -EINVAL;
5076 break;
5077 }
5078
06f7c88c
BL
5079 /*
5080 * Older kernel versions ignored this attribute entirely, so don't
5081 * reject attempts to update it but mark it as unused instead so the
5082 * driver won't look at the data.
5083 */
5084 if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
5085 statype != CFG80211_STA_TDLS_PEER_SETUP)
5086 params->opmode_notif_used = false;
5087
77ee7c89
JB
5088 return 0;
5089}
5090EXPORT_SYMBOL(cfg80211_check_station_change);
5091
5727ef1b 5092/*
c258d2de 5093 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 5094 */
80b99899
JB
5095static struct net_device *get_vlan(struct genl_info *info,
5096 struct cfg80211_registered_device *rdev)
5727ef1b 5097{
463d0183 5098 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
5099 struct net_device *v;
5100 int ret;
5101
5102 if (!vlanattr)
5103 return NULL;
5104
5105 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
5106 if (!v)
5107 return ERR_PTR(-ENODEV);
5108
5109 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
5110 ret = -EINVAL;
5111 goto error;
5727ef1b 5112 }
80b99899 5113
77ee7c89
JB
5114 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
5115 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5116 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
5117 ret = -EINVAL;
5118 goto error;
5119 }
5120
80b99899
JB
5121 if (!netif_running(v)) {
5122 ret = -ENETDOWN;
5123 goto error;
5124 }
5125
5126 return v;
5127 error:
5128 dev_put(v);
5129 return ERR_PTR(ret);
5727ef1b
JB
5130}
5131
94e860f1
JB
5132static const struct nla_policy
5133nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
5134 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
5135 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
5136};
5137
ff276691
JB
5138static int nl80211_parse_sta_wme(struct genl_info *info,
5139 struct station_parameters *params)
df881293 5140{
df881293
JM
5141 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
5142 struct nlattr *nla;
5143 int err;
5144
df881293
JM
5145 /* parse WME attributes if present */
5146 if (!info->attrs[NL80211_ATTR_STA_WME])
5147 return 0;
5148
5149 nla = info->attrs[NL80211_ATTR_STA_WME];
5150 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
fe52145f 5151 nl80211_sta_wme_policy, info->extack);
df881293
JM
5152 if (err)
5153 return err;
5154
5155 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
5156 params->uapsd_queues = nla_get_u8(
5157 tb[NL80211_STA_WME_UAPSD_QUEUES]);
5158 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
5159 return -EINVAL;
5160
5161 if (tb[NL80211_STA_WME_MAX_SP])
5162 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
5163
5164 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
5165 return -EINVAL;
5166
5167 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
5168
5169 return 0;
5170}
5171
c01fc9ad
SD
5172static int nl80211_parse_sta_channel_info(struct genl_info *info,
5173 struct station_parameters *params)
5174{
5175 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
5176 params->supported_channels =
5177 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
5178 params->supported_channels_len =
5179 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
5180 /*
5181 * Need to include at least one (first channel, number of
5182 * channels) tuple for each subband, and must have proper
5183 * tuples for the rest of the data as well.
5184 */
5185 if (params->supported_channels_len < 2)
5186 return -EINVAL;
5187 if (params->supported_channels_len % 2)
5188 return -EINVAL;
5189 }
5190
5191 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
5192 params->supported_oper_classes =
5193 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
5194 params->supported_oper_classes_len =
5195 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
5196 /*
5197 * The value of the Length field of the Supported Operating
5198 * Classes element is between 2 and 253.
5199 */
5200 if (params->supported_oper_classes_len < 2 ||
5201 params->supported_oper_classes_len > 253)
5202 return -EINVAL;
5203 }
5204 return 0;
5205}
5206
ff276691
JB
5207static int nl80211_set_station_tdls(struct genl_info *info,
5208 struct station_parameters *params)
5209{
c01fc9ad 5210 int err;
ff276691 5211 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
5212 if (info->attrs[NL80211_ATTR_PEER_AID])
5213 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
5214 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
5215 params->ht_capa =
5216 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5217 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
5218 params->vht_capa =
5219 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
c4cbaf79
LC
5220 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
5221 params->he_capa =
5222 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5223 params->he_capa_len =
5224 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5225
5226 if (params->he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
5227 return -EINVAL;
5228 }
ff276691 5229
c01fc9ad
SD
5230 err = nl80211_parse_sta_channel_info(info, params);
5231 if (err)
5232 return err;
5233
ff276691
JB
5234 return nl80211_parse_sta_wme(info, params);
5235}
5236
5727ef1b
JB
5237static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
5238{
4c476991 5239 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 5240 struct net_device *dev = info->user_ptr[1];
5727ef1b 5241 struct station_parameters params;
77ee7c89
JB
5242 u8 *mac_addr;
5243 int err;
5727ef1b
JB
5244
5245 memset(&params, 0, sizeof(params));
5246
77ee7c89
JB
5247 if (!rdev->ops->change_station)
5248 return -EOPNOTSUPP;
5249
e4208427
AB
5250 /*
5251 * AID and listen_interval properties can be set only for unassociated
5252 * station. Include these parameters here and will check them in
5253 * cfg80211_check_station_change().
5254 */
a9bc31e4
AB
5255 if (info->attrs[NL80211_ATTR_STA_AID])
5256 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427
AB
5257
5258 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
5259 params.listen_interval =
5260 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
5261 else
5262 params.listen_interval = -1;
5727ef1b 5263
17b94247
AB
5264 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
5265 u8 tmp;
5266
5267 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
5268 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
5269 return -EINVAL;
5270
5271 params.support_p2p_ps = tmp;
5272 } else {
5273 params.support_p2p_ps = -1;
5274 }
5275
5727ef1b
JB
5276 if (!info->attrs[NL80211_ATTR_MAC])
5277 return -EINVAL;
5278
5279 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
5280
5281 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
5282 params.supported_rates =
5283 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5284 params.supported_rates_len =
5285 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5286 }
5287
9d62a986
JM
5288 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
5289 params.capability =
5290 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
5291 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
5292 }
5293
5294 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
5295 params.ext_capab =
5296 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5297 params.ext_capab_len =
5298 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5299 }
5300
bdd3ae3d 5301 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
5302 return -EINVAL;
5303
f8bacc21 5304 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
2ec600d6 5305 params.plink_action =
f8bacc21
JB
5306 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
5307 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
5308 return -EINVAL;
5309 }
2ec600d6 5310
f8bacc21 5311 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 5312 params.plink_state =
f8bacc21
JB
5313 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
5314 if (params.plink_state >= NUM_NL80211_PLINK_STATES)
5315 return -EINVAL;
7d27a0ba
MH
5316 if (info->attrs[NL80211_ATTR_MESH_PEER_AID]) {
5317 params.peer_aid = nla_get_u16(
5318 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
5319 if (params.peer_aid > IEEE80211_MAX_AID)
5320 return -EINVAL;
5321 }
f8bacc21
JB
5322 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
5323 }
9c3990aa 5324
3b1c5a53
MP
5325 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) {
5326 enum nl80211_mesh_power_mode pm = nla_get_u32(
5327 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
5328
5329 if (pm <= NL80211_MESH_POWER_UNKNOWN ||
5330 pm > NL80211_MESH_POWER_MAX)
5331 return -EINVAL;
5332
5333 params.local_pm = pm;
5334 }
5335
06f7c88c
BL
5336 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
5337 params.opmode_notif_used = true;
5338 params.opmode_notif =
5339 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
5340 }
5341
77ee7c89
JB
5342 /* Include parameters for TDLS peer (will check later) */
5343 err = nl80211_set_station_tdls(info, &params);
5344 if (err)
5345 return err;
5346
5347 params.vlan = get_vlan(info, rdev);
5348 if (IS_ERR(params.vlan))
5349 return PTR_ERR(params.vlan);
5350
a97f4424
JB
5351 switch (dev->ieee80211_ptr->iftype) {
5352 case NL80211_IFTYPE_AP:
5353 case NL80211_IFTYPE_AP_VLAN:
074ac8df 5354 case NL80211_IFTYPE_P2P_GO:
074ac8df 5355 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 5356 case NL80211_IFTYPE_STATION:
267335d6 5357 case NL80211_IFTYPE_ADHOC:
a97f4424 5358 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
5359 break;
5360 default:
77ee7c89
JB
5361 err = -EOPNOTSUPP;
5362 goto out_put_vlan;
034d655e
JB
5363 }
5364
77ee7c89 5365 /* driver will call cfg80211_check_station_change() */
e35e4d28 5366 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 5367
77ee7c89 5368 out_put_vlan:
5727ef1b
JB
5369 if (params.vlan)
5370 dev_put(params.vlan);
3b85875a 5371
5727ef1b
JB
5372 return err;
5373}
5374
5375static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
5376{
4c476991 5377 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 5378 int err;
4c476991 5379 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
5380 struct station_parameters params;
5381 u8 *mac_addr = NULL;
bda95eb1
JB
5382 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5383 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
5384
5385 memset(&params, 0, sizeof(params));
5386
984c311b
JB
5387 if (!rdev->ops->add_station)
5388 return -EOPNOTSUPP;
5389
5727ef1b
JB
5390 if (!info->attrs[NL80211_ATTR_MAC])
5391 return -EINVAL;
5392
5727ef1b
JB
5393 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
5394 return -EINVAL;
5395
5396 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
5397 return -EINVAL;
5398
5e4b6f56
JM
5399 if (!info->attrs[NL80211_ATTR_STA_AID] &&
5400 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
5401 return -EINVAL;
5402
5727ef1b
JB
5403 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
5404 params.supported_rates =
5405 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5406 params.supported_rates_len =
5407 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5408 params.listen_interval =
5409 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 5410
17b94247
AB
5411 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
5412 u8 tmp;
5413
5414 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
5415 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
5416 return -EINVAL;
5417
5418 params.support_p2p_ps = tmp;
5419 } else {
5420 /*
5421 * if not specified, assume it's supported for P2P GO interface,
5422 * and is NOT supported for AP interface
5423 */
5424 params.support_p2p_ps =
5425 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
5426 }
5427
3d124ea2 5428 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 5429 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
5430 else
5431 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
0e956c13
TLSC
5432 if (!params.aid || params.aid > IEEE80211_MAX_AID)
5433 return -EINVAL;
51b50fbe 5434
9d62a986
JM
5435 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
5436 params.capability =
5437 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
5438 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
5439 }
5440
5441 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
5442 params.ext_capab =
5443 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5444 params.ext_capab_len =
5445 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5446 }
5447
36aedc90
JM
5448 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
5449 params.ht_capa =
5450 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 5451
f461be3e
MP
5452 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
5453 params.vht_capa =
5454 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
5455
c4cbaf79
LC
5456 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
5457 params.he_capa =
5458 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5459 params.he_capa_len =
5460 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5461
5462 /* max len is validated in nla policy */
5463 if (params.he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
5464 return -EINVAL;
5465 }
5466
60f4a7b1
MK
5467 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
5468 params.opmode_notif_used = true;
5469 params.opmode_notif =
5470 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
5471 }
5472
f8bacc21 5473 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
96b78dff 5474 params.plink_action =
f8bacc21
JB
5475 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
5476 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
5477 return -EINVAL;
5478 }
96b78dff 5479
c01fc9ad
SD
5480 err = nl80211_parse_sta_channel_info(info, &params);
5481 if (err)
5482 return err;
5483
ff276691
JB
5484 err = nl80211_parse_sta_wme(info, &params);
5485 if (err)
5486 return err;
bdd90d5e 5487
bdd3ae3d 5488 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
5489 return -EINVAL;
5490
496fcc29
JB
5491 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
5492 * as userspace might just pass through the capabilities from the IEs
5493 * directly, rather than enforcing this restriction and returning an
5494 * error in this case.
5495 */
5496 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
5497 params.ht_capa = NULL;
5498 params.vht_capa = NULL;
c4cbaf79
LC
5499
5500 /* HE requires WME */
5501 if (params.he_capa_len)
5502 return -EINVAL;
496fcc29
JB
5503 }
5504
77ee7c89
JB
5505 /* When you run into this, adjust the code below for the new flag */
5506 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
5507
bdd90d5e
JB
5508 switch (dev->ieee80211_ptr->iftype) {
5509 case NL80211_IFTYPE_AP:
5510 case NL80211_IFTYPE_AP_VLAN:
5511 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
5512 /* ignore WME attributes if iface/sta is not capable */
5513 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
5514 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
5515 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 5516
bdd90d5e 5517 /* TDLS peers cannot be added */
3d124ea2
JM
5518 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5519 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 5520 return -EINVAL;
bdd90d5e
JB
5521 /* but don't bother the driver with it */
5522 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 5523
d582cffb
JB
5524 /* allow authenticated/associated only if driver handles it */
5525 if (!(rdev->wiphy.features &
5526 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 5527 params.sta_flags_mask & auth_assoc)
d582cffb
JB
5528 return -EINVAL;
5529
bda95eb1
JB
5530 /* Older userspace, or userspace wanting to be compatible with
5531 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
5532 * and assoc flags in the mask, but assumes the station will be
5533 * added as associated anyway since this was the required driver
5534 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
5535 * introduced.
5536 * In order to not bother drivers with this quirk in the API
5537 * set the flags in both the mask and set for new stations in
5538 * this case.
5539 */
5540 if (!(params.sta_flags_mask & auth_assoc)) {
5541 params.sta_flags_mask |= auth_assoc;
5542 params.sta_flags_set |= auth_assoc;
5543 }
5544
bdd90d5e
JB
5545 /* must be last in here for error handling */
5546 params.vlan = get_vlan(info, rdev);
5547 if (IS_ERR(params.vlan))
5548 return PTR_ERR(params.vlan);
5549 break;
5550 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
5551 /* ignore uAPSD data */
5552 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5553
d582cffb
JB
5554 /* associated is disallowed */
5555 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
5556 return -EINVAL;
bdd90d5e 5557 /* TDLS peers cannot be added */
3d124ea2
JM
5558 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5559 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
5560 return -EINVAL;
5561 break;
5562 case NL80211_IFTYPE_STATION:
93d08f0b 5563 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
5564 /* ignore uAPSD data */
5565 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5566
77ee7c89
JB
5567 /* these are disallowed */
5568 if (params.sta_flags_mask &
5569 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
5570 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 5571 return -EINVAL;
bdd90d5e
JB
5572 /* Only TDLS peers can be added */
5573 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
5574 return -EINVAL;
5575 /* Can only add if TDLS ... */
5576 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
5577 return -EOPNOTSUPP;
5578 /* ... with external setup is supported */
5579 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
5580 return -EOPNOTSUPP;
77ee7c89
JB
5581 /*
5582 * Older wpa_supplicant versions always mark the TDLS peer
5583 * as authorized, but it shouldn't yet be.
5584 */
5585 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
5586 break;
5587 default:
5588 return -EOPNOTSUPP;
c75786c9
EP
5589 }
5590
bdd90d5e 5591 /* be aware of params.vlan when changing code here */
5727ef1b 5592
e35e4d28 5593 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 5594
5727ef1b
JB
5595 if (params.vlan)
5596 dev_put(params.vlan);
5727ef1b
JB
5597 return err;
5598}
5599
5600static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
5601{
4c476991
JB
5602 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5603 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
5604 struct station_del_parameters params;
5605
5606 memset(&params, 0, sizeof(params));
5727ef1b
JB
5607
5608 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 5609 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 5610
e80cf853 5611 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
d5d9de02 5612 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
074ac8df 5613 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
5614 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5615 return -EINVAL;
5727ef1b 5616
4c476991
JB
5617 if (!rdev->ops->del_station)
5618 return -EOPNOTSUPP;
3b85875a 5619
98856866
JM
5620 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
5621 params.subtype =
5622 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
5623 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
5624 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
5625 return -EINVAL;
5626 } else {
5627 /* Default to Deauthentication frame */
5628 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
5629 }
5630
5631 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
5632 params.reason_code =
5633 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
5634 if (params.reason_code == 0)
5635 return -EINVAL; /* 0 is reserved */
5636 } else {
5637 /* Default to reason code 2 */
5638 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
5639 }
5640
89c771e5 5641 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
5642}
5643
15e47304 5644static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
5645 int flags, struct net_device *dev,
5646 u8 *dst, u8 *next_hop,
5647 struct mpath_info *pinfo)
5648{
5649 void *hdr;
5650 struct nlattr *pinfoattr;
5651
1ef4c850 5652 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
5653 if (!hdr)
5654 return -1;
5655
9360ffd1
DM
5656 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5657 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
5658 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
5659 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
5660 goto nla_put_failure;
f5ea9120 5661
2ec600d6
LCC
5662 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
5663 if (!pinfoattr)
5664 goto nla_put_failure;
9360ffd1
DM
5665 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
5666 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
5667 pinfo->frame_qlen))
5668 goto nla_put_failure;
5669 if (((pinfo->filled & MPATH_INFO_SN) &&
5670 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
5671 ((pinfo->filled & MPATH_INFO_METRIC) &&
5672 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
5673 pinfo->metric)) ||
5674 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
5675 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
5676 pinfo->exptime)) ||
5677 ((pinfo->filled & MPATH_INFO_FLAGS) &&
5678 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
5679 pinfo->flags)) ||
5680 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
5681 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
5682 pinfo->discovery_timeout)) ||
5683 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
5684 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
5685 pinfo->discovery_retries)))
5686 goto nla_put_failure;
2ec600d6
LCC
5687
5688 nla_nest_end(msg, pinfoattr);
5689
053c095a
JB
5690 genlmsg_end(msg, hdr);
5691 return 0;
2ec600d6
LCC
5692
5693 nla_put_failure:
bc3ed28c
TG
5694 genlmsg_cancel(msg, hdr);
5695 return -EMSGSIZE;
2ec600d6
LCC
5696}
5697
5698static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 5699 struct netlink_callback *cb)
2ec600d6 5700{
2ec600d6 5701 struct mpath_info pinfo;
1b8ec87a 5702 struct cfg80211_registered_device *rdev;
97990a06 5703 struct wireless_dev *wdev;
2ec600d6
LCC
5704 u8 dst[ETH_ALEN];
5705 u8 next_hop[ETH_ALEN];
97990a06 5706 int path_idx = cb->args[2];
2ec600d6 5707 int err;
2ec600d6 5708
ea90e0dc 5709 rtnl_lock();
5297c65c 5710 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 5711 if (err)
ea90e0dc 5712 goto out_err;
bba95fef 5713
1b8ec87a 5714 if (!rdev->ops->dump_mpath) {
eec60b03 5715 err = -EOPNOTSUPP;
bba95fef
JB
5716 goto out_err;
5717 }
5718
97990a06 5719 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 5720 err = -EOPNOTSUPP;
0448b5fc 5721 goto out_err;
eec60b03
JM
5722 }
5723
bba95fef 5724 while (1) {
1b8ec87a 5725 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 5726 next_hop, &pinfo);
bba95fef 5727 if (err == -ENOENT)
2ec600d6 5728 break;
bba95fef 5729 if (err)
3b85875a 5730 goto out_err;
2ec600d6 5731
15e47304 5732 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 5733 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 5734 wdev->netdev, dst, next_hop,
bba95fef
JB
5735 &pinfo) < 0)
5736 goto out;
2ec600d6 5737
bba95fef 5738 path_idx++;
2ec600d6 5739 }
2ec600d6 5740
bba95fef 5741 out:
97990a06 5742 cb->args[2] = path_idx;
bba95fef 5743 err = skb->len;
bba95fef 5744 out_err:
ea90e0dc 5745 rtnl_unlock();
bba95fef 5746 return err;
2ec600d6
LCC
5747}
5748
5749static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
5750{
4c476991 5751 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 5752 int err;
4c476991 5753 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5754 struct mpath_info pinfo;
5755 struct sk_buff *msg;
5756 u8 *dst = NULL;
5757 u8 next_hop[ETH_ALEN];
5758
5759 memset(&pinfo, 0, sizeof(pinfo));
5760
5761 if (!info->attrs[NL80211_ATTR_MAC])
5762 return -EINVAL;
5763
5764 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5765
4c476991
JB
5766 if (!rdev->ops->get_mpath)
5767 return -EOPNOTSUPP;
2ec600d6 5768
4c476991
JB
5769 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5770 return -EOPNOTSUPP;
eec60b03 5771
e35e4d28 5772 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 5773 if (err)
4c476991 5774 return err;
2ec600d6 5775
fd2120ca 5776 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 5777 if (!msg)
4c476991 5778 return -ENOMEM;
2ec600d6 5779
15e47304 5780 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
5781 dev, dst, next_hop, &pinfo) < 0) {
5782 nlmsg_free(msg);
5783 return -ENOBUFS;
5784 }
3b85875a 5785
4c476991 5786 return genlmsg_reply(msg, info);
2ec600d6
LCC
5787}
5788
5789static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
5790{
4c476991
JB
5791 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5792 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5793 u8 *dst = NULL;
5794 u8 *next_hop = NULL;
5795
5796 if (!info->attrs[NL80211_ATTR_MAC])
5797 return -EINVAL;
5798
5799 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5800 return -EINVAL;
5801
5802 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5803 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5804
4c476991
JB
5805 if (!rdev->ops->change_mpath)
5806 return -EOPNOTSUPP;
35a8efe1 5807
4c476991
JB
5808 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5809 return -EOPNOTSUPP;
2ec600d6 5810
e35e4d28 5811 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 5812}
4c476991 5813
2ec600d6
LCC
5814static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
5815{
4c476991
JB
5816 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5817 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5818 u8 *dst = NULL;
5819 u8 *next_hop = NULL;
5820
5821 if (!info->attrs[NL80211_ATTR_MAC])
5822 return -EINVAL;
5823
5824 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5825 return -EINVAL;
5826
5827 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5828 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5829
4c476991
JB
5830 if (!rdev->ops->add_mpath)
5831 return -EOPNOTSUPP;
35a8efe1 5832
4c476991
JB
5833 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5834 return -EOPNOTSUPP;
2ec600d6 5835
e35e4d28 5836 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
5837}
5838
5839static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
5840{
4c476991
JB
5841 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5842 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5843 u8 *dst = NULL;
5844
5845 if (info->attrs[NL80211_ATTR_MAC])
5846 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5847
4c476991
JB
5848 if (!rdev->ops->del_mpath)
5849 return -EOPNOTSUPP;
3b85875a 5850
e35e4d28 5851 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
5852}
5853
66be7d2b
HR
5854static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
5855{
5856 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5857 int err;
5858 struct net_device *dev = info->user_ptr[1];
5859 struct mpath_info pinfo;
5860 struct sk_buff *msg;
5861 u8 *dst = NULL;
5862 u8 mpp[ETH_ALEN];
5863
5864 memset(&pinfo, 0, sizeof(pinfo));
5865
5866 if (!info->attrs[NL80211_ATTR_MAC])
5867 return -EINVAL;
5868
5869 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5870
5871 if (!rdev->ops->get_mpp)
5872 return -EOPNOTSUPP;
5873
5874 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5875 return -EOPNOTSUPP;
5876
5877 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
5878 if (err)
5879 return err;
5880
5881 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5882 if (!msg)
5883 return -ENOMEM;
5884
5885 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
5886 dev, dst, mpp, &pinfo) < 0) {
5887 nlmsg_free(msg);
5888 return -ENOBUFS;
5889 }
5890
5891 return genlmsg_reply(msg, info);
5892}
5893
5894static int nl80211_dump_mpp(struct sk_buff *skb,
5895 struct netlink_callback *cb)
5896{
5897 struct mpath_info pinfo;
5898 struct cfg80211_registered_device *rdev;
5899 struct wireless_dev *wdev;
5900 u8 dst[ETH_ALEN];
5901 u8 mpp[ETH_ALEN];
5902 int path_idx = cb->args[2];
5903 int err;
5904
ea90e0dc 5905 rtnl_lock();
5297c65c 5906 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
66be7d2b 5907 if (err)
ea90e0dc 5908 goto out_err;
66be7d2b
HR
5909
5910 if (!rdev->ops->dump_mpp) {
5911 err = -EOPNOTSUPP;
5912 goto out_err;
5913 }
5914
5915 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
5916 err = -EOPNOTSUPP;
5917 goto out_err;
5918 }
5919
5920 while (1) {
5921 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
5922 mpp, &pinfo);
5923 if (err == -ENOENT)
5924 break;
5925 if (err)
5926 goto out_err;
5927
5928 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
5929 cb->nlh->nlmsg_seq, NLM_F_MULTI,
5930 wdev->netdev, dst, mpp,
5931 &pinfo) < 0)
5932 goto out;
5933
5934 path_idx++;
5935 }
5936
5937 out:
5938 cb->args[2] = path_idx;
5939 err = skb->len;
5940 out_err:
ea90e0dc 5941 rtnl_unlock();
66be7d2b
HR
5942 return err;
5943}
5944
9f1ba906
JM
5945static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
5946{
4c476991
JB
5947 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5948 struct net_device *dev = info->user_ptr[1];
c56589ed 5949 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 5950 struct bss_parameters params;
c56589ed 5951 int err;
9f1ba906
JM
5952
5953 memset(&params, 0, sizeof(params));
5954 /* default to not changing parameters */
5955 params.use_cts_prot = -1;
5956 params.use_short_preamble = -1;
5957 params.use_short_slot_time = -1;
fd8aaaf3 5958 params.ap_isolate = -1;
50b12f59 5959 params.ht_opmode = -1;
53cabad7
JB
5960 params.p2p_ctwindow = -1;
5961 params.p2p_opp_ps = -1;
9f1ba906
JM
5962
5963 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
5964 params.use_cts_prot =
5965 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
5966 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
5967 params.use_short_preamble =
5968 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
5969 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
5970 params.use_short_slot_time =
5971 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
5972 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
5973 params.basic_rates =
5974 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5975 params.basic_rates_len =
5976 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5977 }
fd8aaaf3
FF
5978 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
5979 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
5980 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
5981 params.ht_opmode =
5982 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 5983
53cabad7
JB
5984 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
5985 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5986 return -EINVAL;
5987 params.p2p_ctwindow =
5988 nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
5989 if (params.p2p_ctwindow < 0)
5990 return -EINVAL;
5991 if (params.p2p_ctwindow != 0 &&
5992 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
5993 return -EINVAL;
5994 }
5995
5996 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
5997 u8 tmp;
5998
5999 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6000 return -EINVAL;
6001 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
6002 if (tmp > 1)
6003 return -EINVAL;
6004 params.p2p_opp_ps = tmp;
6005 if (params.p2p_opp_ps &&
6006 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
6007 return -EINVAL;
6008 }
6009
4c476991
JB
6010 if (!rdev->ops->change_bss)
6011 return -EOPNOTSUPP;
9f1ba906 6012
074ac8df 6013 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
6014 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6015 return -EOPNOTSUPP;
3b85875a 6016
c56589ed
SW
6017 wdev_lock(wdev);
6018 err = rdev_change_bss(rdev, dev, &params);
6019 wdev_unlock(wdev);
6020
6021 return err;
9f1ba906
JM
6022}
6023
b2e1b302
LR
6024static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
6025{
b2e1b302 6026 char *data = NULL;
05050753 6027 bool is_indoor;
57b5ce07 6028 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
6029 u32 owner_nlportid;
6030
80778f18
LR
6031 /*
6032 * You should only get this when cfg80211 hasn't yet initialized
6033 * completely when built-in to the kernel right between the time
6034 * window between nl80211_init() and regulatory_init(), if that is
6035 * even possible.
6036 */
458f4f9e 6037 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 6038 return -EINPROGRESS;
80778f18 6039
57b5ce07
LR
6040 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
6041 user_reg_hint_type =
6042 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
6043 else
6044 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
6045
6046 switch (user_reg_hint_type) {
6047 case NL80211_USER_REG_HINT_USER:
6048 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
6049 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
6050 return -EINVAL;
6051
6052 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
6053 return regulatory_hint_user(data, user_reg_hint_type);
6054 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
6055 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
6056 owner_nlportid = info->snd_portid;
6057 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
6058 } else {
6059 owner_nlportid = 0;
6060 is_indoor = true;
6061 }
6062
6063 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
6064 default:
6065 return -EINVAL;
6066 }
b2e1b302
LR
6067}
6068
1ea4ff3e
JB
6069static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
6070{
6071 return reg_reload_regdb();
6072}
6073
24bdd9f4 6074static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 6075 struct genl_info *info)
93da9cc1 6076{
4c476991 6077 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 6078 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
6079 struct wireless_dev *wdev = dev->ieee80211_ptr;
6080 struct mesh_config cur_params;
6081 int err = 0;
93da9cc1 6082 void *hdr;
6083 struct nlattr *pinfoattr;
6084 struct sk_buff *msg;
6085
29cbe68c
JB
6086 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
6087 return -EOPNOTSUPP;
6088
24bdd9f4 6089 if (!rdev->ops->get_mesh_config)
4c476991 6090 return -EOPNOTSUPP;
f3f92586 6091
29cbe68c
JB
6092 wdev_lock(wdev);
6093 /* If not connected, get default parameters */
6094 if (!wdev->mesh_id_len)
6095 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
6096 else
e35e4d28 6097 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
6098 wdev_unlock(wdev);
6099
93da9cc1 6100 if (err)
4c476991 6101 return err;
93da9cc1 6102
6103 /* Draw up a netlink message to send back */
fd2120ca 6104 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
6105 if (!msg)
6106 return -ENOMEM;
15e47304 6107 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 6108 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 6109 if (!hdr)
efe1cf0c 6110 goto out;
24bdd9f4 6111 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 6112 if (!pinfoattr)
6113 goto nla_put_failure;
9360ffd1
DM
6114 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
6115 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
6116 cur_params.dot11MeshRetryTimeout) ||
6117 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
6118 cur_params.dot11MeshConfirmTimeout) ||
6119 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
6120 cur_params.dot11MeshHoldingTimeout) ||
6121 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
6122 cur_params.dot11MeshMaxPeerLinks) ||
6123 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
6124 cur_params.dot11MeshMaxRetries) ||
6125 nla_put_u8(msg, NL80211_MESHCONF_TTL,
6126 cur_params.dot11MeshTTL) ||
6127 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
6128 cur_params.element_ttl) ||
6129 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
6130 cur_params.auto_open_plinks) ||
7eab0f64
JL
6131 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
6132 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
6133 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
6134 cur_params.dot11MeshHWMPmaxPREQretries) ||
6135 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
6136 cur_params.path_refresh_time) ||
6137 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
6138 cur_params.min_discovery_timeout) ||
6139 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
6140 cur_params.dot11MeshHWMPactivePathTimeout) ||
6141 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
6142 cur_params.dot11MeshHWMPpreqMinInterval) ||
6143 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
6144 cur_params.dot11MeshHWMPperrMinInterval) ||
6145 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
6146 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
6147 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
6148 cur_params.dot11MeshHWMPRootMode) ||
6149 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
6150 cur_params.dot11MeshHWMPRannInterval) ||
6151 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
6152 cur_params.dot11MeshGateAnnouncementProtocol) ||
6153 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
6154 cur_params.dot11MeshForwarding) ||
335d5349 6155 nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
6156 cur_params.rssi_threshold) ||
6157 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
6158 cur_params.ht_opmode) ||
6159 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
6160 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
6161 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
6162 cur_params.dot11MeshHWMProotInterval) ||
6163 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
6164 cur_params.dot11MeshHWMPconfirmationInterval) ||
6165 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
6166 cur_params.power_mode) ||
6167 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
6168 cur_params.dot11MeshAwakeWindowDuration) ||
6169 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
6170 cur_params.plink_timeout))
9360ffd1 6171 goto nla_put_failure;
93da9cc1 6172 nla_nest_end(msg, pinfoattr);
6173 genlmsg_end(msg, hdr);
4c476991 6174 return genlmsg_reply(msg, info);
93da9cc1 6175
3b85875a 6176 nla_put_failure:
efe1cf0c 6177 out:
d080e275 6178 nlmsg_free(msg);
4c476991 6179 return -ENOBUFS;
93da9cc1 6180}
6181
b54452b0 6182static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
93da9cc1 6183 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
6184 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
6185 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
6186 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
6187 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
6188 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
45904f21 6189 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
93da9cc1 6190 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
d299a1f2 6191 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
93da9cc1 6192 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
6193 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
6194 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
6195 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
6196 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
dca7e943 6197 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 },
93da9cc1 6198 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
699403db 6199 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
0507e159 6200 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
16dd7267 6201 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
94f90656 6202 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
a4f606ea
CYY
6203 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
6204 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6
CYY
6205 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
6206 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
728b19e5 6207 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
3b1c5a53
MP
6208 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 },
6209 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 6210 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
93da9cc1 6211};
6212
c80d545d
JC
6213static const struct nla_policy
6214 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 6215 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
6216 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
6217 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 6218 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 6219 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 6220 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
581a8b0f 6221 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
a4f606ea 6222 .len = IEEE80211_MAX_DATA_LEN },
b130e5ce 6223 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
6224};
6225
f151d9db
AB
6226static int nl80211_check_bool(const struct nlattr *nla, u8 min, u8 max, bool *out)
6227{
6228 u8 val = nla_get_u8(nla);
6229 if (val < min || val > max)
6230 return -EINVAL;
6231 *out = val;
6232 return 0;
6233}
6234
6235static int nl80211_check_u8(const struct nlattr *nla, u8 min, u8 max, u8 *out)
6236{
6237 u8 val = nla_get_u8(nla);
6238 if (val < min || val > max)
6239 return -EINVAL;
6240 *out = val;
6241 return 0;
6242}
6243
6244static int nl80211_check_u16(const struct nlattr *nla, u16 min, u16 max, u16 *out)
6245{
6246 u16 val = nla_get_u16(nla);
6247 if (val < min || val > max)
6248 return -EINVAL;
6249 *out = val;
6250 return 0;
6251}
6252
6253static int nl80211_check_u32(const struct nlattr *nla, u32 min, u32 max, u32 *out)
6254{
6255 u32 val = nla_get_u32(nla);
6256 if (val < min || val > max)
6257 return -EINVAL;
6258 *out = val;
6259 return 0;
6260}
6261
6262static int nl80211_check_s32(const struct nlattr *nla, s32 min, s32 max, s32 *out)
6263{
6264 s32 val = nla_get_s32(nla);
6265 if (val < min || val > max)
6266 return -EINVAL;
6267 *out = val;
6268 return 0;
6269}
6270
ff9a71af
JB
6271static int nl80211_check_power_mode(const struct nlattr *nla,
6272 enum nl80211_mesh_power_mode min,
6273 enum nl80211_mesh_power_mode max,
6274 enum nl80211_mesh_power_mode *out)
6275{
6276 u32 val = nla_get_u32(nla);
6277 if (val < min || val > max)
6278 return -EINVAL;
6279 *out = val;
6280 return 0;
6281}
6282
24bdd9f4 6283static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
6284 struct mesh_config *cfg,
6285 u32 *mask_out)
93da9cc1 6286{
93da9cc1 6287 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 6288 u32 mask = 0;
9757235f 6289 u16 ht_opmode;
93da9cc1 6290
ea54fba2
MP
6291#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \
6292do { \
6293 if (tb[attr]) { \
f151d9db 6294 if (fn(tb[attr], min, max, &cfg->param)) \
ea54fba2 6295 return -EINVAL; \
ea54fba2
MP
6296 mask |= (1 << (attr - 1)); \
6297 } \
6298} while (0)
bd90fdcc 6299
24bdd9f4 6300 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 6301 return -EINVAL;
6302 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
24bdd9f4 6303 info->attrs[NL80211_ATTR_MESH_CONFIG],
fe52145f 6304 nl80211_meshconf_params_policy, info->extack))
93da9cc1 6305 return -EINVAL;
6306
93da9cc1 6307 /* This makes sure that there aren't more than 32 mesh config
6308 * parameters (otherwise our bitfield scheme would not work.) */
6309 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
6310
6311 /* Fill in the params struct */
ea54fba2 6312 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255,
a4f606ea 6313 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
f151d9db 6314 nl80211_check_u16);
ea54fba2 6315 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255,
a4f606ea 6316 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
f151d9db 6317 nl80211_check_u16);
ea54fba2 6318 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255,
a4f606ea 6319 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
f151d9db 6320 nl80211_check_u16);
ea54fba2 6321 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255,
a4f606ea 6322 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
f151d9db 6323 nl80211_check_u16);
ea54fba2 6324 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16,
a4f606ea 6325 mask, NL80211_MESHCONF_MAX_RETRIES,
f151d9db 6326 nl80211_check_u8);
ea54fba2 6327 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255,
f151d9db 6328 mask, NL80211_MESHCONF_TTL, nl80211_check_u8);
ea54fba2 6329 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255,
a4f606ea 6330 mask, NL80211_MESHCONF_ELEMENT_TTL,
f151d9db 6331 nl80211_check_u8);
ea54fba2 6332 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1,
a4f606ea 6333 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
f151d9db 6334 nl80211_check_bool);
ea54fba2
MP
6335 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
6336 1, 255, mask,
a4f606ea 6337 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
f151d9db 6338 nl80211_check_u32);
ea54fba2 6339 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255,
a4f606ea 6340 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
f151d9db 6341 nl80211_check_u8);
ea54fba2 6342 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535,
a4f606ea 6343 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
f151d9db 6344 nl80211_check_u32);
ea54fba2 6345 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535,
a4f606ea 6346 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
f151d9db 6347 nl80211_check_u16);
ea54fba2
MP
6348 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
6349 1, 65535, mask,
a4f606ea 6350 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
f151d9db 6351 nl80211_check_u32);
93da9cc1 6352 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
ea54fba2
MP
6353 1, 65535, mask,
6354 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
f151d9db 6355 nl80211_check_u16);
dca7e943 6356 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
ea54fba2
MP
6357 1, 65535, mask,
6358 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
f151d9db 6359 nl80211_check_u16);
93da9cc1 6360 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
6361 dot11MeshHWMPnetDiameterTraversalTime,
6362 1, 65535, mask,
a4f606ea 6363 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
f151d9db 6364 nl80211_check_u16);
ea54fba2
MP
6365 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4,
6366 mask, NL80211_MESHCONF_HWMP_ROOTMODE,
f151d9db 6367 nl80211_check_u8);
ea54fba2
MP
6368 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535,
6369 mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
f151d9db 6370 nl80211_check_u16);
63c5723b 6371 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
6372 dot11MeshGateAnnouncementProtocol, 0, 1,
6373 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
f151d9db 6374 nl80211_check_bool);
ea54fba2 6375 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1,
a4f606ea 6376 mask, NL80211_MESHCONF_FORWARDING,
f151d9db 6377 nl80211_check_bool);
83374fe9 6378 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
a4f606ea 6379 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
f151d9db 6380 nl80211_check_s32);
9757235f
MH
6381 /*
6382 * Check HT operation mode based on
188f60ab 6383 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
9757235f
MH
6384 */
6385 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
6386 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
6387
6388 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
6389 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
6390 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
6391 return -EINVAL;
6392
188f60ab
BC
6393 /* NON_HT_STA bit is reserved, but some programs set it */
6394 ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
9757235f 6395
9757235f 6396 cfg->ht_opmode = ht_opmode;
fd551bac 6397 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
9757235f 6398 }
ac1073a6 6399 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
ea54fba2 6400 1, 65535, mask,
ac1073a6 6401 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
f151d9db 6402 nl80211_check_u32);
ea54fba2 6403 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535,
ac1073a6 6404 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
f151d9db 6405 nl80211_check_u16);
728b19e5 6406 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
6407 dot11MeshHWMPconfirmationInterval,
6408 1, 65535, mask,
728b19e5 6409 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
f151d9db 6410 nl80211_check_u16);
3b1c5a53
MP
6411 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode,
6412 NL80211_MESH_POWER_ACTIVE,
6413 NL80211_MESH_POWER_MAX,
6414 mask, NL80211_MESHCONF_POWER_MODE,
ff9a71af 6415 nl80211_check_power_mode);
3b1c5a53
MP
6416 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration,
6417 0, 65535, mask,
f151d9db 6418 NL80211_MESHCONF_AWAKE_WINDOW, nl80211_check_u16);
31f909a2 6419 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 0, 0xffffffff,
8e7c0538 6420 mask, NL80211_MESHCONF_PLINK_TIMEOUT,
f151d9db 6421 nl80211_check_u32);
bd90fdcc
JB
6422 if (mask_out)
6423 *mask_out = mask;
c80d545d 6424
bd90fdcc
JB
6425 return 0;
6426
6427#undef FILL_IN_MESH_PARAM_IF_SET
6428}
6429
c80d545d
JC
6430static int nl80211_parse_mesh_setup(struct genl_info *info,
6431 struct mesh_setup *setup)
6432{
bb2798d4 6433 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
6434 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
6435
6436 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
6437 return -EINVAL;
6438 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
6439 info->attrs[NL80211_ATTR_MESH_SETUP],
fe52145f 6440 nl80211_mesh_setup_params_policy, info->extack))
c80d545d
JC
6441 return -EINVAL;
6442
d299a1f2
JC
6443 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
6444 setup->sync_method =
6445 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
6446 IEEE80211_SYNC_METHOD_VENDOR :
6447 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
6448
c80d545d
JC
6449 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
6450 setup->path_sel_proto =
6451 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
6452 IEEE80211_PATH_PROTOCOL_VENDOR :
6453 IEEE80211_PATH_PROTOCOL_HWMP;
6454
6455 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
6456 setup->path_metric =
6457 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
6458 IEEE80211_PATH_METRIC_VENDOR :
6459 IEEE80211_PATH_METRIC_AIRTIME;
6460
581a8b0f 6461 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 6462 struct nlattr *ieattr =
581a8b0f 6463 tb[NL80211_MESH_SETUP_IE];
c80d545d
JC
6464 if (!is_valid_ie_attr(ieattr))
6465 return -EINVAL;
581a8b0f
JC
6466 setup->ie = nla_data(ieattr);
6467 setup->ie_len = nla_len(ieattr);
c80d545d 6468 }
bb2798d4
TP
6469 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
6470 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
6471 return -EINVAL;
6472 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
6473 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
6474 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
6475 if (setup->is_secure)
6476 setup->user_mpm = true;
c80d545d 6477
6e16d90b
CT
6478 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
6479 if (!setup->user_mpm)
6480 return -EINVAL;
6481 setup->auth_id =
6482 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
6483 }
6484
c80d545d
JC
6485 return 0;
6486}
6487
24bdd9f4 6488static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 6489 struct genl_info *info)
bd90fdcc
JB
6490{
6491 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6492 struct net_device *dev = info->user_ptr[1];
29cbe68c 6493 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
6494 struct mesh_config cfg;
6495 u32 mask;
6496 int err;
6497
29cbe68c
JB
6498 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
6499 return -EOPNOTSUPP;
6500
24bdd9f4 6501 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
6502 return -EOPNOTSUPP;
6503
24bdd9f4 6504 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
6505 if (err)
6506 return err;
6507
29cbe68c
JB
6508 wdev_lock(wdev);
6509 if (!wdev->mesh_id_len)
6510 err = -ENOLINK;
6511
6512 if (!err)
e35e4d28 6513 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
6514
6515 wdev_unlock(wdev);
6516
6517 return err;
93da9cc1 6518}
6519
ad30ca2c
AN
6520static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
6521 struct sk_buff *msg)
f130347c 6522{
f130347c
LR
6523 struct nlattr *nl_reg_rules;
6524 unsigned int i;
f130347c 6525
458f4f9e
JB
6526 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
6527 (regdom->dfs_region &&
6528 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 6529 goto nla_put_failure;
458f4f9e 6530
f130347c
LR
6531 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
6532 if (!nl_reg_rules)
ad30ca2c 6533 goto nla_put_failure;
f130347c 6534
458f4f9e 6535 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
6536 struct nlattr *nl_reg_rule;
6537 const struct ieee80211_reg_rule *reg_rule;
6538 const struct ieee80211_freq_range *freq_range;
6539 const struct ieee80211_power_rule *power_rule;
97524820 6540 unsigned int max_bandwidth_khz;
f130347c 6541
458f4f9e 6542 reg_rule = &regdom->reg_rules[i];
f130347c
LR
6543 freq_range = &reg_rule->freq_range;
6544 power_rule = &reg_rule->power_rule;
6545
6546 nl_reg_rule = nla_nest_start(msg, i);
6547 if (!nl_reg_rule)
ad30ca2c 6548 goto nla_put_failure;
f130347c 6549
97524820
JD
6550 max_bandwidth_khz = freq_range->max_bandwidth_khz;
6551 if (!max_bandwidth_khz)
6552 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
6553 reg_rule);
6554
9360ffd1
DM
6555 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
6556 reg_rule->flags) ||
6557 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
6558 freq_range->start_freq_khz) ||
6559 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
6560 freq_range->end_freq_khz) ||
6561 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 6562 max_bandwidth_khz) ||
9360ffd1
DM
6563 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
6564 power_rule->max_antenna_gain) ||
6565 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
6566 power_rule->max_eirp) ||
6567 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
6568 reg_rule->dfs_cac_ms))
ad30ca2c 6569 goto nla_put_failure;
f130347c
LR
6570
6571 nla_nest_end(msg, nl_reg_rule);
6572 }
6573
6574 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
6575 return 0;
6576
6577nla_put_failure:
6578 return -EMSGSIZE;
6579}
6580
6581static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
6582{
6583 const struct ieee80211_regdomain *regdom = NULL;
6584 struct cfg80211_registered_device *rdev;
6585 struct wiphy *wiphy = NULL;
6586 struct sk_buff *msg;
6587 void *hdr;
6588
6589 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6590 if (!msg)
6591 return -ENOBUFS;
6592
6593 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
6594 NL80211_CMD_GET_REG);
6595 if (!hdr)
6596 goto put_failure;
6597
6598 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
6599 bool self_managed;
6600
ad30ca2c
AN
6601 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
6602 if (IS_ERR(rdev)) {
6603 nlmsg_free(msg);
6604 return PTR_ERR(rdev);
6605 }
6606
6607 wiphy = &rdev->wiphy;
1bdd716c
AN
6608 self_managed = wiphy->regulatory_flags &
6609 REGULATORY_WIPHY_SELF_MANAGED;
ad30ca2c
AN
6610 regdom = get_wiphy_regdom(wiphy);
6611
1bdd716c
AN
6612 /* a self-managed-reg device must have a private regdom */
6613 if (WARN_ON(!regdom && self_managed)) {
6614 nlmsg_free(msg);
6615 return -EINVAL;
6616 }
6617
ad30ca2c
AN
6618 if (regdom &&
6619 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6620 goto nla_put_failure;
6621 }
6622
6623 if (!wiphy && reg_last_request_cell_base() &&
6624 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6625 NL80211_USER_REG_HINT_CELL_BASE))
6626 goto nla_put_failure;
6627
6628 rcu_read_lock();
6629
6630 if (!regdom)
6631 regdom = rcu_dereference(cfg80211_regdomain);
6632
6633 if (nl80211_put_regdom(regdom, msg))
6634 goto nla_put_failure_rcu;
6635
6636 rcu_read_unlock();
f130347c
LR
6637
6638 genlmsg_end(msg, hdr);
5fe231e8 6639 return genlmsg_reply(msg, info);
f130347c 6640
458f4f9e
JB
6641nla_put_failure_rcu:
6642 rcu_read_unlock();
f130347c 6643nla_put_failure:
efe1cf0c 6644put_failure:
d080e275 6645 nlmsg_free(msg);
5fe231e8 6646 return -EMSGSIZE;
f130347c
LR
6647}
6648
ad30ca2c
AN
6649static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
6650 u32 seq, int flags, struct wiphy *wiphy,
6651 const struct ieee80211_regdomain *regdom)
6652{
6653 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
6654 NL80211_CMD_GET_REG);
6655
6656 if (!hdr)
6657 return -1;
6658
0a833c29 6659 genl_dump_check_consistent(cb, hdr);
ad30ca2c
AN
6660
6661 if (nl80211_put_regdom(regdom, msg))
6662 goto nla_put_failure;
6663
6664 if (!wiphy && reg_last_request_cell_base() &&
6665 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6666 NL80211_USER_REG_HINT_CELL_BASE))
6667 goto nla_put_failure;
6668
6669 if (wiphy &&
6670 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6671 goto nla_put_failure;
6672
1bdd716c
AN
6673 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
6674 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
6675 goto nla_put_failure;
6676
053c095a
JB
6677 genlmsg_end(msg, hdr);
6678 return 0;
ad30ca2c
AN
6679
6680nla_put_failure:
6681 genlmsg_cancel(msg, hdr);
6682 return -EMSGSIZE;
6683}
6684
6685static int nl80211_get_reg_dump(struct sk_buff *skb,
6686 struct netlink_callback *cb)
6687{
6688 const struct ieee80211_regdomain *regdom = NULL;
6689 struct cfg80211_registered_device *rdev;
6690 int err, reg_idx, start = cb->args[2];
6691
6692 rtnl_lock();
6693
6694 if (cfg80211_regdomain && start == 0) {
6695 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6696 NLM_F_MULTI, NULL,
6697 rtnl_dereference(cfg80211_regdomain));
6698 if (err < 0)
6699 goto out_err;
6700 }
6701
6702 /* the global regdom is idx 0 */
6703 reg_idx = 1;
6704 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
6705 regdom = get_wiphy_regdom(&rdev->wiphy);
6706 if (!regdom)
6707 continue;
6708
6709 if (++reg_idx <= start)
6710 continue;
6711
6712 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6713 NLM_F_MULTI, &rdev->wiphy, regdom);
6714 if (err < 0) {
6715 reg_idx--;
6716 break;
6717 }
6718 }
6719
6720 cb->args[2] = reg_idx;
6721 err = skb->len;
6722out_err:
6723 rtnl_unlock();
6724 return err;
6725}
6726
b6863036
JB
6727#ifdef CONFIG_CFG80211_CRDA_SUPPORT
6728static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
6729 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
6730 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
6731 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
6732 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
6733 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
6734 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
6735 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
6736};
6737
6738static int parse_reg_rule(struct nlattr *tb[],
6739 struct ieee80211_reg_rule *reg_rule)
6740{
6741 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
6742 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
6743
6744 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
6745 return -EINVAL;
6746 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
6747 return -EINVAL;
6748 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
6749 return -EINVAL;
6750 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
6751 return -EINVAL;
6752 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6753 return -EINVAL;
6754
6755 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
6756
6757 freq_range->start_freq_khz =
6758 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
6759 freq_range->end_freq_khz =
6760 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
6761 freq_range->max_bandwidth_khz =
6762 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
6763
6764 power_rule->max_eirp =
6765 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
6766
6767 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
6768 power_rule->max_antenna_gain =
6769 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
6770
6771 if (tb[NL80211_ATTR_DFS_CAC_TIME])
6772 reg_rule->dfs_cac_ms =
6773 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
6774
6775 return 0;
6776}
6777
b2e1b302
LR
6778static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
6779{
6780 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
6781 struct nlattr *nl_reg_rule;
ea372c54
JB
6782 char *alpha2;
6783 int rem_reg_rules, r;
b2e1b302 6784 u32 num_rules = 0, rule_idx = 0, size_of_regd;
4c7d3982 6785 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 6786 struct ieee80211_regdomain *rd;
b2e1b302
LR
6787
6788 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
6789 return -EINVAL;
6790
6791 if (!info->attrs[NL80211_ATTR_REG_RULES])
6792 return -EINVAL;
6793
6794 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
6795
8b60b078
LR
6796 if (info->attrs[NL80211_ATTR_DFS_REGION])
6797 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
6798
b2e1b302 6799 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6800 rem_reg_rules) {
b2e1b302
LR
6801 num_rules++;
6802 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 6803 return -EINVAL;
b2e1b302
LR
6804 }
6805
e438768f
LR
6806 if (!reg_is_valid_request(alpha2))
6807 return -EINVAL;
6808
b2e1b302 6809 size_of_regd = sizeof(struct ieee80211_regdomain) +
1a919318 6810 num_rules * sizeof(struct ieee80211_reg_rule);
b2e1b302
LR
6811
6812 rd = kzalloc(size_of_regd, GFP_KERNEL);
6913b49a
JB
6813 if (!rd)
6814 return -ENOMEM;
b2e1b302
LR
6815
6816 rd->n_reg_rules = num_rules;
6817 rd->alpha2[0] = alpha2[0];
6818 rd->alpha2[1] = alpha2[1];
6819
8b60b078
LR
6820 /*
6821 * Disable DFS master mode if the DFS region was
6822 * not supported or known on this kernel.
6823 */
6824 if (reg_supported_dfs_region(dfs_region))
6825 rd->dfs_region = dfs_region;
6826
b2e1b302 6827 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6828 rem_reg_rules) {
bfe2c7b1 6829 r = nla_parse_nested(tb, NL80211_REG_RULE_ATTR_MAX,
fe52145f
JB
6830 nl_reg_rule, reg_rule_policy,
6831 info->extack);
ae811e21
JB
6832 if (r)
6833 goto bad_reg;
b2e1b302
LR
6834 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
6835 if (r)
6836 goto bad_reg;
6837
6838 rule_idx++;
6839
d0e18f83
LR
6840 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
6841 r = -EINVAL;
b2e1b302 6842 goto bad_reg;
d0e18f83 6843 }
b2e1b302
LR
6844 }
6845
06627990
JB
6846 /* set_regdom takes ownership of rd */
6847 return set_regdom(rd, REGD_SOURCE_CRDA);
d2372b31 6848 bad_reg:
b2e1b302 6849 kfree(rd);
d0e18f83 6850 return r;
b2e1b302 6851}
b6863036 6852#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 6853
83f5e2cf
JB
6854static int validate_scan_freqs(struct nlattr *freqs)
6855{
6856 struct nlattr *attr1, *attr2;
6857 int n_channels = 0, tmp1, tmp2;
6858
d7f13f74
SD
6859 nla_for_each_nested(attr1, freqs, tmp1)
6860 if (nla_len(attr1) != sizeof(u32))
6861 return 0;
6862
83f5e2cf
JB
6863 nla_for_each_nested(attr1, freqs, tmp1) {
6864 n_channels++;
6865 /*
6866 * Some hardware has a limited channel list for
6867 * scanning, and it is pretty much nonsensical
6868 * to scan for a channel twice, so disallow that
6869 * and don't require drivers to check that the
6870 * channel list they get isn't longer than what
6871 * they can scan, as long as they can scan all
6872 * the channels they registered at once.
6873 */
6874 nla_for_each_nested(attr2, freqs, tmp2)
6875 if (attr1 != attr2 &&
6876 nla_get_u32(attr1) == nla_get_u32(attr2))
6877 return 0;
6878 }
6879
6880 return n_channels;
6881}
6882
57fbcce3 6883static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 6884{
57fbcce3 6885 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
6886}
6887
6888static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
6889 struct cfg80211_bss_selection *bss_select)
6890{
6891 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
6892 struct nlattr *nest;
6893 int err;
6894 bool found = false;
6895 int i;
6896
6897 /* only process one nested attribute */
6898 nest = nla_data(nla);
6899 if (!nla_ok(nest, nla_len(nest)))
6900 return -EINVAL;
6901
bfe2c7b1 6902 err = nla_parse_nested(attr, NL80211_BSS_SELECT_ATTR_MAX, nest,
fceb6435 6903 nl80211_bss_select_policy, NULL);
38de03d2
AS
6904 if (err)
6905 return err;
6906
6907 /* only one attribute may be given */
6908 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
6909 if (attr[i]) {
6910 if (found)
6911 return -EINVAL;
6912 found = true;
6913 }
6914 }
6915
6916 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
6917
6918 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
6919 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
6920
6921 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
6922 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
6923 bss_select->param.band_pref =
6924 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
6925 if (!is_band_valid(wiphy, bss_select->param.band_pref))
6926 return -EINVAL;
6927 }
6928
6929 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
6930 struct nl80211_bss_select_rssi_adjust *adj_param;
6931
6932 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
6933 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
6934 bss_select->param.adjust.band = adj_param->band;
6935 bss_select->param.adjust.delta = adj_param->delta;
6936 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
6937 return -EINVAL;
6938 }
6939
6940 /* user-space did not provide behaviour attribute */
6941 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
6942 return -EINVAL;
6943
6944 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
6945 return -EINVAL;
6946
6947 return 0;
6948}
6949
ad2b26ab
JB
6950static int nl80211_parse_random_mac(struct nlattr **attrs,
6951 u8 *mac_addr, u8 *mac_addr_mask)
6952{
6953 int i;
6954
6955 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
6956 eth_zero_addr(mac_addr);
6957 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
6958 mac_addr[0] = 0x2;
6959 mac_addr_mask[0] = 0x3;
6960
6961 return 0;
6962 }
6963
6964 /* need both or none */
6965 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
6966 return -EINVAL;
6967
6968 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
6969 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
6970
6971 /* don't allow or configure an mcast address */
6972 if (!is_multicast_ether_addr(mac_addr_mask) ||
6973 is_multicast_ether_addr(mac_addr))
6974 return -EINVAL;
6975
6976 /*
6977 * allow users to pass a MAC address that has bits set outside
6978 * of the mask, but don't bother drivers with having to deal
6979 * with such bits
6980 */
6981 for (i = 0; i < ETH_ALEN; i++)
6982 mac_addr[i] &= mac_addr_mask[i];
6983
6984 return 0;
6985}
6986
34373d12
VT
6987static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
6988{
6989 ASSERT_WDEV_LOCK(wdev);
6990
6991 if (!cfg80211_beaconing_iface_active(wdev))
6992 return true;
6993
6994 if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
6995 return true;
6996
6997 return regulatory_pre_cac_allowed(wdev->wiphy);
6998}
6999
db0a4ad8
JB
7000static bool nl80211_check_scan_feat(struct wiphy *wiphy, u32 flags, u32 flag,
7001 enum nl80211_ext_feature_index feat)
7002{
7003 if (!(flags & flag))
7004 return true;
7005 if (wiphy_ext_feature_isset(wiphy, feat))
7006 return true;
7007 return false;
7008}
7009
2d23d073
RZ
7010static int
7011nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
7012 void *request, struct nlattr **attrs,
7013 bool is_sched_scan)
7014{
7015 u8 *mac_addr, *mac_addr_mask;
7016 u32 *flags;
7017 enum nl80211_feature_flags randomness_flag;
7018
7019 if (!attrs[NL80211_ATTR_SCAN_FLAGS])
7020 return 0;
7021
7022 if (is_sched_scan) {
7023 struct cfg80211_sched_scan_request *req = request;
7024
7025 randomness_flag = wdev ?
7026 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
7027 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7028 flags = &req->flags;
7029 mac_addr = req->mac_addr;
7030 mac_addr_mask = req->mac_addr_mask;
7031 } else {
7032 struct cfg80211_scan_request *req = request;
7033
7034 randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
7035 flags = &req->flags;
7036 mac_addr = req->mac_addr;
7037 mac_addr_mask = req->mac_addr_mask;
7038 }
7039
7040 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
7041
5037a009
SD
7042 if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
7043 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
db0a4ad8
JB
7044 !nl80211_check_scan_feat(wiphy, *flags,
7045 NL80211_SCAN_FLAG_LOW_SPAN,
7046 NL80211_EXT_FEATURE_LOW_SPAN_SCAN) ||
7047 !nl80211_check_scan_feat(wiphy, *flags,
7048 NL80211_SCAN_FLAG_LOW_POWER,
7049 NL80211_EXT_FEATURE_LOW_POWER_SCAN) ||
7050 !nl80211_check_scan_feat(wiphy, *flags,
7051 NL80211_SCAN_FLAG_HIGH_ACCURACY,
7052 NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN) ||
7053 !nl80211_check_scan_feat(wiphy, *flags,
7054 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME,
7055 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) ||
7056 !nl80211_check_scan_feat(wiphy, *flags,
7057 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP,
7058 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) ||
7059 !nl80211_check_scan_feat(wiphy, *flags,
7060 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
7061 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) ||
7062 !nl80211_check_scan_feat(wiphy, *flags,
7063 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE,
2e076f19
JB
7064 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) ||
7065 !nl80211_check_scan_feat(wiphy, *flags,
7066 NL80211_SCAN_FLAG_RANDOM_SN,
7067 NL80211_EXT_FEATURE_SCAN_RANDOM_SN) ||
7068 !nl80211_check_scan_feat(wiphy, *flags,
7069 NL80211_SCAN_FLAG_MIN_PREQ_CONTENT,
7070 NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
2d23d073
RZ
7071 return -EOPNOTSUPP;
7072
7073 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
7074 int err;
7075
7076 if (!(wiphy->features & randomness_flag) ||
7077 (wdev && wdev->current_bss))
7078 return -EOPNOTSUPP;
7079
7080 err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
7081 if (err)
7082 return err;
7083 }
7084
2d23d073
RZ
7085 return 0;
7086}
7087
2a519311
JB
7088static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
7089{
4c476991 7090 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 7091 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 7092 struct cfg80211_scan_request *request;
2a519311
JB
7093 struct nlattr *attr;
7094 struct wiphy *wiphy;
83f5e2cf 7095 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 7096 size_t ie_len;
2a519311 7097
f4a11bb0
JB
7098 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
7099 return -EINVAL;
7100
79c97e97 7101 wiphy = &rdev->wiphy;
2a519311 7102
cb3b7d87
AB
7103 if (wdev->iftype == NL80211_IFTYPE_NAN)
7104 return -EOPNOTSUPP;
7105
4c476991
JB
7106 if (!rdev->ops->scan)
7107 return -EOPNOTSUPP;
2a519311 7108
f9d15d16 7109 if (rdev->scan_req || rdev->scan_msg) {
f9f47529
JB
7110 err = -EBUSY;
7111 goto unlock;
7112 }
2a519311
JB
7113
7114 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
7115 n_channels = validate_scan_freqs(
7116 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
f9f47529
JB
7117 if (!n_channels) {
7118 err = -EINVAL;
7119 goto unlock;
7120 }
2a519311 7121 } else {
bdfbec2d 7122 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
7123 }
7124
7125 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
7126 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
7127 n_ssids++;
7128
f9f47529
JB
7129 if (n_ssids > wiphy->max_scan_ssids) {
7130 err = -EINVAL;
7131 goto unlock;
7132 }
2a519311 7133
70692ad2
JM
7134 if (info->attrs[NL80211_ATTR_IE])
7135 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
7136 else
7137 ie_len = 0;
7138
f9f47529
JB
7139 if (ie_len > wiphy->max_scan_ie_len) {
7140 err = -EINVAL;
7141 goto unlock;
7142 }
18a83659 7143
2a519311 7144 request = kzalloc(sizeof(*request)
a2cd43c5
LC
7145 + sizeof(*request->ssids) * n_ssids
7146 + sizeof(*request->channels) * n_channels
70692ad2 7147 + ie_len, GFP_KERNEL);
f9f47529
JB
7148 if (!request) {
7149 err = -ENOMEM;
7150 goto unlock;
7151 }
2a519311 7152
2a519311 7153 if (n_ssids)
5ba63533 7154 request->ssids = (void *)&request->channels[n_channels];
2a519311 7155 request->n_ssids = n_ssids;
70692ad2 7156 if (ie_len) {
13874e4b 7157 if (n_ssids)
70692ad2
JM
7158 request->ie = (void *)(request->ssids + n_ssids);
7159 else
7160 request->ie = (void *)(request->channels + n_channels);
7161 }
2a519311 7162
584991dc 7163 i = 0;
2a519311
JB
7164 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
7165 /* user specified, bail out if channel not found */
2a519311 7166 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
7167 struct ieee80211_channel *chan;
7168
7169 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
7170
7171 if (!chan) {
2a519311
JB
7172 err = -EINVAL;
7173 goto out_free;
7174 }
584991dc
JB
7175
7176 /* ignore disabled channels */
7177 if (chan->flags & IEEE80211_CHAN_DISABLED)
7178 continue;
7179
7180 request->channels[i] = chan;
2a519311
JB
7181 i++;
7182 }
7183 } else {
57fbcce3 7184 enum nl80211_band band;
34850ab2 7185
2a519311 7186 /* all channels */
57fbcce3 7187 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 7188 int j;
7a087e74 7189
2a519311
JB
7190 if (!wiphy->bands[band])
7191 continue;
7192 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
7193 struct ieee80211_channel *chan;
7194
7195 chan = &wiphy->bands[band]->channels[j];
7196
7197 if (chan->flags & IEEE80211_CHAN_DISABLED)
7198 continue;
7199
7200 request->channels[i] = chan;
2a519311
JB
7201 i++;
7202 }
7203 }
7204 }
7205
584991dc
JB
7206 if (!i) {
7207 err = -EINVAL;
7208 goto out_free;
7209 }
7210
7211 request->n_channels = i;
7212
34373d12
VT
7213 wdev_lock(wdev);
7214 if (!cfg80211_off_channel_oper_allowed(wdev)) {
7215 struct ieee80211_channel *chan;
7216
7217 if (request->n_channels != 1) {
7218 wdev_unlock(wdev);
7219 err = -EBUSY;
7220 goto out_free;
7221 }
7222
7223 chan = request->channels[0];
7224 if (chan->center_freq != wdev->chandef.chan->center_freq) {
7225 wdev_unlock(wdev);
7226 err = -EBUSY;
7227 goto out_free;
7228 }
7229 }
7230 wdev_unlock(wdev);
7231
2a519311 7232 i = 0;
13874e4b 7233 if (n_ssids) {
2a519311 7234 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 7235 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
7236 err = -EINVAL;
7237 goto out_free;
7238 }
57a27e1d 7239 request->ssids[i].ssid_len = nla_len(attr);
2a519311 7240 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
7241 i++;
7242 }
7243 }
7244
70692ad2
JM
7245 if (info->attrs[NL80211_ATTR_IE]) {
7246 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
7247 memcpy((void *)request->ie,
7248 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
7249 request->ie_len);
7250 }
7251
57fbcce3 7252 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
7253 if (wiphy->bands[i])
7254 request->rates[i] =
7255 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
7256
7257 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
7258 nla_for_each_nested(attr,
7259 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
7260 tmp) {
57fbcce3 7261 enum nl80211_band band = nla_type(attr);
34850ab2 7262
57fbcce3 7263 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
7264 err = -EINVAL;
7265 goto out_free;
7266 }
1b09cd82
FF
7267
7268 if (!wiphy->bands[band])
7269 continue;
7270
34850ab2
JB
7271 err = ieee80211_get_ratemask(wiphy->bands[band],
7272 nla_data(attr),
7273 nla_len(attr),
7274 &request->rates[band]);
7275 if (err)
7276 goto out_free;
7277 }
7278 }
7279
1d76250b
AS
7280 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
7281 if (!wiphy_ext_feature_isset(wiphy,
7282 NL80211_EXT_FEATURE_SET_SCAN_DWELL)) {
7283 err = -EOPNOTSUPP;
7284 goto out_free;
7285 }
7286
7287 request->duration =
7288 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
7289 request->duration_mandatory =
7290 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
7291 }
7292
2d23d073
RZ
7293 err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
7294 false);
7295 if (err)
7296 goto out_free;
ed473771 7297
e9f935e3
RM
7298 request->no_cck =
7299 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
7300
2fa436b3
VK
7301 /* Initial implementation used NL80211_ATTR_MAC to set the specific
7302 * BSSID to scan for. This was problematic because that same attribute
7303 * was already used for another purpose (local random MAC address). The
7304 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
7305 * compatibility with older userspace components, also use the
7306 * NL80211_ATTR_MAC value here if it can be determined to be used for
7307 * the specific BSSID use case instead of the random MAC address
7308 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
7309 */
7310 if (info->attrs[NL80211_ATTR_BSSID])
7311 memcpy(request->bssid,
7312 nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
7313 else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
7314 info->attrs[NL80211_ATTR_MAC])
818965d3
JM
7315 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
7316 ETH_ALEN);
7317 else
7318 eth_broadcast_addr(request->bssid);
7319
fd014284 7320 request->wdev = wdev;
79c97e97 7321 request->wiphy = &rdev->wiphy;
15d6030b 7322 request->scan_start = jiffies;
2a519311 7323
79c97e97 7324 rdev->scan_req = request;
e35e4d28 7325 err = rdev_scan(rdev, request);
2a519311 7326
463d0183 7327 if (!err) {
fd014284
JB
7328 nl80211_send_scan_start(rdev, wdev);
7329 if (wdev->netdev)
7330 dev_hold(wdev->netdev);
4c476991 7331 } else {
2a519311 7332 out_free:
79c97e97 7333 rdev->scan_req = NULL;
2a519311
JB
7334 kfree(request);
7335 }
3b85875a 7336
f9f47529 7337 unlock:
2a519311
JB
7338 return err;
7339}
7340
91d3ab46
VK
7341static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
7342{
7343 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7344 struct wireless_dev *wdev = info->user_ptr[1];
7345
7346 if (!rdev->ops->abort_scan)
7347 return -EOPNOTSUPP;
7348
7349 if (rdev->scan_msg)
7350 return 0;
7351
7352 if (!rdev->scan_req)
7353 return -ENOENT;
7354
7355 rdev_abort_scan(rdev, wdev);
7356 return 0;
7357}
7358
3b06d277
AS
7359static int
7360nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
7361 struct cfg80211_sched_scan_request *request,
7362 struct nlattr **attrs)
7363{
7364 int tmp, err, i = 0;
7365 struct nlattr *attr;
7366
7367 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
7368 u32 interval;
7369
7370 /*
7371 * If scan plans are not specified,
5a88de53 7372 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
3b06d277
AS
7373 * case one scan plan will be set with the specified scan
7374 * interval and infinite number of iterations.
7375 */
3b06d277
AS
7376 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
7377 if (!interval)
7378 return -EINVAL;
7379
7380 request->scan_plans[0].interval =
7381 DIV_ROUND_UP(interval, MSEC_PER_SEC);
7382 if (!request->scan_plans[0].interval)
7383 return -EINVAL;
7384
7385 if (request->scan_plans[0].interval >
7386 wiphy->max_sched_scan_plan_interval)
7387 request->scan_plans[0].interval =
7388 wiphy->max_sched_scan_plan_interval;
7389
7390 return 0;
7391 }
7392
7393 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
7394 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
7395
7396 if (WARN_ON(i >= n_plans))
7397 return -EINVAL;
7398
bfe2c7b1 7399 err = nla_parse_nested(plan, NL80211_SCHED_SCAN_PLAN_MAX,
fceb6435 7400 attr, nl80211_plan_policy, NULL);
3b06d277
AS
7401 if (err)
7402 return err;
7403
7404 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
7405 return -EINVAL;
7406
7407 request->scan_plans[i].interval =
7408 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
7409 if (!request->scan_plans[i].interval ||
7410 request->scan_plans[i].interval >
7411 wiphy->max_sched_scan_plan_interval)
7412 return -EINVAL;
7413
7414 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
7415 request->scan_plans[i].iterations =
7416 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
7417 if (!request->scan_plans[i].iterations ||
7418 (request->scan_plans[i].iterations >
7419 wiphy->max_sched_scan_plan_iterations))
7420 return -EINVAL;
7421 } else if (i < n_plans - 1) {
7422 /*
7423 * All scan plans but the last one must specify
7424 * a finite number of iterations
7425 */
7426 return -EINVAL;
7427 }
7428
7429 i++;
7430 }
7431
7432 /*
7433 * The last scan plan must not specify the number of
7434 * iterations, it is supposed to run infinitely
7435 */
7436 if (request->scan_plans[n_plans - 1].iterations)
7437 return -EINVAL;
7438
7439 return 0;
7440}
7441
256da02d 7442static struct cfg80211_sched_scan_request *
ad2b26ab 7443nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
aad1e812 7444 struct nlattr **attrs, int max_match_sets)
807f8a8c
LC
7445{
7446 struct cfg80211_sched_scan_request *request;
807f8a8c 7447 struct nlattr *attr;
3b06d277 7448 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 7449 enum nl80211_band band;
807f8a8c 7450 size_t ie_len;
a1f1c21c 7451 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 7452 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 7453
256da02d
LC
7454 if (!is_valid_ie_attr(attrs[NL80211_ATTR_IE]))
7455 return ERR_PTR(-EINVAL);
807f8a8c 7456
256da02d 7457 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 7458 n_channels = validate_scan_freqs(
256da02d 7459 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 7460 if (!n_channels)
256da02d 7461 return ERR_PTR(-EINVAL);
807f8a8c 7462 } else {
bdfbec2d 7463 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
7464 }
7465
256da02d
LC
7466 if (attrs[NL80211_ATTR_SCAN_SSIDS])
7467 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
7468 tmp)
7469 n_ssids++;
7470
93b6aa69 7471 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 7472 return ERR_PTR(-EINVAL);
807f8a8c 7473
ea73cbce
JB
7474 /*
7475 * First, count the number of 'real' matchsets. Due to an issue with
7476 * the old implementation, matchsets containing only the RSSI attribute
7477 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
7478 * RSSI for all matchsets, rather than their own matchset for reporting
7479 * all APs with a strong RSSI. This is needed to be compatible with
7480 * older userspace that treated a matchset with only the RSSI as the
7481 * global RSSI for all other matchsets - if there are other matchsets.
7482 */
256da02d 7483 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 7484 nla_for_each_nested(attr,
256da02d 7485 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
7486 tmp) {
7487 struct nlattr *rssi;
7488
bfe2c7b1
JB
7489 err = nla_parse_nested(tb,
7490 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
fceb6435
JB
7491 attr, nl80211_match_policy,
7492 NULL);
ea73cbce 7493 if (err)
256da02d 7494 return ERR_PTR(err);
3007e352
AVS
7495
7496 /* SSID and BSSID are mutually exclusive */
7497 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
7498 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
7499 return ERR_PTR(-EINVAL);
7500
ea73cbce 7501 /* add other standalone attributes here */
3007e352
AVS
7502 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
7503 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
ea73cbce
JB
7504 n_match_sets++;
7505 continue;
7506 }
7507 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
7508 if (rssi)
7509 default_match_rssi = nla_get_s32(rssi);
7510 }
7511 }
7512
7513 /* However, if there's no other matchset, add the RSSI one */
7514 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
7515 n_match_sets = 1;
a1f1c21c 7516
aad1e812 7517 if (n_match_sets > max_match_sets)
256da02d 7518 return ERR_PTR(-EINVAL);
a1f1c21c 7519
256da02d
LC
7520 if (attrs[NL80211_ATTR_IE])
7521 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
7522 else
7523 ie_len = 0;
7524
5a865bad 7525 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 7526 return ERR_PTR(-EINVAL);
c10841ca 7527
3b06d277
AS
7528 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
7529 /*
7530 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
7531 * each scan plan already specifies its own interval
7532 */
7533 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
7534 return ERR_PTR(-EINVAL);
7535
7536 nla_for_each_nested(attr,
7537 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
7538 n_plans++;
7539 } else {
7540 /*
7541 * The scan interval attribute is kept for backward
7542 * compatibility. If no scan plans are specified and sched scan
7543 * interval is specified, one scan plan will be set with this
7544 * scan interval and infinite number of iterations.
7545 */
7546 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
7547 return ERR_PTR(-EINVAL);
7548
7549 n_plans = 1;
7550 }
7551
7552 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
7553 return ERR_PTR(-EINVAL);
7554
bf95ecdb 7555 if (!wiphy_ext_feature_isset(
7556 wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
7557 (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
7558 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
7559 return ERR_PTR(-EINVAL);
7560
807f8a8c 7561 request = kzalloc(sizeof(*request)
a2cd43c5 7562 + sizeof(*request->ssids) * n_ssids
a1f1c21c 7563 + sizeof(*request->match_sets) * n_match_sets
3b06d277 7564 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 7565 + sizeof(*request->channels) * n_channels
807f8a8c 7566 + ie_len, GFP_KERNEL);
256da02d
LC
7567 if (!request)
7568 return ERR_PTR(-ENOMEM);
807f8a8c
LC
7569
7570 if (n_ssids)
7571 request->ssids = (void *)&request->channels[n_channels];
7572 request->n_ssids = n_ssids;
7573 if (ie_len) {
13874e4b 7574 if (n_ssids)
807f8a8c
LC
7575 request->ie = (void *)(request->ssids + n_ssids);
7576 else
7577 request->ie = (void *)(request->channels + n_channels);
7578 }
7579
a1f1c21c
LC
7580 if (n_match_sets) {
7581 if (request->ie)
7582 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 7583 else if (n_ssids)
a1f1c21c
LC
7584 request->match_sets =
7585 (void *)(request->ssids + n_ssids);
7586 else
7587 request->match_sets =
7588 (void *)(request->channels + n_channels);
7589 }
7590 request->n_match_sets = n_match_sets;
7591
3b06d277
AS
7592 if (n_match_sets)
7593 request->scan_plans = (void *)(request->match_sets +
7594 n_match_sets);
7595 else if (request->ie)
7596 request->scan_plans = (void *)(request->ie + ie_len);
7597 else if (n_ssids)
7598 request->scan_plans = (void *)(request->ssids + n_ssids);
7599 else
7600 request->scan_plans = (void *)(request->channels + n_channels);
7601
7602 request->n_scan_plans = n_plans;
7603
807f8a8c 7604 i = 0;
256da02d 7605 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
7606 /* user specified, bail out if channel not found */
7607 nla_for_each_nested(attr,
256da02d 7608 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
7609 tmp) {
7610 struct ieee80211_channel *chan;
7611
7612 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
7613
7614 if (!chan) {
7615 err = -EINVAL;
7616 goto out_free;
7617 }
7618
7619 /* ignore disabled channels */
7620 if (chan->flags & IEEE80211_CHAN_DISABLED)
7621 continue;
7622
7623 request->channels[i] = chan;
7624 i++;
7625 }
7626 } else {
7627 /* all channels */
57fbcce3 7628 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 7629 int j;
7a087e74 7630
807f8a8c
LC
7631 if (!wiphy->bands[band])
7632 continue;
7633 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
7634 struct ieee80211_channel *chan;
7635
7636 chan = &wiphy->bands[band]->channels[j];
7637
7638 if (chan->flags & IEEE80211_CHAN_DISABLED)
7639 continue;
7640
7641 request->channels[i] = chan;
7642 i++;
7643 }
7644 }
7645 }
7646
7647 if (!i) {
7648 err = -EINVAL;
7649 goto out_free;
7650 }
7651
7652 request->n_channels = i;
7653
7654 i = 0;
13874e4b 7655 if (n_ssids) {
256da02d 7656 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 7657 tmp) {
57a27e1d 7658 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
7659 err = -EINVAL;
7660 goto out_free;
7661 }
57a27e1d 7662 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
7663 memcpy(request->ssids[i].ssid, nla_data(attr),
7664 nla_len(attr));
807f8a8c
LC
7665 i++;
7666 }
7667 }
7668
a1f1c21c 7669 i = 0;
256da02d 7670 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 7671 nla_for_each_nested(attr,
256da02d 7672 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 7673 tmp) {
3007e352 7674 struct nlattr *ssid, *bssid, *rssi;
a1f1c21c 7675
bfe2c7b1
JB
7676 err = nla_parse_nested(tb,
7677 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
fceb6435
JB
7678 attr, nl80211_match_policy,
7679 NULL);
ae811e21
JB
7680 if (err)
7681 goto out_free;
4a4ab0d7 7682 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
3007e352
AVS
7683 bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
7684 if (ssid || bssid) {
ea73cbce
JB
7685 if (WARN_ON(i >= n_match_sets)) {
7686 /* this indicates a programming error,
7687 * the loop above should have verified
7688 * things properly
7689 */
7690 err = -EINVAL;
7691 goto out_free;
7692 }
7693
3007e352
AVS
7694 if (ssid) {
7695 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
7696 err = -EINVAL;
7697 goto out_free;
7698 }
7699 memcpy(request->match_sets[i].ssid.ssid,
7700 nla_data(ssid), nla_len(ssid));
7701 request->match_sets[i].ssid.ssid_len =
7702 nla_len(ssid);
7703 }
7704 if (bssid) {
7705 if (nla_len(bssid) != ETH_ALEN) {
7706 err = -EINVAL;
7707 goto out_free;
7708 }
7709 memcpy(request->match_sets[i].bssid,
7710 nla_data(bssid), ETH_ALEN);
a1f1c21c 7711 }
3007e352 7712
56ab364f 7713 /* special attribute - old implementation w/a */
ea73cbce
JB
7714 request->match_sets[i].rssi_thold =
7715 default_match_rssi;
7716 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
7717 if (rssi)
7718 request->match_sets[i].rssi_thold =
7719 nla_get_s32(rssi);
a1f1c21c
LC
7720 }
7721 i++;
7722 }
ea73cbce
JB
7723
7724 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 7725 if (i == 0 && n_match_sets)
ea73cbce
JB
7726 request->match_sets[0].rssi_thold = default_match_rssi;
7727
7728 request->min_rssi_thold = INT_MAX;
7729 for (i = 0; i < n_match_sets; i++)
7730 request->min_rssi_thold =
7731 min(request->match_sets[i].rssi_thold,
7732 request->min_rssi_thold);
7733 } else {
7734 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
7735 }
7736
9900e484
JB
7737 if (ie_len) {
7738 request->ie_len = ie_len;
807f8a8c 7739 memcpy((void *)request->ie,
256da02d 7740 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
7741 request->ie_len);
7742 }
7743
2d23d073
RZ
7744 err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
7745 if (err)
7746 goto out_free;
ed473771 7747
9c748934
LC
7748 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
7749 request->delay =
7750 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
7751
bf95ecdb 7752 if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
7753 request->relative_rssi = nla_get_s8(
7754 attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
7755 request->relative_rssi_set = true;
7756 }
7757
7758 if (request->relative_rssi_set &&
7759 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
7760 struct nl80211_bss_select_rssi_adjust *rssi_adjust;
7761
7762 rssi_adjust = nla_data(
7763 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
7764 request->rssi_adjust.band = rssi_adjust->band;
7765 request->rssi_adjust.delta = rssi_adjust->delta;
7766 if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
7767 err = -EINVAL;
7768 goto out_free;
7769 }
7770 }
7771
3b06d277
AS
7772 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
7773 if (err)
7774 goto out_free;
7775
15d6030b 7776 request->scan_start = jiffies;
807f8a8c 7777
256da02d 7778 return request;
807f8a8c
LC
7779
7780out_free:
7781 kfree(request);
256da02d
LC
7782 return ERR_PTR(err);
7783}
7784
7785static int nl80211_start_sched_scan(struct sk_buff *skb,
7786 struct genl_info *info)
7787{
7788 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7789 struct net_device *dev = info->user_ptr[1];
ad2b26ab 7790 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 7791 struct cfg80211_sched_scan_request *sched_scan_req;
ca986ad9 7792 bool want_multi;
256da02d
LC
7793 int err;
7794
ca986ad9 7795 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
256da02d
LC
7796 return -EOPNOTSUPP;
7797
ca986ad9
AVS
7798 want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
7799 err = cfg80211_sched_scan_req_possible(rdev, want_multi);
7800 if (err)
7801 return err;
256da02d 7802
31a60ed1 7803 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
aad1e812
AVS
7804 info->attrs,
7805 rdev->wiphy.max_match_sets);
31a60ed1
JR
7806
7807 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
7808 if (err)
7809 goto out_err;
7810
ca986ad9
AVS
7811 /* leave request id zero for legacy request
7812 * or if driver does not support multi-scheduled scan
7813 */
7814 if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1) {
7815 while (!sched_scan_req->reqid)
b60ad348 7816 sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
ca986ad9
AVS
7817 }
7818
31a60ed1 7819 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
7820 if (err)
7821 goto out_free;
7822
31a60ed1
JR
7823 sched_scan_req->dev = dev;
7824 sched_scan_req->wiphy = &rdev->wiphy;
7825
93a1e86c
JR
7826 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
7827 sched_scan_req->owner_nlportid = info->snd_portid;
7828
ca986ad9 7829 cfg80211_add_sched_scan_req(rdev, sched_scan_req);
256da02d 7830
96b08fd6 7831 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
256da02d
LC
7832 return 0;
7833
7834out_free:
31a60ed1 7835 kfree(sched_scan_req);
256da02d 7836out_err:
807f8a8c
LC
7837 return err;
7838}
7839
7840static int nl80211_stop_sched_scan(struct sk_buff *skb,
7841 struct genl_info *info)
7842{
ca986ad9 7843 struct cfg80211_sched_scan_request *req;
807f8a8c 7844 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ca986ad9 7845 u64 cookie;
807f8a8c 7846
ca986ad9 7847 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
807f8a8c
LC
7848 return -EOPNOTSUPP;
7849
ca986ad9
AVS
7850 if (info->attrs[NL80211_ATTR_COOKIE]) {
7851 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
7852 return __cfg80211_stop_sched_scan(rdev, cookie, false);
7853 }
7854
7855 req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
7856 struct cfg80211_sched_scan_request,
7857 list);
7858 if (!req || req->reqid ||
7859 (req->owner_nlportid &&
7860 req->owner_nlportid != info->snd_portid))
7861 return -ENOENT;
7862
7863 return cfg80211_stop_sched_scan_req(rdev, req, false);
807f8a8c
LC
7864}
7865
04f39047
SW
7866static int nl80211_start_radar_detection(struct sk_buff *skb,
7867 struct genl_info *info)
7868{
7869 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7870 struct net_device *dev = info->user_ptr[1];
7871 struct wireless_dev *wdev = dev->ieee80211_ptr;
13cf6dec 7872 struct wiphy *wiphy = wdev->wiphy;
04f39047 7873 struct cfg80211_chan_def chandef;
55f7435c 7874 enum nl80211_dfs_regions dfs_region;
31559f35 7875 unsigned int cac_time_ms;
04f39047
SW
7876 int err;
7877
13cf6dec 7878 dfs_region = reg_get_dfs_region(wiphy);
55f7435c
LR
7879 if (dfs_region == NL80211_DFS_UNSET)
7880 return -EINVAL;
7881
04f39047
SW
7882 err = nl80211_parse_chandef(rdev, info, &chandef);
7883 if (err)
7884 return err;
7885
ff311bc1
SW
7886 if (netif_carrier_ok(dev))
7887 return -EBUSY;
7888
04f39047
SW
7889 if (wdev->cac_started)
7890 return -EBUSY;
7891
13cf6dec 7892 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
04f39047
SW
7893 if (err < 0)
7894 return err;
7895
7896 if (err == 0)
7897 return -EINVAL;
7898
13cf6dec 7899 if (!cfg80211_chandef_dfs_usable(wiphy, &chandef))
04f39047
SW
7900 return -EINVAL;
7901
13cf6dec
DL
7902 /* CAC start is offloaded to HW and can't be started manually */
7903 if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))
7904 return -EOPNOTSUPP;
7905
04f39047
SW
7906 if (!rdev->ops->start_radar_detection)
7907 return -EOPNOTSUPP;
7908
31559f35
JD
7909 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
7910 if (WARN_ON(!cac_time_ms))
7911 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
7912
a1056b1b 7913 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 7914 if (!err) {
9e0e2961 7915 wdev->chandef = chandef;
04f39047
SW
7916 wdev->cac_started = true;
7917 wdev->cac_start_time = jiffies;
31559f35 7918 wdev->cac_time_ms = cac_time_ms;
04f39047 7919 }
04f39047
SW
7920 return err;
7921}
7922
16ef1fe2
SW
7923static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
7924{
7925 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7926 struct net_device *dev = info->user_ptr[1];
7927 struct wireless_dev *wdev = dev->ieee80211_ptr;
7928 struct cfg80211_csa_settings params;
7929 /* csa_attrs is defined static to avoid waste of stack size - this
7930 * function is called under RTNL lock, so this should not be a problem.
7931 */
7932 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
16ef1fe2 7933 int err;
ee4bc9e7 7934 bool need_new_beacon = false;
8d9de16f 7935 bool need_handle_dfs_flag = true;
9a774c78 7936 int len, i;
252e07ca 7937 u32 cs_count;
16ef1fe2
SW
7938
7939 if (!rdev->ops->channel_switch ||
7940 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
7941 return -EOPNOTSUPP;
7942
ee4bc9e7
SW
7943 switch (dev->ieee80211_ptr->iftype) {
7944 case NL80211_IFTYPE_AP:
7945 case NL80211_IFTYPE_P2P_GO:
7946 need_new_beacon = true;
8d9de16f
BB
7947 /* For all modes except AP the handle_dfs flag needs to be
7948 * supplied to tell the kernel that userspace will handle radar
7949 * events when they happen. Otherwise a switch to a channel
7950 * requiring DFS will be rejected.
7951 */
7952 need_handle_dfs_flag = false;
ee4bc9e7
SW
7953
7954 /* useless if AP is not running */
7955 if (!wdev->beacon_interval)
1ff79dfa 7956 return -ENOTCONN;
ee4bc9e7
SW
7957 break;
7958 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
7959 if (!wdev->ssid_len)
7960 return -ENOTCONN;
7961 break;
c6da674a 7962 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
7963 if (!wdev->mesh_id_len)
7964 return -ENOTCONN;
ee4bc9e7
SW
7965 break;
7966 default:
16ef1fe2 7967 return -EOPNOTSUPP;
ee4bc9e7 7968 }
16ef1fe2
SW
7969
7970 memset(&params, 0, sizeof(params));
7971
7972 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
7973 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
7974 return -EINVAL;
7975
7976 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 7977 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
7978 return -EINVAL;
7979
252e07ca
LC
7980 /* Even though the attribute is u32, the specification says
7981 * u8, so let's make sure we don't overflow.
7982 */
7983 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
7984 if (cs_count > 255)
7985 return -EINVAL;
7986
7987 params.count = cs_count;
16ef1fe2 7988
ee4bc9e7
SW
7989 if (!need_new_beacon)
7990 goto skip_beacons;
7991
81e54d08 7992 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after);
16ef1fe2
SW
7993 if (err)
7994 return err;
7995
7996 err = nla_parse_nested(csa_attrs, NL80211_ATTR_MAX,
7997 info->attrs[NL80211_ATTR_CSA_IES],
fe52145f 7998 nl80211_policy, info->extack);
16ef1fe2
SW
7999 if (err)
8000 return err;
8001
81e54d08 8002 err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa);
16ef1fe2
SW
8003 if (err)
8004 return err;
8005
8006 if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON])
8007 return -EINVAL;
8008
9a774c78
AO
8009 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
8010 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
8011 return -EINVAL;
8012
9a774c78
AO
8013 params.n_counter_offsets_beacon = len / sizeof(u16);
8014 if (rdev->wiphy.max_num_csa_counters &&
8015 (params.n_counter_offsets_beacon >
8016 rdev->wiphy.max_num_csa_counters))
16ef1fe2
SW
8017 return -EINVAL;
8018
9a774c78
AO
8019 params.counter_offsets_beacon =
8020 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
8021
8022 /* sanity checks - counters should fit and be the same */
8023 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
8024 u16 offset = params.counter_offsets_beacon[i];
8025
8026 if (offset >= params.beacon_csa.tail_len)
8027 return -EINVAL;
8028
8029 if (params.beacon_csa.tail[offset] != params.count)
8030 return -EINVAL;
8031 }
8032
16ef1fe2 8033 if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) {
9a774c78
AO
8034 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
8035 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
8036 return -EINVAL;
8037
9a774c78
AO
8038 params.n_counter_offsets_presp = len / sizeof(u16);
8039 if (rdev->wiphy.max_num_csa_counters &&
ad5987b4 8040 (params.n_counter_offsets_presp >
9a774c78 8041 rdev->wiphy.max_num_csa_counters))
16ef1fe2 8042 return -EINVAL;
9a774c78
AO
8043
8044 params.counter_offsets_presp =
8045 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
8046
8047 /* sanity checks - counters should fit and be the same */
8048 for (i = 0; i < params.n_counter_offsets_presp; i++) {
8049 u16 offset = params.counter_offsets_presp[i];
8050
8051 if (offset >= params.beacon_csa.probe_resp_len)
8052 return -EINVAL;
8053
8054 if (params.beacon_csa.probe_resp[offset] !=
8055 params.count)
8056 return -EINVAL;
8057 }
16ef1fe2
SW
8058 }
8059
ee4bc9e7 8060skip_beacons:
16ef1fe2
SW
8061 err = nl80211_parse_chandef(rdev, info, &params.chandef);
8062 if (err)
8063 return err;
8064
923b352f
AN
8065 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
8066 wdev->iftype))
16ef1fe2
SW
8067 return -EINVAL;
8068
2beb6dab
LC
8069 err = cfg80211_chandef_dfs_required(wdev->wiphy,
8070 &params.chandef,
8071 wdev->iftype);
8072 if (err < 0)
8073 return err;
8074
8d9de16f 8075 if (err > 0) {
2beb6dab 8076 params.radar_required = true;
8d9de16f
BB
8077 if (need_handle_dfs_flag &&
8078 !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
8079 return -EINVAL;
8080 }
8081 }
16ef1fe2 8082
16ef1fe2
SW
8083 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
8084 params.block_tx = true;
8085
c56589ed
SW
8086 wdev_lock(wdev);
8087 err = rdev_channel_switch(rdev, dev, &params);
8088 wdev_unlock(wdev);
8089
8090 return err;
16ef1fe2
SW
8091}
8092
9720bb3a
JB
8093static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
8094 u32 seq, int flags,
2a519311 8095 struct cfg80211_registered_device *rdev,
48ab905d
JB
8096 struct wireless_dev *wdev,
8097 struct cfg80211_internal_bss *intbss)
2a519311 8098{
48ab905d 8099 struct cfg80211_bss *res = &intbss->pub;
9caf0364 8100 const struct cfg80211_bss_ies *ies;
2a519311
JB
8101 void *hdr;
8102 struct nlattr *bss;
48ab905d
JB
8103
8104 ASSERT_WDEV_LOCK(wdev);
2a519311 8105
15e47304 8106 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
8107 NL80211_CMD_NEW_SCAN_RESULTS);
8108 if (!hdr)
8109 return -1;
8110
0a833c29 8111 genl_dump_check_consistent(cb, hdr);
9720bb3a 8112
97990a06
JB
8113 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
8114 goto nla_put_failure;
8115 if (wdev->netdev &&
9360ffd1
DM
8116 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
8117 goto nla_put_failure;
2dad624e
ND
8118 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
8119 NL80211_ATTR_PAD))
97990a06 8120 goto nla_put_failure;
2a519311
JB
8121
8122 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
8123 if (!bss)
8124 goto nla_put_failure;
9360ffd1 8125 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 8126 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 8127 goto nla_put_failure;
9caf0364
JB
8128
8129 rcu_read_lock();
0e227084
JB
8130 /* indicate whether we have probe response data or not */
8131 if (rcu_access_pointer(res->proberesp_ies) &&
8132 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
8133 goto fail_unlock_rcu;
8134
8135 /* this pointer prefers to be pointed to probe response data
8136 * but is always valid
8137 */
9caf0364 8138 ies = rcu_dereference(res->ies);
8cef2c9d 8139 if (ies) {
2dad624e
ND
8140 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
8141 NL80211_BSS_PAD))
8cef2c9d 8142 goto fail_unlock_rcu;
8cef2c9d
JB
8143 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
8144 ies->len, ies->data))
8145 goto fail_unlock_rcu;
9caf0364 8146 }
0e227084
JB
8147
8148 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 8149 ies = rcu_dereference(res->beacon_ies);
0e227084 8150 if (ies && ies->from_beacon) {
2dad624e
ND
8151 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
8152 NL80211_BSS_PAD))
8cef2c9d
JB
8153 goto fail_unlock_rcu;
8154 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
8155 ies->len, ies->data))
8156 goto fail_unlock_rcu;
9caf0364
JB
8157 }
8158 rcu_read_unlock();
8159
9360ffd1
DM
8160 if (res->beacon_interval &&
8161 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
8162 goto nla_put_failure;
8163 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
8164 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
dcd6eac1 8165 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
8166 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
8167 jiffies_to_msecs(jiffies - intbss->ts)))
8168 goto nla_put_failure;
2a519311 8169
1d76250b
AS
8170 if (intbss->parent_tsf &&
8171 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
8172 intbss->parent_tsf, NL80211_BSS_PAD) ||
8173 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
8174 intbss->parent_bssid)))
8175 goto nla_put_failure;
8176
6e19bc4b 8177 if (intbss->ts_boottime &&
2dad624e
ND
8178 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
8179 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
8180 goto nla_put_failure;
8181
983dafaa
SD
8182 if (!nl80211_put_signal(msg, intbss->pub.chains,
8183 intbss->pub.chain_signal,
8184 NL80211_BSS_CHAIN_SIGNAL))
8185 goto nla_put_failure;
8186
77965c97 8187 switch (rdev->wiphy.signal_type) {
2a519311 8188 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
8189 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
8190 goto nla_put_failure;
2a519311
JB
8191 break;
8192 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
8193 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
8194 goto nla_put_failure;
2a519311
JB
8195 break;
8196 default:
8197 break;
8198 }
8199
48ab905d 8200 switch (wdev->iftype) {
074ac8df 8201 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 8202 case NL80211_IFTYPE_STATION:
9360ffd1
DM
8203 if (intbss == wdev->current_bss &&
8204 nla_put_u32(msg, NL80211_BSS_STATUS,
8205 NL80211_BSS_STATUS_ASSOCIATED))
8206 goto nla_put_failure;
48ab905d
JB
8207 break;
8208 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
8209 if (intbss == wdev->current_bss &&
8210 nla_put_u32(msg, NL80211_BSS_STATUS,
8211 NL80211_BSS_STATUS_IBSS_JOINED))
8212 goto nla_put_failure;
48ab905d
JB
8213 break;
8214 default:
8215 break;
8216 }
8217
2a519311
JB
8218 nla_nest_end(msg, bss);
8219
053c095a
JB
8220 genlmsg_end(msg, hdr);
8221 return 0;
2a519311 8222
8cef2c9d
JB
8223 fail_unlock_rcu:
8224 rcu_read_unlock();
2a519311
JB
8225 nla_put_failure:
8226 genlmsg_cancel(msg, hdr);
8227 return -EMSGSIZE;
8228}
8229
97990a06 8230static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 8231{
48ab905d 8232 struct cfg80211_registered_device *rdev;
2a519311 8233 struct cfg80211_internal_bss *scan;
48ab905d 8234 struct wireless_dev *wdev;
97990a06 8235 int start = cb->args[2], idx = 0;
2a519311
JB
8236 int err;
8237
ea90e0dc 8238 rtnl_lock();
5297c65c 8239 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
ea90e0dc
JB
8240 if (err) {
8241 rtnl_unlock();
67748893 8242 return err;
ea90e0dc 8243 }
2a519311 8244
48ab905d
JB
8245 wdev_lock(wdev);
8246 spin_lock_bh(&rdev->bss_lock);
d1e23c94
DK
8247
8248 /*
8249 * dump_scan will be called multiple times to break up the scan results
8250 * into multiple messages. It is unlikely that any more bss-es will be
8251 * expired after the first call, so only call only call this on the
8252 * first dump_scan invocation.
8253 */
8254 if (start == 0)
8255 cfg80211_bss_expire(rdev);
48ab905d 8256
9720bb3a
JB
8257 cb->seq = rdev->bss_generation;
8258
48ab905d 8259 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
8260 if (++idx <= start)
8261 continue;
9720bb3a 8262 if (nl80211_send_bss(skb, cb,
2a519311 8263 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 8264 rdev, wdev, scan) < 0) {
2a519311 8265 idx--;
67748893 8266 break;
2a519311
JB
8267 }
8268 }
8269
48ab905d
JB
8270 spin_unlock_bh(&rdev->bss_lock);
8271 wdev_unlock(wdev);
2a519311 8272
97990a06 8273 cb->args[2] = idx;
ea90e0dc 8274 rtnl_unlock();
2a519311 8275
67748893 8276 return skb->len;
2a519311
JB
8277}
8278
15e47304 8279static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
8280 int flags, struct net_device *dev,
8281 bool allow_radio_stats,
8282 struct survey_info *survey)
61fa713c
HS
8283{
8284 void *hdr;
8285 struct nlattr *infoattr;
8286
11f78ac3
JB
8287 /* skip radio stats if userspace didn't request them */
8288 if (!survey->channel && !allow_radio_stats)
8289 return 0;
8290
15e47304 8291 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
8292 NL80211_CMD_NEW_SURVEY_RESULTS);
8293 if (!hdr)
8294 return -ENOMEM;
8295
9360ffd1
DM
8296 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
8297 goto nla_put_failure;
61fa713c
HS
8298
8299 infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
8300 if (!infoattr)
8301 goto nla_put_failure;
8302
11f78ac3
JB
8303 if (survey->channel &&
8304 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
8305 survey->channel->center_freq))
8306 goto nla_put_failure;
8307
8308 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
8309 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
8310 goto nla_put_failure;
8311 if ((survey->filled & SURVEY_INFO_IN_USE) &&
8312 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
8313 goto nla_put_failure;
4ed20beb 8314 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
8315 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
8316 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 8317 goto nla_put_failure;
4ed20beb 8318 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
8319 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
8320 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 8321 goto nla_put_failure;
4ed20beb 8322 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
8323 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
8324 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 8325 goto nla_put_failure;
4ed20beb 8326 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
8327 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
8328 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 8329 goto nla_put_failure;
4ed20beb 8330 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
8331 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
8332 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 8333 goto nla_put_failure;
052536ab 8334 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
8335 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
8336 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 8337 goto nla_put_failure;
61fa713c
HS
8338
8339 nla_nest_end(msg, infoattr);
8340
053c095a
JB
8341 genlmsg_end(msg, hdr);
8342 return 0;
61fa713c
HS
8343
8344 nla_put_failure:
8345 genlmsg_cancel(msg, hdr);
8346 return -EMSGSIZE;
8347}
8348
11f78ac3 8349static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c 8350{
c90c39da 8351 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
61fa713c 8352 struct survey_info survey;
1b8ec87a 8353 struct cfg80211_registered_device *rdev;
97990a06
JB
8354 struct wireless_dev *wdev;
8355 int survey_idx = cb->args[2];
61fa713c 8356 int res;
11f78ac3 8357 bool radio_stats;
61fa713c 8358
ea90e0dc 8359 rtnl_lock();
5297c65c 8360 res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 8361 if (res)
ea90e0dc 8362 goto out_err;
61fa713c 8363
11f78ac3 8364 /* prepare_wdev_dump parsed the attributes */
c90c39da 8365 radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
11f78ac3 8366
97990a06
JB
8367 if (!wdev->netdev) {
8368 res = -EINVAL;
8369 goto out_err;
8370 }
8371
1b8ec87a 8372 if (!rdev->ops->dump_survey) {
61fa713c
HS
8373 res = -EOPNOTSUPP;
8374 goto out_err;
8375 }
8376
8377 while (1) {
1b8ec87a 8378 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
8379 if (res == -ENOENT)
8380 break;
8381 if (res)
8382 goto out_err;
8383
11f78ac3
JB
8384 /* don't send disabled channels, but do send non-channel data */
8385 if (survey.channel &&
8386 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
8387 survey_idx++;
8388 continue;
8389 }
8390
61fa713c 8391 if (nl80211_send_survey(skb,
15e47304 8392 NETLINK_CB(cb->skb).portid,
61fa713c 8393 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 8394 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
8395 goto out;
8396 survey_idx++;
8397 }
8398
8399 out:
97990a06 8400 cb->args[2] = survey_idx;
61fa713c
HS
8401 res = skb->len;
8402 out_err:
ea90e0dc 8403 rtnl_unlock();
61fa713c
HS
8404 return res;
8405}
8406
b23aa676
SO
8407static bool nl80211_valid_wpa_versions(u32 wpa_versions)
8408{
8409 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
8410 NL80211_WPA_VERSION_2));
8411}
8412
636a5d36
JM
8413static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
8414{
4c476991
JB
8415 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8416 struct net_device *dev = info->user_ptr[1];
19957bb3 8417 struct ieee80211_channel *chan;
11b6b5a4
JM
8418 const u8 *bssid, *ssid, *ie = NULL, *auth_data = NULL;
8419 int err, ssid_len, ie_len = 0, auth_data_len = 0;
19957bb3 8420 enum nl80211_auth_type auth_type;
fffd0934 8421 struct key_parse key;
d5cdfacb 8422 bool local_state_change;
636a5d36 8423
f4a11bb0
JB
8424 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8425 return -EINVAL;
8426
8427 if (!info->attrs[NL80211_ATTR_MAC])
8428 return -EINVAL;
8429
1778092e
JM
8430 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
8431 return -EINVAL;
8432
19957bb3
JB
8433 if (!info->attrs[NL80211_ATTR_SSID])
8434 return -EINVAL;
8435
8436 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
8437 return -EINVAL;
8438
fffd0934
JB
8439 err = nl80211_parse_key(info, &key);
8440 if (err)
8441 return err;
8442
8443 if (key.idx >= 0) {
e31b8213
JB
8444 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
8445 return -EINVAL;
fffd0934
JB
8446 if (!key.p.key || !key.p.key_len)
8447 return -EINVAL;
8448 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
8449 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
8450 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
8451 key.p.key_len != WLAN_KEY_LEN_WEP104))
8452 return -EINVAL;
b6b5555b 8453 if (key.idx > 3)
fffd0934
JB
8454 return -EINVAL;
8455 } else {
8456 key.p.key_len = 0;
8457 key.p.key = NULL;
8458 }
8459
afea0b7a
JB
8460 if (key.idx >= 0) {
8461 int i;
8462 bool ok = false;
7a087e74 8463
afea0b7a
JB
8464 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
8465 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
8466 ok = true;
8467 break;
8468 }
8469 }
4c476991
JB
8470 if (!ok)
8471 return -EINVAL;
afea0b7a
JB
8472 }
8473
4c476991
JB
8474 if (!rdev->ops->auth)
8475 return -EOPNOTSUPP;
636a5d36 8476
074ac8df 8477 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8478 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8479 return -EOPNOTSUPP;
eec60b03 8480
19957bb3 8481 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
664834de
JM
8482 chan = nl80211_get_valid_chan(&rdev->wiphy,
8483 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8484 if (!chan)
4c476991 8485 return -EINVAL;
636a5d36 8486
19957bb3
JB
8487 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8488 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
8489
8490 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8491 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8492 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8493 }
8494
19957bb3 8495 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 8496 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 8497 return -EINVAL;
636a5d36 8498
63181060
JM
8499 if ((auth_type == NL80211_AUTHTYPE_SAE ||
8500 auth_type == NL80211_AUTHTYPE_FILS_SK ||
8501 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
8502 auth_type == NL80211_AUTHTYPE_FILS_PK) &&
11b6b5a4 8503 !info->attrs[NL80211_ATTR_AUTH_DATA])
e39e5b5e
JM
8504 return -EINVAL;
8505
11b6b5a4 8506 if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
63181060
JM
8507 if (auth_type != NL80211_AUTHTYPE_SAE &&
8508 auth_type != NL80211_AUTHTYPE_FILS_SK &&
8509 auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
8510 auth_type != NL80211_AUTHTYPE_FILS_PK)
e39e5b5e 8511 return -EINVAL;
11b6b5a4
JM
8512 auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
8513 auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
e39e5b5e 8514 /* need to include at least Auth Transaction and Status Code */
11b6b5a4 8515 if (auth_data_len < 4)
e39e5b5e
JM
8516 return -EINVAL;
8517 }
8518
d5cdfacb
JM
8519 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8520
95de817b
JB
8521 /*
8522 * Since we no longer track auth state, ignore
8523 * requests to only change local state.
8524 */
8525 if (local_state_change)
8526 return 0;
8527
91bf9b26
JB
8528 wdev_lock(dev->ieee80211_ptr);
8529 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
8530 ssid, ssid_len, ie, ie_len,
8531 key.p.key, key.p.key_len, key.idx,
11b6b5a4 8532 auth_data, auth_data_len);
91bf9b26
JB
8533 wdev_unlock(dev->ieee80211_ptr);
8534 return err;
636a5d36
JM
8535}
8536
64bf3d4b
DK
8537static int validate_pae_over_nl80211(struct cfg80211_registered_device *rdev,
8538 struct genl_info *info)
8539{
8540 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
8541 GENL_SET_ERR_MSG(info, "SOCKET_OWNER not set");
8542 return -EINVAL;
8543 }
8544
8545 if (!rdev->ops->tx_control_port ||
8546 !wiphy_ext_feature_isset(&rdev->wiphy,
8547 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
8548 return -EOPNOTSUPP;
8549
8550 return 0;
8551}
8552
c0692b8f
JB
8553static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
8554 struct genl_info *info,
3dc27d25
JB
8555 struct cfg80211_crypto_settings *settings,
8556 int cipher_limit)
b23aa676 8557{
c0b2bbd8
JB
8558 memset(settings, 0, sizeof(*settings));
8559
b23aa676
SO
8560 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
8561
c0692b8f
JB
8562 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
8563 u16 proto;
7a087e74 8564
c0692b8f
JB
8565 proto = nla_get_u16(
8566 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
8567 settings->control_port_ethertype = cpu_to_be16(proto);
8568 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
8569 proto != ETH_P_PAE)
8570 return -EINVAL;
8571 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
8572 settings->control_port_no_encrypt = true;
8573 } else
8574 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
8575
64bf3d4b
DK
8576 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
8577 int r = validate_pae_over_nl80211(rdev, info);
8578
8579 if (r < 0)
8580 return r;
8581
8582 settings->control_port_over_nl80211 = true;
8583 }
8584
b23aa676
SO
8585 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
8586 void *data;
8587 int len, i;
8588
8589 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
8590 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
8591 settings->n_ciphers_pairwise = len / sizeof(u32);
8592
8593 if (len % sizeof(u32))
8594 return -EINVAL;
8595
3dc27d25 8596 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
8597 return -EINVAL;
8598
8599 memcpy(settings->ciphers_pairwise, data, len);
8600
8601 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
8602 if (!cfg80211_supported_cipher_suite(
8603 &rdev->wiphy,
b23aa676
SO
8604 settings->ciphers_pairwise[i]))
8605 return -EINVAL;
8606 }
8607
8608 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
8609 settings->cipher_group =
8610 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
8611 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
8612 settings->cipher_group))
b23aa676
SO
8613 return -EINVAL;
8614 }
8615
8616 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
8617 settings->wpa_versions =
8618 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
8619 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
8620 return -EINVAL;
8621 }
8622
8623 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
8624 void *data;
6d30240e 8625 int len;
b23aa676
SO
8626
8627 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
8628 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
8629 settings->n_akm_suites = len / sizeof(u32);
8630
8631 if (len % sizeof(u32))
8632 return -EINVAL;
8633
1b9ca027
JM
8634 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
8635 return -EINVAL;
8636
b23aa676 8637 memcpy(settings->akm_suites, data, len);
b23aa676
SO
8638 }
8639
91b5ab62
EP
8640 if (info->attrs[NL80211_ATTR_PMK]) {
8641 if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
8642 return -EINVAL;
8643 if (!wiphy_ext_feature_isset(&rdev->wiphy,
8644 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
8645 return -EINVAL;
8646 settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
8647 }
8648
b23aa676
SO
8649 return 0;
8650}
8651
636a5d36
JM
8652static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
8653{
4c476991
JB
8654 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8655 struct net_device *dev = info->user_ptr[1];
f444de05 8656 struct ieee80211_channel *chan;
f62fab73
JB
8657 struct cfg80211_assoc_request req = {};
8658 const u8 *bssid, *ssid;
8659 int err, ssid_len = 0;
636a5d36 8660
bad29297
AZ
8661 if (dev->ieee80211_ptr->conn_owner_nlportid &&
8662 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
8663 return -EPERM;
8664
f4a11bb0
JB
8665 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8666 return -EINVAL;
8667
8668 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
8669 !info->attrs[NL80211_ATTR_SSID] ||
8670 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
8671 return -EINVAL;
8672
4c476991
JB
8673 if (!rdev->ops->assoc)
8674 return -EOPNOTSUPP;
636a5d36 8675
074ac8df 8676 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8677 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8678 return -EOPNOTSUPP;
eec60b03 8679
19957bb3 8680 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8681
664834de
JM
8682 chan = nl80211_get_valid_chan(&rdev->wiphy,
8683 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8684 if (!chan)
4c476991 8685 return -EINVAL;
636a5d36 8686
19957bb3
JB
8687 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8688 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
8689
8690 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
8691 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8692 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8693 }
8694
dc6382ce 8695 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 8696 enum nl80211_mfp mfp =
dc6382ce 8697 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 8698 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 8699 req.use_mfp = true;
4c476991
JB
8700 else if (mfp != NL80211_MFP_NO)
8701 return -EINVAL;
dc6382ce
JM
8702 }
8703
3e5d7649 8704 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 8705 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 8706
7e7c8926 8707 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 8708 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
8709
8710 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
8711 memcpy(&req.ht_capa_mask,
8712 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8713 sizeof(req.ht_capa_mask));
7e7c8926
BG
8714
8715 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 8716 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 8717 return -EINVAL;
f62fab73
JB
8718 memcpy(&req.ht_capa,
8719 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8720 sizeof(req.ht_capa));
7e7c8926
BG
8721 }
8722
ee2aca34 8723 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 8724 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34
JB
8725
8726 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
8727 memcpy(&req.vht_capa_mask,
8728 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
8729 sizeof(req.vht_capa_mask));
ee2aca34
JB
8730
8731 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 8732 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 8733 return -EINVAL;
f62fab73
JB
8734 memcpy(&req.vht_capa,
8735 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
8736 sizeof(req.vht_capa));
ee2aca34
JB
8737 }
8738
bab5ab7d 8739 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
8740 if (!((rdev->wiphy.features &
8741 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
8742 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
8743 !wiphy_ext_feature_isset(&rdev->wiphy,
8744 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
8745 return -EINVAL;
8746 req.flags |= ASSOC_REQ_USE_RRM;
8747 }
8748
348bd456
JM
8749 if (info->attrs[NL80211_ATTR_FILS_KEK]) {
8750 req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
8751 req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
8752 if (!info->attrs[NL80211_ATTR_FILS_NONCES])
8753 return -EINVAL;
8754 req.fils_nonces =
8755 nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
8756 }
8757
f62fab73 8758 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
8759 if (!err) {
8760 wdev_lock(dev->ieee80211_ptr);
bd2522b1 8761
f62fab73
JB
8762 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
8763 ssid, ssid_len, &req);
bd2522b1
AZ
8764
8765 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
8766 dev->ieee80211_ptr->conn_owner_nlportid =
8767 info->snd_portid;
8768 memcpy(dev->ieee80211_ptr->disconnect_bssid,
8769 bssid, ETH_ALEN);
8770 }
8771
91bf9b26
JB
8772 wdev_unlock(dev->ieee80211_ptr);
8773 }
636a5d36 8774
636a5d36
JM
8775 return err;
8776}
8777
8778static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
8779{
4c476991
JB
8780 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8781 struct net_device *dev = info->user_ptr[1];
19957bb3 8782 const u8 *ie = NULL, *bssid;
91bf9b26 8783 int ie_len = 0, err;
19957bb3 8784 u16 reason_code;
d5cdfacb 8785 bool local_state_change;
636a5d36 8786
bad29297
AZ
8787 if (dev->ieee80211_ptr->conn_owner_nlportid &&
8788 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
8789 return -EPERM;
8790
f4a11bb0
JB
8791 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8792 return -EINVAL;
8793
8794 if (!info->attrs[NL80211_ATTR_MAC])
8795 return -EINVAL;
8796
8797 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8798 return -EINVAL;
8799
4c476991
JB
8800 if (!rdev->ops->deauth)
8801 return -EOPNOTSUPP;
636a5d36 8802
074ac8df 8803 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8804 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8805 return -EOPNOTSUPP;
eec60b03 8806
19957bb3 8807 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8808
19957bb3
JB
8809 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8810 if (reason_code == 0) {
f4a11bb0 8811 /* Reason Code 0 is reserved */
4c476991 8812 return -EINVAL;
255e737e 8813 }
636a5d36
JM
8814
8815 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8816 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8817 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8818 }
8819
d5cdfacb
JM
8820 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8821
91bf9b26
JB
8822 wdev_lock(dev->ieee80211_ptr);
8823 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
8824 local_state_change);
8825 wdev_unlock(dev->ieee80211_ptr);
8826 return err;
636a5d36
JM
8827}
8828
8829static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
8830{
4c476991
JB
8831 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8832 struct net_device *dev = info->user_ptr[1];
19957bb3 8833 const u8 *ie = NULL, *bssid;
91bf9b26 8834 int ie_len = 0, err;
19957bb3 8835 u16 reason_code;
d5cdfacb 8836 bool local_state_change;
636a5d36 8837
bad29297
AZ
8838 if (dev->ieee80211_ptr->conn_owner_nlportid &&
8839 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
8840 return -EPERM;
8841
f4a11bb0
JB
8842 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8843 return -EINVAL;
8844
8845 if (!info->attrs[NL80211_ATTR_MAC])
8846 return -EINVAL;
8847
8848 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8849 return -EINVAL;
8850
4c476991
JB
8851 if (!rdev->ops->disassoc)
8852 return -EOPNOTSUPP;
636a5d36 8853
074ac8df 8854 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8855 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8856 return -EOPNOTSUPP;
eec60b03 8857
19957bb3 8858 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8859
19957bb3
JB
8860 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8861 if (reason_code == 0) {
f4a11bb0 8862 /* Reason Code 0 is reserved */
4c476991 8863 return -EINVAL;
255e737e 8864 }
636a5d36
JM
8865
8866 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8867 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8868 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8869 }
8870
d5cdfacb
JM
8871 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8872
91bf9b26
JB
8873 wdev_lock(dev->ieee80211_ptr);
8874 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
8875 local_state_change);
8876 wdev_unlock(dev->ieee80211_ptr);
8877 return err;
636a5d36
JM
8878}
8879
dd5b4cc7
FF
8880static bool
8881nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 8882 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
8883 int rateval)
8884{
8885 struct wiphy *wiphy = &rdev->wiphy;
8886 bool found = false;
8887 int band, i;
8888
57fbcce3 8889 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
8890 struct ieee80211_supported_band *sband;
8891
8892 sband = wiphy->bands[band];
8893 if (!sband)
8894 continue;
8895
8896 for (i = 0; i < sband->n_bitrates; i++) {
8897 if (sband->bitrates[i].bitrate == rateval) {
8898 mcast_rate[band] = i + 1;
8899 found = true;
8900 break;
8901 }
8902 }
8903 }
8904
8905 return found;
8906}
8907
04a773ad
JB
8908static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
8909{
4c476991
JB
8910 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8911 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
8912 struct cfg80211_ibss_params ibss;
8913 struct wiphy *wiphy;
fffd0934 8914 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
8915 int err;
8916
8e30bc55
JB
8917 memset(&ibss, 0, sizeof(ibss));
8918
04a773ad
JB
8919 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8920 return -EINVAL;
8921
683b6d3b 8922 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
8923 !nla_len(info->attrs[NL80211_ATTR_SSID]))
8924 return -EINVAL;
8925
8e30bc55
JB
8926 ibss.beacon_interval = 100;
8927
12d20fc9 8928 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
8929 ibss.beacon_interval =
8930 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 8931
0c317a02
PK
8932 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
8933 ibss.beacon_interval);
12d20fc9
PK
8934 if (err)
8935 return err;
8e30bc55 8936
4c476991
JB
8937 if (!rdev->ops->join_ibss)
8938 return -EOPNOTSUPP;
04a773ad 8939
4c476991
JB
8940 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
8941 return -EOPNOTSUPP;
04a773ad 8942
79c97e97 8943 wiphy = &rdev->wiphy;
04a773ad 8944
39193498 8945 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 8946 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
8947
8948 if (!is_valid_ether_addr(ibss.bssid))
8949 return -EINVAL;
8950 }
04a773ad
JB
8951 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8952 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
8953
8954 if (info->attrs[NL80211_ATTR_IE]) {
8955 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8956 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8957 }
8958
683b6d3b
JB
8959 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
8960 if (err)
8961 return err;
04a773ad 8962
174e0cd2
IP
8963 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
8964 NL80211_IFTYPE_ADHOC))
54858ee5
AS
8965 return -EINVAL;
8966
2f301ab2 8967 switch (ibss.chandef.width) {
bf372645
SW
8968 case NL80211_CHAN_WIDTH_5:
8969 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
8970 case NL80211_CHAN_WIDTH_20_NOHT:
8971 break;
8972 case NL80211_CHAN_WIDTH_20:
8973 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
8974 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8975 return -EINVAL;
8976 break;
8977 case NL80211_CHAN_WIDTH_80:
8978 case NL80211_CHAN_WIDTH_80P80:
8979 case NL80211_CHAN_WIDTH_160:
8980 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8981 return -EINVAL;
8982 if (!wiphy_ext_feature_isset(&rdev->wiphy,
8983 NL80211_EXT_FEATURE_VHT_IBSS))
8984 return -EINVAL;
8985 break;
2f301ab2 8986 default:
c04d6150 8987 return -EINVAL;
2f301ab2 8988 }
db9c64cf 8989
04a773ad 8990 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
8991 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
8992
fbd2c8dc
TP
8993 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
8994 u8 *rates =
8995 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8996 int n_rates =
8997 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8998 struct ieee80211_supported_band *sband =
683b6d3b 8999 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 9000
34850ab2
JB
9001 err = ieee80211_get_ratemask(sband, rates, n_rates,
9002 &ibss.basic_rates);
9003 if (err)
9004 return err;
fbd2c8dc 9005 }
dd5b4cc7 9006
803768f5
SW
9007 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
9008 memcpy(&ibss.ht_capa_mask,
9009 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
9010 sizeof(ibss.ht_capa_mask));
9011
9012 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
9013 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
9014 return -EINVAL;
9015 memcpy(&ibss.ht_capa,
9016 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
9017 sizeof(ibss.ht_capa));
9018 }
9019
dd5b4cc7
FF
9020 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
9021 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
9022 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
9023 return -EINVAL;
fbd2c8dc 9024
4c476991 9025 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
9026 bool no_ht = false;
9027
768075eb 9028 connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
4c476991
JB
9029 if (IS_ERR(connkeys))
9030 return PTR_ERR(connkeys);
de7044ee 9031
3d9d1d66
JB
9032 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
9033 no_ht) {
5e950a78 9034 kzfree(connkeys);
de7044ee
SM
9035 return -EINVAL;
9036 }
4c476991 9037 }
04a773ad 9038
267335d6
AQ
9039 ibss.control_port =
9040 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
9041
c3bfe1f6
DK
9042 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
9043 int r = validate_pae_over_nl80211(rdev, info);
9044
9045 if (r < 0)
9046 return r;
9047
9048 ibss.control_port_over_nl80211 = true;
9049 }
9050
5336fa88
SW
9051 ibss.userspace_handles_dfs =
9052 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
9053
f8d16d3e
DK
9054 wdev_lock(dev->ieee80211_ptr);
9055 err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 9056 if (err)
b47f610b 9057 kzfree(connkeys);
f8d16d3e
DK
9058 else if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
9059 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
9060 wdev_unlock(dev->ieee80211_ptr);
9061
04a773ad
JB
9062 return err;
9063}
9064
9065static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
9066{
4c476991
JB
9067 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9068 struct net_device *dev = info->user_ptr[1];
04a773ad 9069
4c476991
JB
9070 if (!rdev->ops->leave_ibss)
9071 return -EOPNOTSUPP;
04a773ad 9072
4c476991
JB
9073 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
9074 return -EOPNOTSUPP;
04a773ad 9075
4c476991 9076 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
9077}
9078
f4e583c8
AQ
9079static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
9080{
9081 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9082 struct net_device *dev = info->user_ptr[1];
57fbcce3 9083 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
9084 u32 nla_rate;
9085 int err;
9086
9087 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
9088 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
9089 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
9090 return -EOPNOTSUPP;
9091
9092 if (!rdev->ops->set_mcast_rate)
9093 return -EOPNOTSUPP;
9094
9095 memset(mcast_rate, 0, sizeof(mcast_rate));
9096
9097 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
9098 return -EINVAL;
9099
9100 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
9101 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
9102 return -EINVAL;
9103
a1056b1b 9104 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
9105
9106 return err;
9107}
9108
ad7e718c
JB
9109static struct sk_buff *
9110__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
9111 struct wireless_dev *wdev, int approxlen,
9112 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
9113 enum nl80211_attrs attr,
9114 const struct nl80211_vendor_cmd_info *info,
9115 gfp_t gfp)
ad7e718c
JB
9116{
9117 struct sk_buff *skb;
9118 void *hdr;
9119 struct nlattr *data;
9120
9121 skb = nlmsg_new(approxlen + 100, gfp);
9122 if (!skb)
9123 return NULL;
9124
9125 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
9126 if (!hdr) {
9127 kfree_skb(skb);
9128 return NULL;
9129 }
9130
9131 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
9132 goto nla_put_failure;
567ffc35
JB
9133
9134 if (info) {
9135 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
9136 info->vendor_id))
9137 goto nla_put_failure;
9138 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
9139 info->subcmd))
9140 goto nla_put_failure;
9141 }
9142
6c09e791 9143 if (wdev) {
2dad624e
ND
9144 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
9145 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
9146 goto nla_put_failure;
9147 if (wdev->netdev &&
9148 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
9149 wdev->netdev->ifindex))
9150 goto nla_put_failure;
9151 }
9152
ad7e718c 9153 data = nla_nest_start(skb, attr);
76e1fb4b
JB
9154 if (!data)
9155 goto nla_put_failure;
ad7e718c
JB
9156
9157 ((void **)skb->cb)[0] = rdev;
9158 ((void **)skb->cb)[1] = hdr;
9159 ((void **)skb->cb)[2] = data;
9160
9161 return skb;
9162
9163 nla_put_failure:
9164 kfree_skb(skb);
9165 return NULL;
9166}
f4e583c8 9167
e03ad6ea 9168struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 9169 struct wireless_dev *wdev,
e03ad6ea
JB
9170 enum nl80211_commands cmd,
9171 enum nl80211_attrs attr,
9172 int vendor_event_idx,
9173 int approxlen, gfp_t gfp)
9174{
f26cbf40 9175 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
9176 const struct nl80211_vendor_cmd_info *info;
9177
9178 switch (cmd) {
9179 case NL80211_CMD_TESTMODE:
9180 if (WARN_ON(vendor_event_idx != -1))
9181 return NULL;
9182 info = NULL;
9183 break;
9184 case NL80211_CMD_VENDOR:
9185 if (WARN_ON(vendor_event_idx < 0 ||
9186 vendor_event_idx >= wiphy->n_vendor_events))
9187 return NULL;
9188 info = &wiphy->vendor_events[vendor_event_idx];
9189 break;
9190 default:
9191 WARN_ON(1);
9192 return NULL;
9193 }
9194
6c09e791 9195 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, 0, 0,
e03ad6ea
JB
9196 cmd, attr, info, gfp);
9197}
9198EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
9199
9200void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
9201{
9202 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
9203 void *hdr = ((void **)skb->cb)[1];
9204 struct nlattr *data = ((void **)skb->cb)[2];
9205 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
9206
bd8c78e7
JB
9207 /* clear CB data for netlink core to own from now on */
9208 memset(skb->cb, 0, sizeof(skb->cb));
9209
e03ad6ea
JB
9210 nla_nest_end(skb, data);
9211 genlmsg_end(skb, hdr);
9212
9213 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
9214 mcgrp = NL80211_MCGRP_VENDOR;
9215
9216 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0,
9217 mcgrp, gfp);
9218}
9219EXPORT_SYMBOL(__cfg80211_send_event_skb);
9220
aff89a9b 9221#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
9222static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
9223{
4c476991 9224 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fc73f11f
DS
9225 struct wireless_dev *wdev =
9226 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
aff89a9b
JB
9227 int err;
9228
fc73f11f
DS
9229 if (!rdev->ops->testmode_cmd)
9230 return -EOPNOTSUPP;
9231
9232 if (IS_ERR(wdev)) {
9233 err = PTR_ERR(wdev);
9234 if (err != -EINVAL)
9235 return err;
9236 wdev = NULL;
9237 } else if (wdev->wiphy != &rdev->wiphy) {
9238 return -EINVAL;
9239 }
9240
aff89a9b
JB
9241 if (!info->attrs[NL80211_ATTR_TESTDATA])
9242 return -EINVAL;
9243
ad7e718c 9244 rdev->cur_cmd_info = info;
fc73f11f 9245 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
9246 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
9247 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 9248 rdev->cur_cmd_info = NULL;
aff89a9b 9249
aff89a9b
JB
9250 return err;
9251}
9252
71063f0e
WYG
9253static int nl80211_testmode_dump(struct sk_buff *skb,
9254 struct netlink_callback *cb)
9255{
00918d33 9256 struct cfg80211_registered_device *rdev;
71063f0e
WYG
9257 int err;
9258 long phy_idx;
9259 void *data = NULL;
9260 int data_len = 0;
9261
5fe231e8
JB
9262 rtnl_lock();
9263
71063f0e
WYG
9264 if (cb->args[0]) {
9265 /*
9266 * 0 is a valid index, but not valid for args[0],
9267 * so we need to offset by 1.
9268 */
9269 phy_idx = cb->args[0] - 1;
a4956dca
LC
9270
9271 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
9272 if (!rdev) {
9273 err = -ENOENT;
9274 goto out_err;
9275 }
71063f0e 9276 } else {
c90c39da
JB
9277 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
9278
71063f0e 9279 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
fceb6435
JB
9280 attrbuf, nl80211_fam.maxattr,
9281 nl80211_policy, NULL);
71063f0e 9282 if (err)
5fe231e8 9283 goto out_err;
00918d33 9284
c90c39da 9285 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
2bd7e35d 9286 if (IS_ERR(rdev)) {
5fe231e8
JB
9287 err = PTR_ERR(rdev);
9288 goto out_err;
00918d33 9289 }
2bd7e35d 9290 phy_idx = rdev->wiphy_idx;
2bd7e35d 9291
c90c39da
JB
9292 if (attrbuf[NL80211_ATTR_TESTDATA])
9293 cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
71063f0e
WYG
9294 }
9295
9296 if (cb->args[1]) {
9297 data = nla_data((void *)cb->args[1]);
9298 data_len = nla_len((void *)cb->args[1]);
9299 }
9300
00918d33 9301 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
9302 err = -EOPNOTSUPP;
9303 goto out_err;
9304 }
9305
9306 while (1) {
15e47304 9307 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
9308 cb->nlh->nlmsg_seq, NLM_F_MULTI,
9309 NL80211_CMD_TESTMODE);
9310 struct nlattr *tmdata;
9311
cb35fba3
DC
9312 if (!hdr)
9313 break;
9314
9360ffd1 9315 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
9316 genlmsg_cancel(skb, hdr);
9317 break;
9318 }
9319
9320 tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
9321 if (!tmdata) {
9322 genlmsg_cancel(skb, hdr);
9323 break;
9324 }
e35e4d28 9325 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
9326 nla_nest_end(skb, tmdata);
9327
9328 if (err == -ENOBUFS || err == -ENOENT) {
9329 genlmsg_cancel(skb, hdr);
9330 break;
9331 } else if (err) {
9332 genlmsg_cancel(skb, hdr);
9333 goto out_err;
9334 }
9335
9336 genlmsg_end(skb, hdr);
9337 }
9338
9339 err = skb->len;
9340 /* see above */
9341 cb->args[0] = phy_idx + 1;
9342 out_err:
5fe231e8 9343 rtnl_unlock();
71063f0e
WYG
9344 return err;
9345}
aff89a9b
JB
9346#endif
9347
b23aa676
SO
9348static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
9349{
4c476991
JB
9350 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9351 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
9352 struct cfg80211_connect_params connect;
9353 struct wiphy *wiphy;
fffd0934 9354 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
9355 int err;
9356
9357 memset(&connect, 0, sizeof(connect));
9358
9359 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
9360 return -EINVAL;
9361
9362 if (!info->attrs[NL80211_ATTR_SSID] ||
9363 !nla_len(info->attrs[NL80211_ATTR_SSID]))
9364 return -EINVAL;
9365
9366 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
9367 connect.auth_type =
9368 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
9369 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
9370 NL80211_CMD_CONNECT))
b23aa676
SO
9371 return -EINVAL;
9372 } else
9373 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
9374
9375 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
9376
3a00df57
AS
9377 if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
9378 !wiphy_ext_feature_isset(&rdev->wiphy,
9379 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
9380 return -EINVAL;
9381 connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
9382
c0692b8f 9383 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 9384 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
9385 if (err)
9386 return err;
b23aa676 9387
074ac8df 9388 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9389 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9390 return -EOPNOTSUPP;
b23aa676 9391
79c97e97 9392 wiphy = &rdev->wiphy;
b23aa676 9393
4486ea98
BS
9394 connect.bg_scan_period = -1;
9395 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
9396 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
9397 connect.bg_scan_period =
9398 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
9399 }
9400
b23aa676
SO
9401 if (info->attrs[NL80211_ATTR_MAC])
9402 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
9403 else if (info->attrs[NL80211_ATTR_MAC_HINT])
9404 connect.bssid_hint =
9405 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
9406 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9407 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
9408
9409 if (info->attrs[NL80211_ATTR_IE]) {
9410 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9411 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9412 }
9413
cee00a95
JM
9414 if (info->attrs[NL80211_ATTR_USE_MFP]) {
9415 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
65026002
EG
9416 if (connect.mfp == NL80211_MFP_OPTIONAL &&
9417 !wiphy_ext_feature_isset(&rdev->wiphy,
9418 NL80211_EXT_FEATURE_MFP_OPTIONAL))
9419 return -EOPNOTSUPP;
9420
cee00a95 9421 if (connect.mfp != NL80211_MFP_REQUIRED &&
65026002
EG
9422 connect.mfp != NL80211_MFP_NO &&
9423 connect.mfp != NL80211_MFP_OPTIONAL)
cee00a95
JM
9424 return -EINVAL;
9425 } else {
9426 connect.mfp = NL80211_MFP_NO;
9427 }
9428
ba6fbacf
JM
9429 if (info->attrs[NL80211_ATTR_PREV_BSSID])
9430 connect.prev_bssid =
9431 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
9432
b23aa676 9433 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
664834de
JM
9434 connect.channel = nl80211_get_valid_chan(
9435 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
9436 if (!connect.channel)
1df4a510
JM
9437 return -EINVAL;
9438 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
664834de
JM
9439 connect.channel_hint = nl80211_get_valid_chan(
9440 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
9441 if (!connect.channel_hint)
4c476991 9442 return -EINVAL;
b23aa676
SO
9443 }
9444
fffd0934 9445 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
768075eb 9446 connkeys = nl80211_parse_connkeys(rdev, info, NULL);
4c476991
JB
9447 if (IS_ERR(connkeys))
9448 return PTR_ERR(connkeys);
fffd0934
JB
9449 }
9450
7e7c8926
BG
9451 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
9452 connect.flags |= ASSOC_REQ_DISABLE_HT;
9453
9454 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
9455 memcpy(&connect.ht_capa_mask,
9456 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
9457 sizeof(connect.ht_capa_mask));
9458
9459 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 9460 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
b47f610b 9461 kzfree(connkeys);
7e7c8926 9462 return -EINVAL;
b4e4f47e 9463 }
7e7c8926
BG
9464 memcpy(&connect.ht_capa,
9465 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
9466 sizeof(connect.ht_capa));
9467 }
9468
ee2aca34
JB
9469 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
9470 connect.flags |= ASSOC_REQ_DISABLE_VHT;
9471
9472 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
9473 memcpy(&connect.vht_capa_mask,
9474 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
9475 sizeof(connect.vht_capa_mask));
9476
9477 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
9478 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
b47f610b 9479 kzfree(connkeys);
ee2aca34
JB
9480 return -EINVAL;
9481 }
9482 memcpy(&connect.vht_capa,
9483 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
9484 sizeof(connect.vht_capa));
9485 }
9486
bab5ab7d 9487 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
9488 if (!((rdev->wiphy.features &
9489 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
9490 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
9491 !wiphy_ext_feature_isset(&rdev->wiphy,
9492 NL80211_EXT_FEATURE_RRM)) {
707554b4 9493 kzfree(connkeys);
bab5ab7d 9494 return -EINVAL;
707554b4 9495 }
bab5ab7d
AK
9496 connect.flags |= ASSOC_REQ_USE_RRM;
9497 }
9498
34d50519 9499 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 9500 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
34d50519
LD
9501 kzfree(connkeys);
9502 return -EOPNOTSUPP;
9503 }
9504
38de03d2
AS
9505 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
9506 /* bss selection makes no sense if bssid is set */
9507 if (connect.bssid) {
9508 kzfree(connkeys);
9509 return -EINVAL;
9510 }
9511
9512 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
9513 wiphy, &connect.bss_select);
9514 if (err) {
9515 kzfree(connkeys);
9516 return err;
9517 }
9518 }
9519
a3caf744
VK
9520 if (wiphy_ext_feature_isset(&rdev->wiphy,
9521 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
9522 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
9523 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
9524 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
9525 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9526 connect.fils_erp_username =
9527 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9528 connect.fils_erp_username_len =
9529 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9530 connect.fils_erp_realm =
9531 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9532 connect.fils_erp_realm_len =
9533 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9534 connect.fils_erp_next_seq_num =
9535 nla_get_u16(
9536 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
9537 connect.fils_erp_rrk =
9538 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9539 connect.fils_erp_rrk_len =
9540 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9541 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
9542 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
9543 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
9544 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9545 kzfree(connkeys);
9546 return -EINVAL;
9547 }
9548
40cbfa90
SD
9549 if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
9550 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
2f0605a6 9551 kzfree(connkeys);
40cbfa90
SD
9552 GENL_SET_ERR_MSG(info,
9553 "external auth requires connection ownership");
9554 return -EINVAL;
9555 }
9556 connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
9557 }
9558
83739b03 9559 wdev_lock(dev->ieee80211_ptr);
bd2522b1 9560
4ce2bd9c
JM
9561 err = cfg80211_connect(rdev, dev, &connect, connkeys,
9562 connect.prev_bssid);
fffd0934 9563 if (err)
b47f610b 9564 kzfree(connkeys);
bd2522b1
AZ
9565
9566 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
9567 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
9568 if (connect.bssid)
9569 memcpy(dev->ieee80211_ptr->disconnect_bssid,
9570 connect.bssid, ETH_ALEN);
9571 else
9572 memset(dev->ieee80211_ptr->disconnect_bssid,
9573 0, ETH_ALEN);
9574 }
9575
9576 wdev_unlock(dev->ieee80211_ptr);
9577
b23aa676
SO
9578 return err;
9579}
9580
088e8df8 9581static int nl80211_update_connect_params(struct sk_buff *skb,
9582 struct genl_info *info)
9583{
9584 struct cfg80211_connect_params connect = {};
9585 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9586 struct net_device *dev = info->user_ptr[1];
9587 struct wireless_dev *wdev = dev->ieee80211_ptr;
7f9a3e15
VK
9588 bool fils_sk_offload;
9589 u32 auth_type;
088e8df8 9590 u32 changed = 0;
9591 int ret;
9592
9593 if (!rdev->ops->update_connect_params)
9594 return -EOPNOTSUPP;
9595
9596 if (info->attrs[NL80211_ATTR_IE]) {
9597 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
9598 return -EINVAL;
9599 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9600 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9601 changed |= UPDATE_ASSOC_IES;
9602 }
9603
7f9a3e15
VK
9604 fils_sk_offload = wiphy_ext_feature_isset(&rdev->wiphy,
9605 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
9606
9607 /*
9608 * when driver supports fils-sk offload all attributes must be
9609 * provided. So the else covers "fils-sk-not-all" and
9610 * "no-fils-sk-any".
9611 */
9612 if (fils_sk_offload &&
9613 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
9614 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
9615 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
9616 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9617 connect.fils_erp_username =
9618 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9619 connect.fils_erp_username_len =
9620 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9621 connect.fils_erp_realm =
9622 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9623 connect.fils_erp_realm_len =
9624 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9625 connect.fils_erp_next_seq_num =
9626 nla_get_u16(
9627 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
9628 connect.fils_erp_rrk =
9629 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9630 connect.fils_erp_rrk_len =
9631 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9632 changed |= UPDATE_FILS_ERP_INFO;
9633 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
9634 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
9635 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
9636 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9637 return -EINVAL;
9638 }
9639
9640 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
9641 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
9642 if (!nl80211_valid_auth_type(rdev, auth_type,
9643 NL80211_CMD_CONNECT))
9644 return -EINVAL;
9645
9646 if (auth_type == NL80211_AUTHTYPE_FILS_SK &&
9647 fils_sk_offload && !(changed & UPDATE_FILS_ERP_INFO))
9648 return -EINVAL;
9649
9650 connect.auth_type = auth_type;
9651 changed |= UPDATE_AUTH_TYPE;
9652 }
9653
088e8df8 9654 wdev_lock(dev->ieee80211_ptr);
9655 if (!wdev->current_bss)
9656 ret = -ENOLINK;
9657 else
9658 ret = rdev_update_connect_params(rdev, dev, &connect, changed);
9659 wdev_unlock(dev->ieee80211_ptr);
9660
9661 return ret;
9662}
9663
b23aa676
SO
9664static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
9665{
4c476991
JB
9666 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9667 struct net_device *dev = info->user_ptr[1];
b23aa676 9668 u16 reason;
83739b03 9669 int ret;
b23aa676 9670
bad29297
AZ
9671 if (dev->ieee80211_ptr->conn_owner_nlportid &&
9672 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
9673 return -EPERM;
9674
b23aa676
SO
9675 if (!info->attrs[NL80211_ATTR_REASON_CODE])
9676 reason = WLAN_REASON_DEAUTH_LEAVING;
9677 else
9678 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
9679
9680 if (reason == 0)
9681 return -EINVAL;
9682
074ac8df 9683 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9684 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9685 return -EOPNOTSUPP;
b23aa676 9686
83739b03
JB
9687 wdev_lock(dev->ieee80211_ptr);
9688 ret = cfg80211_disconnect(rdev, dev, reason, true);
9689 wdev_unlock(dev->ieee80211_ptr);
9690 return ret;
b23aa676
SO
9691}
9692
463d0183
JB
9693static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
9694{
4c476991 9695 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
9696 struct net *net;
9697 int err;
463d0183 9698
4b681c82
VK
9699 if (info->attrs[NL80211_ATTR_PID]) {
9700 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
9701
9702 net = get_net_ns_by_pid(pid);
9703 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
9704 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 9705
4b681c82
VK
9706 net = get_net_ns_by_fd(fd);
9707 } else {
9708 return -EINVAL;
9709 }
463d0183 9710
4c476991
JB
9711 if (IS_ERR(net))
9712 return PTR_ERR(net);
463d0183
JB
9713
9714 err = 0;
9715
9716 /* check if anything to do */
4c476991
JB
9717 if (!net_eq(wiphy_net(&rdev->wiphy), net))
9718 err = cfg80211_switch_netns(rdev, net);
463d0183 9719
463d0183 9720 put_net(net);
463d0183
JB
9721 return err;
9722}
9723
67fbb16b
SO
9724static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
9725{
4c476991 9726 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
9727 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
9728 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 9729 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
9730 struct cfg80211_pmksa pmksa;
9731
9732 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
9733
67fbb16b
SO
9734 if (!info->attrs[NL80211_ATTR_PMKID])
9735 return -EINVAL;
9736
67fbb16b 9737 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
a3caf744
VK
9738
9739 if (info->attrs[NL80211_ATTR_MAC]) {
9740 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
9741 } else if (info->attrs[NL80211_ATTR_SSID] &&
9742 info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
9743 (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
9744 info->attrs[NL80211_ATTR_PMK])) {
9745 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9746 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
9747 pmksa.cache_id =
9748 nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
9749 } else {
9750 return -EINVAL;
9751 }
9752 if (info->attrs[NL80211_ATTR_PMK]) {
9753 pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
9754 pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
9755 }
67fbb16b 9756
074ac8df 9757 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9758 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9759 return -EOPNOTSUPP;
67fbb16b
SO
9760
9761 switch (info->genlhdr->cmd) {
9762 case NL80211_CMD_SET_PMKSA:
9763 rdev_ops = rdev->ops->set_pmksa;
9764 break;
9765 case NL80211_CMD_DEL_PMKSA:
9766 rdev_ops = rdev->ops->del_pmksa;
9767 break;
9768 default:
9769 WARN_ON(1);
9770 break;
9771 }
9772
4c476991
JB
9773 if (!rdev_ops)
9774 return -EOPNOTSUPP;
67fbb16b 9775
4c476991 9776 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
9777}
9778
9779static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
9780{
4c476991
JB
9781 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9782 struct net_device *dev = info->user_ptr[1];
67fbb16b 9783
074ac8df 9784 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9785 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9786 return -EOPNOTSUPP;
67fbb16b 9787
4c476991
JB
9788 if (!rdev->ops->flush_pmksa)
9789 return -EOPNOTSUPP;
67fbb16b 9790
e35e4d28 9791 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
9792}
9793
109086ce
AN
9794static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
9795{
9796 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9797 struct net_device *dev = info->user_ptr[1];
9798 u8 action_code, dialog_token;
df942e7b 9799 u32 peer_capability = 0;
109086ce
AN
9800 u16 status_code;
9801 u8 *peer;
31fa97c5 9802 bool initiator;
109086ce
AN
9803
9804 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
9805 !rdev->ops->tdls_mgmt)
9806 return -EOPNOTSUPP;
9807
9808 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
9809 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
9810 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
9811 !info->attrs[NL80211_ATTR_IE] ||
9812 !info->attrs[NL80211_ATTR_MAC])
9813 return -EINVAL;
9814
9815 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
9816 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
9817 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
9818 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 9819 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
9820 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
9821 peer_capability =
9822 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 9823
e35e4d28 9824 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 9825 dialog_token, status_code, peer_capability,
31fa97c5 9826 initiator,
e35e4d28
HG
9827 nla_data(info->attrs[NL80211_ATTR_IE]),
9828 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
9829}
9830
9831static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
9832{
9833 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9834 struct net_device *dev = info->user_ptr[1];
9835 enum nl80211_tdls_operation operation;
9836 u8 *peer;
9837
9838 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
9839 !rdev->ops->tdls_oper)
9840 return -EOPNOTSUPP;
9841
9842 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
9843 !info->attrs[NL80211_ATTR_MAC])
9844 return -EINVAL;
9845
9846 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
9847 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
9848
e35e4d28 9849 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
9850}
9851
9588bbd5
JM
9852static int nl80211_remain_on_channel(struct sk_buff *skb,
9853 struct genl_info *info)
9854{
4c476991 9855 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9856 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 9857 struct cfg80211_chan_def chandef;
34373d12 9858 const struct cfg80211_chan_def *compat_chandef;
9588bbd5
JM
9859 struct sk_buff *msg;
9860 void *hdr;
9861 u64 cookie;
683b6d3b 9862 u32 duration;
9588bbd5
JM
9863 int err;
9864
9865 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
9866 !info->attrs[NL80211_ATTR_DURATION])
9867 return -EINVAL;
9868
9869 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
9870
ebf348fc
JB
9871 if (!rdev->ops->remain_on_channel ||
9872 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
9873 return -EOPNOTSUPP;
9874
9588bbd5 9875 /*
ebf348fc
JB
9876 * We should be on that channel for at least a minimum amount of
9877 * time (10ms) but no longer than the driver supports.
9588bbd5 9878 */
ebf348fc 9879 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 9880 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
9881 return -EINVAL;
9882
683b6d3b
JB
9883 err = nl80211_parse_chandef(rdev, info, &chandef);
9884 if (err)
9885 return err;
9588bbd5 9886
34373d12
VT
9887 wdev_lock(wdev);
9888 if (!cfg80211_off_channel_oper_allowed(wdev) &&
9889 !cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
9890 compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
9891 &chandef);
9892 if (compat_chandef != &chandef) {
9893 wdev_unlock(wdev);
9894 return -EBUSY;
9895 }
9896 }
9897 wdev_unlock(wdev);
9898
9588bbd5 9899 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
9900 if (!msg)
9901 return -ENOMEM;
9588bbd5 9902
15e47304 9903 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 9904 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
9905 if (!hdr) {
9906 err = -ENOBUFS;
9588bbd5
JM
9907 goto free_msg;
9908 }
9909
683b6d3b
JB
9910 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
9911 duration, &cookie);
9588bbd5
JM
9912
9913 if (err)
9914 goto free_msg;
9915
2dad624e
ND
9916 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
9917 NL80211_ATTR_PAD))
9360ffd1 9918 goto nla_put_failure;
9588bbd5
JM
9919
9920 genlmsg_end(msg, hdr);
4c476991
JB
9921
9922 return genlmsg_reply(msg, info);
9588bbd5
JM
9923
9924 nla_put_failure:
9925 err = -ENOBUFS;
9926 free_msg:
9927 nlmsg_free(msg);
9588bbd5
JM
9928 return err;
9929}
9930
9931static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
9932 struct genl_info *info)
9933{
4c476991 9934 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9935 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 9936 u64 cookie;
9588bbd5
JM
9937
9938 if (!info->attrs[NL80211_ATTR_COOKIE])
9939 return -EINVAL;
9940
4c476991
JB
9941 if (!rdev->ops->cancel_remain_on_channel)
9942 return -EOPNOTSUPP;
9588bbd5 9943
9588bbd5
JM
9944 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9945
e35e4d28 9946 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
9947}
9948
13ae75b1
JM
9949static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
9950 struct genl_info *info)
9951{
13ae75b1 9952 struct cfg80211_bitrate_mask mask;
a7c7fbff 9953 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 9954 struct net_device *dev = info->user_ptr[1];
a7c7fbff 9955 int err;
13ae75b1 9956
4c476991
JB
9957 if (!rdev->ops->set_bitrate_mask)
9958 return -EOPNOTSUPP;
13ae75b1 9959
a7c7fbff
PK
9960 err = nl80211_parse_tx_bitrate_mask(info, &mask);
9961 if (err)
9962 return err;
13ae75b1 9963
e35e4d28 9964 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
9965}
9966
2e161f78 9967static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 9968{
4c476991 9969 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9970 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 9971 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
9972
9973 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
9974 return -EINVAL;
9975
2e161f78
JB
9976 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
9977 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 9978
71bbc994
JB
9979 switch (wdev->iftype) {
9980 case NL80211_IFTYPE_STATION:
9981 case NL80211_IFTYPE_ADHOC:
9982 case NL80211_IFTYPE_P2P_CLIENT:
9983 case NL80211_IFTYPE_AP:
9984 case NL80211_IFTYPE_AP_VLAN:
9985 case NL80211_IFTYPE_MESH_POINT:
9986 case NL80211_IFTYPE_P2P_GO:
98104fde 9987 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 9988 break;
cb3b7d87 9989 case NL80211_IFTYPE_NAN:
71bbc994 9990 default:
4c476991 9991 return -EOPNOTSUPP;
71bbc994 9992 }
026331c4
JM
9993
9994 /* not much point in registering if we can't reply */
4c476991
JB
9995 if (!rdev->ops->mgmt_tx)
9996 return -EOPNOTSUPP;
026331c4 9997
15e47304 9998 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
026331c4
JM
9999 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
10000 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
026331c4
JM
10001}
10002
2e161f78 10003static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 10004{
4c476991 10005 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10006 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 10007 struct cfg80211_chan_def chandef;
026331c4 10008 int err;
d64d373f 10009 void *hdr = NULL;
026331c4 10010 u64 cookie;
e247bd90 10011 struct sk_buff *msg = NULL;
b176e629
AO
10012 struct cfg80211_mgmt_tx_params params = {
10013 .dont_wait_for_ack =
10014 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
10015 };
026331c4 10016
683b6d3b 10017 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
10018 return -EINVAL;
10019
4c476991
JB
10020 if (!rdev->ops->mgmt_tx)
10021 return -EOPNOTSUPP;
026331c4 10022
71bbc994 10023 switch (wdev->iftype) {
ea141b75
AQ
10024 case NL80211_IFTYPE_P2P_DEVICE:
10025 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
10026 return -EINVAL;
71bbc994
JB
10027 case NL80211_IFTYPE_STATION:
10028 case NL80211_IFTYPE_ADHOC:
10029 case NL80211_IFTYPE_P2P_CLIENT:
10030 case NL80211_IFTYPE_AP:
10031 case NL80211_IFTYPE_AP_VLAN:
10032 case NL80211_IFTYPE_MESH_POINT:
10033 case NL80211_IFTYPE_P2P_GO:
10034 break;
cb3b7d87 10035 case NL80211_IFTYPE_NAN:
71bbc994 10036 default:
4c476991 10037 return -EOPNOTSUPP;
71bbc994 10038 }
026331c4 10039
f7ca38df 10040 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 10041 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 10042 return -EINVAL;
b176e629 10043 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
10044
10045 /*
10046 * We should wait on the channel for at least a minimum amount
10047 * of time (10ms) but no longer than the driver supports.
10048 */
b176e629
AO
10049 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
10050 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 10051 return -EINVAL;
f7ca38df
JB
10052 }
10053
b176e629 10054 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 10055
b176e629 10056 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
10057 return -EINVAL;
10058
b176e629 10059 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 10060
ea141b75
AQ
10061 /* get the channel if any has been specified, otherwise pass NULL to
10062 * the driver. The latter will use the current one
10063 */
10064 chandef.chan = NULL;
10065 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
10066 err = nl80211_parse_chandef(rdev, info, &chandef);
10067 if (err)
10068 return err;
10069 }
10070
b176e629 10071 if (!chandef.chan && params.offchan)
ea141b75 10072 return -EINVAL;
026331c4 10073
34373d12
VT
10074 wdev_lock(wdev);
10075 if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
10076 wdev_unlock(wdev);
10077 return -EBUSY;
10078 }
10079 wdev_unlock(wdev);
10080
34d22ce2
AO
10081 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
10082 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
10083
10084 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
10085 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
10086 int i;
10087
10088 if (len % sizeof(u16))
10089 return -EINVAL;
10090
10091 params.n_csa_offsets = len / sizeof(u16);
10092 params.csa_offsets =
10093 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
10094
10095 /* check that all the offsets fit the frame */
10096 for (i = 0; i < params.n_csa_offsets; i++) {
10097 if (params.csa_offsets[i] >= params.len)
10098 return -EINVAL;
10099 }
10100 }
10101
b176e629 10102 if (!params.dont_wait_for_ack) {
e247bd90
JB
10103 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10104 if (!msg)
10105 return -ENOMEM;
026331c4 10106
15e47304 10107 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 10108 NL80211_CMD_FRAME);
cb35fba3
DC
10109 if (!hdr) {
10110 err = -ENOBUFS;
e247bd90
JB
10111 goto free_msg;
10112 }
026331c4 10113 }
e247bd90 10114
b176e629
AO
10115 params.chan = chandef.chan;
10116 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
10117 if (err)
10118 goto free_msg;
10119
e247bd90 10120 if (msg) {
2dad624e
ND
10121 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
10122 NL80211_ATTR_PAD))
9360ffd1 10123 goto nla_put_failure;
026331c4 10124
e247bd90
JB
10125 genlmsg_end(msg, hdr);
10126 return genlmsg_reply(msg, info);
10127 }
10128
10129 return 0;
026331c4
JM
10130
10131 nla_put_failure:
10132 err = -ENOBUFS;
10133 free_msg:
10134 nlmsg_free(msg);
026331c4
JM
10135 return err;
10136}
10137
f7ca38df
JB
10138static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
10139{
10140 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10141 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
10142 u64 cookie;
10143
10144 if (!info->attrs[NL80211_ATTR_COOKIE])
10145 return -EINVAL;
10146
10147 if (!rdev->ops->mgmt_tx_cancel_wait)
10148 return -EOPNOTSUPP;
10149
71bbc994
JB
10150 switch (wdev->iftype) {
10151 case NL80211_IFTYPE_STATION:
10152 case NL80211_IFTYPE_ADHOC:
10153 case NL80211_IFTYPE_P2P_CLIENT:
10154 case NL80211_IFTYPE_AP:
10155 case NL80211_IFTYPE_AP_VLAN:
10156 case NL80211_IFTYPE_P2P_GO:
98104fde 10157 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 10158 break;
cb3b7d87 10159 case NL80211_IFTYPE_NAN:
71bbc994 10160 default:
f7ca38df 10161 return -EOPNOTSUPP;
71bbc994 10162 }
f7ca38df
JB
10163
10164 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
10165
e35e4d28 10166 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
10167}
10168
ffb9eb3d
KV
10169static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
10170{
4c476991 10171 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 10172 struct wireless_dev *wdev;
4c476991 10173 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
10174 u8 ps_state;
10175 bool state;
10176 int err;
10177
4c476991
JB
10178 if (!info->attrs[NL80211_ATTR_PS_STATE])
10179 return -EINVAL;
ffb9eb3d
KV
10180
10181 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
10182
4c476991
JB
10183 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
10184 return -EINVAL;
ffb9eb3d
KV
10185
10186 wdev = dev->ieee80211_ptr;
10187
4c476991
JB
10188 if (!rdev->ops->set_power_mgmt)
10189 return -EOPNOTSUPP;
ffb9eb3d
KV
10190
10191 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
10192
10193 if (state == wdev->ps)
4c476991 10194 return 0;
ffb9eb3d 10195
e35e4d28 10196 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
10197 if (!err)
10198 wdev->ps = state;
ffb9eb3d
KV
10199 return err;
10200}
10201
10202static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
10203{
4c476991 10204 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
10205 enum nl80211_ps_state ps_state;
10206 struct wireless_dev *wdev;
4c476991 10207 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
10208 struct sk_buff *msg;
10209 void *hdr;
10210 int err;
10211
ffb9eb3d
KV
10212 wdev = dev->ieee80211_ptr;
10213
4c476991
JB
10214 if (!rdev->ops->set_power_mgmt)
10215 return -EOPNOTSUPP;
ffb9eb3d
KV
10216
10217 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
10218 if (!msg)
10219 return -ENOMEM;
ffb9eb3d 10220
15e47304 10221 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
10222 NL80211_CMD_GET_POWER_SAVE);
10223 if (!hdr) {
4c476991 10224 err = -ENOBUFS;
ffb9eb3d
KV
10225 goto free_msg;
10226 }
10227
10228 if (wdev->ps)
10229 ps_state = NL80211_PS_ENABLED;
10230 else
10231 ps_state = NL80211_PS_DISABLED;
10232
9360ffd1
DM
10233 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
10234 goto nla_put_failure;
ffb9eb3d
KV
10235
10236 genlmsg_end(msg, hdr);
4c476991 10237 return genlmsg_reply(msg, info);
ffb9eb3d 10238
4c476991 10239 nla_put_failure:
ffb9eb3d 10240 err = -ENOBUFS;
4c476991 10241 free_msg:
ffb9eb3d 10242 nlmsg_free(msg);
ffb9eb3d
KV
10243 return err;
10244}
10245
94e860f1
JB
10246static const struct nla_policy
10247nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
4a4b8169 10248 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
d6dc1a38
JO
10249 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
10250 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
10251 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
10252 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
10253 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
bee427b8 10254 [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 },
d6dc1a38
JO
10255};
10256
84f10708 10257static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 10258 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
10259{
10260 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 10261 struct net_device *dev = info->user_ptr[1];
1da5fcc8 10262 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 10263
d9d8b019 10264 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
10265 return -EINVAL;
10266
84f10708
TP
10267 if (!rdev->ops->set_cqm_txe_config)
10268 return -EOPNOTSUPP;
10269
10270 if (wdev->iftype != NL80211_IFTYPE_STATION &&
10271 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
10272 return -EOPNOTSUPP;
10273
e35e4d28 10274 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
10275}
10276
4a4b8169
AZ
10277static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
10278 struct net_device *dev)
10279{
10280 struct wireless_dev *wdev = dev->ieee80211_ptr;
10281 s32 last, low, high;
10282 u32 hyst;
1222a160 10283 int i, n, low_index;
4a4b8169
AZ
10284 int err;
10285
10286 /* RSSI reporting disabled? */
10287 if (!wdev->cqm_config)
10288 return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
10289
10290 /*
10291 * Obtain current RSSI value if possible, if not and no RSSI threshold
10292 * event has been received yet, we should receive an event after a
10293 * connection is established and enough beacons received to calculate
10294 * the average.
10295 */
10296 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
10297 rdev->ops->get_station) {
73887fd9 10298 struct station_info sinfo = {};
4a4b8169
AZ
10299 u8 *mac_addr;
10300
10301 mac_addr = wdev->current_bss->pub.bssid;
10302
73887fd9
JB
10303 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
10304 if (err)
4a4b8169
AZ
10305 return err;
10306
397c657a 10307 if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
4a4b8169 10308 wdev->cqm_config->last_rssi_event_value =
73887fd9 10309 (s8) sinfo.rx_beacon_signal_avg;
4a4b8169
AZ
10310 }
10311
10312 last = wdev->cqm_config->last_rssi_event_value;
10313 hyst = wdev->cqm_config->rssi_hyst;
10314 n = wdev->cqm_config->n_rssi_thresholds;
10315
10316 for (i = 0; i < n; i++)
10317 if (last < wdev->cqm_config->rssi_thresholds[i])
10318 break;
10319
1222a160
MH
10320 low_index = i - 1;
10321 if (low_index >= 0) {
10322 low_index = array_index_nospec(low_index, n);
10323 low = wdev->cqm_config->rssi_thresholds[low_index] - hyst;
10324 } else {
10325 low = S32_MIN;
10326 }
10327 if (i < n) {
10328 i = array_index_nospec(i, n);
10329 high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1;
10330 } else {
10331 high = S32_MAX;
10332 }
4a4b8169
AZ
10333
10334 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
10335}
10336
d6dc1a38 10337static int nl80211_set_cqm_rssi(struct genl_info *info,
4a4b8169
AZ
10338 const s32 *thresholds, int n_thresholds,
10339 u32 hysteresis)
d6dc1a38 10340{
4c476991 10341 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 10342 struct net_device *dev = info->user_ptr[1];
1da5fcc8 10343 struct wireless_dev *wdev = dev->ieee80211_ptr;
4a4b8169
AZ
10344 int i, err;
10345 s32 prev = S32_MIN;
d6dc1a38 10346
4a4b8169
AZ
10347 /* Check all values negative and sorted */
10348 for (i = 0; i < n_thresholds; i++) {
10349 if (thresholds[i] > 0 || thresholds[i] <= prev)
10350 return -EINVAL;
d6dc1a38 10351
4a4b8169
AZ
10352 prev = thresholds[i];
10353 }
d6dc1a38 10354
074ac8df 10355 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10356 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
10357 return -EOPNOTSUPP;
d6dc1a38 10358
4a4b8169
AZ
10359 wdev_lock(wdev);
10360 cfg80211_cqm_config_free(wdev);
10361 wdev_unlock(wdev);
10362
10363 if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
10364 if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
10365 return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
10366
10367 return rdev_set_cqm_rssi_config(rdev, dev,
10368 thresholds[0], hysteresis);
10369 }
10370
10371 if (!wiphy_ext_feature_isset(&rdev->wiphy,
10372 NL80211_EXT_FEATURE_CQM_RSSI_LIST))
10373 return -EOPNOTSUPP;
10374
10375 if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
10376 n_thresholds = 0;
10377
10378 wdev_lock(wdev);
10379 if (n_thresholds) {
10380 struct cfg80211_cqm_config *cqm_config;
10381
10382 cqm_config = kzalloc(sizeof(struct cfg80211_cqm_config) +
10383 n_thresholds * sizeof(s32), GFP_KERNEL);
10384 if (!cqm_config) {
10385 err = -ENOMEM;
10386 goto unlock;
10387 }
10388
10389 cqm_config->rssi_hyst = hysteresis;
10390 cqm_config->n_rssi_thresholds = n_thresholds;
10391 memcpy(cqm_config->rssi_thresholds, thresholds,
10392 n_thresholds * sizeof(s32));
10393
10394 wdev->cqm_config = cqm_config;
10395 }
10396
10397 err = cfg80211_cqm_rssi_update(rdev, dev);
10398
10399unlock:
10400 wdev_unlock(wdev);
10401
10402 return err;
d6dc1a38
JO
10403}
10404
10405static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
10406{
10407 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
10408 struct nlattr *cqm;
10409 int err;
10410
10411 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
10412 if (!cqm)
10413 return -EINVAL;
d6dc1a38
JO
10414
10415 err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
fe52145f 10416 nl80211_attr_cqm_policy, info->extack);
d6dc1a38 10417 if (err)
1da5fcc8 10418 return err;
d6dc1a38
JO
10419
10420 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
10421 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
4a4b8169
AZ
10422 const s32 *thresholds =
10423 nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
10424 int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
1da5fcc8 10425 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 10426
4a4b8169
AZ
10427 if (len % 4)
10428 return -EINVAL;
10429
10430 return nl80211_set_cqm_rssi(info, thresholds, len / 4,
10431 hysteresis);
1da5fcc8
JB
10432 }
10433
10434 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
10435 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
10436 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
10437 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
10438 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
10439 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
10440
10441 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
10442 }
10443
10444 return -EINVAL;
d6dc1a38
JO
10445}
10446
6e0bd6c3
RL
10447static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
10448{
10449 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10450 struct net_device *dev = info->user_ptr[1];
10451 struct ocb_setup setup = {};
10452 int err;
10453
10454 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
10455 if (err)
10456 return err;
10457
10458 return cfg80211_join_ocb(rdev, dev, &setup);
10459}
10460
10461static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
10462{
10463 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10464 struct net_device *dev = info->user_ptr[1];
10465
10466 return cfg80211_leave_ocb(rdev, dev);
10467}
10468
29cbe68c
JB
10469static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
10470{
10471 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10472 struct net_device *dev = info->user_ptr[1];
10473 struct mesh_config cfg;
c80d545d 10474 struct mesh_setup setup;
29cbe68c
JB
10475 int err;
10476
10477 /* start with default */
10478 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 10479 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 10480
24bdd9f4 10481 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 10482 /* and parse parameters if given */
24bdd9f4 10483 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
10484 if (err)
10485 return err;
10486 }
10487
10488 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
10489 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
10490 return -EINVAL;
10491
c80d545d
JC
10492 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
10493 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
10494
4bb62344
CYY
10495 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
10496 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
10497 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
10498 return -EINVAL;
10499
9bdbf04d
MP
10500 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
10501 setup.beacon_interval =
10502 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 10503
0c317a02
PK
10504 err = cfg80211_validate_beacon_int(rdev,
10505 NL80211_IFTYPE_MESH_POINT,
10506 setup.beacon_interval);
12d20fc9
PK
10507 if (err)
10508 return err;
9bdbf04d
MP
10509 }
10510
10511 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
10512 setup.dtim_period =
10513 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
10514 if (setup.dtim_period < 1 || setup.dtim_period > 100)
10515 return -EINVAL;
10516 }
10517
c80d545d
JC
10518 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
10519 /* parse additional setup parameters if given */
10520 err = nl80211_parse_mesh_setup(info, &setup);
10521 if (err)
10522 return err;
10523 }
10524
d37bb18a
TP
10525 if (setup.user_mpm)
10526 cfg.auto_open_plinks = false;
10527
cc1d2806 10528 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
10529 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
10530 if (err)
10531 return err;
cc1d2806 10532 } else {
188c1b3c 10533 /* __cfg80211_join_mesh() will sort it out */
683b6d3b 10534 setup.chandef.chan = NULL;
cc1d2806
JB
10535 }
10536
ffb3cf30
AN
10537 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
10538 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10539 int n_rates =
10540 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10541 struct ieee80211_supported_band *sband;
10542
10543 if (!setup.chandef.chan)
10544 return -EINVAL;
10545
10546 sband = rdev->wiphy.bands[setup.chandef.chan->band];
10547
10548 err = ieee80211_get_ratemask(sband, rates, n_rates,
10549 &setup.basic_rates);
10550 if (err)
10551 return err;
10552 }
10553
8564e382
JB
10554 if (info->attrs[NL80211_ATTR_TX_RATES]) {
10555 err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate);
10556 if (err)
10557 return err;
10558
265698d7
JB
10559 if (!setup.chandef.chan)
10560 return -EINVAL;
10561
8564e382
JB
10562 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
10563 &setup.beacon_rate);
10564 if (err)
10565 return err;
10566 }
10567
d37d49c2
BB
10568 setup.userspace_handles_dfs =
10569 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
10570
1224f583
DK
10571 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
10572 int r = validate_pae_over_nl80211(rdev, info);
10573
10574 if (r < 0)
10575 return r;
10576
10577 setup.control_port_over_nl80211 = true;
10578 }
10579
188c1b3c
DK
10580 wdev_lock(dev->ieee80211_ptr);
10581 err = __cfg80211_join_mesh(rdev, dev, &setup, &cfg);
10582 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER])
10583 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
10584 wdev_unlock(dev->ieee80211_ptr);
10585
10586 return err;
29cbe68c
JB
10587}
10588
10589static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
10590{
10591 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10592 struct net_device *dev = info->user_ptr[1];
10593
10594 return cfg80211_leave_mesh(rdev, dev);
10595}
10596
dfb89c56 10597#ifdef CONFIG_PM
bb92d199
AK
10598static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
10599 struct cfg80211_registered_device *rdev)
10600{
6abb9cb9 10601 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
10602 struct nlattr *nl_pats, *nl_pat;
10603 int i, pat_len;
10604
6abb9cb9 10605 if (!wowlan->n_patterns)
bb92d199
AK
10606 return 0;
10607
10608 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
10609 if (!nl_pats)
10610 return -ENOBUFS;
10611
6abb9cb9 10612 for (i = 0; i < wowlan->n_patterns; i++) {
bb92d199
AK
10613 nl_pat = nla_nest_start(msg, i + 1);
10614 if (!nl_pat)
10615 return -ENOBUFS;
6abb9cb9 10616 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 10617 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 10618 wowlan->patterns[i].mask) ||
50ac6607
AK
10619 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
10620 wowlan->patterns[i].pattern) ||
10621 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 10622 wowlan->patterns[i].pkt_offset))
bb92d199
AK
10623 return -ENOBUFS;
10624 nla_nest_end(msg, nl_pat);
10625 }
10626 nla_nest_end(msg, nl_pats);
10627
10628 return 0;
10629}
10630
2a0e047e
JB
10631static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
10632 struct cfg80211_wowlan_tcp *tcp)
10633{
10634 struct nlattr *nl_tcp;
10635
10636 if (!tcp)
10637 return 0;
10638
10639 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
10640 if (!nl_tcp)
10641 return -ENOBUFS;
10642
930345ea
JB
10643 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
10644 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
10645 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
10646 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
10647 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
10648 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
10649 tcp->payload_len, tcp->payload) ||
10650 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
10651 tcp->data_interval) ||
10652 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
10653 tcp->wake_len, tcp->wake_data) ||
10654 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
10655 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
10656 return -ENOBUFS;
10657
10658 if (tcp->payload_seq.len &&
10659 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
10660 sizeof(tcp->payload_seq), &tcp->payload_seq))
10661 return -ENOBUFS;
10662
10663 if (tcp->payload_tok.len &&
10664 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
10665 sizeof(tcp->payload_tok) + tcp->tokens_size,
10666 &tcp->payload_tok))
10667 return -ENOBUFS;
10668
e248ad30
JB
10669 nla_nest_end(msg, nl_tcp);
10670
2a0e047e
JB
10671 return 0;
10672}
10673
75453ccb
LC
10674static int nl80211_send_wowlan_nd(struct sk_buff *msg,
10675 struct cfg80211_sched_scan_request *req)
10676{
3b06d277 10677 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
10678 int i;
10679
10680 if (!req)
10681 return 0;
10682
10683 nd = nla_nest_start(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
10684 if (!nd)
10685 return -ENOBUFS;
10686
3b06d277
AS
10687 if (req->n_scan_plans == 1 &&
10688 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
10689 req->scan_plans[0].interval * 1000))
75453ccb
LC
10690 return -ENOBUFS;
10691
21fea567
LC
10692 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
10693 return -ENOBUFS;
10694
bf95ecdb 10695 if (req->relative_rssi_set) {
10696 struct nl80211_bss_select_rssi_adjust rssi_adjust;
10697
10698 if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
10699 req->relative_rssi))
10700 return -ENOBUFS;
10701
10702 rssi_adjust.band = req->rssi_adjust.band;
10703 rssi_adjust.delta = req->rssi_adjust.delta;
10704 if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
10705 sizeof(rssi_adjust), &rssi_adjust))
10706 return -ENOBUFS;
10707 }
10708
75453ccb
LC
10709 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
10710 if (!freqs)
10711 return -ENOBUFS;
10712
53b18980
JB
10713 for (i = 0; i < req->n_channels; i++) {
10714 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
10715 return -ENOBUFS;
10716 }
75453ccb
LC
10717
10718 nla_nest_end(msg, freqs);
10719
10720 if (req->n_match_sets) {
10721 matches = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
10722 if (!matches)
10723 return -ENOBUFS;
10724
75453ccb
LC
10725 for (i = 0; i < req->n_match_sets; i++) {
10726 match = nla_nest_start(msg, i);
76e1fb4b
JB
10727 if (!match)
10728 return -ENOBUFS;
10729
53b18980
JB
10730 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
10731 req->match_sets[i].ssid.ssid_len,
10732 req->match_sets[i].ssid.ssid))
10733 return -ENOBUFS;
75453ccb
LC
10734 nla_nest_end(msg, match);
10735 }
10736 nla_nest_end(msg, matches);
10737 }
10738
3b06d277
AS
10739 scan_plans = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
10740 if (!scan_plans)
10741 return -ENOBUFS;
10742
10743 for (i = 0; i < req->n_scan_plans; i++) {
10744 scan_plan = nla_nest_start(msg, i + 1);
76e1fb4b
JB
10745 if (!scan_plan)
10746 return -ENOBUFS;
10747
67626964 10748 if (nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
3b06d277
AS
10749 req->scan_plans[i].interval) ||
10750 (req->scan_plans[i].iterations &&
10751 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
10752 req->scan_plans[i].iterations)))
10753 return -ENOBUFS;
10754 nla_nest_end(msg, scan_plan);
10755 }
10756 nla_nest_end(msg, scan_plans);
10757
75453ccb
LC
10758 nla_nest_end(msg, nd);
10759
10760 return 0;
10761}
10762
ff1b6e69
JB
10763static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
10764{
10765 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10766 struct sk_buff *msg;
10767 void *hdr;
2a0e047e 10768 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 10769
964dc9e2 10770 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
10771 return -EOPNOTSUPP;
10772
6abb9cb9 10773 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 10774 /* adjust size to have room for all the data */
6abb9cb9
JB
10775 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
10776 rdev->wiphy.wowlan_config->tcp->payload_len +
10777 rdev->wiphy.wowlan_config->tcp->wake_len +
10778 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
10779 }
10780
10781 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
10782 if (!msg)
10783 return -ENOMEM;
10784
15e47304 10785 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
10786 NL80211_CMD_GET_WOWLAN);
10787 if (!hdr)
10788 goto nla_put_failure;
10789
6abb9cb9 10790 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
10791 struct nlattr *nl_wowlan;
10792
10793 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
10794 if (!nl_wowlan)
10795 goto nla_put_failure;
10796
6abb9cb9 10797 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 10798 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 10799 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 10800 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 10801 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 10802 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 10803 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 10804 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 10805 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 10806 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 10807 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 10808 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 10809 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
10810 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
10811 goto nla_put_failure;
2a0e047e 10812
bb92d199
AK
10813 if (nl80211_send_wowlan_patterns(msg, rdev))
10814 goto nla_put_failure;
2a0e047e 10815
6abb9cb9
JB
10816 if (nl80211_send_wowlan_tcp(msg,
10817 rdev->wiphy.wowlan_config->tcp))
2a0e047e 10818 goto nla_put_failure;
75453ccb
LC
10819
10820 if (nl80211_send_wowlan_nd(
10821 msg,
10822 rdev->wiphy.wowlan_config->nd_config))
10823 goto nla_put_failure;
2a0e047e 10824
ff1b6e69
JB
10825 nla_nest_end(msg, nl_wowlan);
10826 }
10827
10828 genlmsg_end(msg, hdr);
10829 return genlmsg_reply(msg, info);
10830
10831nla_put_failure:
10832 nlmsg_free(msg);
10833 return -ENOBUFS;
10834}
10835
2a0e047e
JB
10836static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
10837 struct nlattr *attr,
10838 struct cfg80211_wowlan *trig)
10839{
10840 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
10841 struct cfg80211_wowlan_tcp *cfg;
10842 struct nl80211_wowlan_tcp_data_token *tok = NULL;
10843 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
10844 u32 size;
10845 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
10846 int err, port;
10847
964dc9e2 10848 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
10849 return -EINVAL;
10850
bfe2c7b1 10851 err = nla_parse_nested(tb, MAX_NL80211_WOWLAN_TCP, attr,
fceb6435 10852 nl80211_wowlan_tcp_policy, NULL);
2a0e047e
JB
10853 if (err)
10854 return err;
10855
10856 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
10857 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
10858 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
10859 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
10860 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
10861 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
10862 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
10863 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
10864 return -EINVAL;
10865
10866 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 10867 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
10868 return -EINVAL;
10869
10870 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 10871 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 10872 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
10873 return -EINVAL;
10874
10875 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 10876 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
10877 return -EINVAL;
10878
10879 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
10880 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
10881 return -EINVAL;
10882
10883 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
10884 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
10885
10886 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
10887 tokens_size = tokln - sizeof(*tok);
10888
10889 if (!tok->len || tokens_size % tok->len)
10890 return -EINVAL;
964dc9e2 10891 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 10892 return -EINVAL;
964dc9e2 10893 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 10894 return -EINVAL;
964dc9e2 10895 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 10896 return -EINVAL;
964dc9e2 10897 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
10898 return -EINVAL;
10899 if (tok->offset + tok->len > data_size)
10900 return -EINVAL;
10901 }
10902
10903 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
10904 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 10905 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
10906 return -EINVAL;
10907 if (seq->len == 0 || seq->len > 4)
10908 return -EINVAL;
10909 if (seq->len + seq->offset > data_size)
10910 return -EINVAL;
10911 }
10912
10913 size = sizeof(*cfg);
10914 size += data_size;
10915 size += wake_size + wake_mask_size;
10916 size += tokens_size;
10917
10918 cfg = kzalloc(size, GFP_KERNEL);
10919 if (!cfg)
10920 return -ENOMEM;
67b61f6c
JB
10921 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
10922 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
10923 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
10924 ETH_ALEN);
10925 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
10926 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
10927 else
10928 port = 0;
10929#ifdef CONFIG_INET
10930 /* allocate a socket and port for it and use it */
10931 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
10932 IPPROTO_TCP, &cfg->sock, 1);
10933 if (err) {
10934 kfree(cfg);
10935 return err;
10936 }
10937 if (inet_csk_get_port(cfg->sock->sk, port)) {
10938 sock_release(cfg->sock);
10939 kfree(cfg);
10940 return -EADDRINUSE;
10941 }
10942 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
10943#else
10944 if (!port) {
10945 kfree(cfg);
10946 return -EINVAL;
10947 }
10948 cfg->src_port = port;
10949#endif
10950
10951 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
10952 cfg->payload_len = data_size;
10953 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
10954 memcpy((void *)cfg->payload,
10955 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
10956 data_size);
10957 if (seq)
10958 cfg->payload_seq = *seq;
10959 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
10960 cfg->wake_len = wake_size;
10961 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
10962 memcpy((void *)cfg->wake_data,
10963 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
10964 wake_size);
10965 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
10966 data_size + wake_size;
10967 memcpy((void *)cfg->wake_mask,
10968 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
10969 wake_mask_size);
10970 if (tok) {
10971 cfg->tokens_size = tokens_size;
10972 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
10973 }
10974
10975 trig->tcp = cfg;
10976
10977 return 0;
10978}
10979
8cd4d456
LC
10980static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
10981 const struct wiphy_wowlan_support *wowlan,
10982 struct nlattr *attr,
10983 struct cfg80211_wowlan *trig)
10984{
10985 struct nlattr **tb;
10986 int err;
10987
6396bb22 10988 tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
8cd4d456
LC
10989 if (!tb)
10990 return -ENOMEM;
10991
10992 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
10993 err = -EOPNOTSUPP;
10994 goto out;
10995 }
10996
fceb6435
JB
10997 err = nla_parse_nested(tb, NL80211_ATTR_MAX, attr, nl80211_policy,
10998 NULL);
8cd4d456
LC
10999 if (err)
11000 goto out;
11001
aad1e812
AVS
11002 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb,
11003 wowlan->max_nd_match_sets);
8cd4d456
LC
11004 err = PTR_ERR_OR_ZERO(trig->nd_config);
11005 if (err)
11006 trig->nd_config = NULL;
11007
11008out:
11009 kfree(tb);
11010 return err;
11011}
11012
ff1b6e69
JB
11013static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
11014{
11015 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11016 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 11017 struct cfg80211_wowlan new_triggers = {};
ae33bd81 11018 struct cfg80211_wowlan *ntrig;
964dc9e2 11019 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 11020 int err, i;
6abb9cb9 11021 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 11022 bool regular = false;
ff1b6e69 11023
964dc9e2 11024 if (!wowlan)
ff1b6e69
JB
11025 return -EOPNOTSUPP;
11026
ae33bd81
JB
11027 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
11028 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 11029 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
11030 goto set_wakeup;
11031 }
ff1b6e69 11032
bfe2c7b1
JB
11033 err = nla_parse_nested(tb, MAX_NL80211_WOWLAN_TRIG,
11034 info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
fe52145f 11035 nl80211_wowlan_policy, info->extack);
ff1b6e69
JB
11036 if (err)
11037 return err;
11038
11039 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
11040 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
11041 return -EINVAL;
11042 new_triggers.any = true;
11043 }
11044
11045 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
11046 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
11047 return -EINVAL;
11048 new_triggers.disconnect = true;
98fc4386 11049 regular = true;
ff1b6e69
JB
11050 }
11051
11052 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
11053 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
11054 return -EINVAL;
11055 new_triggers.magic_pkt = true;
98fc4386 11056 regular = true;
ff1b6e69
JB
11057 }
11058
77dbbb13
JB
11059 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
11060 return -EINVAL;
11061
11062 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
11063 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
11064 return -EINVAL;
11065 new_triggers.gtk_rekey_failure = true;
98fc4386 11066 regular = true;
77dbbb13
JB
11067 }
11068
11069 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
11070 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
11071 return -EINVAL;
11072 new_triggers.eap_identity_req = true;
98fc4386 11073 regular = true;
77dbbb13
JB
11074 }
11075
11076 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
11077 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
11078 return -EINVAL;
11079 new_triggers.four_way_handshake = true;
98fc4386 11080 regular = true;
77dbbb13
JB
11081 }
11082
11083 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
11084 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
11085 return -EINVAL;
11086 new_triggers.rfkill_release = true;
98fc4386 11087 regular = true;
77dbbb13
JB
11088 }
11089
ff1b6e69
JB
11090 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
11091 struct nlattr *pat;
11092 int n_patterns = 0;
bb92d199 11093 int rem, pat_len, mask_len, pkt_offset;
50ac6607 11094 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 11095
98fc4386
JB
11096 regular = true;
11097
ff1b6e69
JB
11098 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
11099 rem)
11100 n_patterns++;
11101 if (n_patterns > wowlan->n_patterns)
11102 return -EINVAL;
11103
11104 new_triggers.patterns = kcalloc(n_patterns,
11105 sizeof(new_triggers.patterns[0]),
11106 GFP_KERNEL);
11107 if (!new_triggers.patterns)
11108 return -ENOMEM;
11109
11110 new_triggers.n_patterns = n_patterns;
11111 i = 0;
11112
11113 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
11114 rem) {
922bd80f
JB
11115 u8 *mask_pat;
11116
95bca62f
JB
11117 err = nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat,
11118 nl80211_packet_pattern_policy,
11119 info->extack);
11120 if (err)
11121 goto error;
11122
ff1b6e69 11123 err = -EINVAL;
50ac6607
AK
11124 if (!pat_tb[NL80211_PKTPAT_MASK] ||
11125 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 11126 goto error;
50ac6607 11127 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 11128 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 11129 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
11130 goto error;
11131 if (pat_len > wowlan->pattern_max_len ||
11132 pat_len < wowlan->pattern_min_len)
11133 goto error;
11134
50ac6607 11135 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
11136 pkt_offset = 0;
11137 else
11138 pkt_offset = nla_get_u32(
50ac6607 11139 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
11140 if (pkt_offset > wowlan->max_pkt_offset)
11141 goto error;
11142 new_triggers.patterns[i].pkt_offset = pkt_offset;
11143
922bd80f
JB
11144 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
11145 if (!mask_pat) {
ff1b6e69
JB
11146 err = -ENOMEM;
11147 goto error;
11148 }
922bd80f
JB
11149 new_triggers.patterns[i].mask = mask_pat;
11150 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 11151 mask_len);
922bd80f
JB
11152 mask_pat += mask_len;
11153 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 11154 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 11155 memcpy(mask_pat,
50ac6607 11156 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
11157 pat_len);
11158 i++;
11159 }
11160 }
11161
2a0e047e 11162 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 11163 regular = true;
2a0e047e
JB
11164 err = nl80211_parse_wowlan_tcp(
11165 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
11166 &new_triggers);
11167 if (err)
11168 goto error;
11169 }
11170
8cd4d456 11171 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 11172 regular = true;
8cd4d456
LC
11173 err = nl80211_parse_wowlan_nd(
11174 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
11175 &new_triggers);
11176 if (err)
11177 goto error;
11178 }
11179
98fc4386
JB
11180 /* The 'any' trigger means the device continues operating more or less
11181 * as in its normal operation mode and wakes up the host on most of the
11182 * normal interrupts (like packet RX, ...)
11183 * It therefore makes little sense to combine with the more constrained
11184 * wakeup trigger modes.
11185 */
11186 if (new_triggers.any && regular) {
11187 err = -EINVAL;
11188 goto error;
11189 }
11190
ae33bd81
JB
11191 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
11192 if (!ntrig) {
11193 err = -ENOMEM;
11194 goto error;
ff1b6e69 11195 }
ae33bd81 11196 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 11197 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 11198
ae33bd81 11199 set_wakeup:
6abb9cb9
JB
11200 if (rdev->ops->set_wakeup &&
11201 prev_enabled != !!rdev->wiphy.wowlan_config)
11202 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 11203
ff1b6e69
JB
11204 return 0;
11205 error:
11206 for (i = 0; i < new_triggers.n_patterns; i++)
11207 kfree(new_triggers.patterns[i].mask);
11208 kfree(new_triggers.patterns);
2a0e047e
JB
11209 if (new_triggers.tcp && new_triggers.tcp->sock)
11210 sock_release(new_triggers.tcp->sock);
11211 kfree(new_triggers.tcp);
e5dbe070 11212 kfree(new_triggers.nd_config);
ff1b6e69
JB
11213 return err;
11214}
dfb89c56 11215#endif
ff1b6e69 11216
be29b99a
AK
11217static int nl80211_send_coalesce_rules(struct sk_buff *msg,
11218 struct cfg80211_registered_device *rdev)
11219{
11220 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
11221 int i, j, pat_len;
11222 struct cfg80211_coalesce_rules *rule;
11223
11224 if (!rdev->coalesce->n_rules)
11225 return 0;
11226
11227 nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
11228 if (!nl_rules)
11229 return -ENOBUFS;
11230
11231 for (i = 0; i < rdev->coalesce->n_rules; i++) {
11232 nl_rule = nla_nest_start(msg, i + 1);
11233 if (!nl_rule)
11234 return -ENOBUFS;
11235
11236 rule = &rdev->coalesce->rules[i];
11237 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
11238 rule->delay))
11239 return -ENOBUFS;
11240
11241 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
11242 rule->condition))
11243 return -ENOBUFS;
11244
11245 nl_pats = nla_nest_start(msg,
11246 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
11247 if (!nl_pats)
11248 return -ENOBUFS;
11249
11250 for (j = 0; j < rule->n_patterns; j++) {
11251 nl_pat = nla_nest_start(msg, j + 1);
11252 if (!nl_pat)
11253 return -ENOBUFS;
11254 pat_len = rule->patterns[j].pattern_len;
11255 if (nla_put(msg, NL80211_PKTPAT_MASK,
11256 DIV_ROUND_UP(pat_len, 8),
11257 rule->patterns[j].mask) ||
11258 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
11259 rule->patterns[j].pattern) ||
11260 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
11261 rule->patterns[j].pkt_offset))
11262 return -ENOBUFS;
11263 nla_nest_end(msg, nl_pat);
11264 }
11265 nla_nest_end(msg, nl_pats);
11266 nla_nest_end(msg, nl_rule);
11267 }
11268 nla_nest_end(msg, nl_rules);
11269
11270 return 0;
11271}
11272
11273static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
11274{
11275 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11276 struct sk_buff *msg;
11277 void *hdr;
11278
11279 if (!rdev->wiphy.coalesce)
11280 return -EOPNOTSUPP;
11281
11282 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11283 if (!msg)
11284 return -ENOMEM;
11285
11286 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11287 NL80211_CMD_GET_COALESCE);
11288 if (!hdr)
11289 goto nla_put_failure;
11290
11291 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
11292 goto nla_put_failure;
11293
11294 genlmsg_end(msg, hdr);
11295 return genlmsg_reply(msg, info);
11296
11297nla_put_failure:
11298 nlmsg_free(msg);
11299 return -ENOBUFS;
11300}
11301
11302void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
11303{
11304 struct cfg80211_coalesce *coalesce = rdev->coalesce;
11305 int i, j;
11306 struct cfg80211_coalesce_rules *rule;
11307
11308 if (!coalesce)
11309 return;
11310
11311 for (i = 0; i < coalesce->n_rules; i++) {
11312 rule = &coalesce->rules[i];
11313 for (j = 0; j < rule->n_patterns; j++)
11314 kfree(rule->patterns[j].mask);
11315 kfree(rule->patterns);
11316 }
11317 kfree(coalesce->rules);
11318 kfree(coalesce);
11319 rdev->coalesce = NULL;
11320}
11321
11322static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
11323 struct nlattr *rule,
11324 struct cfg80211_coalesce_rules *new_rule)
11325{
11326 int err, i;
11327 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
11328 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
11329 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
11330 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
11331
bfe2c7b1 11332 err = nla_parse_nested(tb, NL80211_ATTR_COALESCE_RULE_MAX, rule,
fceb6435 11333 nl80211_coalesce_policy, NULL);
be29b99a
AK
11334 if (err)
11335 return err;
11336
11337 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
11338 new_rule->delay =
11339 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
11340 if (new_rule->delay > coalesce->max_delay)
11341 return -EINVAL;
11342
11343 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
11344 new_rule->condition =
11345 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
11346 if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH &&
11347 new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH)
11348 return -EINVAL;
11349
11350 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
11351 return -EINVAL;
11352
11353 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
11354 rem)
11355 n_patterns++;
11356 if (n_patterns > coalesce->n_patterns)
11357 return -EINVAL;
11358
11359 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
11360 GFP_KERNEL);
11361 if (!new_rule->patterns)
11362 return -ENOMEM;
11363
11364 new_rule->n_patterns = n_patterns;
11365 i = 0;
11366
11367 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
11368 rem) {
922bd80f
JB
11369 u8 *mask_pat;
11370
95bca62f
JB
11371 err = nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat,
11372 nl80211_packet_pattern_policy, NULL);
11373 if (err)
11374 return err;
11375
be29b99a
AK
11376 if (!pat_tb[NL80211_PKTPAT_MASK] ||
11377 !pat_tb[NL80211_PKTPAT_PATTERN])
11378 return -EINVAL;
11379 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
11380 mask_len = DIV_ROUND_UP(pat_len, 8);
11381 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
11382 return -EINVAL;
11383 if (pat_len > coalesce->pattern_max_len ||
11384 pat_len < coalesce->pattern_min_len)
11385 return -EINVAL;
11386
11387 if (!pat_tb[NL80211_PKTPAT_OFFSET])
11388 pkt_offset = 0;
11389 else
11390 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
11391 if (pkt_offset > coalesce->max_pkt_offset)
11392 return -EINVAL;
11393 new_rule->patterns[i].pkt_offset = pkt_offset;
11394
922bd80f
JB
11395 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
11396 if (!mask_pat)
be29b99a 11397 return -ENOMEM;
922bd80f
JB
11398
11399 new_rule->patterns[i].mask = mask_pat;
11400 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
11401 mask_len);
11402
11403 mask_pat += mask_len;
11404 new_rule->patterns[i].pattern = mask_pat;
be29b99a 11405 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
11406 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
11407 pat_len);
be29b99a
AK
11408 i++;
11409 }
11410
11411 return 0;
11412}
11413
11414static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
11415{
11416 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11417 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
11418 struct cfg80211_coalesce new_coalesce = {};
11419 struct cfg80211_coalesce *n_coalesce;
11420 int err, rem_rule, n_rules = 0, i, j;
11421 struct nlattr *rule;
11422 struct cfg80211_coalesce_rules *tmp_rule;
11423
11424 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
11425 return -EOPNOTSUPP;
11426
11427 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
11428 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 11429 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
11430 return 0;
11431 }
11432
11433 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
11434 rem_rule)
11435 n_rules++;
11436 if (n_rules > coalesce->n_rules)
11437 return -EINVAL;
11438
11439 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
11440 GFP_KERNEL);
11441 if (!new_coalesce.rules)
11442 return -ENOMEM;
11443
11444 new_coalesce.n_rules = n_rules;
11445 i = 0;
11446
11447 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
11448 rem_rule) {
11449 err = nl80211_parse_coalesce_rule(rdev, rule,
11450 &new_coalesce.rules[i]);
11451 if (err)
11452 goto error;
11453
11454 i++;
11455 }
11456
a1056b1b 11457 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
11458 if (err)
11459 goto error;
11460
11461 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
11462 if (!n_coalesce) {
11463 err = -ENOMEM;
11464 goto error;
11465 }
11466 cfg80211_rdev_free_coalesce(rdev);
11467 rdev->coalesce = n_coalesce;
11468
11469 return 0;
11470error:
11471 for (i = 0; i < new_coalesce.n_rules; i++) {
11472 tmp_rule = &new_coalesce.rules[i];
11473 for (j = 0; j < tmp_rule->n_patterns; j++)
11474 kfree(tmp_rule->patterns[j].mask);
11475 kfree(tmp_rule->patterns);
11476 }
11477 kfree(new_coalesce.rules);
11478
11479 return err;
11480}
11481
e5497d76
JB
11482static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
11483{
11484 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11485 struct net_device *dev = info->user_ptr[1];
11486 struct wireless_dev *wdev = dev->ieee80211_ptr;
11487 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
11488 struct cfg80211_gtk_rekey_data rekey_data;
11489 int err;
11490
11491 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
11492 return -EINVAL;
11493
bfe2c7b1
JB
11494 err = nla_parse_nested(tb, MAX_NL80211_REKEY_DATA,
11495 info->attrs[NL80211_ATTR_REKEY_DATA],
fe52145f 11496 nl80211_rekey_policy, info->extack);
e5497d76
JB
11497 if (err)
11498 return err;
11499
e785fa0a
VD
11500 if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
11501 !tb[NL80211_REKEY_DATA_KCK])
11502 return -EINVAL;
e5497d76
JB
11503 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
11504 return -ERANGE;
11505 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
11506 return -ERANGE;
11507 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
11508 return -ERANGE;
11509
78f686ca
JB
11510 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
11511 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
11512 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
e5497d76
JB
11513
11514 wdev_lock(wdev);
11515 if (!wdev->current_bss) {
11516 err = -ENOTCONN;
11517 goto out;
11518 }
11519
11520 if (!rdev->ops->set_rekey_data) {
11521 err = -EOPNOTSUPP;
11522 goto out;
11523 }
11524
e35e4d28 11525 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
11526 out:
11527 wdev_unlock(wdev);
11528 return err;
11529}
11530
28946da7
JB
11531static int nl80211_register_unexpected_frame(struct sk_buff *skb,
11532 struct genl_info *info)
11533{
11534 struct net_device *dev = info->user_ptr[1];
11535 struct wireless_dev *wdev = dev->ieee80211_ptr;
11536
11537 if (wdev->iftype != NL80211_IFTYPE_AP &&
11538 wdev->iftype != NL80211_IFTYPE_P2P_GO)
11539 return -EINVAL;
11540
15e47304 11541 if (wdev->ap_unexpected_nlportid)
28946da7
JB
11542 return -EBUSY;
11543
15e47304 11544 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
11545 return 0;
11546}
11547
7f6cf311
JB
11548static int nl80211_probe_client(struct sk_buff *skb,
11549 struct genl_info *info)
11550{
11551 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11552 struct net_device *dev = info->user_ptr[1];
11553 struct wireless_dev *wdev = dev->ieee80211_ptr;
11554 struct sk_buff *msg;
11555 void *hdr;
11556 const u8 *addr;
11557 u64 cookie;
11558 int err;
11559
11560 if (wdev->iftype != NL80211_IFTYPE_AP &&
11561 wdev->iftype != NL80211_IFTYPE_P2P_GO)
11562 return -EOPNOTSUPP;
11563
11564 if (!info->attrs[NL80211_ATTR_MAC])
11565 return -EINVAL;
11566
11567 if (!rdev->ops->probe_client)
11568 return -EOPNOTSUPP;
11569
11570 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11571 if (!msg)
11572 return -ENOMEM;
11573
15e47304 11574 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 11575 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
11576 if (!hdr) {
11577 err = -ENOBUFS;
7f6cf311
JB
11578 goto free_msg;
11579 }
11580
11581 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11582
e35e4d28 11583 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
11584 if (err)
11585 goto free_msg;
11586
2dad624e
ND
11587 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11588 NL80211_ATTR_PAD))
9360ffd1 11589 goto nla_put_failure;
7f6cf311
JB
11590
11591 genlmsg_end(msg, hdr);
11592
11593 return genlmsg_reply(msg, info);
11594
11595 nla_put_failure:
11596 err = -ENOBUFS;
11597 free_msg:
11598 nlmsg_free(msg);
11599 return err;
11600}
11601
5e760230
JB
11602static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
11603{
11604 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
11605 struct cfg80211_beacon_registration *reg, *nreg;
11606 int rv;
5e760230
JB
11607
11608 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
11609 return -EOPNOTSUPP;
11610
37c73b5f
BG
11611 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
11612 if (!nreg)
11613 return -ENOMEM;
11614
11615 /* First, check if already registered. */
11616 spin_lock_bh(&rdev->beacon_registrations_lock);
11617 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
11618 if (reg->nlportid == info->snd_portid) {
11619 rv = -EALREADY;
11620 goto out_err;
11621 }
11622 }
11623 /* Add it to the list */
11624 nreg->nlportid = info->snd_portid;
11625 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 11626
37c73b5f 11627 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
11628
11629 return 0;
37c73b5f
BG
11630out_err:
11631 spin_unlock_bh(&rdev->beacon_registrations_lock);
11632 kfree(nreg);
11633 return rv;
5e760230
JB
11634}
11635
98104fde
JB
11636static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
11637{
11638 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11639 struct wireless_dev *wdev = info->user_ptr[1];
11640 int err;
11641
11642 if (!rdev->ops->start_p2p_device)
11643 return -EOPNOTSUPP;
11644
11645 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
11646 return -EOPNOTSUPP;
11647
73c7da3d 11648 if (wdev_running(wdev))
98104fde
JB
11649 return 0;
11650
b6a55015
LC
11651 if (rfkill_blocked(rdev->rfkill))
11652 return -ERFKILL;
98104fde 11653
eeb126e9 11654 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
11655 if (err)
11656 return err;
11657
73c7da3d 11658 wdev->is_running = true;
98104fde 11659 rdev->opencount++;
98104fde
JB
11660
11661 return 0;
11662}
11663
11664static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
11665{
11666 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11667 struct wireless_dev *wdev = info->user_ptr[1];
11668
11669 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
11670 return -EOPNOTSUPP;
11671
11672 if (!rdev->ops->stop_p2p_device)
11673 return -EOPNOTSUPP;
11674
f9f47529 11675 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
11676
11677 return 0;
11678}
11679
cb3b7d87
AB
11680static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
11681{
11682 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11683 struct wireless_dev *wdev = info->user_ptr[1];
11684 struct cfg80211_nan_conf conf = {};
11685 int err;
11686
11687 if (wdev->iftype != NL80211_IFTYPE_NAN)
11688 return -EOPNOTSUPP;
11689
eeb04a96 11690 if (wdev_running(wdev))
cb3b7d87
AB
11691 return -EEXIST;
11692
11693 if (rfkill_blocked(rdev->rfkill))
11694 return -ERFKILL;
11695
11696 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
11697 return -EINVAL;
11698
cb3b7d87
AB
11699 conf.master_pref =
11700 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
11701 if (!conf.master_pref)
11702 return -EINVAL;
11703
8585989d
LC
11704 if (info->attrs[NL80211_ATTR_BANDS]) {
11705 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
11706
11707 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
11708 return -EOPNOTSUPP;
11709
11710 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
11711 return -EINVAL;
11712
11713 conf.bands = bands;
11714 }
cb3b7d87
AB
11715
11716 err = rdev_start_nan(rdev, wdev, &conf);
11717 if (err)
11718 return err;
11719
73c7da3d 11720 wdev->is_running = true;
cb3b7d87
AB
11721 rdev->opencount++;
11722
11723 return 0;
11724}
11725
11726static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
11727{
11728 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11729 struct wireless_dev *wdev = info->user_ptr[1];
11730
11731 if (wdev->iftype != NL80211_IFTYPE_NAN)
11732 return -EOPNOTSUPP;
11733
11734 cfg80211_stop_nan(rdev, wdev);
11735
11736 return 0;
11737}
11738
a442b761
AB
11739static int validate_nan_filter(struct nlattr *filter_attr)
11740{
11741 struct nlattr *attr;
11742 int len = 0, n_entries = 0, rem;
11743
11744 nla_for_each_nested(attr, filter_attr, rem) {
11745 len += nla_len(attr);
11746 n_entries++;
11747 }
11748
11749 if (len >= U8_MAX)
11750 return -EINVAL;
11751
11752 return n_entries;
11753}
11754
11755static int handle_nan_filter(struct nlattr *attr_filter,
11756 struct cfg80211_nan_func *func,
11757 bool tx)
11758{
11759 struct nlattr *attr;
11760 int n_entries, rem, i;
11761 struct cfg80211_nan_func_filter *filter;
11762
11763 n_entries = validate_nan_filter(attr_filter);
11764 if (n_entries < 0)
11765 return n_entries;
11766
11767 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
11768
11769 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
11770 if (!filter)
11771 return -ENOMEM;
11772
11773 i = 0;
11774 nla_for_each_nested(attr, attr_filter, rem) {
b15ca182 11775 filter[i].filter = nla_memdup(attr, GFP_KERNEL);
a442b761
AB
11776 filter[i].len = nla_len(attr);
11777 i++;
11778 }
11779 if (tx) {
11780 func->num_tx_filters = n_entries;
11781 func->tx_filters = filter;
11782 } else {
11783 func->num_rx_filters = n_entries;
11784 func->rx_filters = filter;
11785 }
11786
11787 return 0;
11788}
11789
11790static int nl80211_nan_add_func(struct sk_buff *skb,
11791 struct genl_info *info)
11792{
11793 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11794 struct wireless_dev *wdev = info->user_ptr[1];
11795 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
11796 struct cfg80211_nan_func *func;
11797 struct sk_buff *msg = NULL;
11798 void *hdr = NULL;
11799 int err = 0;
11800
11801 if (wdev->iftype != NL80211_IFTYPE_NAN)
11802 return -EOPNOTSUPP;
11803
73c7da3d 11804 if (!wdev_running(wdev))
a442b761
AB
11805 return -ENOTCONN;
11806
11807 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
11808 return -EINVAL;
11809
bfe2c7b1
JB
11810 err = nla_parse_nested(tb, NL80211_NAN_FUNC_ATTR_MAX,
11811 info->attrs[NL80211_ATTR_NAN_FUNC],
fe52145f 11812 nl80211_nan_func_policy, info->extack);
a442b761
AB
11813 if (err)
11814 return err;
11815
11816 func = kzalloc(sizeof(*func), GFP_KERNEL);
11817 if (!func)
11818 return -ENOMEM;
11819
b60ad348 11820 func->cookie = cfg80211_assign_cookie(rdev);
a442b761
AB
11821
11822 if (!tb[NL80211_NAN_FUNC_TYPE] ||
11823 nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
11824 err = -EINVAL;
11825 goto out;
11826 }
11827
11828
11829 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
11830
11831 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
11832 err = -EINVAL;
11833 goto out;
11834 }
11835
11836 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
11837 sizeof(func->service_id));
11838
11839 func->close_range =
11840 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
11841
11842 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
11843 func->serv_spec_info_len =
11844 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
11845 func->serv_spec_info =
11846 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
11847 func->serv_spec_info_len,
11848 GFP_KERNEL);
11849 if (!func->serv_spec_info) {
11850 err = -ENOMEM;
11851 goto out;
11852 }
11853 }
11854
11855 if (tb[NL80211_NAN_FUNC_TTL])
11856 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
11857
11858 switch (func->type) {
11859 case NL80211_NAN_FUNC_PUBLISH:
11860 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
11861 err = -EINVAL;
11862 goto out;
11863 }
11864
11865 func->publish_type =
11866 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
11867 func->publish_bcast =
11868 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
11869
11870 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
11871 func->publish_bcast) {
11872 err = -EINVAL;
11873 goto out;
11874 }
11875 break;
11876 case NL80211_NAN_FUNC_SUBSCRIBE:
11877 func->subscribe_active =
11878 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
11879 break;
11880 case NL80211_NAN_FUNC_FOLLOW_UP:
11881 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
3ea15452
HC
11882 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] ||
11883 !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) {
a442b761
AB
11884 err = -EINVAL;
11885 goto out;
11886 }
11887
11888 func->followup_id =
11889 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
11890 func->followup_reqid =
11891 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
11892 memcpy(func->followup_dest.addr,
11893 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
11894 sizeof(func->followup_dest.addr));
11895 if (func->ttl) {
11896 err = -EINVAL;
11897 goto out;
11898 }
11899 break;
11900 default:
11901 err = -EINVAL;
11902 goto out;
11903 }
11904
11905 if (tb[NL80211_NAN_FUNC_SRF]) {
11906 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
11907
bfe2c7b1
JB
11908 err = nla_parse_nested(srf_tb, NL80211_NAN_SRF_ATTR_MAX,
11909 tb[NL80211_NAN_FUNC_SRF],
fe52145f 11910 nl80211_nan_srf_policy, info->extack);
a442b761
AB
11911 if (err)
11912 goto out;
11913
11914 func->srf_include =
11915 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
11916
11917 if (srf_tb[NL80211_NAN_SRF_BF]) {
11918 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
11919 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
11920 err = -EINVAL;
11921 goto out;
11922 }
11923
11924 func->srf_bf_len =
11925 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
11926 func->srf_bf =
11927 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
11928 func->srf_bf_len, GFP_KERNEL);
11929 if (!func->srf_bf) {
11930 err = -ENOMEM;
11931 goto out;
11932 }
11933
11934 func->srf_bf_idx =
11935 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
11936 } else {
11937 struct nlattr *attr, *mac_attr =
11938 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
11939 int n_entries, rem, i = 0;
11940
11941 if (!mac_attr) {
11942 err = -EINVAL;
11943 goto out;
11944 }
11945
11946 n_entries = validate_acl_mac_addrs(mac_attr);
11947 if (n_entries <= 0) {
11948 err = -EINVAL;
11949 goto out;
11950 }
11951
11952 func->srf_num_macs = n_entries;
11953 func->srf_macs =
6396bb22 11954 kcalloc(n_entries, sizeof(*func->srf_macs),
a442b761
AB
11955 GFP_KERNEL);
11956 if (!func->srf_macs) {
11957 err = -ENOMEM;
11958 goto out;
11959 }
11960
11961 nla_for_each_nested(attr, mac_attr, rem)
11962 memcpy(func->srf_macs[i++].addr, nla_data(attr),
11963 sizeof(*func->srf_macs));
11964 }
11965 }
11966
11967 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
11968 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
11969 func, true);
11970 if (err)
11971 goto out;
11972 }
11973
11974 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
11975 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
11976 func, false);
11977 if (err)
11978 goto out;
11979 }
11980
11981 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11982 if (!msg) {
11983 err = -ENOMEM;
11984 goto out;
11985 }
11986
11987 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11988 NL80211_CMD_ADD_NAN_FUNCTION);
11989 /* This can't really happen - we just allocated 4KB */
11990 if (WARN_ON(!hdr)) {
11991 err = -ENOMEM;
11992 goto out;
11993 }
11994
11995 err = rdev_add_nan_func(rdev, wdev, func);
11996out:
11997 if (err < 0) {
11998 cfg80211_free_nan_func(func);
11999 nlmsg_free(msg);
12000 return err;
12001 }
12002
12003 /* propagate the instance id and cookie to userspace */
12004 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
12005 NL80211_ATTR_PAD))
12006 goto nla_put_failure;
12007
12008 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
12009 if (!func_attr)
12010 goto nla_put_failure;
12011
12012 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
12013 func->instance_id))
12014 goto nla_put_failure;
12015
12016 nla_nest_end(msg, func_attr);
12017
12018 genlmsg_end(msg, hdr);
12019 return genlmsg_reply(msg, info);
12020
12021nla_put_failure:
12022 nlmsg_free(msg);
12023 return -ENOBUFS;
12024}
12025
12026static int nl80211_nan_del_func(struct sk_buff *skb,
12027 struct genl_info *info)
12028{
12029 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12030 struct wireless_dev *wdev = info->user_ptr[1];
12031 u64 cookie;
12032
12033 if (wdev->iftype != NL80211_IFTYPE_NAN)
12034 return -EOPNOTSUPP;
12035
73c7da3d 12036 if (!wdev_running(wdev))
a442b761
AB
12037 return -ENOTCONN;
12038
12039 if (!info->attrs[NL80211_ATTR_COOKIE])
12040 return -EINVAL;
12041
a442b761
AB
12042 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
12043
12044 rdev_del_nan_func(rdev, wdev, cookie);
12045
12046 return 0;
12047}
12048
a5a9dcf2
AB
12049static int nl80211_nan_change_config(struct sk_buff *skb,
12050 struct genl_info *info)
12051{
12052 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12053 struct wireless_dev *wdev = info->user_ptr[1];
12054 struct cfg80211_nan_conf conf = {};
12055 u32 changed = 0;
12056
12057 if (wdev->iftype != NL80211_IFTYPE_NAN)
12058 return -EOPNOTSUPP;
12059
73c7da3d 12060 if (!wdev_running(wdev))
a5a9dcf2
AB
12061 return -ENOTCONN;
12062
12063 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
12064 conf.master_pref =
12065 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
12066 if (conf.master_pref <= 1 || conf.master_pref == 255)
12067 return -EINVAL;
12068
12069 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
12070 }
12071
8585989d
LC
12072 if (info->attrs[NL80211_ATTR_BANDS]) {
12073 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
12074
12075 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
12076 return -EOPNOTSUPP;
12077
12078 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
12079 return -EINVAL;
12080
12081 conf.bands = bands;
12082 changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
a5a9dcf2
AB
12083 }
12084
12085 if (!changed)
12086 return -EINVAL;
12087
12088 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
12089}
12090
50bcd31d
AB
12091void cfg80211_nan_match(struct wireless_dev *wdev,
12092 struct cfg80211_nan_match_params *match, gfp_t gfp)
12093{
12094 struct wiphy *wiphy = wdev->wiphy;
12095 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
12096 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
12097 struct sk_buff *msg;
12098 void *hdr;
12099
12100 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
12101 return;
12102
12103 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
12104 if (!msg)
12105 return;
12106
12107 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
12108 if (!hdr) {
12109 nlmsg_free(msg);
12110 return;
12111 }
12112
12113 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12114 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12115 wdev->netdev->ifindex)) ||
12116 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12117 NL80211_ATTR_PAD))
12118 goto nla_put_failure;
12119
12120 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
12121 NL80211_ATTR_PAD) ||
12122 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
12123 goto nla_put_failure;
12124
12125 match_attr = nla_nest_start(msg, NL80211_ATTR_NAN_MATCH);
12126 if (!match_attr)
12127 goto nla_put_failure;
12128
12129 local_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_LOCAL);
12130 if (!local_func_attr)
12131 goto nla_put_failure;
12132
12133 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
12134 goto nla_put_failure;
12135
12136 nla_nest_end(msg, local_func_attr);
12137
12138 peer_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_PEER);
12139 if (!peer_func_attr)
12140 goto nla_put_failure;
12141
12142 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
12143 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
12144 goto nla_put_failure;
12145
12146 if (match->info && match->info_len &&
12147 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
12148 match->info))
12149 goto nla_put_failure;
12150
12151 nla_nest_end(msg, peer_func_attr);
12152 nla_nest_end(msg, match_attr);
12153 genlmsg_end(msg, hdr);
12154
12155 if (!wdev->owner_nlportid)
12156 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
12157 msg, 0, NL80211_MCGRP_NAN, gfp);
12158 else
12159 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
12160 wdev->owner_nlportid);
12161
12162 return;
12163
12164nla_put_failure:
12165 nlmsg_free(msg);
12166}
12167EXPORT_SYMBOL(cfg80211_nan_match);
12168
368e5a7b
AB
12169void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
12170 u8 inst_id,
12171 enum nl80211_nan_func_term_reason reason,
12172 u64 cookie, gfp_t gfp)
12173{
12174 struct wiphy *wiphy = wdev->wiphy;
12175 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
12176 struct sk_buff *msg;
12177 struct nlattr *func_attr;
12178 void *hdr;
12179
12180 if (WARN_ON(!inst_id))
12181 return;
12182
12183 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
12184 if (!msg)
12185 return;
12186
12187 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
12188 if (!hdr) {
12189 nlmsg_free(msg);
12190 return;
12191 }
12192
12193 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12194 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12195 wdev->netdev->ifindex)) ||
12196 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12197 NL80211_ATTR_PAD))
12198 goto nla_put_failure;
12199
12200 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
12201 NL80211_ATTR_PAD))
12202 goto nla_put_failure;
12203
12204 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
12205 if (!func_attr)
12206 goto nla_put_failure;
12207
12208 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
12209 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
12210 goto nla_put_failure;
12211
12212 nla_nest_end(msg, func_attr);
12213 genlmsg_end(msg, hdr);
12214
12215 if (!wdev->owner_nlportid)
12216 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
12217 msg, 0, NL80211_MCGRP_NAN, gfp);
12218 else
12219 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
12220 wdev->owner_nlportid);
12221
12222 return;
12223
12224nla_put_failure:
12225 nlmsg_free(msg);
12226}
12227EXPORT_SYMBOL(cfg80211_nan_func_terminated);
12228
3713b4e3
JB
12229static int nl80211_get_protocol_features(struct sk_buff *skb,
12230 struct genl_info *info)
12231{
12232 void *hdr;
12233 struct sk_buff *msg;
12234
12235 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12236 if (!msg)
12237 return -ENOMEM;
12238
12239 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12240 NL80211_CMD_GET_PROTOCOL_FEATURES);
12241 if (!hdr)
12242 goto nla_put_failure;
12243
12244 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
12245 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
12246 goto nla_put_failure;
12247
12248 genlmsg_end(msg, hdr);
12249 return genlmsg_reply(msg, info);
12250
12251 nla_put_failure:
12252 kfree_skb(msg);
12253 return -ENOBUFS;
12254}
12255
355199e0
JM
12256static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
12257{
12258 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12259 struct cfg80211_update_ft_ies_params ft_params;
12260 struct net_device *dev = info->user_ptr[1];
12261
12262 if (!rdev->ops->update_ft_ies)
12263 return -EOPNOTSUPP;
12264
12265 if (!info->attrs[NL80211_ATTR_MDID] ||
4f0223bf 12266 !info->attrs[NL80211_ATTR_IE] ||
355199e0
JM
12267 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
12268 return -EINVAL;
12269
12270 memset(&ft_params, 0, sizeof(ft_params));
12271 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
12272 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
12273 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
12274
12275 return rdev_update_ft_ies(rdev, dev, &ft_params);
12276}
12277
5de17984
AS
12278static int nl80211_crit_protocol_start(struct sk_buff *skb,
12279 struct genl_info *info)
12280{
12281 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12282 struct wireless_dev *wdev = info->user_ptr[1];
12283 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
12284 u16 duration;
12285 int ret;
12286
12287 if (!rdev->ops->crit_proto_start)
12288 return -EOPNOTSUPP;
12289
12290 if (WARN_ON(!rdev->ops->crit_proto_stop))
12291 return -EINVAL;
12292
12293 if (rdev->crit_proto_nlportid)
12294 return -EBUSY;
12295
12296 /* determine protocol if provided */
12297 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
12298 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
12299
12300 if (proto >= NUM_NL80211_CRIT_PROTO)
12301 return -EINVAL;
12302
12303 /* timeout must be provided */
12304 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
12305 return -EINVAL;
12306
12307 duration =
12308 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
12309
12310 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
12311 return -ERANGE;
12312
12313 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
12314 if (!ret)
12315 rdev->crit_proto_nlportid = info->snd_portid;
12316
12317 return ret;
12318}
12319
12320static int nl80211_crit_protocol_stop(struct sk_buff *skb,
12321 struct genl_info *info)
12322{
12323 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12324 struct wireless_dev *wdev = info->user_ptr[1];
12325
12326 if (!rdev->ops->crit_proto_stop)
12327 return -EOPNOTSUPP;
12328
12329 if (rdev->crit_proto_nlportid) {
12330 rdev->crit_proto_nlportid = 0;
12331 rdev_crit_proto_stop(rdev, wdev);
12332 }
12333 return 0;
12334}
12335
ad7e718c
JB
12336static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
12337{
12338 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12339 struct wireless_dev *wdev =
12340 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
12341 int i, err;
12342 u32 vid, subcmd;
12343
12344 if (!rdev->wiphy.vendor_commands)
12345 return -EOPNOTSUPP;
12346
12347 if (IS_ERR(wdev)) {
12348 err = PTR_ERR(wdev);
12349 if (err != -EINVAL)
12350 return err;
12351 wdev = NULL;
12352 } else if (wdev->wiphy != &rdev->wiphy) {
12353 return -EINVAL;
12354 }
12355
12356 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
12357 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
12358 return -EINVAL;
12359
12360 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
12361 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
12362 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
12363 const struct wiphy_vendor_command *vcmd;
12364 void *data = NULL;
12365 int len = 0;
12366
12367 vcmd = &rdev->wiphy.vendor_commands[i];
12368
12369 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
12370 continue;
12371
12372 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
12373 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
12374 if (!wdev)
12375 return -EINVAL;
12376 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
12377 !wdev->netdev)
12378 return -EINVAL;
12379
12380 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 12381 if (!wdev_running(wdev))
ad7e718c
JB
12382 return -ENETDOWN;
12383 }
7bdbe400
JB
12384
12385 if (!vcmd->doit)
12386 return -EOPNOTSUPP;
ad7e718c
JB
12387 } else {
12388 wdev = NULL;
12389 }
12390
12391 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
12392 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
12393 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
12394 }
12395
12396 rdev->cur_cmd_info = info;
12397 err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
12398 data, len);
12399 rdev->cur_cmd_info = NULL;
12400 return err;
12401 }
12402
12403 return -EOPNOTSUPP;
12404}
12405
7bdbe400
JB
12406static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
12407 struct netlink_callback *cb,
12408 struct cfg80211_registered_device **rdev,
12409 struct wireless_dev **wdev)
12410{
c90c39da 12411 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
7bdbe400
JB
12412 u32 vid, subcmd;
12413 unsigned int i;
12414 int vcmd_idx = -1;
12415 int err;
12416 void *data = NULL;
12417 unsigned int data_len = 0;
12418
7bdbe400
JB
12419 if (cb->args[0]) {
12420 /* subtract the 1 again here */
12421 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
12422 struct wireless_dev *tmp;
12423
ea90e0dc
JB
12424 if (!wiphy)
12425 return -ENODEV;
7bdbe400
JB
12426 *rdev = wiphy_to_rdev(wiphy);
12427 *wdev = NULL;
12428
12429 if (cb->args[1]) {
53873f13 12430 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
12431 if (tmp->identifier == cb->args[1] - 1) {
12432 *wdev = tmp;
12433 break;
12434 }
12435 }
12436 }
12437
12438 /* keep rtnl locked in successful case */
12439 return 0;
12440 }
12441
fceb6435
JB
12442 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, attrbuf,
12443 nl80211_fam.maxattr, nl80211_policy, NULL);
7bdbe400 12444 if (err)
ea90e0dc 12445 return err;
7bdbe400 12446
c90c39da 12447 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
ea90e0dc
JB
12448 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD])
12449 return -EINVAL;
7bdbe400 12450
c90c39da 12451 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
7bdbe400
JB
12452 if (IS_ERR(*wdev))
12453 *wdev = NULL;
12454
c90c39da 12455 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
ea90e0dc
JB
12456 if (IS_ERR(*rdev))
12457 return PTR_ERR(*rdev);
7bdbe400 12458
c90c39da
JB
12459 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
12460 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
7bdbe400
JB
12461
12462 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
12463 const struct wiphy_vendor_command *vcmd;
12464
12465 vcmd = &(*rdev)->wiphy.vendor_commands[i];
12466
12467 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
12468 continue;
12469
ea90e0dc
JB
12470 if (!vcmd->dumpit)
12471 return -EOPNOTSUPP;
7bdbe400
JB
12472
12473 vcmd_idx = i;
12474 break;
12475 }
12476
ea90e0dc
JB
12477 if (vcmd_idx < 0)
12478 return -EOPNOTSUPP;
7bdbe400 12479
c90c39da
JB
12480 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
12481 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
12482 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
7bdbe400
JB
12483 }
12484
12485 /* 0 is the first index - add 1 to parse only once */
12486 cb->args[0] = (*rdev)->wiphy_idx + 1;
12487 /* add 1 to know if it was NULL */
12488 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
12489 cb->args[2] = vcmd_idx;
12490 cb->args[3] = (unsigned long)data;
12491 cb->args[4] = data_len;
12492
12493 /* keep rtnl locked in successful case */
12494 return 0;
7bdbe400
JB
12495}
12496
12497static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
12498 struct netlink_callback *cb)
12499{
12500 struct cfg80211_registered_device *rdev;
12501 struct wireless_dev *wdev;
12502 unsigned int vcmd_idx;
12503 const struct wiphy_vendor_command *vcmd;
12504 void *data;
12505 int data_len;
12506 int err;
12507 struct nlattr *vendor_data;
12508
ea90e0dc 12509 rtnl_lock();
7bdbe400
JB
12510 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
12511 if (err)
ea90e0dc 12512 goto out;
7bdbe400
JB
12513
12514 vcmd_idx = cb->args[2];
12515 data = (void *)cb->args[3];
12516 data_len = cb->args[4];
12517 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
12518
12519 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
12520 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
ea90e0dc
JB
12521 if (!wdev) {
12522 err = -EINVAL;
12523 goto out;
12524 }
7bdbe400 12525 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
ea90e0dc
JB
12526 !wdev->netdev) {
12527 err = -EINVAL;
12528 goto out;
12529 }
7bdbe400
JB
12530
12531 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
ea90e0dc
JB
12532 if (!wdev_running(wdev)) {
12533 err = -ENETDOWN;
12534 goto out;
12535 }
7bdbe400
JB
12536 }
12537 }
12538
12539 while (1) {
12540 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
12541 cb->nlh->nlmsg_seq, NLM_F_MULTI,
12542 NL80211_CMD_VENDOR);
12543 if (!hdr)
12544 break;
12545
12546 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
12547 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
12548 wdev_id(wdev),
12549 NL80211_ATTR_PAD))) {
7bdbe400
JB
12550 genlmsg_cancel(skb, hdr);
12551 break;
12552 }
12553
12554 vendor_data = nla_nest_start(skb, NL80211_ATTR_VENDOR_DATA);
12555 if (!vendor_data) {
12556 genlmsg_cancel(skb, hdr);
12557 break;
12558 }
12559
12560 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
12561 (unsigned long *)&cb->args[5]);
12562 nla_nest_end(skb, vendor_data);
12563
12564 if (err == -ENOBUFS || err == -ENOENT) {
12565 genlmsg_cancel(skb, hdr);
12566 break;
12567 } else if (err) {
12568 genlmsg_cancel(skb, hdr);
12569 goto out;
12570 }
12571
12572 genlmsg_end(skb, hdr);
12573 }
12574
12575 err = skb->len;
12576 out:
12577 rtnl_unlock();
12578 return err;
12579}
12580
ad7e718c
JB
12581struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
12582 enum nl80211_commands cmd,
12583 enum nl80211_attrs attr,
12584 int approxlen)
12585{
f26cbf40 12586 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
12587
12588 if (WARN_ON(!rdev->cur_cmd_info))
12589 return NULL;
12590
6c09e791 12591 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
12592 rdev->cur_cmd_info->snd_portid,
12593 rdev->cur_cmd_info->snd_seq,
567ffc35 12594 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
12595}
12596EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
12597
12598int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
12599{
12600 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
12601 void *hdr = ((void **)skb->cb)[1];
12602 struct nlattr *data = ((void **)skb->cb)[2];
12603
bd8c78e7
JB
12604 /* clear CB data for netlink core to own from now on */
12605 memset(skb->cb, 0, sizeof(skb->cb));
12606
ad7e718c
JB
12607 if (WARN_ON(!rdev->cur_cmd_info)) {
12608 kfree_skb(skb);
12609 return -EINVAL;
12610 }
12611
12612 nla_nest_end(skb, data);
12613 genlmsg_end(skb, hdr);
12614 return genlmsg_reply(skb, rdev->cur_cmd_info);
12615}
12616EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
12617
fa9ffc74
KP
12618static int nl80211_set_qos_map(struct sk_buff *skb,
12619 struct genl_info *info)
12620{
12621 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12622 struct cfg80211_qos_map *qos_map = NULL;
12623 struct net_device *dev = info->user_ptr[1];
12624 u8 *pos, len, num_des, des_len, des;
12625 int ret;
12626
12627 if (!rdev->ops->set_qos_map)
12628 return -EOPNOTSUPP;
12629
12630 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
12631 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
12632 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
12633
12634 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
12635 len > IEEE80211_QOS_MAP_LEN_MAX)
12636 return -EINVAL;
12637
12638 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
12639 if (!qos_map)
12640 return -ENOMEM;
12641
12642 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
12643 if (num_des) {
12644 des_len = num_des *
12645 sizeof(struct cfg80211_dscp_exception);
12646 memcpy(qos_map->dscp_exception, pos, des_len);
12647 qos_map->num_des = num_des;
12648 for (des = 0; des < num_des; des++) {
12649 if (qos_map->dscp_exception[des].up > 7) {
12650 kfree(qos_map);
12651 return -EINVAL;
12652 }
12653 }
12654 pos += des_len;
12655 }
12656 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
12657 }
12658
12659 wdev_lock(dev->ieee80211_ptr);
12660 ret = nl80211_key_allowed(dev->ieee80211_ptr);
12661 if (!ret)
12662 ret = rdev_set_qos_map(rdev, dev, qos_map);
12663 wdev_unlock(dev->ieee80211_ptr);
12664
12665 kfree(qos_map);
12666 return ret;
12667}
12668
960d01ac
JB
12669static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
12670{
12671 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12672 struct net_device *dev = info->user_ptr[1];
12673 struct wireless_dev *wdev = dev->ieee80211_ptr;
12674 const u8 *peer;
12675 u8 tsid, up;
12676 u16 admitted_time = 0;
12677 int err;
12678
723e73ac 12679 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
12680 return -EOPNOTSUPP;
12681
12682 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
12683 !info->attrs[NL80211_ATTR_USER_PRIO])
12684 return -EINVAL;
12685
12686 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
12687 if (tsid >= IEEE80211_NUM_TIDS)
12688 return -EINVAL;
12689
12690 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
12691 if (up >= IEEE80211_NUM_UPS)
12692 return -EINVAL;
12693
12694 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 12695 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 12696 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
12697 * need more attributes for that (e.g. BA session requirement);
12698 * change the WMM adminssion test above to allow both then
960d01ac
JB
12699 */
12700 return -EINVAL;
12701 }
12702
12703 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
12704
12705 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
12706 admitted_time =
12707 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
12708 if (!admitted_time)
12709 return -EINVAL;
12710 }
12711
12712 wdev_lock(wdev);
12713 switch (wdev->iftype) {
12714 case NL80211_IFTYPE_STATION:
12715 case NL80211_IFTYPE_P2P_CLIENT:
12716 if (wdev->current_bss)
12717 break;
12718 err = -ENOTCONN;
12719 goto out;
12720 default:
12721 err = -EOPNOTSUPP;
12722 goto out;
12723 }
12724
12725 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
12726
12727 out:
12728 wdev_unlock(wdev);
12729 return err;
12730}
12731
12732static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
12733{
12734 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12735 struct net_device *dev = info->user_ptr[1];
12736 struct wireless_dev *wdev = dev->ieee80211_ptr;
12737 const u8 *peer;
12738 u8 tsid;
12739 int err;
12740
12741 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
12742 return -EINVAL;
12743
12744 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
12745 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
12746
12747 wdev_lock(wdev);
12748 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
12749 wdev_unlock(wdev);
12750
12751 return err;
12752}
12753
1057d35e
AN
12754static int nl80211_tdls_channel_switch(struct sk_buff *skb,
12755 struct genl_info *info)
12756{
12757 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12758 struct net_device *dev = info->user_ptr[1];
12759 struct wireless_dev *wdev = dev->ieee80211_ptr;
12760 struct cfg80211_chan_def chandef = {};
12761 const u8 *addr;
12762 u8 oper_class;
12763 int err;
12764
12765 if (!rdev->ops->tdls_channel_switch ||
12766 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
12767 return -EOPNOTSUPP;
12768
12769 switch (dev->ieee80211_ptr->iftype) {
12770 case NL80211_IFTYPE_STATION:
12771 case NL80211_IFTYPE_P2P_CLIENT:
12772 break;
12773 default:
12774 return -EOPNOTSUPP;
12775 }
12776
12777 if (!info->attrs[NL80211_ATTR_MAC] ||
12778 !info->attrs[NL80211_ATTR_OPER_CLASS])
12779 return -EINVAL;
12780
12781 err = nl80211_parse_chandef(rdev, info, &chandef);
12782 if (err)
12783 return err;
12784
12785 /*
12786 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
12787 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
12788 * specification is not defined for them.
12789 */
57fbcce3 12790 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
12791 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
12792 chandef.width != NL80211_CHAN_WIDTH_20)
12793 return -EINVAL;
12794
12795 /* we will be active on the TDLS link */
923b352f
AN
12796 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
12797 wdev->iftype))
1057d35e
AN
12798 return -EINVAL;
12799
12800 /* don't allow switching to DFS channels */
12801 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
12802 return -EINVAL;
12803
12804 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
12805 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
12806
12807 wdev_lock(wdev);
12808 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
12809 wdev_unlock(wdev);
12810
12811 return err;
12812}
12813
12814static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
12815 struct genl_info *info)
12816{
12817 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12818 struct net_device *dev = info->user_ptr[1];
12819 struct wireless_dev *wdev = dev->ieee80211_ptr;
12820 const u8 *addr;
12821
12822 if (!rdev->ops->tdls_channel_switch ||
12823 !rdev->ops->tdls_cancel_channel_switch ||
12824 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
12825 return -EOPNOTSUPP;
12826
12827 switch (dev->ieee80211_ptr->iftype) {
12828 case NL80211_IFTYPE_STATION:
12829 case NL80211_IFTYPE_P2P_CLIENT:
12830 break;
12831 default:
12832 return -EOPNOTSUPP;
12833 }
12834
12835 if (!info->attrs[NL80211_ATTR_MAC])
12836 return -EINVAL;
12837
12838 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
12839
12840 wdev_lock(wdev);
12841 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
12842 wdev_unlock(wdev);
12843
12844 return 0;
12845}
12846
ce0ce13a
MB
12847static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
12848 struct genl_info *info)
12849{
12850 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12851 struct net_device *dev = info->user_ptr[1];
12852 struct wireless_dev *wdev = dev->ieee80211_ptr;
12853 const struct nlattr *nla;
12854 bool enabled;
12855
ce0ce13a
MB
12856 if (!rdev->ops->set_multicast_to_unicast)
12857 return -EOPNOTSUPP;
12858
12859 if (wdev->iftype != NL80211_IFTYPE_AP &&
12860 wdev->iftype != NL80211_IFTYPE_P2P_GO)
12861 return -EOPNOTSUPP;
12862
12863 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
12864 enabled = nla_get_flag(nla);
12865
12866 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
12867}
12868
3a00df57
AS
12869static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
12870{
12871 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12872 struct net_device *dev = info->user_ptr[1];
12873 struct wireless_dev *wdev = dev->ieee80211_ptr;
12874 struct cfg80211_pmk_conf pmk_conf = {};
12875 int ret;
12876
12877 if (wdev->iftype != NL80211_IFTYPE_STATION &&
12878 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
12879 return -EOPNOTSUPP;
12880
12881 if (!wiphy_ext_feature_isset(&rdev->wiphy,
12882 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
12883 return -EOPNOTSUPP;
12884
12885 if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
12886 return -EINVAL;
12887
12888 wdev_lock(wdev);
12889 if (!wdev->current_bss) {
12890 ret = -ENOTCONN;
12891 goto out;
12892 }
12893
12894 pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
12895 if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
12896 ret = -EINVAL;
12897 goto out;
12898 }
12899
12900 pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
12901 pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
12902 if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
12903 pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
12904 ret = -EINVAL;
12905 goto out;
12906 }
12907
12908 if (info->attrs[NL80211_ATTR_PMKR0_NAME]) {
12909 int r0_name_len = nla_len(info->attrs[NL80211_ATTR_PMKR0_NAME]);
12910
12911 if (r0_name_len != WLAN_PMK_NAME_LEN) {
12912 ret = -EINVAL;
12913 goto out;
12914 }
12915
12916 pmk_conf.pmk_r0_name =
12917 nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
12918 }
12919
12920 ret = rdev_set_pmk(rdev, dev, &pmk_conf);
12921out:
12922 wdev_unlock(wdev);
12923 return ret;
12924}
12925
12926static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
12927{
12928 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12929 struct net_device *dev = info->user_ptr[1];
12930 struct wireless_dev *wdev = dev->ieee80211_ptr;
12931 const u8 *aa;
12932 int ret;
12933
12934 if (wdev->iftype != NL80211_IFTYPE_STATION &&
12935 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
12936 return -EOPNOTSUPP;
12937
12938 if (!wiphy_ext_feature_isset(&rdev->wiphy,
12939 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
12940 return -EOPNOTSUPP;
12941
12942 if (!info->attrs[NL80211_ATTR_MAC])
12943 return -EINVAL;
12944
12945 wdev_lock(wdev);
12946 aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
12947 ret = rdev_del_pmk(rdev, dev, aa);
12948 wdev_unlock(wdev);
12949
12950 return ret;
12951}
12952
40cbfa90
SD
12953static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
12954{
12955 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12956 struct net_device *dev = info->user_ptr[1];
12957 struct cfg80211_external_auth_params params;
12958
db8d93a7 12959 if (!rdev->ops->external_auth)
40cbfa90
SD
12960 return -EOPNOTSUPP;
12961
12962 if (!info->attrs[NL80211_ATTR_SSID])
12963 return -EINVAL;
12964
12965 if (!info->attrs[NL80211_ATTR_BSSID])
12966 return -EINVAL;
12967
12968 if (!info->attrs[NL80211_ATTR_STATUS_CODE])
12969 return -EINVAL;
12970
12971 memset(&params, 0, sizeof(params));
12972
12973 params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
12974 if (params.ssid.ssid_len == 0 ||
12975 params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
12976 return -EINVAL;
12977 memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
12978 params.ssid.ssid_len);
12979
12980 memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
12981 ETH_ALEN);
12982
12983 params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
12984
12985 return rdev_external_auth(rdev, dev, &params);
12986}
12987
2576a9ac
DK
12988static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
12989{
12990 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12991 struct net_device *dev = info->user_ptr[1];
12992 struct wireless_dev *wdev = dev->ieee80211_ptr;
12993 const u8 *buf;
12994 size_t len;
12995 u8 *dest;
12996 u16 proto;
12997 bool noencrypt;
12998 int err;
12999
13000 if (!wiphy_ext_feature_isset(&rdev->wiphy,
13001 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
13002 return -EOPNOTSUPP;
13003
13004 if (!rdev->ops->tx_control_port)
13005 return -EOPNOTSUPP;
13006
13007 if (!info->attrs[NL80211_ATTR_FRAME] ||
13008 !info->attrs[NL80211_ATTR_MAC] ||
13009 !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
13010 GENL_SET_ERR_MSG(info, "Frame, MAC or ethertype missing");
13011 return -EINVAL;
13012 }
13013
13014 wdev_lock(wdev);
13015
13016 switch (wdev->iftype) {
13017 case NL80211_IFTYPE_AP:
13018 case NL80211_IFTYPE_P2P_GO:
13019 case NL80211_IFTYPE_MESH_POINT:
13020 break;
13021 case NL80211_IFTYPE_ADHOC:
13022 case NL80211_IFTYPE_STATION:
13023 case NL80211_IFTYPE_P2P_CLIENT:
13024 if (wdev->current_bss)
13025 break;
13026 err = -ENOTCONN;
13027 goto out;
13028 default:
13029 err = -EOPNOTSUPP;
13030 goto out;
13031 }
13032
13033 wdev_unlock(wdev);
13034
13035 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
13036 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
13037 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
13038 proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
13039 noencrypt =
13040 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
13041
13042 return rdev_tx_control_port(rdev, dev, buf, len,
13043 dest, cpu_to_be16(proto), noencrypt);
13044
13045 out:
13046 wdev_unlock(wdev);
13047 return err;
13048}
13049
81e54d08
PKC
13050static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
13051 struct genl_info *info)
13052{
13053 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13054 struct net_device *dev = info->user_ptr[1];
13055 struct wireless_dev *wdev = dev->ieee80211_ptr;
13056 struct cfg80211_ftm_responder_stats ftm_stats = {};
13057 struct sk_buff *msg;
13058 void *hdr;
13059 struct nlattr *ftm_stats_attr;
13060 int err;
13061
13062 if (wdev->iftype != NL80211_IFTYPE_AP || !wdev->beacon_interval)
13063 return -EOPNOTSUPP;
13064
13065 err = rdev_get_ftm_responder_stats(rdev, dev, &ftm_stats);
13066 if (err)
13067 return err;
13068
13069 if (!ftm_stats.filled)
13070 return -ENODATA;
13071
13072 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13073 if (!msg)
13074 return -ENOMEM;
13075
13076 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13077 NL80211_CMD_GET_FTM_RESPONDER_STATS);
13078 if (!hdr)
13079 return -ENOBUFS;
13080
13081 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
13082 goto nla_put_failure;
13083
13084 ftm_stats_attr = nla_nest_start(msg, NL80211_ATTR_FTM_RESPONDER_STATS);
13085 if (!ftm_stats_attr)
13086 goto nla_put_failure;
13087
13088#define SET_FTM(field, name, type) \
13089 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
13090 nla_put_ ## type(msg, NL80211_FTM_STATS_ ## name, \
13091 ftm_stats.field)) \
13092 goto nla_put_failure; } while (0)
13093#define SET_FTM_U64(field, name) \
13094 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
13095 nla_put_u64_64bit(msg, NL80211_FTM_STATS_ ## name, \
13096 ftm_stats.field, NL80211_FTM_STATS_PAD)) \
13097 goto nla_put_failure; } while (0)
13098
13099 SET_FTM(success_num, SUCCESS_NUM, u32);
13100 SET_FTM(partial_num, PARTIAL_NUM, u32);
13101 SET_FTM(failed_num, FAILED_NUM, u32);
13102 SET_FTM(asap_num, ASAP_NUM, u32);
13103 SET_FTM(non_asap_num, NON_ASAP_NUM, u32);
13104 SET_FTM_U64(total_duration_ms, TOTAL_DURATION_MSEC);
13105 SET_FTM(unknown_triggers_num, UNKNOWN_TRIGGERS_NUM, u32);
13106 SET_FTM(reschedule_requests_num, RESCHEDULE_REQUESTS_NUM, u32);
13107 SET_FTM(out_of_window_triggers_num, OUT_OF_WINDOW_TRIGGERS_NUM, u32);
13108#undef SET_FTM
13109
13110 nla_nest_end(msg, ftm_stats_attr);
13111
13112 genlmsg_end(msg, hdr);
13113 return genlmsg_reply(msg, info);
13114
13115nla_put_failure:
13116 nlmsg_free(msg);
13117 return -ENOBUFS;
13118}
13119
4c476991
JB
13120#define NL80211_FLAG_NEED_WIPHY 0x01
13121#define NL80211_FLAG_NEED_NETDEV 0x02
13122#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
13123#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
13124#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
13125 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 13126#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 13127/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
13128#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
13129 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 13130#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 13131
f84f771d 13132static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
13133 struct genl_info *info)
13134{
13135 struct cfg80211_registered_device *rdev;
89a54e48 13136 struct wireless_dev *wdev;
4c476991 13137 struct net_device *dev;
4c476991
JB
13138 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
13139
13140 if (rtnl)
13141 rtnl_lock();
13142
13143 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 13144 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
13145 if (IS_ERR(rdev)) {
13146 if (rtnl)
13147 rtnl_unlock();
13148 return PTR_ERR(rdev);
13149 }
13150 info->user_ptr[0] = rdev;
1bf614ef
JB
13151 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
13152 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
13153 ASSERT_RTNL();
13154
89a54e48
JB
13155 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
13156 info->attrs);
13157 if (IS_ERR(wdev)) {
4c476991
JB
13158 if (rtnl)
13159 rtnl_unlock();
89a54e48 13160 return PTR_ERR(wdev);
4c476991 13161 }
89a54e48 13162
89a54e48 13163 dev = wdev->netdev;
f26cbf40 13164 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 13165
1bf614ef
JB
13166 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
13167 if (!dev) {
1bf614ef
JB
13168 if (rtnl)
13169 rtnl_unlock();
13170 return -EINVAL;
13171 }
13172
13173 info->user_ptr[1] = dev;
13174 } else {
13175 info->user_ptr[1] = wdev;
41265714 13176 }
1bf614ef 13177
73c7da3d
AVS
13178 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
13179 !wdev_running(wdev)) {
13180 if (rtnl)
13181 rtnl_unlock();
13182 return -ENETDOWN;
13183 }
1bf614ef 13184
73c7da3d 13185 if (dev)
1bf614ef 13186 dev_hold(dev);
89a54e48 13187
4c476991 13188 info->user_ptr[0] = rdev;
4c476991
JB
13189 }
13190
13191 return 0;
13192}
13193
f84f771d 13194static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
13195 struct genl_info *info)
13196{
1bf614ef
JB
13197 if (info->user_ptr[1]) {
13198 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
13199 struct wireless_dev *wdev = info->user_ptr[1];
13200
13201 if (wdev->netdev)
13202 dev_put(wdev->netdev);
13203 } else {
13204 dev_put(info->user_ptr[1]);
13205 }
13206 }
5393b917 13207
4c476991
JB
13208 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
13209 rtnl_unlock();
5393b917
JB
13210
13211 /* If needed, clear the netlink message payload from the SKB
13212 * as it might contain key data that shouldn't stick around on
13213 * the heap after the SKB is freed. The netlink message header
13214 * is still needed for further processing, so leave it intact.
13215 */
13216 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
13217 struct nlmsghdr *nlh = nlmsg_hdr(skb);
13218
13219 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
13220 }
4c476991
JB
13221}
13222
4534de83 13223static const struct genl_ops nl80211_ops[] = {
55682965
JB
13224 {
13225 .cmd = NL80211_CMD_GET_WIPHY,
13226 .doit = nl80211_get_wiphy,
13227 .dumpit = nl80211_dump_wiphy,
86e8cf98 13228 .done = nl80211_dump_wiphy_done,
55682965
JB
13229 .policy = nl80211_policy,
13230 /* can be retrieved by unprivileged users */
5fe231e8
JB
13231 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13232 NL80211_FLAG_NEED_RTNL,
55682965
JB
13233 },
13234 {
13235 .cmd = NL80211_CMD_SET_WIPHY,
13236 .doit = nl80211_set_wiphy,
13237 .policy = nl80211_policy,
5617c6cd 13238 .flags = GENL_UNS_ADMIN_PERM,
4c476991 13239 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
13240 },
13241 {
13242 .cmd = NL80211_CMD_GET_INTERFACE,
13243 .doit = nl80211_get_interface,
13244 .dumpit = nl80211_dump_interface,
13245 .policy = nl80211_policy,
13246 /* can be retrieved by unprivileged users */
5fe231e8
JB
13247 .internal_flags = NL80211_FLAG_NEED_WDEV |
13248 NL80211_FLAG_NEED_RTNL,
55682965
JB
13249 },
13250 {
13251 .cmd = NL80211_CMD_SET_INTERFACE,
13252 .doit = nl80211_set_interface,
13253 .policy = nl80211_policy,
5617c6cd 13254 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13255 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13256 NL80211_FLAG_NEED_RTNL,
55682965
JB
13257 },
13258 {
13259 .cmd = NL80211_CMD_NEW_INTERFACE,
13260 .doit = nl80211_new_interface,
13261 .policy = nl80211_policy,
5617c6cd 13262 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13263 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13264 NL80211_FLAG_NEED_RTNL,
55682965
JB
13265 },
13266 {
13267 .cmd = NL80211_CMD_DEL_INTERFACE,
13268 .doit = nl80211_del_interface,
13269 .policy = nl80211_policy,
5617c6cd 13270 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 13271 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 13272 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
13273 },
13274 {
13275 .cmd = NL80211_CMD_GET_KEY,
13276 .doit = nl80211_get_key,
13277 .policy = nl80211_policy,
5617c6cd 13278 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13279 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13280 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
13281 },
13282 {
13283 .cmd = NL80211_CMD_SET_KEY,
13284 .doit = nl80211_set_key,
13285 .policy = nl80211_policy,
5617c6cd 13286 .flags = GENL_UNS_ADMIN_PERM,
41265714 13287 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
13288 NL80211_FLAG_NEED_RTNL |
13289 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
13290 },
13291 {
13292 .cmd = NL80211_CMD_NEW_KEY,
13293 .doit = nl80211_new_key,
13294 .policy = nl80211_policy,
5617c6cd 13295 .flags = GENL_UNS_ADMIN_PERM,
41265714 13296 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
13297 NL80211_FLAG_NEED_RTNL |
13298 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
13299 },
13300 {
13301 .cmd = NL80211_CMD_DEL_KEY,
13302 .doit = nl80211_del_key,
13303 .policy = nl80211_policy,
5617c6cd 13304 .flags = GENL_UNS_ADMIN_PERM,
41265714 13305 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13306 NL80211_FLAG_NEED_RTNL,
55682965 13307 },
ed1b6cc7
JB
13308 {
13309 .cmd = NL80211_CMD_SET_BEACON,
13310 .policy = nl80211_policy,
5617c6cd 13311 .flags = GENL_UNS_ADMIN_PERM,
8860020e 13312 .doit = nl80211_set_beacon,
2b5f8b0b 13313 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13314 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
13315 },
13316 {
8860020e 13317 .cmd = NL80211_CMD_START_AP,
ed1b6cc7 13318 .policy = nl80211_policy,
5617c6cd 13319 .flags = GENL_UNS_ADMIN_PERM,
8860020e 13320 .doit = nl80211_start_ap,
2b5f8b0b 13321 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13322 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
13323 },
13324 {
8860020e 13325 .cmd = NL80211_CMD_STOP_AP,
ed1b6cc7 13326 .policy = nl80211_policy,
5617c6cd 13327 .flags = GENL_UNS_ADMIN_PERM,
8860020e 13328 .doit = nl80211_stop_ap,
2b5f8b0b 13329 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13330 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 13331 },
5727ef1b
JB
13332 {
13333 .cmd = NL80211_CMD_GET_STATION,
13334 .doit = nl80211_get_station,
2ec600d6 13335 .dumpit = nl80211_dump_station,
5727ef1b 13336 .policy = nl80211_policy,
4c476991
JB
13337 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13338 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
13339 },
13340 {
13341 .cmd = NL80211_CMD_SET_STATION,
13342 .doit = nl80211_set_station,
13343 .policy = nl80211_policy,
5617c6cd 13344 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13345 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13346 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
13347 },
13348 {
13349 .cmd = NL80211_CMD_NEW_STATION,
13350 .doit = nl80211_new_station,
13351 .policy = nl80211_policy,
5617c6cd 13352 .flags = GENL_UNS_ADMIN_PERM,
41265714 13353 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13354 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
13355 },
13356 {
13357 .cmd = NL80211_CMD_DEL_STATION,
13358 .doit = nl80211_del_station,
13359 .policy = nl80211_policy,
5617c6cd 13360 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13361 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13362 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
13363 },
13364 {
13365 .cmd = NL80211_CMD_GET_MPATH,
13366 .doit = nl80211_get_mpath,
13367 .dumpit = nl80211_dump_mpath,
13368 .policy = nl80211_policy,
5617c6cd 13369 .flags = GENL_UNS_ADMIN_PERM,
41265714 13370 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13371 NL80211_FLAG_NEED_RTNL,
2ec600d6 13372 },
66be7d2b
HR
13373 {
13374 .cmd = NL80211_CMD_GET_MPP,
13375 .doit = nl80211_get_mpp,
13376 .dumpit = nl80211_dump_mpp,
13377 .policy = nl80211_policy,
5617c6cd 13378 .flags = GENL_UNS_ADMIN_PERM,
66be7d2b
HR
13379 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13380 NL80211_FLAG_NEED_RTNL,
13381 },
2ec600d6
LCC
13382 {
13383 .cmd = NL80211_CMD_SET_MPATH,
13384 .doit = nl80211_set_mpath,
13385 .policy = nl80211_policy,
5617c6cd 13386 .flags = GENL_UNS_ADMIN_PERM,
41265714 13387 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13388 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
13389 },
13390 {
13391 .cmd = NL80211_CMD_NEW_MPATH,
13392 .doit = nl80211_new_mpath,
13393 .policy = nl80211_policy,
5617c6cd 13394 .flags = GENL_UNS_ADMIN_PERM,
41265714 13395 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13396 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
13397 },
13398 {
13399 .cmd = NL80211_CMD_DEL_MPATH,
13400 .doit = nl80211_del_mpath,
13401 .policy = nl80211_policy,
5617c6cd 13402 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13403 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13404 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
13405 },
13406 {
13407 .cmd = NL80211_CMD_SET_BSS,
13408 .doit = nl80211_set_bss,
13409 .policy = nl80211_policy,
5617c6cd 13410 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13411 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13412 NL80211_FLAG_NEED_RTNL,
b2e1b302 13413 },
f130347c
LR
13414 {
13415 .cmd = NL80211_CMD_GET_REG,
ad30ca2c
AN
13416 .doit = nl80211_get_reg_do,
13417 .dumpit = nl80211_get_reg_dump,
f130347c 13418 .policy = nl80211_policy,
5fe231e8 13419 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
13420 /* can be retrieved by unprivileged users */
13421 },
b6863036 13422#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
13423 {
13424 .cmd = NL80211_CMD_SET_REG,
13425 .doit = nl80211_set_reg,
13426 .policy = nl80211_policy,
13427 .flags = GENL_ADMIN_PERM,
5fe231e8 13428 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302 13429 },
b6863036 13430#endif
b2e1b302
LR
13431 {
13432 .cmd = NL80211_CMD_REQ_SET_REG,
13433 .doit = nl80211_req_set_reg,
13434 .policy = nl80211_policy,
93da9cc1 13435 .flags = GENL_ADMIN_PERM,
13436 },
1ea4ff3e
JB
13437 {
13438 .cmd = NL80211_CMD_RELOAD_REGDB,
13439 .doit = nl80211_reload_regdb,
13440 .policy = nl80211_policy,
13441 .flags = GENL_ADMIN_PERM,
13442 },
93da9cc1 13443 {
24bdd9f4
JC
13444 .cmd = NL80211_CMD_GET_MESH_CONFIG,
13445 .doit = nl80211_get_mesh_config,
93da9cc1 13446 .policy = nl80211_policy,
13447 /* can be retrieved by unprivileged users */
2b5f8b0b 13448 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13449 NL80211_FLAG_NEED_RTNL,
93da9cc1 13450 },
13451 {
24bdd9f4
JC
13452 .cmd = NL80211_CMD_SET_MESH_CONFIG,
13453 .doit = nl80211_update_mesh_config,
93da9cc1 13454 .policy = nl80211_policy,
5617c6cd 13455 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c 13456 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13457 NL80211_FLAG_NEED_RTNL,
9aed3cc1 13458 },
2a519311
JB
13459 {
13460 .cmd = NL80211_CMD_TRIGGER_SCAN,
13461 .doit = nl80211_trigger_scan,
13462 .policy = nl80211_policy,
5617c6cd 13463 .flags = GENL_UNS_ADMIN_PERM,
fd014284 13464 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 13465 NL80211_FLAG_NEED_RTNL,
2a519311 13466 },
91d3ab46
VK
13467 {
13468 .cmd = NL80211_CMD_ABORT_SCAN,
13469 .doit = nl80211_abort_scan,
13470 .policy = nl80211_policy,
5617c6cd 13471 .flags = GENL_UNS_ADMIN_PERM,
91d3ab46
VK
13472 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13473 NL80211_FLAG_NEED_RTNL,
13474 },
2a519311
JB
13475 {
13476 .cmd = NL80211_CMD_GET_SCAN,
13477 .policy = nl80211_policy,
13478 .dumpit = nl80211_dump_scan,
13479 },
807f8a8c
LC
13480 {
13481 .cmd = NL80211_CMD_START_SCHED_SCAN,
13482 .doit = nl80211_start_sched_scan,
13483 .policy = nl80211_policy,
5617c6cd 13484 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
13485 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13486 NL80211_FLAG_NEED_RTNL,
13487 },
13488 {
13489 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
13490 .doit = nl80211_stop_sched_scan,
13491 .policy = nl80211_policy,
5617c6cd 13492 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
13493 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13494 NL80211_FLAG_NEED_RTNL,
13495 },
636a5d36
JM
13496 {
13497 .cmd = NL80211_CMD_AUTHENTICATE,
13498 .doit = nl80211_authenticate,
13499 .policy = nl80211_policy,
5617c6cd 13500 .flags = GENL_UNS_ADMIN_PERM,
41265714 13501 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
13502 NL80211_FLAG_NEED_RTNL |
13503 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
13504 },
13505 {
13506 .cmd = NL80211_CMD_ASSOCIATE,
13507 .doit = nl80211_associate,
13508 .policy = nl80211_policy,
5617c6cd 13509 .flags = GENL_UNS_ADMIN_PERM,
41265714 13510 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13511 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
13512 },
13513 {
13514 .cmd = NL80211_CMD_DEAUTHENTICATE,
13515 .doit = nl80211_deauthenticate,
13516 .policy = nl80211_policy,
5617c6cd 13517 .flags = GENL_UNS_ADMIN_PERM,
41265714 13518 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13519 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
13520 },
13521 {
13522 .cmd = NL80211_CMD_DISASSOCIATE,
13523 .doit = nl80211_disassociate,
13524 .policy = nl80211_policy,
5617c6cd 13525 .flags = GENL_UNS_ADMIN_PERM,
41265714 13526 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13527 NL80211_FLAG_NEED_RTNL,
636a5d36 13528 },
04a773ad
JB
13529 {
13530 .cmd = NL80211_CMD_JOIN_IBSS,
13531 .doit = nl80211_join_ibss,
13532 .policy = nl80211_policy,
5617c6cd 13533 .flags = GENL_UNS_ADMIN_PERM,
41265714 13534 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13535 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
13536 },
13537 {
13538 .cmd = NL80211_CMD_LEAVE_IBSS,
13539 .doit = nl80211_leave_ibss,
13540 .policy = nl80211_policy,
5617c6cd 13541 .flags = GENL_UNS_ADMIN_PERM,
41265714 13542 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13543 NL80211_FLAG_NEED_RTNL,
04a773ad 13544 },
aff89a9b
JB
13545#ifdef CONFIG_NL80211_TESTMODE
13546 {
13547 .cmd = NL80211_CMD_TESTMODE,
13548 .doit = nl80211_testmode_do,
71063f0e 13549 .dumpit = nl80211_testmode_dump,
aff89a9b 13550 .policy = nl80211_policy,
5617c6cd 13551 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13552 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13553 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
13554 },
13555#endif
b23aa676
SO
13556 {
13557 .cmd = NL80211_CMD_CONNECT,
13558 .doit = nl80211_connect,
13559 .policy = nl80211_policy,
5617c6cd 13560 .flags = GENL_UNS_ADMIN_PERM,
41265714 13561 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13562 NL80211_FLAG_NEED_RTNL,
b23aa676 13563 },
088e8df8 13564 {
13565 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
13566 .doit = nl80211_update_connect_params,
13567 .policy = nl80211_policy,
13568 .flags = GENL_ADMIN_PERM,
13569 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13570 NL80211_FLAG_NEED_RTNL,
13571 },
b23aa676
SO
13572 {
13573 .cmd = NL80211_CMD_DISCONNECT,
13574 .doit = nl80211_disconnect,
13575 .policy = nl80211_policy,
5617c6cd 13576 .flags = GENL_UNS_ADMIN_PERM,
41265714 13577 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13578 NL80211_FLAG_NEED_RTNL,
b23aa676 13579 },
463d0183
JB
13580 {
13581 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
13582 .doit = nl80211_wiphy_netns,
13583 .policy = nl80211_policy,
5617c6cd 13584 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13585 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13586 NL80211_FLAG_NEED_RTNL,
463d0183 13587 },
61fa713c
HS
13588 {
13589 .cmd = NL80211_CMD_GET_SURVEY,
13590 .policy = nl80211_policy,
13591 .dumpit = nl80211_dump_survey,
13592 },
67fbb16b
SO
13593 {
13594 .cmd = NL80211_CMD_SET_PMKSA,
13595 .doit = nl80211_setdel_pmksa,
13596 .policy = nl80211_policy,
5617c6cd 13597 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13598 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13599 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
13600 },
13601 {
13602 .cmd = NL80211_CMD_DEL_PMKSA,
13603 .doit = nl80211_setdel_pmksa,
13604 .policy = nl80211_policy,
5617c6cd 13605 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13606 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13607 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
13608 },
13609 {
13610 .cmd = NL80211_CMD_FLUSH_PMKSA,
13611 .doit = nl80211_flush_pmksa,
13612 .policy = nl80211_policy,
5617c6cd 13613 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13614 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13615 NL80211_FLAG_NEED_RTNL,
67fbb16b 13616 },
9588bbd5
JM
13617 {
13618 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
13619 .doit = nl80211_remain_on_channel,
13620 .policy = nl80211_policy,
5617c6cd 13621 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 13622 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 13623 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
13624 },
13625 {
13626 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
13627 .doit = nl80211_cancel_remain_on_channel,
13628 .policy = nl80211_policy,
5617c6cd 13629 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 13630 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 13631 NL80211_FLAG_NEED_RTNL,
9588bbd5 13632 },
13ae75b1
JM
13633 {
13634 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
13635 .doit = nl80211_set_tx_bitrate_mask,
13636 .policy = nl80211_policy,
5617c6cd 13637 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13638 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13639 NL80211_FLAG_NEED_RTNL,
13ae75b1 13640 },
026331c4 13641 {
2e161f78
JB
13642 .cmd = NL80211_CMD_REGISTER_FRAME,
13643 .doit = nl80211_register_mgmt,
026331c4 13644 .policy = nl80211_policy,
5617c6cd 13645 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 13646 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 13647 NL80211_FLAG_NEED_RTNL,
026331c4
JM
13648 },
13649 {
2e161f78
JB
13650 .cmd = NL80211_CMD_FRAME,
13651 .doit = nl80211_tx_mgmt,
026331c4 13652 .policy = nl80211_policy,
5617c6cd 13653 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 13654 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
13655 NL80211_FLAG_NEED_RTNL,
13656 },
13657 {
13658 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
13659 .doit = nl80211_tx_mgmt_cancel_wait,
13660 .policy = nl80211_policy,
5617c6cd 13661 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 13662 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 13663 NL80211_FLAG_NEED_RTNL,
026331c4 13664 },
ffb9eb3d
KV
13665 {
13666 .cmd = NL80211_CMD_SET_POWER_SAVE,
13667 .doit = nl80211_set_power_save,
13668 .policy = nl80211_policy,
5617c6cd 13669 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13670 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13671 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
13672 },
13673 {
13674 .cmd = NL80211_CMD_GET_POWER_SAVE,
13675 .doit = nl80211_get_power_save,
13676 .policy = nl80211_policy,
13677 /* can be retrieved by unprivileged users */
4c476991
JB
13678 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13679 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 13680 },
d6dc1a38
JO
13681 {
13682 .cmd = NL80211_CMD_SET_CQM,
13683 .doit = nl80211_set_cqm,
13684 .policy = nl80211_policy,
5617c6cd 13685 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13686 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13687 NL80211_FLAG_NEED_RTNL,
d6dc1a38 13688 },
f444de05
JB
13689 {
13690 .cmd = NL80211_CMD_SET_CHANNEL,
13691 .doit = nl80211_set_channel,
13692 .policy = nl80211_policy,
5617c6cd 13693 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13694 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13695 NL80211_FLAG_NEED_RTNL,
f444de05 13696 },
e8347eba
BJ
13697 {
13698 .cmd = NL80211_CMD_SET_WDS_PEER,
13699 .doit = nl80211_set_wds_peer,
13700 .policy = nl80211_policy,
5617c6cd 13701 .flags = GENL_UNS_ADMIN_PERM,
43b19952
JB
13702 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13703 NL80211_FLAG_NEED_RTNL,
e8347eba 13704 },
29cbe68c
JB
13705 {
13706 .cmd = NL80211_CMD_JOIN_MESH,
13707 .doit = nl80211_join_mesh,
13708 .policy = nl80211_policy,
5617c6cd 13709 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
13710 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13711 NL80211_FLAG_NEED_RTNL,
13712 },
13713 {
13714 .cmd = NL80211_CMD_LEAVE_MESH,
13715 .doit = nl80211_leave_mesh,
13716 .policy = nl80211_policy,
5617c6cd 13717 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
13718 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13719 NL80211_FLAG_NEED_RTNL,
13720 },
6e0bd6c3
RL
13721 {
13722 .cmd = NL80211_CMD_JOIN_OCB,
13723 .doit = nl80211_join_ocb,
13724 .policy = nl80211_policy,
5617c6cd 13725 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
13726 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13727 NL80211_FLAG_NEED_RTNL,
13728 },
13729 {
13730 .cmd = NL80211_CMD_LEAVE_OCB,
13731 .doit = nl80211_leave_ocb,
13732 .policy = nl80211_policy,
5617c6cd 13733 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
13734 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13735 NL80211_FLAG_NEED_RTNL,
13736 },
dfb89c56 13737#ifdef CONFIG_PM
ff1b6e69
JB
13738 {
13739 .cmd = NL80211_CMD_GET_WOWLAN,
13740 .doit = nl80211_get_wowlan,
13741 .policy = nl80211_policy,
13742 /* can be retrieved by unprivileged users */
13743 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13744 NL80211_FLAG_NEED_RTNL,
13745 },
13746 {
13747 .cmd = NL80211_CMD_SET_WOWLAN,
13748 .doit = nl80211_set_wowlan,
13749 .policy = nl80211_policy,
5617c6cd 13750 .flags = GENL_UNS_ADMIN_PERM,
ff1b6e69
JB
13751 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13752 NL80211_FLAG_NEED_RTNL,
13753 },
dfb89c56 13754#endif
e5497d76
JB
13755 {
13756 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
13757 .doit = nl80211_set_rekey_data,
13758 .policy = nl80211_policy,
5617c6cd 13759 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 13760 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
13761 NL80211_FLAG_NEED_RTNL |
13762 NL80211_FLAG_CLEAR_SKB,
e5497d76 13763 },
109086ce
AN
13764 {
13765 .cmd = NL80211_CMD_TDLS_MGMT,
13766 .doit = nl80211_tdls_mgmt,
13767 .policy = nl80211_policy,
5617c6cd 13768 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
13769 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13770 NL80211_FLAG_NEED_RTNL,
13771 },
13772 {
13773 .cmd = NL80211_CMD_TDLS_OPER,
13774 .doit = nl80211_tdls_oper,
13775 .policy = nl80211_policy,
5617c6cd 13776 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
13777 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13778 NL80211_FLAG_NEED_RTNL,
13779 },
28946da7
JB
13780 {
13781 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
13782 .doit = nl80211_register_unexpected_frame,
13783 .policy = nl80211_policy,
5617c6cd 13784 .flags = GENL_UNS_ADMIN_PERM,
28946da7
JB
13785 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13786 NL80211_FLAG_NEED_RTNL,
13787 },
7f6cf311
JB
13788 {
13789 .cmd = NL80211_CMD_PROBE_CLIENT,
13790 .doit = nl80211_probe_client,
13791 .policy = nl80211_policy,
5617c6cd 13792 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13793 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
13794 NL80211_FLAG_NEED_RTNL,
13795 },
5e760230
JB
13796 {
13797 .cmd = NL80211_CMD_REGISTER_BEACONS,
13798 .doit = nl80211_register_beacons,
13799 .policy = nl80211_policy,
5617c6cd 13800 .flags = GENL_UNS_ADMIN_PERM,
5e760230
JB
13801 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13802 NL80211_FLAG_NEED_RTNL,
13803 },
1d9d9213
SW
13804 {
13805 .cmd = NL80211_CMD_SET_NOACK_MAP,
13806 .doit = nl80211_set_noack_map,
13807 .policy = nl80211_policy,
5617c6cd 13808 .flags = GENL_UNS_ADMIN_PERM,
1d9d9213
SW
13809 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13810 NL80211_FLAG_NEED_RTNL,
13811 },
98104fde
JB
13812 {
13813 .cmd = NL80211_CMD_START_P2P_DEVICE,
13814 .doit = nl80211_start_p2p_device,
13815 .policy = nl80211_policy,
5617c6cd 13816 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
13817 .internal_flags = NL80211_FLAG_NEED_WDEV |
13818 NL80211_FLAG_NEED_RTNL,
13819 },
13820 {
13821 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
13822 .doit = nl80211_stop_p2p_device,
13823 .policy = nl80211_policy,
5617c6cd 13824 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
13825 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13826 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
13827 },
13828 {
13829 .cmd = NL80211_CMD_START_NAN,
13830 .doit = nl80211_start_nan,
13831 .policy = nl80211_policy,
13832 .flags = GENL_ADMIN_PERM,
13833 .internal_flags = NL80211_FLAG_NEED_WDEV |
13834 NL80211_FLAG_NEED_RTNL,
13835 },
13836 {
13837 .cmd = NL80211_CMD_STOP_NAN,
13838 .doit = nl80211_stop_nan,
13839 .policy = nl80211_policy,
13840 .flags = GENL_ADMIN_PERM,
13841 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13842 NL80211_FLAG_NEED_RTNL,
a442b761
AB
13843 },
13844 {
13845 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
13846 .doit = nl80211_nan_add_func,
13847 .policy = nl80211_policy,
13848 .flags = GENL_ADMIN_PERM,
13849 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13850 NL80211_FLAG_NEED_RTNL,
13851 },
13852 {
13853 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
13854 .doit = nl80211_nan_del_func,
13855 .policy = nl80211_policy,
13856 .flags = GENL_ADMIN_PERM,
13857 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13858 NL80211_FLAG_NEED_RTNL,
a5a9dcf2
AB
13859 },
13860 {
13861 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
13862 .doit = nl80211_nan_change_config,
13863 .policy = nl80211_policy,
13864 .flags = GENL_ADMIN_PERM,
13865 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13866 NL80211_FLAG_NEED_RTNL,
98104fde 13867 },
f4e583c8
AQ
13868 {
13869 .cmd = NL80211_CMD_SET_MCAST_RATE,
13870 .doit = nl80211_set_mcast_rate,
77765eaf 13871 .policy = nl80211_policy,
5617c6cd 13872 .flags = GENL_UNS_ADMIN_PERM,
77765eaf
VT
13873 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13874 NL80211_FLAG_NEED_RTNL,
13875 },
13876 {
13877 .cmd = NL80211_CMD_SET_MAC_ACL,
13878 .doit = nl80211_set_mac_acl,
f4e583c8 13879 .policy = nl80211_policy,
5617c6cd 13880 .flags = GENL_UNS_ADMIN_PERM,
f4e583c8
AQ
13881 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13882 NL80211_FLAG_NEED_RTNL,
13883 },
04f39047
SW
13884 {
13885 .cmd = NL80211_CMD_RADAR_DETECT,
13886 .doit = nl80211_start_radar_detection,
13887 .policy = nl80211_policy,
5617c6cd 13888 .flags = GENL_UNS_ADMIN_PERM,
04f39047
SW
13889 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13890 NL80211_FLAG_NEED_RTNL,
13891 },
3713b4e3
JB
13892 {
13893 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
13894 .doit = nl80211_get_protocol_features,
13895 .policy = nl80211_policy,
13896 },
355199e0
JM
13897 {
13898 .cmd = NL80211_CMD_UPDATE_FT_IES,
13899 .doit = nl80211_update_ft_ies,
13900 .policy = nl80211_policy,
5617c6cd 13901 .flags = GENL_UNS_ADMIN_PERM,
355199e0
JM
13902 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13903 NL80211_FLAG_NEED_RTNL,
13904 },
5de17984
AS
13905 {
13906 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
13907 .doit = nl80211_crit_protocol_start,
13908 .policy = nl80211_policy,
5617c6cd 13909 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
13910 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13911 NL80211_FLAG_NEED_RTNL,
13912 },
13913 {
13914 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
13915 .doit = nl80211_crit_protocol_stop,
13916 .policy = nl80211_policy,
5617c6cd 13917 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
13918 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13919 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
13920 },
13921 {
13922 .cmd = NL80211_CMD_GET_COALESCE,
13923 .doit = nl80211_get_coalesce,
13924 .policy = nl80211_policy,
13925 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13926 NL80211_FLAG_NEED_RTNL,
13927 },
13928 {
13929 .cmd = NL80211_CMD_SET_COALESCE,
13930 .doit = nl80211_set_coalesce,
13931 .policy = nl80211_policy,
5617c6cd 13932 .flags = GENL_UNS_ADMIN_PERM,
be29b99a
AK
13933 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13934 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
13935 },
13936 {
13937 .cmd = NL80211_CMD_CHANNEL_SWITCH,
13938 .doit = nl80211_channel_switch,
13939 .policy = nl80211_policy,
5617c6cd 13940 .flags = GENL_UNS_ADMIN_PERM,
16ef1fe2
SW
13941 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13942 NL80211_FLAG_NEED_RTNL,
13943 },
ad7e718c
JB
13944 {
13945 .cmd = NL80211_CMD_VENDOR,
13946 .doit = nl80211_vendor_cmd,
7bdbe400 13947 .dumpit = nl80211_vendor_cmd_dump,
ad7e718c 13948 .policy = nl80211_policy,
5617c6cd 13949 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c
JB
13950 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13951 NL80211_FLAG_NEED_RTNL,
13952 },
fa9ffc74
KP
13953 {
13954 .cmd = NL80211_CMD_SET_QOS_MAP,
13955 .doit = nl80211_set_qos_map,
13956 .policy = nl80211_policy,
5617c6cd 13957 .flags = GENL_UNS_ADMIN_PERM,
fa9ffc74
KP
13958 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13959 NL80211_FLAG_NEED_RTNL,
13960 },
960d01ac
JB
13961 {
13962 .cmd = NL80211_CMD_ADD_TX_TS,
13963 .doit = nl80211_add_tx_ts,
13964 .policy = nl80211_policy,
5617c6cd 13965 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
13966 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13967 NL80211_FLAG_NEED_RTNL,
13968 },
13969 {
13970 .cmd = NL80211_CMD_DEL_TX_TS,
13971 .doit = nl80211_del_tx_ts,
13972 .policy = nl80211_policy,
5617c6cd 13973 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
13974 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13975 NL80211_FLAG_NEED_RTNL,
13976 },
1057d35e
AN
13977 {
13978 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
13979 .doit = nl80211_tdls_channel_switch,
13980 .policy = nl80211_policy,
5617c6cd 13981 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
13982 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13983 NL80211_FLAG_NEED_RTNL,
13984 },
13985 {
13986 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
13987 .doit = nl80211_tdls_cancel_channel_switch,
13988 .policy = nl80211_policy,
5617c6cd 13989 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
13990 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13991 NL80211_FLAG_NEED_RTNL,
13992 },
ce0ce13a
MB
13993 {
13994 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
13995 .doit = nl80211_set_multicast_to_unicast,
13996 .policy = nl80211_policy,
13997 .flags = GENL_UNS_ADMIN_PERM,
13998 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13999 NL80211_FLAG_NEED_RTNL,
14000 },
3a00df57
AS
14001 {
14002 .cmd = NL80211_CMD_SET_PMK,
14003 .doit = nl80211_set_pmk,
14004 .policy = nl80211_policy,
14005 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14006 NL80211_FLAG_NEED_RTNL,
14007 },
14008 {
14009 .cmd = NL80211_CMD_DEL_PMK,
14010 .doit = nl80211_del_pmk,
14011 .policy = nl80211_policy,
14012 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14013 NL80211_FLAG_NEED_RTNL,
14014 },
40cbfa90
SD
14015 {
14016 .cmd = NL80211_CMD_EXTERNAL_AUTH,
14017 .doit = nl80211_external_auth,
14018 .policy = nl80211_policy,
14019 .flags = GENL_ADMIN_PERM,
14020 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14021 NL80211_FLAG_NEED_RTNL,
14022 },
2576a9ac
DK
14023 {
14024 .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
14025 .doit = nl80211_tx_control_port,
14026 .policy = nl80211_policy,
14027 .flags = GENL_UNS_ADMIN_PERM,
14028 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14029 NL80211_FLAG_NEED_RTNL,
14030 },
81e54d08
PKC
14031 {
14032 .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
14033 .doit = nl80211_get_ftm_responder_stats,
14034 .policy = nl80211_policy,
14035 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14036 NL80211_FLAG_NEED_RTNL,
14037 },
55682965 14038};
9588bbd5 14039
56989f6d 14040static struct genl_family nl80211_fam __ro_after_init = {
489111e5
JB
14041 .name = NL80211_GENL_NAME, /* have users key off the name instead */
14042 .hdrsize = 0, /* no private header */
14043 .version = 1, /* no particular meaning now */
14044 .maxattr = NL80211_ATTR_MAX,
14045 .netnsok = true,
14046 .pre_doit = nl80211_pre_doit,
14047 .post_doit = nl80211_post_doit,
14048 .module = THIS_MODULE,
14049 .ops = nl80211_ops,
14050 .n_ops = ARRAY_SIZE(nl80211_ops),
14051 .mcgrps = nl80211_mcgrps,
14052 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
14053};
14054
55682965
JB
14055/* notification functions */
14056
3bb20556
JB
14057void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
14058 enum nl80211_commands cmd)
55682965
JB
14059{
14060 struct sk_buff *msg;
86e8cf98 14061 struct nl80211_dump_wiphy_state state = {};
55682965 14062
3bb20556
JB
14063 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
14064 cmd != NL80211_CMD_DEL_WIPHY);
14065
fd2120ca 14066 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
14067 if (!msg)
14068 return;
14069
3bb20556 14070 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
14071 nlmsg_free(msg);
14072 return;
14073 }
14074
68eb5503 14075 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14076 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
14077}
14078
896ff063
DK
14079void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
14080 struct wireless_dev *wdev,
14081 enum nl80211_commands cmd)
14082{
14083 struct sk_buff *msg;
14084
14085 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
14086 cmd != NL80211_CMD_DEL_INTERFACE);
14087
14088 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14089 if (!msg)
14090 return;
14091
14092 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev,
14093 cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
14094 nlmsg_free(msg);
14095 return;
14096 }
14097
14098 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
14099 NL80211_MCGRP_CONFIG, GFP_KERNEL);
14100}
14101
362a415d
JB
14102static int nl80211_add_scan_req(struct sk_buff *msg,
14103 struct cfg80211_registered_device *rdev)
14104{
14105 struct cfg80211_scan_request *req = rdev->scan_req;
14106 struct nlattr *nest;
14107 int i;
14108
14109 if (WARN_ON(!req))
14110 return 0;
14111
14112 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
14113 if (!nest)
14114 goto nla_put_failure;
9360ffd1
DM
14115 for (i = 0; i < req->n_ssids; i++) {
14116 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
14117 goto nla_put_failure;
14118 }
362a415d
JB
14119 nla_nest_end(msg, nest);
14120
14121 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
14122 if (!nest)
14123 goto nla_put_failure;
9360ffd1
DM
14124 for (i = 0; i < req->n_channels; i++) {
14125 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
14126 goto nla_put_failure;
14127 }
362a415d
JB
14128 nla_nest_end(msg, nest);
14129
9360ffd1
DM
14130 if (req->ie &&
14131 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
14132 goto nla_put_failure;
362a415d 14133
ae917c9f
JB
14134 if (req->flags &&
14135 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
14136 goto nla_put_failure;
ed473771 14137
1d76250b
AS
14138 if (req->info.scan_start_tsf &&
14139 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
14140 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
14141 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
14142 req->info.tsf_bssid)))
14143 goto nla_put_failure;
14144
362a415d
JB
14145 return 0;
14146 nla_put_failure:
14147 return -ENOBUFS;
14148}
14149
505a2e88 14150static int nl80211_prep_scan_msg(struct sk_buff *msg,
a538e2d5 14151 struct cfg80211_registered_device *rdev,
fd014284 14152 struct wireless_dev *wdev,
15e47304 14153 u32 portid, u32 seq, int flags,
a538e2d5 14154 u32 cmd)
2a519311
JB
14155{
14156 void *hdr;
14157
15e47304 14158 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
14159 if (!hdr)
14160 return -1;
14161
9360ffd1 14162 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
14163 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14164 wdev->netdev->ifindex)) ||
2dad624e
ND
14165 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14166 NL80211_ATTR_PAD))
9360ffd1 14167 goto nla_put_failure;
2a519311 14168
362a415d
JB
14169 /* ignore errors and send incomplete event anyway */
14170 nl80211_add_scan_req(msg, rdev);
2a519311 14171
053c095a
JB
14172 genlmsg_end(msg, hdr);
14173 return 0;
2a519311
JB
14174
14175 nla_put_failure:
14176 genlmsg_cancel(msg, hdr);
14177 return -EMSGSIZE;
14178}
14179
807f8a8c 14180static int
505a2e88 14181nl80211_prep_sched_scan_msg(struct sk_buff *msg,
96b08fd6 14182 struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
14183{
14184 void *hdr;
14185
96b08fd6 14186 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
807f8a8c
LC
14187 if (!hdr)
14188 return -1;
14189
96b08fd6
AVS
14190 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
14191 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
14192 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
14193 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
14194 NL80211_ATTR_PAD))
9360ffd1 14195 goto nla_put_failure;
807f8a8c 14196
053c095a
JB
14197 genlmsg_end(msg, hdr);
14198 return 0;
807f8a8c
LC
14199
14200 nla_put_failure:
14201 genlmsg_cancel(msg, hdr);
14202 return -EMSGSIZE;
14203}
14204
a538e2d5 14205void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 14206 struct wireless_dev *wdev)
a538e2d5
JB
14207{
14208 struct sk_buff *msg;
14209
58050fce 14210 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
14211 if (!msg)
14212 return;
14213
505a2e88 14214 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
14215 NL80211_CMD_TRIGGER_SCAN) < 0) {
14216 nlmsg_free(msg);
14217 return;
14218 }
14219
68eb5503 14220 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14221 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
14222}
14223
f9d15d16
JB
14224struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
14225 struct wireless_dev *wdev, bool aborted)
2a519311
JB
14226{
14227 struct sk_buff *msg;
14228
fd2120ca 14229 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 14230 if (!msg)
f9d15d16 14231 return NULL;
2a519311 14232
505a2e88 14233 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
14234 aborted ? NL80211_CMD_SCAN_ABORTED :
14235 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 14236 nlmsg_free(msg);
f9d15d16 14237 return NULL;
2a519311
JB
14238 }
14239
f9d15d16 14240 return msg;
2a519311
JB
14241}
14242
505a2e88
AVS
14243/* send message created by nl80211_build_scan_msg() */
14244void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
14245 struct sk_buff *msg)
807f8a8c 14246{
807f8a8c
LC
14247 if (!msg)
14248 return;
14249
68eb5503 14250 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14251 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
14252}
14253
96b08fd6 14254void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
14255{
14256 struct sk_buff *msg;
14257
58050fce 14258 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
14259 if (!msg)
14260 return;
14261
96b08fd6 14262 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
807f8a8c
LC
14263 nlmsg_free(msg);
14264 return;
14265 }
14266
96b08fd6 14267 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
2a94fe48 14268 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
14269}
14270
b0d7aa59
JD
14271static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
14272 struct regulatory_request *request)
73d54c9e 14273{
73d54c9e 14274 /* Userspace can always count this one always being set */
9360ffd1
DM
14275 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
14276 goto nla_put_failure;
14277
14278 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
14279 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
14280 NL80211_REGDOM_TYPE_WORLD))
14281 goto nla_put_failure;
14282 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
14283 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
14284 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
14285 goto nla_put_failure;
14286 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
14287 request->intersect) {
14288 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
14289 NL80211_REGDOM_TYPE_INTERSECTION))
14290 goto nla_put_failure;
14291 } else {
14292 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
14293 NL80211_REGDOM_TYPE_COUNTRY) ||
14294 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
14295 request->alpha2))
14296 goto nla_put_failure;
14297 }
14298
ad30ca2c
AN
14299 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
14300 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
14301
14302 if (wiphy &&
14303 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
14304 goto nla_put_failure;
1bdd716c
AN
14305
14306 if (wiphy &&
14307 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
14308 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
14309 goto nla_put_failure;
ad30ca2c 14310 }
73d54c9e 14311
b0d7aa59
JD
14312 return true;
14313
14314nla_put_failure:
14315 return false;
14316}
14317
14318/*
14319 * This can happen on global regulatory changes or device specific settings
14320 * based on custom regulatory domains.
14321 */
14322void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
14323 struct regulatory_request *request)
14324{
14325 struct sk_buff *msg;
14326 void *hdr;
14327
14328 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14329 if (!msg)
14330 return;
14331
14332 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
14333 if (!hdr) {
14334 nlmsg_free(msg);
14335 return;
14336 }
14337
14338 if (nl80211_reg_change_event_fill(msg, request) == false)
14339 goto nla_put_failure;
14340
3b7b72ee 14341 genlmsg_end(msg, hdr);
73d54c9e 14342
bc43b28c 14343 rcu_read_lock();
68eb5503 14344 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 14345 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 14346 rcu_read_unlock();
73d54c9e
LR
14347
14348 return;
14349
14350nla_put_failure:
73d54c9e
LR
14351 nlmsg_free(msg);
14352}
14353
6039f6d2
JM
14354static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
14355 struct net_device *netdev,
14356 const u8 *buf, size_t len,
b0b6aa2c
EP
14357 enum nl80211_commands cmd, gfp_t gfp,
14358 int uapsd_queues)
6039f6d2
JM
14359{
14360 struct sk_buff *msg;
14361 void *hdr;
14362
4ef8c1c9 14363 msg = nlmsg_new(100 + len, gfp);
6039f6d2
JM
14364 if (!msg)
14365 return;
14366
14367 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
14368 if (!hdr) {
14369 nlmsg_free(msg);
14370 return;
14371 }
14372
9360ffd1
DM
14373 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14374 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14375 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
14376 goto nla_put_failure;
6039f6d2 14377
b0b6aa2c
EP
14378 if (uapsd_queues >= 0) {
14379 struct nlattr *nla_wmm =
14380 nla_nest_start(msg, NL80211_ATTR_STA_WME);
14381 if (!nla_wmm)
14382 goto nla_put_failure;
14383
14384 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
14385 uapsd_queues))
14386 goto nla_put_failure;
14387
14388 nla_nest_end(msg, nla_wmm);
14389 }
14390
3b7b72ee 14391 genlmsg_end(msg, hdr);
6039f6d2 14392
68eb5503 14393 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14394 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
14395 return;
14396
14397 nla_put_failure:
6039f6d2
JM
14398 nlmsg_free(msg);
14399}
14400
14401void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
14402 struct net_device *netdev, const u8 *buf,
14403 size_t len, gfp_t gfp)
6039f6d2
JM
14404{
14405 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 14406 NL80211_CMD_AUTHENTICATE, gfp, -1);
6039f6d2
JM
14407}
14408
14409void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
14410 struct net_device *netdev, const u8 *buf,
b0b6aa2c 14411 size_t len, gfp_t gfp, int uapsd_queues)
6039f6d2 14412{
e6d6e342 14413 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 14414 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues);
6039f6d2
JM
14415}
14416
53b46b84 14417void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
14418 struct net_device *netdev, const u8 *buf,
14419 size_t len, gfp_t gfp)
6039f6d2
JM
14420{
14421 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 14422 NL80211_CMD_DEAUTHENTICATE, gfp, -1);
6039f6d2
JM
14423}
14424
53b46b84
JM
14425void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
14426 struct net_device *netdev, const u8 *buf,
e6d6e342 14427 size_t len, gfp_t gfp)
6039f6d2
JM
14428{
14429 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 14430 NL80211_CMD_DISASSOCIATE, gfp, -1);
6039f6d2
JM
14431}
14432
6ff57cf8
JB
14433void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
14434 size_t len)
cf4e594e 14435{
947add36
JB
14436 struct wireless_dev *wdev = dev->ieee80211_ptr;
14437 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14438 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
14439 const struct ieee80211_mgmt *mgmt = (void *)buf;
14440 u32 cmd;
947add36 14441
6ff57cf8
JB
14442 if (WARN_ON(len < 2))
14443 return;
cf4e594e 14444
6ff57cf8
JB
14445 if (ieee80211_is_deauth(mgmt->frame_control))
14446 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
14447 else
14448 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 14449
6ff57cf8 14450 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
b0b6aa2c 14451 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1);
cf4e594e 14452}
6ff57cf8 14453EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 14454
1b06bb40
LR
14455static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
14456 struct net_device *netdev, int cmd,
e6d6e342 14457 const u8 *addr, gfp_t gfp)
1965c853
JM
14458{
14459 struct sk_buff *msg;
14460 void *hdr;
14461
e6d6e342 14462 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
14463 if (!msg)
14464 return;
14465
14466 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
14467 if (!hdr) {
14468 nlmsg_free(msg);
14469 return;
14470 }
14471
9360ffd1
DM
14472 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14473 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14474 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
14475 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
14476 goto nla_put_failure;
1965c853 14477
3b7b72ee 14478 genlmsg_end(msg, hdr);
1965c853 14479
68eb5503 14480 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14481 NL80211_MCGRP_MLME, gfp);
1965c853
JM
14482 return;
14483
14484 nla_put_failure:
1965c853
JM
14485 nlmsg_free(msg);
14486}
14487
14488void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
14489 struct net_device *netdev, const u8 *addr,
14490 gfp_t gfp)
1965c853
JM
14491{
14492 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 14493 addr, gfp);
1965c853
JM
14494}
14495
14496void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
14497 struct net_device *netdev, const u8 *addr,
14498 gfp_t gfp)
1965c853 14499{
e6d6e342
JB
14500 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
14501 addr, gfp);
1965c853
JM
14502}
14503
b23aa676 14504void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
5349a0f7
VK
14505 struct net_device *netdev,
14506 struct cfg80211_connect_resp_params *cr,
3093ebbe 14507 gfp_t gfp)
b23aa676
SO
14508{
14509 struct sk_buff *msg;
14510 void *hdr;
14511
a3caf744 14512 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
76804d28
AVS
14513 cr->fils.kek_len + cr->fils.pmk_len +
14514 (cr->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
14515 if (!msg)
14516 return;
14517
14518 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
14519 if (!hdr) {
14520 nlmsg_free(msg);
14521 return;
14522 }
14523
9360ffd1
DM
14524 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14525 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
5349a0f7
VK
14526 (cr->bssid &&
14527 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
bf1ecd21 14528 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
5349a0f7
VK
14529 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
14530 cr->status) ||
14531 (cr->status < 0 &&
3093ebbe 14532 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
5349a0f7
VK
14533 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
14534 cr->timeout_reason))) ||
14535 (cr->req_ie &&
14536 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
14537 (cr->resp_ie &&
14538 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
a3caf744 14539 cr->resp_ie)) ||
76804d28 14540 (cr->fils.update_erp_next_seq_num &&
a3caf744 14541 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
76804d28 14542 cr->fils.erp_next_seq_num)) ||
a3caf744 14543 (cr->status == WLAN_STATUS_SUCCESS &&
76804d28
AVS
14544 ((cr->fils.kek &&
14545 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils.kek_len,
14546 cr->fils.kek)) ||
14547 (cr->fils.pmk &&
14548 nla_put(msg, NL80211_ATTR_PMK, cr->fils.pmk_len, cr->fils.pmk)) ||
14549 (cr->fils.pmkid &&
14550 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))))
9360ffd1 14551 goto nla_put_failure;
b23aa676 14552
3b7b72ee 14553 genlmsg_end(msg, hdr);
b23aa676 14554
68eb5503 14555 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14556 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
14557 return;
14558
14559 nla_put_failure:
b23aa676 14560 nlmsg_free(msg);
b23aa676
SO
14561}
14562
14563void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
29ce6ecb
AS
14564 struct net_device *netdev,
14565 struct cfg80211_roam_info *info, gfp_t gfp)
b23aa676
SO
14566{
14567 struct sk_buff *msg;
14568 void *hdr;
29ce6ecb 14569 const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
b23aa676 14570
e841b7b1
AVS
14571 msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len +
14572 info->fils.kek_len + info->fils.pmk_len +
14573 (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
14574 if (!msg)
14575 return;
14576
14577 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
14578 if (!hdr) {
14579 nlmsg_free(msg);
14580 return;
14581 }
14582
9360ffd1
DM
14583 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14584 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14585 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
29ce6ecb
AS
14586 (info->req_ie &&
14587 nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
14588 info->req_ie)) ||
14589 (info->resp_ie &&
14590 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
e841b7b1
AVS
14591 info->resp_ie)) ||
14592 (info->fils.update_erp_next_seq_num &&
14593 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
14594 info->fils.erp_next_seq_num)) ||
14595 (info->fils.kek &&
14596 nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len,
14597 info->fils.kek)) ||
14598 (info->fils.pmk &&
14599 nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
14600 (info->fils.pmkid &&
14601 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
9360ffd1 14602 goto nla_put_failure;
b23aa676 14603
3b7b72ee 14604 genlmsg_end(msg, hdr);
b23aa676 14605
68eb5503 14606 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14607 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
14608 return;
14609
503c1fb9 14610 nla_put_failure:
503c1fb9
AS
14611 nlmsg_free(msg);
14612}
14613
14614void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
14615 struct net_device *netdev, const u8 *bssid)
14616{
14617 struct sk_buff *msg;
14618 void *hdr;
14619
14620 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14621 if (!msg)
14622 return;
14623
14624 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
14625 if (!hdr) {
14626 nlmsg_free(msg);
14627 return;
14628 }
14629
14630 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
14631 goto nla_put_failure;
14632
14633 genlmsg_end(msg, hdr);
14634
14635 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
14636 NL80211_MCGRP_MLME, GFP_KERNEL);
14637 return;
14638
b23aa676 14639 nla_put_failure:
b23aa676 14640 nlmsg_free(msg);
b23aa676
SO
14641}
14642
14643void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
14644 struct net_device *netdev, u16 reason,
667503dd 14645 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
14646{
14647 struct sk_buff *msg;
14648 void *hdr;
14649
4ef8c1c9 14650 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
b23aa676
SO
14651 if (!msg)
14652 return;
14653
14654 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
14655 if (!hdr) {
14656 nlmsg_free(msg);
14657 return;
14658 }
14659
9360ffd1
DM
14660 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14661 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
86b6c465 14662 (reason &&
9360ffd1
DM
14663 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
14664 (from_ap &&
14665 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
14666 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
14667 goto nla_put_failure;
b23aa676 14668
3b7b72ee 14669 genlmsg_end(msg, hdr);
b23aa676 14670
68eb5503 14671 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14672 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
14673 return;
14674
14675 nla_put_failure:
b23aa676 14676 nlmsg_free(msg);
b23aa676
SO
14677}
14678
04a773ad
JB
14679void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
14680 struct net_device *netdev, const u8 *bssid,
14681 gfp_t gfp)
14682{
14683 struct sk_buff *msg;
14684 void *hdr;
14685
fd2120ca 14686 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
14687 if (!msg)
14688 return;
14689
14690 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
14691 if (!hdr) {
14692 nlmsg_free(msg);
14693 return;
14694 }
14695
9360ffd1
DM
14696 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14697 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14698 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
14699 goto nla_put_failure;
04a773ad 14700
3b7b72ee 14701 genlmsg_end(msg, hdr);
04a773ad 14702
68eb5503 14703 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14704 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
14705 return;
14706
14707 nla_put_failure:
04a773ad
JB
14708 nlmsg_free(msg);
14709}
14710
947add36
JB
14711void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
14712 const u8* ie, u8 ie_len, gfp_t gfp)
c93b5e71 14713{
947add36 14714 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14715 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
14716 struct sk_buff *msg;
14717 void *hdr;
14718
947add36
JB
14719 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
14720 return;
14721
14722 trace_cfg80211_notify_new_peer_candidate(dev, addr);
14723
4ef8c1c9 14724 msg = nlmsg_new(100 + ie_len, gfp);
c93b5e71
JC
14725 if (!msg)
14726 return;
14727
14728 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
14729 if (!hdr) {
14730 nlmsg_free(msg);
14731 return;
14732 }
14733
9360ffd1 14734 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
14735 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14736 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1
DM
14737 (ie_len && ie &&
14738 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
14739 goto nla_put_failure;
c93b5e71 14740
3b7b72ee 14741 genlmsg_end(msg, hdr);
c93b5e71 14742
68eb5503 14743 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14744 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
14745 return;
14746
14747 nla_put_failure:
c93b5e71
JC
14748 nlmsg_free(msg);
14749}
947add36 14750EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 14751
a3b8b056
JM
14752void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
14753 struct net_device *netdev, const u8 *addr,
14754 enum nl80211_key_type key_type, int key_id,
e6d6e342 14755 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
14756{
14757 struct sk_buff *msg;
14758 void *hdr;
14759
e6d6e342 14760 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
14761 if (!msg)
14762 return;
14763
14764 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
14765 if (!hdr) {
14766 nlmsg_free(msg);
14767 return;
14768 }
14769
9360ffd1
DM
14770 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14771 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14772 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
14773 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
14774 (key_id != -1 &&
14775 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
14776 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
14777 goto nla_put_failure;
a3b8b056 14778
3b7b72ee 14779 genlmsg_end(msg, hdr);
a3b8b056 14780
68eb5503 14781 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14782 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
14783 return;
14784
14785 nla_put_failure:
a3b8b056
JM
14786 nlmsg_free(msg);
14787}
14788
6bad8766
LR
14789void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
14790 struct ieee80211_channel *channel_before,
14791 struct ieee80211_channel *channel_after)
14792{
14793 struct sk_buff *msg;
14794 void *hdr;
14795 struct nlattr *nl_freq;
14796
fd2120ca 14797 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
14798 if (!msg)
14799 return;
14800
14801 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
14802 if (!hdr) {
14803 nlmsg_free(msg);
14804 return;
14805 }
14806
14807 /*
14808 * Since we are applying the beacon hint to a wiphy we know its
14809 * wiphy_idx is valid
14810 */
9360ffd1
DM
14811 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
14812 goto nla_put_failure;
6bad8766
LR
14813
14814 /* Before */
14815 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
14816 if (!nl_freq)
14817 goto nla_put_failure;
50f32718
HD
14818
14819 if (nl80211_msg_put_channel(msg, wiphy, channel_before, false))
6bad8766
LR
14820 goto nla_put_failure;
14821 nla_nest_end(msg, nl_freq);
14822
14823 /* After */
14824 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
14825 if (!nl_freq)
14826 goto nla_put_failure;
50f32718
HD
14827
14828 if (nl80211_msg_put_channel(msg, wiphy, channel_after, false))
6bad8766
LR
14829 goto nla_put_failure;
14830 nla_nest_end(msg, nl_freq);
14831
3b7b72ee 14832 genlmsg_end(msg, hdr);
6bad8766 14833
463d0183 14834 rcu_read_lock();
68eb5503 14835 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 14836 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 14837 rcu_read_unlock();
6bad8766
LR
14838
14839 return;
14840
14841nla_put_failure:
6bad8766
LR
14842 nlmsg_free(msg);
14843}
14844
9588bbd5
JM
14845static void nl80211_send_remain_on_chan_event(
14846 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 14847 struct wireless_dev *wdev, u64 cookie,
9588bbd5 14848 struct ieee80211_channel *chan,
9588bbd5
JM
14849 unsigned int duration, gfp_t gfp)
14850{
14851 struct sk_buff *msg;
14852 void *hdr;
14853
14854 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14855 if (!msg)
14856 return;
14857
14858 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
14859 if (!hdr) {
14860 nlmsg_free(msg);
14861 return;
14862 }
14863
9360ffd1 14864 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
14865 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14866 wdev->netdev->ifindex)) ||
2dad624e
ND
14867 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14868 NL80211_ATTR_PAD) ||
9360ffd1 14869 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
14870 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
14871 NL80211_CHAN_NO_HT) ||
2dad624e
ND
14872 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14873 NL80211_ATTR_PAD))
9360ffd1 14874 goto nla_put_failure;
9588bbd5 14875
9360ffd1
DM
14876 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
14877 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
14878 goto nla_put_failure;
9588bbd5 14879
3b7b72ee 14880 genlmsg_end(msg, hdr);
9588bbd5 14881
68eb5503 14882 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14883 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
14884 return;
14885
14886 nla_put_failure:
9588bbd5
JM
14887 nlmsg_free(msg);
14888}
14889
947add36
JB
14890void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
14891 struct ieee80211_channel *chan,
14892 unsigned int duration, gfp_t gfp)
9588bbd5 14893{
947add36 14894 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14895 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14896
14897 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 14898 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 14899 rdev, wdev, cookie, chan,
42d97a59 14900 duration, gfp);
9588bbd5 14901}
947add36 14902EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 14903
947add36
JB
14904void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
14905 struct ieee80211_channel *chan,
14906 gfp_t gfp)
9588bbd5 14907{
947add36 14908 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14909 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14910
14911 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 14912 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 14913 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 14914}
947add36 14915EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 14916
947add36
JB
14917void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
14918 struct station_info *sinfo, gfp_t gfp)
98b62183 14919{
947add36 14920 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 14921 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
14922 struct sk_buff *msg;
14923
947add36
JB
14924 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
14925
58050fce 14926 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
14927 if (!msg)
14928 return;
14929
cf5ead82 14930 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 14931 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
14932 nlmsg_free(msg);
14933 return;
14934 }
14935
68eb5503 14936 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14937 NL80211_MCGRP_MLME, gfp);
98b62183 14938}
947add36 14939EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 14940
cf5ead82
JB
14941void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
14942 struct station_info *sinfo, gfp_t gfp)
ec15e68b 14943{
947add36 14944 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 14945 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 14946 struct sk_buff *msg;
73887fd9 14947 struct station_info empty_sinfo = {};
cf5ead82 14948
73887fd9
JB
14949 if (!sinfo)
14950 sinfo = &empty_sinfo;
ec15e68b 14951
947add36
JB
14952 trace_cfg80211_del_sta(dev, mac_addr);
14953
58050fce 14954 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7ea3e110
JB
14955 if (!msg) {
14956 cfg80211_sinfo_release_content(sinfo);
73887fd9 14957 return;
7ea3e110 14958 }
ec15e68b 14959
cf5ead82 14960 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 14961 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b 14962 nlmsg_free(msg);
73887fd9 14963 return;
ec15e68b
JM
14964 }
14965
68eb5503 14966 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14967 NL80211_MCGRP_MLME, gfp);
ec15e68b 14968}
cf5ead82 14969EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 14970
947add36
JB
14971void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
14972 enum nl80211_connect_failed_reason reason,
14973 gfp_t gfp)
ed44a951 14974{
947add36 14975 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 14976 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
14977 struct sk_buff *msg;
14978 void *hdr;
14979
14980 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
14981 if (!msg)
14982 return;
14983
14984 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
14985 if (!hdr) {
14986 nlmsg_free(msg);
14987 return;
14988 }
14989
14990 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14991 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
14992 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
14993 goto nla_put_failure;
14994
14995 genlmsg_end(msg, hdr);
14996
68eb5503 14997 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14998 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
14999 return;
15000
15001 nla_put_failure:
ed44a951
PP
15002 nlmsg_free(msg);
15003}
947add36 15004EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 15005
b92ab5d8
JB
15006static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
15007 const u8 *addr, gfp_t gfp)
28946da7
JB
15008{
15009 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 15010 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
15011 struct sk_buff *msg;
15012 void *hdr;
6aa7de05 15013 u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
28946da7 15014
15e47304 15015 if (!nlportid)
28946da7
JB
15016 return false;
15017
15018 msg = nlmsg_new(100, gfp);
15019 if (!msg)
15020 return true;
15021
b92ab5d8 15022 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
15023 if (!hdr) {
15024 nlmsg_free(msg);
15025 return true;
15026 }
15027
9360ffd1
DM
15028 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15029 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15030 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
15031 goto nla_put_failure;
28946da7 15032
9c90a9f6 15033 genlmsg_end(msg, hdr);
15e47304 15034 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
15035 return true;
15036
15037 nla_put_failure:
28946da7
JB
15038 nlmsg_free(msg);
15039 return true;
15040}
15041
947add36
JB
15042bool cfg80211_rx_spurious_frame(struct net_device *dev,
15043 const u8 *addr, gfp_t gfp)
b92ab5d8 15044{
947add36
JB
15045 struct wireless_dev *wdev = dev->ieee80211_ptr;
15046 bool ret;
15047
15048 trace_cfg80211_rx_spurious_frame(dev, addr);
15049
15050 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
15051 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
15052 trace_cfg80211_return_bool(false);
15053 return false;
15054 }
15055 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
15056 addr, gfp);
15057 trace_cfg80211_return_bool(ret);
15058 return ret;
b92ab5d8 15059}
947add36 15060EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 15061
947add36
JB
15062bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
15063 const u8 *addr, gfp_t gfp)
b92ab5d8 15064{
947add36
JB
15065 struct wireless_dev *wdev = dev->ieee80211_ptr;
15066 bool ret;
15067
15068 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
15069
15070 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
15071 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
15072 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
15073 trace_cfg80211_return_bool(false);
15074 return false;
15075 }
15076 ret = __nl80211_unexpected_frame(dev,
15077 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
15078 addr, gfp);
15079 trace_cfg80211_return_bool(ret);
15080 return ret;
b92ab5d8 15081}
947add36 15082EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 15083
2e161f78 15084int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 15085 struct wireless_dev *wdev, u32 nlportid,
804483e9 15086 int freq, int sig_dbm,
19504cf5 15087 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 15088{
71bbc994 15089 struct net_device *netdev = wdev->netdev;
026331c4
JM
15090 struct sk_buff *msg;
15091 void *hdr;
026331c4 15092
4ef8c1c9 15093 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
15094 if (!msg)
15095 return -ENOMEM;
15096
2e161f78 15097 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
15098 if (!hdr) {
15099 nlmsg_free(msg);
15100 return -ENOMEM;
15101 }
15102
9360ffd1 15103 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
15104 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15105 netdev->ifindex)) ||
2dad624e
ND
15106 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15107 NL80211_ATTR_PAD) ||
9360ffd1
DM
15108 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
15109 (sig_dbm &&
15110 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
15111 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
15112 (flags &&
15113 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 15114 goto nla_put_failure;
026331c4 15115
3b7b72ee 15116 genlmsg_end(msg, hdr);
026331c4 15117
15e47304 15118 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
15119
15120 nla_put_failure:
026331c4
JM
15121 nlmsg_free(msg);
15122 return -ENOBUFS;
15123}
15124
947add36
JB
15125void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
15126 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 15127{
947add36 15128 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15129 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 15130 struct net_device *netdev = wdev->netdev;
026331c4
JM
15131 struct sk_buff *msg;
15132 void *hdr;
15133
947add36
JB
15134 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
15135
4ef8c1c9 15136 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
15137 if (!msg)
15138 return;
15139
2e161f78 15140 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
15141 if (!hdr) {
15142 nlmsg_free(msg);
15143 return;
15144 }
15145
9360ffd1 15146 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
15147 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15148 netdev->ifindex)) ||
2dad624e
ND
15149 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15150 NL80211_ATTR_PAD) ||
9360ffd1 15151 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
15152 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
15153 NL80211_ATTR_PAD) ||
9360ffd1
DM
15154 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
15155 goto nla_put_failure;
026331c4 15156
3b7b72ee 15157 genlmsg_end(msg, hdr);
026331c4 15158
68eb5503 15159 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15160 NL80211_MCGRP_MLME, gfp);
026331c4
JM
15161 return;
15162
15163 nla_put_failure:
026331c4
JM
15164 nlmsg_free(msg);
15165}
947add36 15166EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 15167
6a671a50 15168static int __nl80211_rx_control_port(struct net_device *dev,
a948f713 15169 struct sk_buff *skb,
6a671a50
DK
15170 bool unencrypted, gfp_t gfp)
15171{
15172 struct wireless_dev *wdev = dev->ieee80211_ptr;
15173 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
a948f713
DK
15174 struct ethhdr *ehdr = eth_hdr(skb);
15175 const u8 *addr = ehdr->h_source;
15176 u16 proto = be16_to_cpu(skb->protocol);
6a671a50
DK
15177 struct sk_buff *msg;
15178 void *hdr;
a948f713
DK
15179 struct nlattr *frame;
15180
6a671a50
DK
15181 u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
15182
15183 if (!nlportid)
15184 return -ENOENT;
15185
a948f713 15186 msg = nlmsg_new(100 + skb->len, gfp);
6a671a50
DK
15187 if (!msg)
15188 return -ENOMEM;
15189
15190 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
15191 if (!hdr) {
15192 nlmsg_free(msg);
15193 return -ENOBUFS;
15194 }
15195
15196 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15197 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15198 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15199 NL80211_ATTR_PAD) ||
6a671a50
DK
15200 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
15201 nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
15202 (unencrypted && nla_put_flag(msg,
15203 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
15204 goto nla_put_failure;
15205
a948f713
DK
15206 frame = nla_reserve(msg, NL80211_ATTR_FRAME, skb->len);
15207 if (!frame)
15208 goto nla_put_failure;
15209
15210 skb_copy_bits(skb, 0, nla_data(frame), skb->len);
6a671a50
DK
15211 genlmsg_end(msg, hdr);
15212
15213 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
15214
15215 nla_put_failure:
15216 nlmsg_free(msg);
15217 return -ENOBUFS;
15218}
15219
15220bool cfg80211_rx_control_port(struct net_device *dev,
a948f713 15221 struct sk_buff *skb, bool unencrypted)
6a671a50
DK
15222{
15223 int ret;
15224
a948f713
DK
15225 trace_cfg80211_rx_control_port(dev, skb, unencrypted);
15226 ret = __nl80211_rx_control_port(dev, skb, unencrypted, GFP_ATOMIC);
6a671a50
DK
15227 trace_cfg80211_return_bool(ret == 0);
15228 return ret == 0;
15229}
15230EXPORT_SYMBOL(cfg80211_rx_control_port);
15231
5b97f49d
JB
15232static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
15233 const char *mac, gfp_t gfp)
d6dc1a38 15234{
947add36 15235 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
15236 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
15237 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15238 void **cb;
947add36 15239
d6dc1a38 15240 if (!msg)
5b97f49d 15241 return NULL;
d6dc1a38 15242
5b97f49d
JB
15243 cb = (void **)msg->cb;
15244
15245 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
15246 if (!cb[0]) {
d6dc1a38 15247 nlmsg_free(msg);
5b97f49d 15248 return NULL;
d6dc1a38
JO
15249 }
15250
9360ffd1 15251 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 15252 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 15253 goto nla_put_failure;
d6dc1a38 15254
5b97f49d 15255 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
15256 goto nla_put_failure;
15257
5b97f49d
JB
15258 cb[1] = nla_nest_start(msg, NL80211_ATTR_CQM);
15259 if (!cb[1])
9360ffd1 15260 goto nla_put_failure;
d6dc1a38 15261
5b97f49d 15262 cb[2] = rdev;
d6dc1a38 15263
5b97f49d
JB
15264 return msg;
15265 nla_put_failure:
15266 nlmsg_free(msg);
15267 return NULL;
15268}
15269
15270static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
15271{
15272 void **cb = (void **)msg->cb;
15273 struct cfg80211_registered_device *rdev = cb[2];
15274
15275 nla_nest_end(msg, cb[1]);
15276 genlmsg_end(msg, cb[0]);
15277
15278 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 15279
68eb5503 15280 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15281 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
15282}
15283
15284void cfg80211_cqm_rssi_notify(struct net_device *dev,
15285 enum nl80211_cqm_rssi_threshold_event rssi_event,
bee427b8 15286 s32 rssi_level, gfp_t gfp)
5b97f49d
JB
15287{
15288 struct sk_buff *msg;
4a4b8169
AZ
15289 struct wireless_dev *wdev = dev->ieee80211_ptr;
15290 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
5b97f49d 15291
bee427b8 15292 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
5b97f49d 15293
98f03342
JB
15294 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
15295 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
15296 return;
15297
4a4b8169
AZ
15298 if (wdev->cqm_config) {
15299 wdev->cqm_config->last_rssi_event_value = rssi_level;
15300
15301 cfg80211_cqm_rssi_update(rdev, dev);
15302
15303 if (rssi_level == 0)
15304 rssi_level = wdev->cqm_config->last_rssi_event_value;
15305 }
15306
5b97f49d
JB
15307 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
15308 if (!msg)
15309 return;
15310
15311 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
15312 rssi_event))
15313 goto nla_put_failure;
15314
bee427b8
AZ
15315 if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
15316 rssi_level))
15317 goto nla_put_failure;
15318
5b97f49d
JB
15319 cfg80211_send_cqm(msg, gfp);
15320
d6dc1a38
JO
15321 return;
15322
15323 nla_put_failure:
d6dc1a38
JO
15324 nlmsg_free(msg);
15325}
947add36 15326EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 15327
5b97f49d
JB
15328void cfg80211_cqm_txe_notify(struct net_device *dev,
15329 const u8 *peer, u32 num_packets,
15330 u32 rate, u32 intvl, gfp_t gfp)
15331{
15332 struct sk_buff *msg;
15333
15334 msg = cfg80211_prepare_cqm(dev, peer, gfp);
15335 if (!msg)
15336 return;
15337
15338 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
15339 goto nla_put_failure;
15340
15341 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
15342 goto nla_put_failure;
15343
15344 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
15345 goto nla_put_failure;
15346
15347 cfg80211_send_cqm(msg, gfp);
15348 return;
15349
15350 nla_put_failure:
15351 nlmsg_free(msg);
15352}
15353EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
15354
15355void cfg80211_cqm_pktloss_notify(struct net_device *dev,
15356 const u8 *peer, u32 num_packets, gfp_t gfp)
15357{
15358 struct sk_buff *msg;
15359
15360 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
15361
15362 msg = cfg80211_prepare_cqm(dev, peer, gfp);
15363 if (!msg)
15364 return;
15365
15366 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
15367 goto nla_put_failure;
15368
15369 cfg80211_send_cqm(msg, gfp);
15370 return;
15371
15372 nla_put_failure:
15373 nlmsg_free(msg);
15374}
15375EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
15376
98f03342
JB
15377void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
15378{
15379 struct sk_buff *msg;
15380
15381 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
15382 if (!msg)
15383 return;
15384
15385 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
15386 goto nla_put_failure;
15387
15388 cfg80211_send_cqm(msg, gfp);
15389 return;
15390
15391 nla_put_failure:
15392 nlmsg_free(msg);
15393}
15394EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
15395
947add36
JB
15396static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
15397 struct net_device *netdev, const u8 *bssid,
15398 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
15399{
15400 struct sk_buff *msg;
15401 struct nlattr *rekey_attr;
15402 void *hdr;
15403
58050fce 15404 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
15405 if (!msg)
15406 return;
15407
15408 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
15409 if (!hdr) {
15410 nlmsg_free(msg);
15411 return;
15412 }
15413
9360ffd1
DM
15414 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15415 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15416 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
15417 goto nla_put_failure;
e5497d76
JB
15418
15419 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
15420 if (!rekey_attr)
15421 goto nla_put_failure;
15422
9360ffd1
DM
15423 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
15424 NL80211_REPLAY_CTR_LEN, replay_ctr))
15425 goto nla_put_failure;
e5497d76
JB
15426
15427 nla_nest_end(msg, rekey_attr);
15428
3b7b72ee 15429 genlmsg_end(msg, hdr);
e5497d76 15430
68eb5503 15431 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15432 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
15433 return;
15434
15435 nla_put_failure:
e5497d76
JB
15436 nlmsg_free(msg);
15437}
15438
947add36
JB
15439void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
15440 const u8 *replay_ctr, gfp_t gfp)
15441{
15442 struct wireless_dev *wdev = dev->ieee80211_ptr;
15443 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15444 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
15445
15446 trace_cfg80211_gtk_rekey_notify(dev, bssid);
15447 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
15448}
15449EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
15450
15451static void
15452nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
15453 struct net_device *netdev, int index,
15454 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
15455{
15456 struct sk_buff *msg;
15457 struct nlattr *attr;
15458 void *hdr;
15459
58050fce 15460 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
15461 if (!msg)
15462 return;
15463
15464 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
15465 if (!hdr) {
15466 nlmsg_free(msg);
15467 return;
15468 }
15469
9360ffd1
DM
15470 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15471 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
15472 goto nla_put_failure;
c9df56b4
JM
15473
15474 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
15475 if (!attr)
15476 goto nla_put_failure;
15477
9360ffd1
DM
15478 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
15479 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
15480 (preauth &&
15481 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
15482 goto nla_put_failure;
c9df56b4
JM
15483
15484 nla_nest_end(msg, attr);
15485
3b7b72ee 15486 genlmsg_end(msg, hdr);
c9df56b4 15487
68eb5503 15488 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15489 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
15490 return;
15491
15492 nla_put_failure:
c9df56b4
JM
15493 nlmsg_free(msg);
15494}
15495
947add36
JB
15496void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
15497 const u8 *bssid, bool preauth, gfp_t gfp)
15498{
15499 struct wireless_dev *wdev = dev->ieee80211_ptr;
15500 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15501 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
15502
15503 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
15504 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
15505}
15506EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
15507
15508static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
15509 struct net_device *netdev,
15510 struct cfg80211_chan_def *chandef,
f8d7552e
LC
15511 gfp_t gfp,
15512 enum nl80211_commands notif,
15513 u8 count)
5314526b
TP
15514{
15515 struct sk_buff *msg;
15516 void *hdr;
15517
58050fce 15518 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
15519 if (!msg)
15520 return;
15521
f8d7552e 15522 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
15523 if (!hdr) {
15524 nlmsg_free(msg);
15525 return;
15526 }
15527
683b6d3b
JB
15528 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
15529 goto nla_put_failure;
15530
15531 if (nl80211_send_chandef(msg, chandef))
7eab0f64 15532 goto nla_put_failure;
5314526b 15533
f8d7552e
LC
15534 if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
15535 (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
15536 goto nla_put_failure;
15537
5314526b
TP
15538 genlmsg_end(msg, hdr);
15539
68eb5503 15540 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15541 NL80211_MCGRP_MLME, gfp);
5314526b
TP
15542 return;
15543
15544 nla_put_failure:
5314526b
TP
15545 nlmsg_free(msg);
15546}
15547
947add36
JB
15548void cfg80211_ch_switch_notify(struct net_device *dev,
15549 struct cfg80211_chan_def *chandef)
84f10708 15550{
947add36
JB
15551 struct wireless_dev *wdev = dev->ieee80211_ptr;
15552 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15553 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 15554
e487eaeb 15555 ASSERT_WDEV_LOCK(wdev);
947add36 15556
e487eaeb 15557 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 15558
9e0e2961 15559 wdev->chandef = *chandef;
96f55f12 15560 wdev->preset_chandef = *chandef;
f8d7552e
LC
15561 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
15562 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
947add36
JB
15563}
15564EXPORT_SYMBOL(cfg80211_ch_switch_notify);
15565
f8d7552e
LC
15566void cfg80211_ch_switch_started_notify(struct net_device *dev,
15567 struct cfg80211_chan_def *chandef,
15568 u8 count)
15569{
15570 struct wireless_dev *wdev = dev->ieee80211_ptr;
15571 struct wiphy *wiphy = wdev->wiphy;
15572 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
15573
15574 trace_cfg80211_ch_switch_started_notify(dev, chandef);
15575
15576 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
15577 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
15578}
15579EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
15580
04f39047
SW
15581void
15582nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 15583 const struct cfg80211_chan_def *chandef,
04f39047
SW
15584 enum nl80211_radar_event event,
15585 struct net_device *netdev, gfp_t gfp)
15586{
15587 struct sk_buff *msg;
15588 void *hdr;
15589
15590 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15591 if (!msg)
15592 return;
15593
15594 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
15595 if (!hdr) {
15596 nlmsg_free(msg);
15597 return;
15598 }
15599
15600 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
15601 goto nla_put_failure;
15602
15603 /* NOP and radar events don't need a netdev parameter */
15604 if (netdev) {
15605 struct wireless_dev *wdev = netdev->ieee80211_ptr;
15606
15607 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
15608 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15609 NL80211_ATTR_PAD))
04f39047
SW
15610 goto nla_put_failure;
15611 }
15612
15613 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
15614 goto nla_put_failure;
15615
15616 if (nl80211_send_chandef(msg, chandef))
15617 goto nla_put_failure;
15618
9c90a9f6 15619 genlmsg_end(msg, hdr);
04f39047 15620
68eb5503 15621 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15622 NL80211_MCGRP_MLME, gfp);
04f39047
SW
15623 return;
15624
15625 nla_put_failure:
04f39047
SW
15626 nlmsg_free(msg);
15627}
15628
466b9936 15629void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
15630 struct sta_opmode_info *sta_opmode,
15631 gfp_t gfp)
15632{
15633 struct sk_buff *msg;
15634 struct wireless_dev *wdev = dev->ieee80211_ptr;
15635 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
15636 void *hdr;
15637
15638 if (WARN_ON(!mac))
15639 return;
15640
15641 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15642 if (!msg)
15643 return;
15644
15645 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
15646 if (!hdr) {
15647 nlmsg_free(msg);
15648 return;
15649 }
15650
15651 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
15652 goto nla_put_failure;
15653
15654 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
15655 goto nla_put_failure;
15656
15657 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
15658 goto nla_put_failure;
15659
15660 if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
15661 nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
15662 goto nla_put_failure;
15663
15664 if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
15665 nla_put_u8(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
15666 goto nla_put_failure;
15667
15668 if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
15669 nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
15670 goto nla_put_failure;
15671
15672 genlmsg_end(msg, hdr);
15673
15674 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
15675 NL80211_MCGRP_MLME, gfp);
15676
15677 return;
15678
15679nla_put_failure:
15680 nlmsg_free(msg);
15681}
15682EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
15683
7f6cf311 15684void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
c4b50cd3
VN
15685 u64 cookie, bool acked, s32 ack_signal,
15686 bool is_valid_ack_signal, gfp_t gfp)
7f6cf311
JB
15687{
15688 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 15689 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
15690 struct sk_buff *msg;
15691 void *hdr;
7f6cf311 15692
4ee3e063
BL
15693 trace_cfg80211_probe_status(dev, addr, cookie, acked);
15694
58050fce 15695 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 15696
7f6cf311
JB
15697 if (!msg)
15698 return;
15699
15700 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
15701 if (!hdr) {
15702 nlmsg_free(msg);
15703 return;
15704 }
15705
9360ffd1
DM
15706 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15707 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15708 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
15709 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
15710 NL80211_ATTR_PAD) ||
c4b50cd3
VN
15711 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
15712 (is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
15713 ack_signal)))
9360ffd1 15714 goto nla_put_failure;
7f6cf311 15715
9c90a9f6 15716 genlmsg_end(msg, hdr);
7f6cf311 15717
68eb5503 15718 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15719 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
15720 return;
15721
15722 nla_put_failure:
7f6cf311
JB
15723 nlmsg_free(msg);
15724}
15725EXPORT_SYMBOL(cfg80211_probe_status);
15726
5e760230
JB
15727void cfg80211_report_obss_beacon(struct wiphy *wiphy,
15728 const u8 *frame, size_t len,
37c73b5f 15729 int freq, int sig_dbm)
5e760230 15730{
f26cbf40 15731 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
15732 struct sk_buff *msg;
15733 void *hdr;
37c73b5f 15734 struct cfg80211_beacon_registration *reg;
5e760230 15735
4ee3e063
BL
15736 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
15737
37c73b5f
BG
15738 spin_lock_bh(&rdev->beacon_registrations_lock);
15739 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
15740 msg = nlmsg_new(len + 100, GFP_ATOMIC);
15741 if (!msg) {
15742 spin_unlock_bh(&rdev->beacon_registrations_lock);
15743 return;
15744 }
5e760230 15745
37c73b5f
BG
15746 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
15747 if (!hdr)
15748 goto nla_put_failure;
5e760230 15749
37c73b5f
BG
15750 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15751 (freq &&
15752 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
15753 (sig_dbm &&
15754 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
15755 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
15756 goto nla_put_failure;
5e760230 15757
37c73b5f 15758 genlmsg_end(msg, hdr);
5e760230 15759
37c73b5f
BG
15760 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
15761 }
15762 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
15763 return;
15764
15765 nla_put_failure:
37c73b5f 15766 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
15767 nlmsg_free(msg);
15768}
15769EXPORT_SYMBOL(cfg80211_report_obss_beacon);
15770
cd8f7cb4 15771#ifdef CONFIG_PM
8cd4d456
LC
15772static int cfg80211_net_detect_results(struct sk_buff *msg,
15773 struct cfg80211_wowlan_wakeup *wakeup)
15774{
15775 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
15776 struct nlattr *nl_results, *nl_match, *nl_freqs;
15777 int i, j;
15778
15779 nl_results = nla_nest_start(
15780 msg, NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
15781 if (!nl_results)
15782 return -EMSGSIZE;
15783
15784 for (i = 0; i < nd->n_matches; i++) {
15785 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
15786
15787 nl_match = nla_nest_start(msg, i);
15788 if (!nl_match)
15789 break;
15790
15791 /* The SSID attribute is optional in nl80211, but for
15792 * simplicity reasons it's always present in the
15793 * cfg80211 structure. If a driver can't pass the
15794 * SSID, that needs to be changed. A zero length SSID
15795 * is still a valid SSID (wildcard), so it cannot be
15796 * used for this purpose.
15797 */
15798 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
15799 match->ssid.ssid)) {
15800 nla_nest_cancel(msg, nl_match);
15801 goto out;
15802 }
15803
15804 if (match->n_channels) {
15805 nl_freqs = nla_nest_start(
15806 msg, NL80211_ATTR_SCAN_FREQUENCIES);
15807 if (!nl_freqs) {
15808 nla_nest_cancel(msg, nl_match);
15809 goto out;
15810 }
15811
15812 for (j = 0; j < match->n_channels; j++) {
5528fae8 15813 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
15814 nla_nest_cancel(msg, nl_freqs);
15815 nla_nest_cancel(msg, nl_match);
15816 goto out;
15817 }
15818 }
15819
15820 nla_nest_end(msg, nl_freqs);
15821 }
15822
15823 nla_nest_end(msg, nl_match);
15824 }
15825
15826out:
15827 nla_nest_end(msg, nl_results);
15828 return 0;
15829}
15830
cd8f7cb4
JB
15831void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
15832 struct cfg80211_wowlan_wakeup *wakeup,
15833 gfp_t gfp)
15834{
f26cbf40 15835 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
15836 struct sk_buff *msg;
15837 void *hdr;
9c90a9f6 15838 int size = 200;
cd8f7cb4
JB
15839
15840 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
15841
15842 if (wakeup)
15843 size += wakeup->packet_present_len;
15844
15845 msg = nlmsg_new(size, gfp);
15846 if (!msg)
15847 return;
15848
15849 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
15850 if (!hdr)
15851 goto free_msg;
15852
15853 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
15854 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15855 NL80211_ATTR_PAD))
cd8f7cb4
JB
15856 goto free_msg;
15857
15858 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15859 wdev->netdev->ifindex))
15860 goto free_msg;
15861
15862 if (wakeup) {
15863 struct nlattr *reasons;
15864
15865 reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
15866 if (!reasons)
15867 goto free_msg;
cd8f7cb4
JB
15868
15869 if (wakeup->disconnect &&
15870 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
15871 goto free_msg;
15872 if (wakeup->magic_pkt &&
15873 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
15874 goto free_msg;
15875 if (wakeup->gtk_rekey_failure &&
15876 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
15877 goto free_msg;
15878 if (wakeup->eap_identity_req &&
15879 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
15880 goto free_msg;
15881 if (wakeup->four_way_handshake &&
15882 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
15883 goto free_msg;
15884 if (wakeup->rfkill_release &&
15885 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
15886 goto free_msg;
15887
15888 if (wakeup->pattern_idx >= 0 &&
15889 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
15890 wakeup->pattern_idx))
15891 goto free_msg;
15892
ae917c9f
JB
15893 if (wakeup->tcp_match &&
15894 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
15895 goto free_msg;
2a0e047e 15896
ae917c9f
JB
15897 if (wakeup->tcp_connlost &&
15898 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
15899 goto free_msg;
2a0e047e 15900
ae917c9f
JB
15901 if (wakeup->tcp_nomoretokens &&
15902 nla_put_flag(msg,
15903 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
15904 goto free_msg;
2a0e047e 15905
cd8f7cb4
JB
15906 if (wakeup->packet) {
15907 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
15908 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
15909
15910 if (!wakeup->packet_80211) {
15911 pkt_attr =
15912 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
15913 len_attr =
15914 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
15915 }
15916
15917 if (wakeup->packet_len &&
15918 nla_put_u32(msg, len_attr, wakeup->packet_len))
15919 goto free_msg;
15920
15921 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
15922 wakeup->packet))
15923 goto free_msg;
15924 }
15925
8cd4d456
LC
15926 if (wakeup->net_detect &&
15927 cfg80211_net_detect_results(msg, wakeup))
15928 goto free_msg;
15929
cd8f7cb4
JB
15930 nla_nest_end(msg, reasons);
15931 }
15932
9c90a9f6 15933 genlmsg_end(msg, hdr);
cd8f7cb4 15934
68eb5503 15935 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15936 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
15937 return;
15938
15939 free_msg:
15940 nlmsg_free(msg);
15941}
15942EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
15943#endif
15944
3475b094
JM
15945void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
15946 enum nl80211_tdls_operation oper,
15947 u16 reason_code, gfp_t gfp)
15948{
15949 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 15950 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
15951 struct sk_buff *msg;
15952 void *hdr;
3475b094
JM
15953
15954 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
15955 reason_code);
15956
15957 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15958 if (!msg)
15959 return;
15960
15961 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
15962 if (!hdr) {
15963 nlmsg_free(msg);
15964 return;
15965 }
15966
15967 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15968 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15969 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
15970 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
15971 (reason_code > 0 &&
15972 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
15973 goto nla_put_failure;
15974
9c90a9f6 15975 genlmsg_end(msg, hdr);
3475b094 15976
68eb5503 15977 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15978 NL80211_MCGRP_MLME, gfp);
3475b094
JM
15979 return;
15980
15981 nla_put_failure:
3475b094
JM
15982 nlmsg_free(msg);
15983}
15984EXPORT_SYMBOL(cfg80211_tdls_oper_request);
15985
026331c4
JM
15986static int nl80211_netlink_notify(struct notifier_block * nb,
15987 unsigned long state,
15988 void *_notify)
15989{
15990 struct netlink_notify *notify = _notify;
15991 struct cfg80211_registered_device *rdev;
15992 struct wireless_dev *wdev;
37c73b5f 15993 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 15994
8f815cdd 15995 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
15996 return NOTIFY_DONE;
15997
15998 rcu_read_lock();
15999
5e760230 16000 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
ca986ad9 16001 struct cfg80211_sched_scan_request *sched_scan_req;
753aacfd 16002
ca986ad9
AVS
16003 list_for_each_entry_rcu(sched_scan_req,
16004 &rdev->sched_scan_req_list,
16005 list) {
16006 if (sched_scan_req->owner_nlportid == notify->portid) {
16007 sched_scan_req->nl_owner_dead = true;
753aacfd 16008 schedule_work(&rdev->sched_scan_stop_wk);
ca986ad9 16009 }
753aacfd 16010 }
78f22b6a 16011
53873f13 16012 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 16013 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 16014
ab81007a
JB
16015 if (wdev->owner_nlportid == notify->portid) {
16016 wdev->nl_owner_dead = true;
16017 schedule_work(&rdev->destroy_work);
16018 } else if (wdev->conn_owner_nlportid == notify->portid) {
bd2522b1 16019 schedule_work(&wdev->disconnect_wk);
ab81007a 16020 }
78f22b6a
JB
16021 }
16022
37c73b5f
BG
16023 spin_lock_bh(&rdev->beacon_registrations_lock);
16024 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
16025 list) {
16026 if (reg->nlportid == notify->portid) {
16027 list_del(&reg->list);
16028 kfree(reg);
16029 break;
16030 }
16031 }
16032 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230 16033 }
026331c4
JM
16034
16035 rcu_read_unlock();
16036
05050753
I
16037 /*
16038 * It is possible that the user space process that is controlling the
16039 * indoor setting disappeared, so notify the regulatory core.
16040 */
16041 regulatory_netlink_notify(notify->portid);
6784c7db 16042 return NOTIFY_OK;
026331c4
JM
16043}
16044
16045static struct notifier_block nl80211_netlink_notifier = {
16046 .notifier_call = nl80211_netlink_notify,
16047};
16048
355199e0
JM
16049void cfg80211_ft_event(struct net_device *netdev,
16050 struct cfg80211_ft_event_params *ft_event)
16051{
16052 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 16053 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
16054 struct sk_buff *msg;
16055 void *hdr;
355199e0
JM
16056
16057 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
16058
16059 if (!ft_event->target_ap)
16060 return;
16061
1039d081
DL
16062 msg = nlmsg_new(100 + ft_event->ies_len + ft_event->ric_ies_len,
16063 GFP_KERNEL);
355199e0
JM
16064 if (!msg)
16065 return;
16066
16067 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
16068 if (!hdr)
16069 goto out;
355199e0 16070
ae917c9f
JB
16071 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16072 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16073 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
16074 goto out;
355199e0 16075
ae917c9f
JB
16076 if (ft_event->ies &&
16077 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
16078 goto out;
16079 if (ft_event->ric_ies &&
16080 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
16081 ft_event->ric_ies))
16082 goto out;
355199e0 16083
9c90a9f6 16084 genlmsg_end(msg, hdr);
355199e0 16085
68eb5503 16086 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16087 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
16088 return;
16089 out:
16090 nlmsg_free(msg);
355199e0
JM
16091}
16092EXPORT_SYMBOL(cfg80211_ft_event);
16093
5de17984
AS
16094void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
16095{
16096 struct cfg80211_registered_device *rdev;
16097 struct sk_buff *msg;
16098 void *hdr;
16099 u32 nlportid;
16100
f26cbf40 16101 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
16102 if (!rdev->crit_proto_nlportid)
16103 return;
16104
16105 nlportid = rdev->crit_proto_nlportid;
16106 rdev->crit_proto_nlportid = 0;
16107
16108 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16109 if (!msg)
16110 return;
16111
16112 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
16113 if (!hdr)
16114 goto nla_put_failure;
16115
16116 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
16117 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16118 NL80211_ATTR_PAD))
5de17984
AS
16119 goto nla_put_failure;
16120
16121 genlmsg_end(msg, hdr);
16122
16123 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
16124 return;
16125
16126 nla_put_failure:
5de17984 16127 nlmsg_free(msg);
5de17984
AS
16128}
16129EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
16130
348baf0e
JB
16131void nl80211_send_ap_stopped(struct wireless_dev *wdev)
16132{
16133 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16134 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
16135 struct sk_buff *msg;
16136 void *hdr;
16137
16138 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
16139 if (!msg)
16140 return;
16141
16142 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
16143 if (!hdr)
16144 goto out;
16145
16146 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16147 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
16148 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16149 NL80211_ATTR_PAD))
348baf0e
JB
16150 goto out;
16151
16152 genlmsg_end(msg, hdr);
16153
16154 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
16155 NL80211_MCGRP_MLME, GFP_KERNEL);
16156 return;
16157 out:
16158 nlmsg_free(msg);
16159}
16160
40cbfa90
SD
16161int cfg80211_external_auth_request(struct net_device *dev,
16162 struct cfg80211_external_auth_params *params,
16163 gfp_t gfp)
16164{
16165 struct wireless_dev *wdev = dev->ieee80211_ptr;
16166 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
16167 struct sk_buff *msg;
16168 void *hdr;
16169
16170 if (!wdev->conn_owner_nlportid)
16171 return -EINVAL;
16172
16173 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16174 if (!msg)
16175 return -ENOMEM;
16176
16177 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
16178 if (!hdr)
16179 goto nla_put_failure;
16180
16181 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16182 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16183 nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
16184 nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
16185 params->action) ||
16186 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
16187 nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
16188 params->ssid.ssid))
16189 goto nla_put_failure;
16190
16191 genlmsg_end(msg, hdr);
16192 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
16193 wdev->conn_owner_nlportid);
16194 return 0;
16195
16196 nla_put_failure:
16197 nlmsg_free(msg);
16198 return -ENOBUFS;
16199}
16200EXPORT_SYMBOL(cfg80211_external_auth_request);
16201
55682965
JB
16202/* initialisation/exit functions */
16203
56989f6d 16204int __init nl80211_init(void)
55682965 16205{
0d63cbb5 16206 int err;
55682965 16207
489111e5 16208 err = genl_register_family(&nl80211_fam);
55682965
JB
16209 if (err)
16210 return err;
16211
026331c4
JM
16212 err = netlink_register_notifier(&nl80211_netlink_notifier);
16213 if (err)
16214 goto err_out;
16215
55682965
JB
16216 return 0;
16217 err_out:
16218 genl_unregister_family(&nl80211_fam);
16219 return err;
16220}
16221
16222void nl80211_exit(void)
16223{
026331c4 16224 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
16225 genl_unregister_family(&nl80211_fam);
16226}