]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - net/wireless/nl80211.c
Merge tag 'char-misc-4.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregk...
[mirror_ubuntu-bionic-kernel.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
55682965
JB
7 */
8
9#include <linux/if.h>
10#include <linux/module.h>
11#include <linux/err.h>
5a0e3ad6 12#include <linux/slab.h>
55682965
JB
13#include <linux/list.h>
14#include <linux/if_ether.h>
15#include <linux/ieee80211.h>
16#include <linux/nl80211.h>
17#include <linux/rtnetlink.h>
18#include <linux/netlink.h>
2a519311 19#include <linux/etherdevice.h>
463d0183 20#include <net/net_namespace.h>
55682965
JB
21#include <net/genetlink.h>
22#include <net/cfg80211.h>
463d0183 23#include <net/sock.h>
2a0e047e 24#include <net/inet_connection_sock.h>
55682965
JB
25#include "core.h"
26#include "nl80211.h"
b2e1b302 27#include "reg.h"
e35e4d28 28#include "rdev-ops.h"
55682965 29
5fb628e9
JM
30static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
31 struct genl_info *info,
32 struct cfg80211_crypto_settings *settings,
33 int cipher_limit);
34
55682965 35/* the netlink family */
489111e5 36static struct genl_family nl80211_fam;
55682965 37
2a94fe48
JB
38/* multicast groups */
39enum nl80211_multicast_groups {
40 NL80211_MCGRP_CONFIG,
41 NL80211_MCGRP_SCAN,
42 NL80211_MCGRP_REGULATORY,
43 NL80211_MCGRP_MLME,
567ffc35 44 NL80211_MCGRP_VENDOR,
50bcd31d 45 NL80211_MCGRP_NAN,
2a94fe48
JB
46 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
47};
48
49static const struct genl_multicast_group nl80211_mcgrps[] = {
71b836ec
JB
50 [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
51 [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
52 [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
53 [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
54 [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
50bcd31d 55 [NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
2a94fe48 56#ifdef CONFIG_NL80211_TESTMODE
71b836ec 57 [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
2a94fe48
JB
58#endif
59};
60
89a54e48
JB
61/* returns ERR_PTR values */
62static struct wireless_dev *
63__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
55682965 64{
89a54e48
JB
65 struct cfg80211_registered_device *rdev;
66 struct wireless_dev *result = NULL;
67 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
68 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
69 u64 wdev_id;
70 int wiphy_idx = -1;
71 int ifidx = -1;
55682965 72
5fe231e8 73 ASSERT_RTNL();
55682965 74
89a54e48
JB
75 if (!have_ifidx && !have_wdev_id)
76 return ERR_PTR(-EINVAL);
55682965 77
89a54e48
JB
78 if (have_ifidx)
79 ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
80 if (have_wdev_id) {
81 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
82 wiphy_idx = wdev_id >> 32;
55682965
JB
83 }
84
89a54e48
JB
85 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
86 struct wireless_dev *wdev;
87
88 if (wiphy_net(&rdev->wiphy) != netns)
89 continue;
90
91 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
92 continue;
93
53873f13 94 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
89a54e48
JB
95 if (have_ifidx && wdev->netdev &&
96 wdev->netdev->ifindex == ifidx) {
97 result = wdev;
98 break;
99 }
100 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
101 result = wdev;
102 break;
103 }
104 }
89a54e48
JB
105
106 if (result)
107 break;
108 }
109
110 if (result)
111 return result;
112 return ERR_PTR(-ENODEV);
55682965
JB
113}
114
a9455408 115static struct cfg80211_registered_device *
878d9ec7 116__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
a9455408 117{
7fee4778
JB
118 struct cfg80211_registered_device *rdev = NULL, *tmp;
119 struct net_device *netdev;
a9455408 120
5fe231e8 121 ASSERT_RTNL();
a9455408 122
878d9ec7 123 if (!attrs[NL80211_ATTR_WIPHY] &&
89a54e48
JB
124 !attrs[NL80211_ATTR_IFINDEX] &&
125 !attrs[NL80211_ATTR_WDEV])
7fee4778
JB
126 return ERR_PTR(-EINVAL);
127
878d9ec7 128 if (attrs[NL80211_ATTR_WIPHY])
7fee4778 129 rdev = cfg80211_rdev_by_wiphy_idx(
878d9ec7 130 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
a9455408 131
89a54e48
JB
132 if (attrs[NL80211_ATTR_WDEV]) {
133 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
134 struct wireless_dev *wdev;
135 bool found = false;
136
137 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
138 if (tmp) {
139 /* make sure wdev exists */
53873f13 140 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
89a54e48
JB
141 if (wdev->identifier != (u32)wdev_id)
142 continue;
143 found = true;
144 break;
145 }
89a54e48
JB
146
147 if (!found)
148 tmp = NULL;
149
150 if (rdev && tmp != rdev)
151 return ERR_PTR(-EINVAL);
152 rdev = tmp;
153 }
154 }
155
878d9ec7
JB
156 if (attrs[NL80211_ATTR_IFINDEX]) {
157 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
7a087e74 158
7f2b8562 159 netdev = __dev_get_by_index(netns, ifindex);
7fee4778
JB
160 if (netdev) {
161 if (netdev->ieee80211_ptr)
f26cbf40
ZG
162 tmp = wiphy_to_rdev(
163 netdev->ieee80211_ptr->wiphy);
7fee4778
JB
164 else
165 tmp = NULL;
166
7fee4778
JB
167 /* not wireless device -- return error */
168 if (!tmp)
169 return ERR_PTR(-EINVAL);
170
171 /* mismatch -- return error */
172 if (rdev && tmp != rdev)
173 return ERR_PTR(-EINVAL);
174
175 rdev = tmp;
a9455408 176 }
a9455408 177 }
a9455408 178
4f7eff10
JB
179 if (!rdev)
180 return ERR_PTR(-ENODEV);
a9455408 181
4f7eff10
JB
182 if (netns != wiphy_net(&rdev->wiphy))
183 return ERR_PTR(-ENODEV);
184
185 return rdev;
a9455408
JB
186}
187
188/*
189 * This function returns a pointer to the driver
190 * that the genl_info item that is passed refers to.
a9455408
JB
191 *
192 * The result of this can be a PTR_ERR and hence must
193 * be checked with IS_ERR() for errors.
194 */
195static struct cfg80211_registered_device *
4f7eff10 196cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
a9455408 197{
5fe231e8 198 return __cfg80211_rdev_from_attrs(netns, info->attrs);
a9455408
JB
199}
200
55682965 201/* policy for the attributes */
8cd4d456 202static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
55682965
JB
203 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
204 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 205 .len = 20-1 },
31888487 206 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 207
72bdcf34 208 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 209 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
3d9d1d66
JB
210 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
211 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
212 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
213
b9a5f8ca
JM
214 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
215 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
216 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
217 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 218 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
3057dbfd 219 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
55682965
JB
220
221 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
222 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
223 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 224
e007b857
EP
225 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
226 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
41ade00f 227
b9454e83 228 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
229 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
230 .len = WLAN_MAX_KEY_LEN },
231 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
232 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
233 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 234 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
e31b8213 235 [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
ed1b6cc7
JB
236
237 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
238 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
239 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
240 .len = IEEE80211_MAX_DATA_LEN },
241 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
242 .len = IEEE80211_MAX_DATA_LEN },
5727ef1b
JB
243 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
244 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
245 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
246 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
247 .len = NL80211_MAX_SUPP_RATES },
2ec600d6 248 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
5727ef1b 249 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 250 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 251 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 252 .len = IEEE80211_MAX_MESH_ID_LEN },
2ec600d6 253 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
9f1ba906 254
b2e1b302
LR
255 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
256 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
257
9f1ba906
JM
258 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
259 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
260 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
261 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
262 .len = NL80211_MAX_SUPP_RATES },
50b12f59 263 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 264
24bdd9f4 265 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 266 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 267
6c739419 268 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
9aed3cc1
JM
269
270 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
271 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
272 .len = IEEE80211_MAX_DATA_LEN },
2a519311
JB
273 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
274 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
275
276 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
277 .len = IEEE80211_MAX_SSID_LEN },
278 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
279 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 280 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 281 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
dc6382ce 282 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
eccb8e8f
JB
283 [NL80211_ATTR_STA_FLAGS2] = {
284 .len = sizeof(struct nl80211_sta_flag_update),
285 },
3f77316c 286 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
287 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
288 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
b23aa676
SO
289 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
290 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
291 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 292 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 293 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
9361df14 294 [NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN },
9588bbd5
JM
295 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
296 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 297 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
298 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
299 .len = IEEE80211_MAX_DATA_LEN },
300 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ffb9eb3d 301 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
d6dc1a38 302 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 303 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 304 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
305 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
306 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 307 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
308 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
309 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 310 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 311 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 312 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 313 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
9c3990aa 314 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
bbe6ad6d 315 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 316 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 317 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
32e9de84 318 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
9946ecfb
JM
319 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
320 .len = IEEE80211_MAX_DATA_LEN },
321 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
322 .len = IEEE80211_MAX_DATA_LEN },
f4b34b55 323 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 324 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 325 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
326 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
327 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
328 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
329 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
330 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 331 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 332 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
333 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
334 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 335 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
336 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
337 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
338 .len = NL80211_HT_CAPABILITY_LEN
339 },
1d9d9213 340 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 341 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 342 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 343 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 344 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
11b6b5a4 345 [NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, },
f461be3e 346 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
ed473771 347 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
53cabad7
JB
348 [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
349 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
8feb69c7 350 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] = {. type = NLA_U32 },
77765eaf
VT
351 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
352 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
353 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
354 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 355 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
356 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
357 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
358 .len = NL80211_VHT_CAPABILITY_LEN,
359 },
355199e0
JM
360 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
361 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
362 .len = IEEE80211_MAX_DATA_LEN },
5e4b6f56 363 [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
16ef1fe2
SW
364 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
365 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
366 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
9a774c78
AO
367 [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY },
368 [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY },
c01fc9ad
SD
369 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
370 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
5336fa88 371 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 372 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
373 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
374 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
375 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
fa9ffc74
KP
376 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
377 .len = IEEE80211_QOS_MAP_LEN_MAX },
1df4a510
JM
378 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
379 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
df942e7b 380 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
18e5ca65 381 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
34d22ce2 382 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
bab5ab7d 383 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
960d01ac
JB
384 [NL80211_ATTR_TSID] = { .type = NLA_U8 },
385 [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
386 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
18998c38 387 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
ad2b26ab 388 [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
1bdd716c 389 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
4b681c82 390 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
9c748934 391 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
05050753 392 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
34d50519 393 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
38de03d2 394 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
17b94247 395 [NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 },
c6e6a0c8
AE
396 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
397 .len = VHT_MUMIMO_GROUPS_DATA_LEN
398 },
399 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
cb3b7d87 400 [NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 },
8585989d 401 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
a442b761 402 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
348bd456
JM
403 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
404 .len = FILS_MAX_KEK_LEN },
405 [NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
ce0ce13a 406 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
2fa436b3 407 [NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
bf95ecdb 408 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
409 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
410 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
411 },
3093ebbe 412 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
a3caf744
VK
413 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
414 .len = FILS_ERP_MAX_USERNAME_LEN },
415 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
416 .len = FILS_ERP_MAX_REALM_LEN },
417 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
418 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
419 .len = FILS_ERP_MAX_RRK_LEN },
420 [NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
421 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
ca986ad9 422 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
55682965
JB
423};
424
e31b8213 425/* policy for the key attributes */
b54452b0 426static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 427 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
428 [NL80211_KEY_IDX] = { .type = NLA_U8 },
429 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 430 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
431 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
432 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
e31b8213 433 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
dbd2fd65
JB
434 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
435};
436
437/* policy for the key default flags */
438static const struct nla_policy
439nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
440 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
441 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
442};
443
f83ace3b 444#ifdef CONFIG_PM
ff1b6e69
JB
445/* policy for WoWLAN attributes */
446static const struct nla_policy
447nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
448 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
449 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
450 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
451 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
452 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
453 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
454 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
455 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 456 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 457 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
458};
459
460static const struct nla_policy
461nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
462 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
463 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
464 [NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
465 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
466 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
467 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
468 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
469 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
470 },
471 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
472 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
473 },
474 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
475 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
476 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
ff1b6e69 477};
f83ace3b 478#endif /* CONFIG_PM */
ff1b6e69 479
be29b99a
AK
480/* policy for coalesce rule attributes */
481static const struct nla_policy
482nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
483 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
484 [NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U32 },
485 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
486};
487
e5497d76
JB
488/* policy for GTK rekey offload attributes */
489static const struct nla_policy
490nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
491 [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
492 [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
493 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
494};
495
a1f1c21c
LC
496static const struct nla_policy
497nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 498 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 499 .len = IEEE80211_MAX_SSID_LEN },
3007e352 500 [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
88e920b4 501 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
a1f1c21c
LC
502};
503
3b06d277
AS
504static const struct nla_policy
505nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
506 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
507 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
508};
509
38de03d2
AS
510static const struct nla_policy
511nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
512 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
513 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
514 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
515 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
516 },
517};
518
a442b761
AB
519/* policy for NAN function attributes */
520static const struct nla_policy
521nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
522 [NL80211_NAN_FUNC_TYPE] = { .type = NLA_U8 },
0a27844c 523 [NL80211_NAN_FUNC_SERVICE_ID] = {
a442b761
AB
524 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
525 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
526 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
527 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
528 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
529 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
530 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = { .len = ETH_ALEN },
531 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
532 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
533 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
534 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
535 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
536 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
537 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
538 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
539 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
540};
541
542/* policy for Service Response Filter attributes */
543static const struct nla_policy
544nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
545 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
546 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
547 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
548 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
549 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
550};
551
ad670233
PX
552/* policy for packet pattern attributes */
553static const struct nla_policy
554nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
555 [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
556 [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
557 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
558};
559
97990a06
JB
560static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
561 struct netlink_callback *cb,
562 struct cfg80211_registered_device **rdev,
563 struct wireless_dev **wdev)
a043897a 564{
97990a06 565 int err;
a043897a 566
97990a06
JB
567 if (!cb->args[0]) {
568 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
c90c39da 569 genl_family_attrbuf(&nl80211_fam),
fceb6435 570 nl80211_fam.maxattr, nl80211_policy, NULL);
97990a06 571 if (err)
ea90e0dc 572 return err;
67748893 573
c90c39da
JB
574 *wdev = __cfg80211_wdev_from_attrs(
575 sock_net(skb->sk),
576 genl_family_attrbuf(&nl80211_fam));
ea90e0dc
JB
577 if (IS_ERR(*wdev))
578 return PTR_ERR(*wdev);
f26cbf40 579 *rdev = wiphy_to_rdev((*wdev)->wiphy);
c319d50b
JB
580 /* 0 is the first index - add 1 to parse only once */
581 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
582 cb->args[1] = (*wdev)->identifier;
583 } else {
c319d50b
JB
584 /* subtract the 1 again here */
585 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
97990a06 586 struct wireless_dev *tmp;
67748893 587
ea90e0dc
JB
588 if (!wiphy)
589 return -ENODEV;
f26cbf40 590 *rdev = wiphy_to_rdev(wiphy);
97990a06 591 *wdev = NULL;
67748893 592
53873f13 593 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
594 if (tmp->identifier == cb->args[1]) {
595 *wdev = tmp;
596 break;
597 }
598 }
67748893 599
ea90e0dc
JB
600 if (!*wdev)
601 return -ENODEV;
67748893
JB
602 }
603
67748893 604 return 0;
67748893
JB
605}
606
f4a11bb0
JB
607/* IE validation */
608static bool is_valid_ie_attr(const struct nlattr *attr)
609{
610 const u8 *pos;
611 int len;
612
613 if (!attr)
614 return true;
615
616 pos = nla_data(attr);
617 len = nla_len(attr);
618
619 while (len) {
620 u8 elemlen;
621
622 if (len < 2)
623 return false;
624 len -= 2;
625
626 elemlen = pos[1];
627 if (elemlen > len)
628 return false;
629
630 len -= elemlen;
631 pos += 2 + elemlen;
632 }
633
634 return true;
635}
636
55682965 637/* message building helper */
15e47304 638static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
55682965
JB
639 int flags, u8 cmd)
640{
641 /* since there is no private header just add the generic one */
15e47304 642 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
643}
644
5dab3b8a 645static int nl80211_msg_put_channel(struct sk_buff *msg,
cdc89b97
JB
646 struct ieee80211_channel *chan,
647 bool large)
5dab3b8a 648{
ea077c1c
RL
649 /* Some channels must be completely excluded from the
650 * list to protect old user-space tools from breaking
651 */
652 if (!large && chan->flags &
653 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
654 return 0;
655
9360ffd1
DM
656 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
657 chan->center_freq))
658 goto nla_put_failure;
5dab3b8a 659
9360ffd1
DM
660 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
661 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
662 goto nla_put_failure;
8fe02e16
LR
663 if (chan->flags & IEEE80211_CHAN_NO_IR) {
664 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
665 goto nla_put_failure;
666 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
667 goto nla_put_failure;
668 }
cdc89b97
JB
669 if (chan->flags & IEEE80211_CHAN_RADAR) {
670 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
671 goto nla_put_failure;
672 if (large) {
673 u32 time;
674
675 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
676
677 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
678 chan->dfs_state))
679 goto nla_put_failure;
680 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
681 time))
682 goto nla_put_failure;
089027e5
JD
683 if (nla_put_u32(msg,
684 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
685 chan->dfs_cac_ms))
686 goto nla_put_failure;
cdc89b97
JB
687 }
688 }
5dab3b8a 689
fe1abafd
JB
690 if (large) {
691 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
692 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
693 goto nla_put_failure;
694 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
695 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
696 goto nla_put_failure;
697 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
698 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
699 goto nla_put_failure;
700 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
701 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
702 goto nla_put_failure;
570dbde1
DS
703 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
704 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
705 goto nla_put_failure;
06f207fc
AN
706 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
707 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 708 goto nla_put_failure;
ea077c1c
RL
709 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
710 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
711 goto nla_put_failure;
712 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
713 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
714 goto nla_put_failure;
fe1abafd
JB
715 }
716
9360ffd1
DM
717 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
718 DBM_TO_MBM(chan->max_power)))
719 goto nla_put_failure;
5dab3b8a
LR
720
721 return 0;
722
723 nla_put_failure:
724 return -ENOBUFS;
725}
726
55682965
JB
727/* netlink command implementations */
728
b9454e83
JB
729struct key_parse {
730 struct key_params p;
731 int idx;
e31b8213 732 int type;
b9454e83 733 bool def, defmgmt;
dbd2fd65 734 bool def_uni, def_multi;
b9454e83
JB
735};
736
737static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
738{
739 struct nlattr *tb[NL80211_KEY_MAX + 1];
740 int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
fceb6435 741 nl80211_key_policy, NULL);
b9454e83
JB
742 if (err)
743 return err;
744
745 k->def = !!tb[NL80211_KEY_DEFAULT];
746 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
747
dbd2fd65
JB
748 if (k->def) {
749 k->def_uni = true;
750 k->def_multi = true;
751 }
752 if (k->defmgmt)
753 k->def_multi = true;
754
b9454e83
JB
755 if (tb[NL80211_KEY_IDX])
756 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
757
758 if (tb[NL80211_KEY_DATA]) {
759 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
760 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
761 }
762
763 if (tb[NL80211_KEY_SEQ]) {
764 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
765 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
766 }
767
768 if (tb[NL80211_KEY_CIPHER])
769 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
770
e31b8213
JB
771 if (tb[NL80211_KEY_TYPE]) {
772 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
773 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
774 return -EINVAL;
775 }
776
dbd2fd65
JB
777 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
778 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 779
2da8f419
JB
780 err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
781 tb[NL80211_KEY_DEFAULT_TYPES],
fceb6435 782 nl80211_key_default_policy, NULL);
dbd2fd65
JB
783 if (err)
784 return err;
785
786 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
787 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
788 }
789
b9454e83
JB
790 return 0;
791}
792
793static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
794{
795 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
796 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
797 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
798 }
799
800 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
801 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
802 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
803 }
804
805 if (info->attrs[NL80211_ATTR_KEY_IDX])
806 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
807
808 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
809 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
810
811 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
812 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
813
dbd2fd65
JB
814 if (k->def) {
815 k->def_uni = true;
816 k->def_multi = true;
817 }
818 if (k->defmgmt)
819 k->def_multi = true;
820
e31b8213
JB
821 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
822 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
823 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
824 return -EINVAL;
825 }
826
dbd2fd65
JB
827 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
828 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
fceb6435
JB
829 int err = nla_parse_nested(kdt,
830 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
831 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
fe52145f
JB
832 nl80211_key_default_policy,
833 info->extack);
dbd2fd65
JB
834 if (err)
835 return err;
836
837 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
838 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
839 }
840
b9454e83
JB
841 return 0;
842}
843
844static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
845{
846 int err;
847
848 memset(k, 0, sizeof(*k));
849 k->idx = -1;
e31b8213 850 k->type = -1;
b9454e83
JB
851
852 if (info->attrs[NL80211_ATTR_KEY])
853 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
854 else
855 err = nl80211_parse_key_old(info, k);
856
857 if (err)
858 return err;
859
860 if (k->def && k->defmgmt)
861 return -EINVAL;
862
dbd2fd65
JB
863 if (k->defmgmt) {
864 if (k->def_uni || !k->def_multi)
865 return -EINVAL;
866 }
867
b9454e83
JB
868 if (k->idx != -1) {
869 if (k->defmgmt) {
870 if (k->idx < 4 || k->idx > 5)
871 return -EINVAL;
872 } else if (k->def) {
873 if (k->idx < 0 || k->idx > 3)
874 return -EINVAL;
875 } else {
876 if (k->idx < 0 || k->idx > 5)
877 return -EINVAL;
878 }
879 }
880
881 return 0;
882}
883
fffd0934
JB
884static struct cfg80211_cached_keys *
885nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
de7044ee 886 struct nlattr *keys, bool *no_ht)
fffd0934
JB
887{
888 struct key_parse parse;
889 struct nlattr *key;
890 struct cfg80211_cached_keys *result;
891 int rem, err, def = 0;
f1c1f17a
JB
892 bool have_key = false;
893
894 nla_for_each_nested(key, keys, rem) {
895 have_key = true;
896 break;
897 }
898
899 if (!have_key)
900 return NULL;
fffd0934
JB
901
902 result = kzalloc(sizeof(*result), GFP_KERNEL);
903 if (!result)
904 return ERR_PTR(-ENOMEM);
905
906 result->def = -1;
fffd0934
JB
907
908 nla_for_each_nested(key, keys, rem) {
909 memset(&parse, 0, sizeof(parse));
910 parse.idx = -1;
911
912 err = nl80211_parse_key_new(key, &parse);
913 if (err)
914 goto error;
915 err = -EINVAL;
916 if (!parse.p.key)
917 goto error;
42ee231c 918 if (parse.idx < 0 || parse.idx > 3)
fffd0934
JB
919 goto error;
920 if (parse.def) {
921 if (def)
922 goto error;
923 def = 1;
924 result->def = parse.idx;
dbd2fd65
JB
925 if (!parse.def_uni || !parse.def_multi)
926 goto error;
fffd0934
JB
927 } else if (parse.defmgmt)
928 goto error;
929 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 930 parse.idx, false, NULL);
fffd0934
JB
931 if (err)
932 goto error;
386b1f27
JB
933 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
934 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
935 err = -EINVAL;
936 goto error;
937 }
fffd0934
JB
938 result->params[parse.idx].cipher = parse.p.cipher;
939 result->params[parse.idx].key_len = parse.p.key_len;
940 result->params[parse.idx].key = result->data[parse.idx];
941 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 942
386b1f27
JB
943 /* must be WEP key if we got here */
944 if (no_ht)
945 *no_ht = true;
fffd0934
JB
946 }
947
f1c1f17a
JB
948 if (result->def < 0) {
949 err = -EINVAL;
950 goto error;
951 }
952
fffd0934
JB
953 return result;
954 error:
955 kfree(result);
956 return ERR_PTR(err);
957}
958
959static int nl80211_key_allowed(struct wireless_dev *wdev)
960{
961 ASSERT_WDEV_LOCK(wdev);
962
fffd0934
JB
963 switch (wdev->iftype) {
964 case NL80211_IFTYPE_AP:
965 case NL80211_IFTYPE_AP_VLAN:
074ac8df 966 case NL80211_IFTYPE_P2P_GO:
ff973af7 967 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
968 break;
969 case NL80211_IFTYPE_ADHOC:
fffd0934 970 case NL80211_IFTYPE_STATION:
074ac8df 971 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 972 if (!wdev->current_bss)
fffd0934
JB
973 return -ENOLINK;
974 break;
de4fcbad 975 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 976 case NL80211_IFTYPE_OCB:
de4fcbad 977 case NL80211_IFTYPE_MONITOR:
cb3b7d87 978 case NL80211_IFTYPE_NAN:
de4fcbad
JB
979 case NL80211_IFTYPE_P2P_DEVICE:
980 case NL80211_IFTYPE_WDS:
981 case NUM_NL80211_IFTYPES:
fffd0934
JB
982 return -EINVAL;
983 }
984
985 return 0;
986}
987
664834de
JM
988static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
989 struct nlattr *tb)
990{
991 struct ieee80211_channel *chan;
992
993 if (tb == NULL)
994 return NULL;
995 chan = ieee80211_get_channel(wiphy, nla_get_u32(tb));
996 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
997 return NULL;
998 return chan;
999}
1000
7527a782
JB
1001static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
1002{
1003 struct nlattr *nl_modes = nla_nest_start(msg, attr);
1004 int i;
1005
1006 if (!nl_modes)
1007 goto nla_put_failure;
1008
1009 i = 0;
1010 while (ifmodes) {
9360ffd1
DM
1011 if ((ifmodes & 1) && nla_put_flag(msg, i))
1012 goto nla_put_failure;
7527a782
JB
1013 ifmodes >>= 1;
1014 i++;
1015 }
1016
1017 nla_nest_end(msg, nl_modes);
1018 return 0;
1019
1020nla_put_failure:
1021 return -ENOBUFS;
1022}
1023
1024static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1025 struct sk_buff *msg,
1026 bool large)
7527a782
JB
1027{
1028 struct nlattr *nl_combis;
1029 int i, j;
1030
1031 nl_combis = nla_nest_start(msg,
1032 NL80211_ATTR_INTERFACE_COMBINATIONS);
1033 if (!nl_combis)
1034 goto nla_put_failure;
1035
1036 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1037 const struct ieee80211_iface_combination *c;
1038 struct nlattr *nl_combi, *nl_limits;
1039
1040 c = &wiphy->iface_combinations[i];
1041
1042 nl_combi = nla_nest_start(msg, i + 1);
1043 if (!nl_combi)
1044 goto nla_put_failure;
1045
1046 nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
1047 if (!nl_limits)
1048 goto nla_put_failure;
1049
1050 for (j = 0; j < c->n_limits; j++) {
1051 struct nlattr *nl_limit;
1052
1053 nl_limit = nla_nest_start(msg, j + 1);
1054 if (!nl_limit)
1055 goto nla_put_failure;
9360ffd1
DM
1056 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1057 c->limits[j].max))
1058 goto nla_put_failure;
7527a782
JB
1059 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1060 c->limits[j].types))
1061 goto nla_put_failure;
1062 nla_nest_end(msg, nl_limit);
1063 }
1064
1065 nla_nest_end(msg, nl_limits);
1066
9360ffd1
DM
1067 if (c->beacon_int_infra_match &&
1068 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1069 goto nla_put_failure;
1070 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1071 c->num_different_channels) ||
1072 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1073 c->max_interfaces))
1074 goto nla_put_failure;
cdc89b97 1075 if (large &&
8c48b50a
FF
1076 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1077 c->radar_detect_widths) ||
1078 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1079 c->radar_detect_regions)))
cdc89b97 1080 goto nla_put_failure;
0c317a02
PK
1081 if (c->beacon_int_min_gcd &&
1082 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1083 c->beacon_int_min_gcd))
1084 goto nla_put_failure;
7527a782
JB
1085
1086 nla_nest_end(msg, nl_combi);
1087 }
1088
1089 nla_nest_end(msg, nl_combis);
1090
1091 return 0;
1092nla_put_failure:
1093 return -ENOBUFS;
1094}
1095
3713b4e3 1096#ifdef CONFIG_PM
b56cf720
JB
1097static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1098 struct sk_buff *msg)
1099{
964dc9e2 1100 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1101 struct nlattr *nl_tcp;
1102
1103 if (!tcp)
1104 return 0;
1105
1106 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
1107 if (!nl_tcp)
1108 return -ENOBUFS;
1109
1110 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1111 tcp->data_payload_max))
1112 return -ENOBUFS;
1113
1114 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1115 tcp->data_payload_max))
1116 return -ENOBUFS;
1117
1118 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1119 return -ENOBUFS;
1120
1121 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1122 sizeof(*tcp->tok), tcp->tok))
1123 return -ENOBUFS;
1124
1125 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1126 tcp->data_interval_max))
1127 return -ENOBUFS;
1128
1129 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1130 tcp->wake_payload_max))
1131 return -ENOBUFS;
1132
1133 nla_nest_end(msg, nl_tcp);
1134 return 0;
1135}
1136
3713b4e3 1137static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1138 struct cfg80211_registered_device *rdev,
b56cf720 1139 bool large)
55682965 1140{
3713b4e3 1141 struct nlattr *nl_wowlan;
55682965 1142
1b8ec87a 1143 if (!rdev->wiphy.wowlan)
3713b4e3 1144 return 0;
55682965 1145
3713b4e3
JB
1146 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
1147 if (!nl_wowlan)
1148 return -ENOBUFS;
9360ffd1 1149
1b8ec87a 1150 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1151 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1152 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1153 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1154 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1155 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1156 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1157 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1158 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1159 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1160 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1161 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1162 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1163 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1164 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1165 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1166 return -ENOBUFS;
9360ffd1 1167
1b8ec87a 1168 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1169 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1170 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1171 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1172 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1173 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1174 };
9360ffd1 1175
3713b4e3
JB
1176 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1177 sizeof(pat), &pat))
1178 return -ENOBUFS;
1179 }
9360ffd1 1180
75453ccb
LC
1181 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1182 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1183 rdev->wiphy.wowlan->max_nd_match_sets))
1184 return -ENOBUFS;
1185
1b8ec87a 1186 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1187 return -ENOBUFS;
1188
3713b4e3 1189 nla_nest_end(msg, nl_wowlan);
9360ffd1 1190
3713b4e3
JB
1191 return 0;
1192}
1193#endif
9360ffd1 1194
be29b99a 1195static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1196 struct cfg80211_registered_device *rdev)
be29b99a
AK
1197{
1198 struct nl80211_coalesce_rule_support rule;
1199
1b8ec87a 1200 if (!rdev->wiphy.coalesce)
be29b99a
AK
1201 return 0;
1202
1b8ec87a
ZG
1203 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1204 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1205 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1206 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1207 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1208 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1209
1210 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1211 return -ENOBUFS;
1212
1213 return 0;
1214}
1215
3713b4e3
JB
1216static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1217 struct ieee80211_supported_band *sband)
1218{
1219 struct nlattr *nl_rates, *nl_rate;
1220 struct ieee80211_rate *rate;
1221 int i;
87bbbe22 1222
3713b4e3
JB
1223 /* add HT info */
1224 if (sband->ht_cap.ht_supported &&
1225 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1226 sizeof(sband->ht_cap.mcs),
1227 &sband->ht_cap.mcs) ||
1228 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1229 sband->ht_cap.cap) ||
1230 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1231 sband->ht_cap.ampdu_factor) ||
1232 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1233 sband->ht_cap.ampdu_density)))
1234 return -ENOBUFS;
afe0cbf8 1235
3713b4e3
JB
1236 /* add VHT info */
1237 if (sband->vht_cap.vht_supported &&
1238 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1239 sizeof(sband->vht_cap.vht_mcs),
1240 &sband->vht_cap.vht_mcs) ||
1241 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1242 sband->vht_cap.cap)))
1243 return -ENOBUFS;
f59ac048 1244
3713b4e3
JB
1245 /* add bitrates */
1246 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
1247 if (!nl_rates)
1248 return -ENOBUFS;
ee688b00 1249
3713b4e3
JB
1250 for (i = 0; i < sband->n_bitrates; i++) {
1251 nl_rate = nla_nest_start(msg, i);
1252 if (!nl_rate)
1253 return -ENOBUFS;
ee688b00 1254
3713b4e3
JB
1255 rate = &sband->bitrates[i];
1256 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1257 rate->bitrate))
1258 return -ENOBUFS;
1259 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1260 nla_put_flag(msg,
1261 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1262 return -ENOBUFS;
ee688b00 1263
3713b4e3
JB
1264 nla_nest_end(msg, nl_rate);
1265 }
d51626df 1266
3713b4e3 1267 nla_nest_end(msg, nl_rates);
bf0c111e 1268
3713b4e3
JB
1269 return 0;
1270}
ee688b00 1271
3713b4e3
JB
1272static int
1273nl80211_send_mgmt_stypes(struct sk_buff *msg,
1274 const struct ieee80211_txrx_stypes *mgmt_stypes)
1275{
1276 u16 stypes;
1277 struct nlattr *nl_ftypes, *nl_ifs;
1278 enum nl80211_iftype ift;
1279 int i;
ee688b00 1280
3713b4e3
JB
1281 if (!mgmt_stypes)
1282 return 0;
5dab3b8a 1283
3713b4e3
JB
1284 nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES);
1285 if (!nl_ifs)
1286 return -ENOBUFS;
e2f367f2 1287
3713b4e3
JB
1288 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1289 nl_ftypes = nla_nest_start(msg, ift);
1290 if (!nl_ftypes)
1291 return -ENOBUFS;
1292 i = 0;
1293 stypes = mgmt_stypes[ift].tx;
1294 while (stypes) {
1295 if ((stypes & 1) &&
1296 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1297 (i << 4) | IEEE80211_FTYPE_MGMT))
1298 return -ENOBUFS;
1299 stypes >>= 1;
1300 i++;
ee688b00 1301 }
3713b4e3
JB
1302 nla_nest_end(msg, nl_ftypes);
1303 }
ee688b00 1304
3713b4e3 1305 nla_nest_end(msg, nl_ifs);
ee688b00 1306
3713b4e3
JB
1307 nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES);
1308 if (!nl_ifs)
1309 return -ENOBUFS;
ee688b00 1310
3713b4e3
JB
1311 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1312 nl_ftypes = nla_nest_start(msg, ift);
1313 if (!nl_ftypes)
1314 return -ENOBUFS;
1315 i = 0;
1316 stypes = mgmt_stypes[ift].rx;
1317 while (stypes) {
1318 if ((stypes & 1) &&
1319 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1320 (i << 4) | IEEE80211_FTYPE_MGMT))
1321 return -ENOBUFS;
1322 stypes >>= 1;
1323 i++;
1324 }
1325 nla_nest_end(msg, nl_ftypes);
1326 }
1327 nla_nest_end(msg, nl_ifs);
ee688b00 1328
3713b4e3
JB
1329 return 0;
1330}
ee688b00 1331
1794899e
JB
1332#define CMD(op, n) \
1333 do { \
1334 if (rdev->ops->op) { \
1335 i++; \
1336 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1337 goto nla_put_failure; \
1338 } \
1339 } while (0)
1340
1341static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
1342 struct sk_buff *msg)
1343{
1344 int i = 0;
1345
1346 /*
1347 * do *NOT* add anything into this function, new things need to be
1348 * advertised only to new versions of userspace that can deal with
1349 * the split (and they can't possibly care about new features...
1350 */
1351 CMD(add_virtual_intf, NEW_INTERFACE);
1352 CMD(change_virtual_intf, SET_INTERFACE);
1353 CMD(add_key, NEW_KEY);
1354 CMD(start_ap, START_AP);
1355 CMD(add_station, NEW_STATION);
1356 CMD(add_mpath, NEW_MPATH);
1357 CMD(update_mesh_config, SET_MESH_CONFIG);
1358 CMD(change_bss, SET_BSS);
1359 CMD(auth, AUTHENTICATE);
1360 CMD(assoc, ASSOCIATE);
1361 CMD(deauth, DEAUTHENTICATE);
1362 CMD(disassoc, DISASSOCIATE);
1363 CMD(join_ibss, JOIN_IBSS);
1364 CMD(join_mesh, JOIN_MESH);
1365 CMD(set_pmksa, SET_PMKSA);
1366 CMD(del_pmksa, DEL_PMKSA);
1367 CMD(flush_pmksa, FLUSH_PMKSA);
1368 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1369 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1370 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1371 CMD(mgmt_tx, FRAME);
1372 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1373 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1374 i++;
1375 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1376 goto nla_put_failure;
1377 }
1378 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
1379 rdev->ops->join_mesh) {
1380 i++;
1381 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1382 goto nla_put_failure;
1383 }
1384 CMD(set_wds_peer, SET_WDS_PEER);
1385 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1386 CMD(tdls_mgmt, TDLS_MGMT);
1387 CMD(tdls_oper, TDLS_OPER);
1388 }
ca986ad9 1389 if (rdev->wiphy.max_sched_scan_reqs)
1794899e
JB
1390 CMD(sched_scan_start, START_SCHED_SCAN);
1391 CMD(probe_client, PROBE_CLIENT);
1392 CMD(set_noack_map, SET_NOACK_MAP);
1393 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1394 i++;
1395 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1396 goto nla_put_failure;
1397 }
1398 CMD(start_p2p_device, START_P2P_DEVICE);
1399 CMD(set_mcast_rate, SET_MCAST_RATE);
1400#ifdef CONFIG_NL80211_TESTMODE
1401 CMD(testmode_cmd, TESTMODE);
1402#endif
1403
1404 if (rdev->ops->connect || rdev->ops->auth) {
1405 i++;
1406 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1407 goto nla_put_failure;
1408 }
1409
1410 if (rdev->ops->disconnect || rdev->ops->deauth) {
1411 i++;
1412 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1413 goto nla_put_failure;
1414 }
1415
1416 return i;
1417 nla_put_failure:
1418 return -ENOBUFS;
1419}
1420
86e8cf98
JB
1421struct nl80211_dump_wiphy_state {
1422 s64 filter_wiphy;
1423 long start;
019ae3a9 1424 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
1425 bool split;
1426};
1427
1b8ec87a 1428static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 1429 enum nl80211_commands cmd,
3713b4e3 1430 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 1431 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
1432{
1433 void *hdr;
1434 struct nlattr *nl_bands, *nl_band;
1435 struct nlattr *nl_freqs, *nl_freq;
1436 struct nlattr *nl_cmds;
57fbcce3 1437 enum nl80211_band band;
3713b4e3
JB
1438 struct ieee80211_channel *chan;
1439 int i;
1440 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 1441 rdev->wiphy.mgmt_stypes;
fe1abafd 1442 u32 features;
ee688b00 1443
3bb20556 1444 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
1445 if (!hdr)
1446 return -ENOBUFS;
ee688b00 1447
86e8cf98
JB
1448 if (WARN_ON(!state))
1449 return -EINVAL;
ee688b00 1450
1b8ec87a 1451 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 1452 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 1453 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
1454 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1455 cfg80211_rdev_list_generation))
8fdc621d
JB
1456 goto nla_put_failure;
1457
3bb20556
JB
1458 if (cmd != NL80211_CMD_NEW_WIPHY)
1459 goto finish;
1460
86e8cf98 1461 switch (state->split_start) {
3713b4e3
JB
1462 case 0:
1463 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 1464 rdev->wiphy.retry_short) ||
3713b4e3 1465 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 1466 rdev->wiphy.retry_long) ||
3713b4e3 1467 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 1468 rdev->wiphy.frag_threshold) ||
3713b4e3 1469 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 1470 rdev->wiphy.rts_threshold) ||
3713b4e3 1471 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 1472 rdev->wiphy.coverage_class) ||
3713b4e3 1473 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 1474 rdev->wiphy.max_scan_ssids) ||
3713b4e3 1475 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 1476 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 1477 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 1478 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 1479 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 1480 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 1481 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
3b06d277
AS
1482 rdev->wiphy.max_match_sets) ||
1483 nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
1484 rdev->wiphy.max_sched_scan_plans) ||
1485 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
1486 rdev->wiphy.max_sched_scan_plan_interval) ||
1487 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
1488 rdev->wiphy.max_sched_scan_plan_iterations))
9360ffd1 1489 goto nla_put_failure;
3713b4e3 1490
1b8ec87a 1491 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 1492 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 1493 goto nla_put_failure;
1b8ec87a 1494 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
1495 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
1496 goto nla_put_failure;
1b8ec87a 1497 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
1498 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
1499 goto nla_put_failure;
1b8ec87a 1500 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
1501 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
1502 goto nla_put_failure;
1b8ec87a 1503 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
1504 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
1505 goto nla_put_failure;
1b8ec87a 1506 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 1507 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 1508 goto nla_put_failure;
86e8cf98
JB
1509 state->split_start++;
1510 if (state->split)
3713b4e3
JB
1511 break;
1512 case 1:
1513 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
1514 sizeof(u32) * rdev->wiphy.n_cipher_suites,
1515 rdev->wiphy.cipher_suites))
3713b4e3 1516 goto nla_put_failure;
4745fc09 1517
3713b4e3 1518 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 1519 rdev->wiphy.max_num_pmkids))
3713b4e3 1520 goto nla_put_failure;
b23aa676 1521
1b8ec87a 1522 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 1523 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 1524 goto nla_put_failure;
b23aa676 1525
3713b4e3 1526 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 1527 rdev->wiphy.available_antennas_tx) ||
3713b4e3 1528 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 1529 rdev->wiphy.available_antennas_rx))
9360ffd1 1530 goto nla_put_failure;
b23aa676 1531
1b8ec87a 1532 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 1533 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 1534 rdev->wiphy.probe_resp_offload))
3713b4e3 1535 goto nla_put_failure;
8fdc621d 1536
1b8ec87a
ZG
1537 if ((rdev->wiphy.available_antennas_tx ||
1538 rdev->wiphy.available_antennas_rx) &&
1539 rdev->ops->get_antenna) {
3713b4e3
JB
1540 u32 tx_ant = 0, rx_ant = 0;
1541 int res;
7a087e74 1542
1b8ec87a 1543 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
1544 if (!res) {
1545 if (nla_put_u32(msg,
1546 NL80211_ATTR_WIPHY_ANTENNA_TX,
1547 tx_ant) ||
1548 nla_put_u32(msg,
1549 NL80211_ATTR_WIPHY_ANTENNA_RX,
1550 rx_ant))
1551 goto nla_put_failure;
1552 }
1553 }
a293911d 1554
86e8cf98
JB
1555 state->split_start++;
1556 if (state->split)
3713b4e3
JB
1557 break;
1558 case 2:
1559 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 1560 rdev->wiphy.interface_modes))
3713b4e3 1561 goto nla_put_failure;
86e8cf98
JB
1562 state->split_start++;
1563 if (state->split)
3713b4e3
JB
1564 break;
1565 case 3:
1566 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1567 if (!nl_bands)
1568 goto nla_put_failure;
f7ca38df 1569
86e8cf98 1570 for (band = state->band_start;
57fbcce3 1571 band < NUM_NL80211_BANDS; band++) {
3713b4e3 1572 struct ieee80211_supported_band *sband;
2e161f78 1573
1b8ec87a 1574 sband = rdev->wiphy.bands[band];
2e161f78 1575
3713b4e3
JB
1576 if (!sband)
1577 continue;
1578
1579 nl_band = nla_nest_start(msg, band);
1580 if (!nl_band)
2e161f78 1581 goto nla_put_failure;
3713b4e3 1582
86e8cf98 1583 switch (state->chan_start) {
3713b4e3
JB
1584 case 0:
1585 if (nl80211_send_band_rateinfo(msg, sband))
9360ffd1 1586 goto nla_put_failure;
86e8cf98
JB
1587 state->chan_start++;
1588 if (state->split)
3713b4e3
JB
1589 break;
1590 default:
1591 /* add frequencies */
1592 nl_freqs = nla_nest_start(
1593 msg, NL80211_BAND_ATTR_FREQS);
1594 if (!nl_freqs)
1595 goto nla_put_failure;
1596
86e8cf98 1597 for (i = state->chan_start - 1;
3713b4e3
JB
1598 i < sband->n_channels;
1599 i++) {
1600 nl_freq = nla_nest_start(msg, i);
1601 if (!nl_freq)
1602 goto nla_put_failure;
1603
1604 chan = &sband->channels[i];
1605
86e8cf98
JB
1606 if (nl80211_msg_put_channel(
1607 msg, chan,
1608 state->split))
3713b4e3
JB
1609 goto nla_put_failure;
1610
1611 nla_nest_end(msg, nl_freq);
86e8cf98 1612 if (state->split)
3713b4e3
JB
1613 break;
1614 }
1615 if (i < sband->n_channels)
86e8cf98 1616 state->chan_start = i + 2;
3713b4e3 1617 else
86e8cf98 1618 state->chan_start = 0;
3713b4e3
JB
1619 nla_nest_end(msg, nl_freqs);
1620 }
1621
1622 nla_nest_end(msg, nl_band);
1623
86e8cf98 1624 if (state->split) {
3713b4e3 1625 /* start again here */
86e8cf98 1626 if (state->chan_start)
3713b4e3
JB
1627 band--;
1628 break;
2e161f78 1629 }
2e161f78 1630 }
3713b4e3 1631 nla_nest_end(msg, nl_bands);
2e161f78 1632
57fbcce3 1633 if (band < NUM_NL80211_BANDS)
86e8cf98 1634 state->band_start = band + 1;
3713b4e3 1635 else
86e8cf98 1636 state->band_start = 0;
74b70a4e 1637
3713b4e3 1638 /* if bands & channels are done, continue outside */
86e8cf98
JB
1639 if (state->band_start == 0 && state->chan_start == 0)
1640 state->split_start++;
1641 if (state->split)
3713b4e3
JB
1642 break;
1643 case 4:
1644 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
1645 if (!nl_cmds)
2e161f78
JB
1646 goto nla_put_failure;
1647
1794899e
JB
1648 i = nl80211_add_commands_unsplit(rdev, msg);
1649 if (i < 0)
1650 goto nla_put_failure;
86e8cf98 1651 if (state->split) {
5de17984
AS
1652 CMD(crit_proto_start, CRIT_PROTOCOL_START);
1653 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 1654 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 1655 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 1656 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
1657 if (rdev->wiphy.features &
1658 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 1659 CMD(add_tx_ts, ADD_TX_TS);
ce0ce13a 1660 CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
088e8df8 1661 CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
5de17984 1662 }
3713b4e3 1663#undef CMD
ff1b6e69 1664
3713b4e3 1665 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
1666 state->split_start++;
1667 if (state->split)
3713b4e3
JB
1668 break;
1669 case 5:
1b8ec87a
ZG
1670 if (rdev->ops->remain_on_channel &&
1671 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
1672 nla_put_u32(msg,
1673 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 1674 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
1675 goto nla_put_failure;
1676
1b8ec87a 1677 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
1678 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
1679 goto nla_put_failure;
1680
1681 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
1682 goto nla_put_failure;
86e8cf98
JB
1683 state->split_start++;
1684 if (state->split)
3713b4e3
JB
1685 break;
1686 case 6:
1687#ifdef CONFIG_PM
1b8ec87a 1688 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 1689 goto nla_put_failure;
86e8cf98
JB
1690 state->split_start++;
1691 if (state->split)
3713b4e3
JB
1692 break;
1693#else
86e8cf98 1694 state->split_start++;
dfb89c56 1695#endif
3713b4e3
JB
1696 case 7:
1697 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 1698 rdev->wiphy.software_iftypes))
3713b4e3 1699 goto nla_put_failure;
ff1b6e69 1700
1b8ec87a 1701 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 1702 state->split))
3713b4e3 1703 goto nla_put_failure;
7527a782 1704
86e8cf98
JB
1705 state->split_start++;
1706 if (state->split)
3713b4e3
JB
1707 break;
1708 case 8:
1b8ec87a 1709 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 1710 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 1711 rdev->wiphy.ap_sme_capa))
3713b4e3 1712 goto nla_put_failure;
7527a782 1713
1b8ec87a 1714 features = rdev->wiphy.features;
fe1abafd
JB
1715 /*
1716 * We can only add the per-channel limit information if the
1717 * dump is split, otherwise it makes it too big. Therefore
1718 * only advertise it in that case.
1719 */
86e8cf98 1720 if (state->split)
fe1abafd
JB
1721 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
1722 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 1723 goto nla_put_failure;
562a7480 1724
1b8ec87a 1725 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 1726 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
1727 sizeof(*rdev->wiphy.ht_capa_mod_mask),
1728 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 1729 goto nla_put_failure;
1f074bd8 1730
1b8ec87a
ZG
1731 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
1732 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 1733 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 1734 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 1735 goto nla_put_failure;
7e7c8926 1736
3713b4e3
JB
1737 /*
1738 * Any information below this point is only available to
1739 * applications that can deal with it being split. This
1740 * helps ensure that newly added capabilities don't break
1741 * older tools by overrunning their buffers.
1742 *
1743 * We still increment split_start so that in the split
1744 * case we'll continue with more data in the next round,
1745 * but break unconditionally so unsplit data stops here.
1746 */
86e8cf98 1747 state->split_start++;
3713b4e3
JB
1748 break;
1749 case 9:
1b8ec87a 1750 if (rdev->wiphy.extended_capabilities &&
fe1abafd 1751 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
1752 rdev->wiphy.extended_capabilities_len,
1753 rdev->wiphy.extended_capabilities) ||
fe1abafd 1754 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
1755 rdev->wiphy.extended_capabilities_len,
1756 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 1757 goto nla_put_failure;
a50df0c4 1758
1b8ec87a 1759 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 1760 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
1761 sizeof(*rdev->wiphy.vht_capa_mod_mask),
1762 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
1763 goto nla_put_failure;
1764
be29b99a
AK
1765 state->split_start++;
1766 break;
1767 case 10:
1b8ec87a 1768 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
1769 goto nla_put_failure;
1770
1b8ec87a 1771 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
1772 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
1773 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
1774 goto nla_put_failure;
b43504cf 1775
1b8ec87a 1776 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 1777 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 1778 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
1779 goto nla_put_failure;
1780
ad7e718c
JB
1781 state->split_start++;
1782 break;
1783 case 11:
1b8ec87a 1784 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
1785 const struct nl80211_vendor_cmd_info *info;
1786 struct nlattr *nested;
1787
1788 nested = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1789 if (!nested)
1790 goto nla_put_failure;
1791
1b8ec87a
ZG
1792 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
1793 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
1794 if (nla_put(msg, i + 1, sizeof(*info), info))
1795 goto nla_put_failure;
1796 }
1797 nla_nest_end(msg, nested);
1798 }
1799
1b8ec87a 1800 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
1801 const struct nl80211_vendor_cmd_info *info;
1802 struct nlattr *nested;
ad7e718c 1803
567ffc35
JB
1804 nested = nla_nest_start(msg,
1805 NL80211_ATTR_VENDOR_EVENTS);
1806 if (!nested)
ad7e718c 1807 goto nla_put_failure;
567ffc35 1808
1b8ec87a
ZG
1809 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
1810 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
1811 if (nla_put(msg, i + 1, sizeof(*info), info))
1812 goto nla_put_failure;
1813 }
1814 nla_nest_end(msg, nested);
1815 }
9a774c78
AO
1816 state->split_start++;
1817 break;
1818 case 12:
1819 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
1820 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
1821 rdev->wiphy.max_num_csa_counters))
1822 goto nla_put_failure;
01e0daa4 1823
1bdd716c
AN
1824 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
1825 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
1826 goto nla_put_failure;
1827
ca986ad9
AVS
1828 if (rdev->wiphy.max_sched_scan_reqs &&
1829 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
1830 rdev->wiphy.max_sched_scan_reqs))
1831 goto nla_put_failure;
1832
d75bb06b
GKS
1833 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
1834 sizeof(rdev->wiphy.ext_features),
1835 rdev->wiphy.ext_features))
1836 goto nla_put_failure;
1837
38de03d2
AS
1838 if (rdev->wiphy.bss_select_support) {
1839 struct nlattr *nested;
1840 u32 bss_select_support = rdev->wiphy.bss_select_support;
1841
1842 nested = nla_nest_start(msg, NL80211_ATTR_BSS_SELECT);
1843 if (!nested)
1844 goto nla_put_failure;
1845
1846 i = 0;
1847 while (bss_select_support) {
1848 if ((bss_select_support & 1) &&
1849 nla_put_flag(msg, i))
1850 goto nla_put_failure;
1851 i++;
1852 bss_select_support >>= 1;
1853 }
1854 nla_nest_end(msg, nested);
1855 }
1856
019ae3a9
KV
1857 state->split_start++;
1858 break;
1859 case 13:
1860 if (rdev->wiphy.num_iftype_ext_capab &&
1861 rdev->wiphy.iftype_ext_capab) {
1862 struct nlattr *nested_ext_capab, *nested;
1863
1864 nested = nla_nest_start(msg,
1865 NL80211_ATTR_IFTYPE_EXT_CAPA);
1866 if (!nested)
1867 goto nla_put_failure;
1868
1869 for (i = state->capa_start;
1870 i < rdev->wiphy.num_iftype_ext_capab; i++) {
1871 const struct wiphy_iftype_ext_capab *capab;
1872
1873 capab = &rdev->wiphy.iftype_ext_capab[i];
1874
1875 nested_ext_capab = nla_nest_start(msg, i);
1876 if (!nested_ext_capab ||
1877 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
1878 capab->iftype) ||
1879 nla_put(msg, NL80211_ATTR_EXT_CAPA,
1880 capab->extended_capabilities_len,
1881 capab->extended_capabilities) ||
1882 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1883 capab->extended_capabilities_len,
1884 capab->extended_capabilities_mask))
1885 goto nla_put_failure;
1886
1887 nla_nest_end(msg, nested_ext_capab);
1888 if (state->split)
1889 break;
1890 }
1891 nla_nest_end(msg, nested);
1892 if (i < rdev->wiphy.num_iftype_ext_capab) {
1893 state->capa_start = i + 1;
1894 break;
1895 }
1896 }
1897
8585989d
LC
1898 if (nla_put_u32(msg, NL80211_ATTR_BANDS,
1899 rdev->wiphy.nan_supported_bands))
1900 goto nla_put_failure;
1901
3713b4e3 1902 /* done */
86e8cf98 1903 state->split_start = 0;
3713b4e3
JB
1904 break;
1905 }
3bb20556 1906 finish:
053c095a
JB
1907 genlmsg_end(msg, hdr);
1908 return 0;
55682965
JB
1909
1910 nla_put_failure:
bc3ed28c
TG
1911 genlmsg_cancel(msg, hdr);
1912 return -EMSGSIZE;
55682965
JB
1913}
1914
86e8cf98
JB
1915static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
1916 struct netlink_callback *cb,
1917 struct nl80211_dump_wiphy_state *state)
1918{
c90c39da 1919 struct nlattr **tb = genl_family_attrbuf(&nl80211_fam);
fceb6435
JB
1920 int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, tb,
1921 nl80211_fam.maxattr, nl80211_policy, NULL);
86e8cf98
JB
1922 /* ignore parse errors for backward compatibility */
1923 if (ret)
1924 return 0;
1925
1926 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
1927 if (tb[NL80211_ATTR_WIPHY])
1928 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1929 if (tb[NL80211_ATTR_WDEV])
1930 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
1931 if (tb[NL80211_ATTR_IFINDEX]) {
1932 struct net_device *netdev;
1933 struct cfg80211_registered_device *rdev;
1934 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1935
7f2b8562 1936 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
86e8cf98
JB
1937 if (!netdev)
1938 return -ENODEV;
1939 if (netdev->ieee80211_ptr) {
f26cbf40 1940 rdev = wiphy_to_rdev(
86e8cf98
JB
1941 netdev->ieee80211_ptr->wiphy);
1942 state->filter_wiphy = rdev->wiphy_idx;
1943 }
86e8cf98
JB
1944 }
1945
1946 return 0;
1947}
1948
55682965
JB
1949static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1950{
645e77de 1951 int idx = 0, ret;
86e8cf98 1952 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 1953 struct cfg80211_registered_device *rdev;
3a5a423b 1954
5fe231e8 1955 rtnl_lock();
86e8cf98
JB
1956 if (!state) {
1957 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
1958 if (!state) {
1959 rtnl_unlock();
86e8cf98 1960 return -ENOMEM;
3713b4e3 1961 }
86e8cf98
JB
1962 state->filter_wiphy = -1;
1963 ret = nl80211_dump_wiphy_parse(skb, cb, state);
1964 if (ret) {
1965 kfree(state);
1966 rtnl_unlock();
1967 return ret;
3713b4e3 1968 }
86e8cf98 1969 cb->args[0] = (long)state;
3713b4e3
JB
1970 }
1971
1b8ec87a
ZG
1972 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1973 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 1974 continue;
86e8cf98 1975 if (++idx <= state->start)
55682965 1976 continue;
86e8cf98 1977 if (state->filter_wiphy != -1 &&
1b8ec87a 1978 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
1979 continue;
1980 /* attempt to fit multiple wiphy data chunks into the skb */
1981 do {
3bb20556
JB
1982 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
1983 skb,
3713b4e3
JB
1984 NETLINK_CB(cb->skb).portid,
1985 cb->nlh->nlmsg_seq,
86e8cf98 1986 NLM_F_MULTI, state);
3713b4e3
JB
1987 if (ret < 0) {
1988 /*
1989 * If sending the wiphy data didn't fit (ENOBUFS
1990 * or EMSGSIZE returned), this SKB is still
1991 * empty (so it's not too big because another
1992 * wiphy dataset is already in the skb) and
1993 * we've not tried to adjust the dump allocation
1994 * yet ... then adjust the alloc size to be
1995 * bigger, and return 1 but with the empty skb.
1996 * This results in an empty message being RX'ed
1997 * in userspace, but that is ignored.
1998 *
1999 * We can then retry with the larger buffer.
2000 */
2001 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 2002 !skb->len && !state->split &&
3713b4e3
JB
2003 cb->min_dump_alloc < 4096) {
2004 cb->min_dump_alloc = 4096;
f12cb289 2005 state->split_start = 0;
d98cae64 2006 rtnl_unlock();
3713b4e3
JB
2007 return 1;
2008 }
2009 idx--;
2010 break;
645e77de 2011 }
86e8cf98 2012 } while (state->split_start > 0);
3713b4e3 2013 break;
55682965 2014 }
5fe231e8 2015 rtnl_unlock();
55682965 2016
86e8cf98 2017 state->start = idx;
55682965
JB
2018
2019 return skb->len;
2020}
2021
86e8cf98
JB
2022static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
2023{
2024 kfree((void *)cb->args[0]);
2025 return 0;
2026}
2027
55682965
JB
2028static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
2029{
2030 struct sk_buff *msg;
1b8ec87a 2031 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 2032 struct nl80211_dump_wiphy_state state = {};
55682965 2033
645e77de 2034 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 2035 if (!msg)
4c476991 2036 return -ENOMEM;
55682965 2037
3bb20556
JB
2038 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
2039 info->snd_portid, info->snd_seq, 0,
86e8cf98 2040 &state) < 0) {
4c476991
JB
2041 nlmsg_free(msg);
2042 return -ENOBUFS;
2043 }
55682965 2044
134e6375 2045 return genlmsg_reply(msg, info);
55682965
JB
2046}
2047
31888487
JM
2048static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
2049 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
2050 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
2051 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
2052 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
2053 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
2054};
2055
2056static int parse_txq_params(struct nlattr *tb[],
2057 struct ieee80211_txq_params *txq_params)
2058{
a3304b0a 2059 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
2060 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
2061 !tb[NL80211_TXQ_ATTR_AIFS])
2062 return -EINVAL;
2063
a3304b0a 2064 txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
2065 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
2066 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
2067 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
2068 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
2069
a3304b0a
JB
2070 if (txq_params->ac >= NL80211_NUM_ACS)
2071 return -EINVAL;
2072
31888487
JM
2073 return 0;
2074}
2075
f444de05
JB
2076static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2077{
2078 /*
cc1d2806
JB
2079 * You can only set the channel explicitly for WDS interfaces,
2080 * all others have their channel managed via their respective
2081 * "establish a connection" command (connect, join, ...)
2082 *
2083 * For AP/GO and mesh mode, the channel can be set with the
2084 * channel userspace API, but is only stored and passed to the
2085 * low-level driver when the AP starts or the mesh is joined.
2086 * This is for backward compatibility, userspace can also give
2087 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
2088 *
2089 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
2090 * whatever else is going on, so they have their own special
2091 * operation to set the monitor channel if possible.
f444de05
JB
2092 */
2093 return !wdev ||
2094 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 2095 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
2096 wdev->iftype == NL80211_IFTYPE_MONITOR ||
2097 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
2098}
2099
683b6d3b
JB
2100static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2101 struct genl_info *info,
2102 struct cfg80211_chan_def *chandef)
2103{
dbeca2ea 2104 u32 control_freq;
683b6d3b
JB
2105
2106 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
2107 return -EINVAL;
2108
2109 control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
2110
2111 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
3d9d1d66
JB
2112 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
2113 chandef->center_freq1 = control_freq;
2114 chandef->center_freq2 = 0;
683b6d3b
JB
2115
2116 /* Primary channel not allowed */
2117 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
2118 return -EINVAL;
2119
3d9d1d66
JB
2120 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2121 enum nl80211_channel_type chantype;
2122
2123 chantype = nla_get_u32(
2124 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
2125
2126 switch (chantype) {
2127 case NL80211_CHAN_NO_HT:
2128 case NL80211_CHAN_HT20:
2129 case NL80211_CHAN_HT40PLUS:
2130 case NL80211_CHAN_HT40MINUS:
2131 cfg80211_chandef_create(chandef, chandef->chan,
2132 chantype);
ffa4629e
TM
2133 /* user input for center_freq is incorrect */
2134 if (info->attrs[NL80211_ATTR_CENTER_FREQ1] &&
2135 chandef->center_freq1 != nla_get_u32(
2136 info->attrs[NL80211_ATTR_CENTER_FREQ1]))
2137 return -EINVAL;
2138 /* center_freq2 must be zero */
2139 if (info->attrs[NL80211_ATTR_CENTER_FREQ2] &&
2140 nla_get_u32(info->attrs[NL80211_ATTR_CENTER_FREQ2]))
2141 return -EINVAL;
3d9d1d66
JB
2142 break;
2143 default:
2144 return -EINVAL;
2145 }
2146 } else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
2147 chandef->width =
2148 nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
2149 if (info->attrs[NL80211_ATTR_CENTER_FREQ1])
2150 chandef->center_freq1 =
2151 nla_get_u32(
2152 info->attrs[NL80211_ATTR_CENTER_FREQ1]);
2153 if (info->attrs[NL80211_ATTR_CENTER_FREQ2])
2154 chandef->center_freq2 =
2155 nla_get_u32(
2156 info->attrs[NL80211_ATTR_CENTER_FREQ2]);
2157 }
2158
9f5e8f6e 2159 if (!cfg80211_chandef_valid(chandef))
3d9d1d66
JB
2160 return -EINVAL;
2161
9f5e8f6e
JB
2162 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
2163 IEEE80211_CHAN_DISABLED))
3d9d1d66
JB
2164 return -EINVAL;
2165
2f301ab2
SW
2166 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
2167 chandef->width == NL80211_CHAN_WIDTH_10) &&
2168 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ))
2169 return -EINVAL;
2170
683b6d3b
JB
2171 return 0;
2172}
2173
f444de05 2174static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 2175 struct net_device *dev,
f444de05
JB
2176 struct genl_info *info)
2177{
683b6d3b 2178 struct cfg80211_chan_def chandef;
f444de05 2179 int result;
e8c9bd5b 2180 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 2181 struct wireless_dev *wdev = NULL;
e8c9bd5b 2182
e16821bc
JM
2183 if (dev)
2184 wdev = dev->ieee80211_ptr;
f444de05
JB
2185 if (!nl80211_can_set_dev_channel(wdev))
2186 return -EOPNOTSUPP;
e16821bc
JM
2187 if (wdev)
2188 iftype = wdev->iftype;
f444de05 2189
683b6d3b
JB
2190 result = nl80211_parse_chandef(rdev, info, &chandef);
2191 if (result)
2192 return result;
f444de05 2193
e8c9bd5b 2194 switch (iftype) {
aa430da4
JB
2195 case NL80211_IFTYPE_AP:
2196 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
2197 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
2198 iftype)) {
aa430da4
JB
2199 result = -EINVAL;
2200 break;
2201 }
e16821bc
JM
2202 if (wdev->beacon_interval) {
2203 if (!dev || !rdev->ops->set_ap_chanwidth ||
2204 !(rdev->wiphy.features &
2205 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
2206 result = -EBUSY;
2207 break;
2208 }
2209
2210 /* Only allow dynamic channel width changes */
2211 if (chandef.chan != wdev->preset_chandef.chan) {
2212 result = -EBUSY;
2213 break;
2214 }
2215 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
2216 if (result)
2217 break;
2218 }
683b6d3b 2219 wdev->preset_chandef = chandef;
aa430da4
JB
2220 result = 0;
2221 break;
cc1d2806 2222 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 2223 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 2224 break;
e8c9bd5b 2225 case NL80211_IFTYPE_MONITOR:
683b6d3b 2226 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 2227 break;
aa430da4 2228 default:
e8c9bd5b 2229 result = -EINVAL;
f444de05 2230 }
f444de05
JB
2231
2232 return result;
2233}
2234
2235static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
2236{
4c476991
JB
2237 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2238 struct net_device *netdev = info->user_ptr[1];
f444de05 2239
e16821bc 2240 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
2241}
2242
e8347eba
BJ
2243static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
2244{
43b19952
JB
2245 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2246 struct net_device *dev = info->user_ptr[1];
2247 struct wireless_dev *wdev = dev->ieee80211_ptr;
388ac775 2248 const u8 *bssid;
e8347eba
BJ
2249
2250 if (!info->attrs[NL80211_ATTR_MAC])
2251 return -EINVAL;
2252
43b19952
JB
2253 if (netif_running(dev))
2254 return -EBUSY;
e8347eba 2255
43b19952
JB
2256 if (!rdev->ops->set_wds_peer)
2257 return -EOPNOTSUPP;
e8347eba 2258
43b19952
JB
2259 if (wdev->iftype != NL80211_IFTYPE_WDS)
2260 return -EOPNOTSUPP;
e8347eba
BJ
2261
2262 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
e35e4d28 2263 return rdev_set_wds_peer(rdev, dev, bssid);
e8347eba
BJ
2264}
2265
55682965
JB
2266static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2267{
2268 struct cfg80211_registered_device *rdev;
f444de05
JB
2269 struct net_device *netdev = NULL;
2270 struct wireless_dev *wdev;
a1e567c8 2271 int result = 0, rem_txq_params = 0;
31888487 2272 struct nlattr *nl_txq_params;
b9a5f8ca
JM
2273 u32 changed;
2274 u8 retry_short = 0, retry_long = 0;
2275 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 2276 u8 coverage_class = 0;
55682965 2277
5fe231e8
JB
2278 ASSERT_RTNL();
2279
f444de05
JB
2280 /*
2281 * Try to find the wiphy and netdev. Normally this
2282 * function shouldn't need the netdev, but this is
2283 * done for backward compatibility -- previously
2284 * setting the channel was done per wiphy, but now
2285 * it is per netdev. Previous userland like hostapd
2286 * also passed a netdev to set_wiphy, so that it is
2287 * possible to let that go to the right netdev!
2288 */
4bbf4d56 2289
f444de05
JB
2290 if (info->attrs[NL80211_ATTR_IFINDEX]) {
2291 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
2292
7f2b8562 2293 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 2294 if (netdev && netdev->ieee80211_ptr)
f26cbf40 2295 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 2296 else
f444de05 2297 netdev = NULL;
4bbf4d56
JB
2298 }
2299
f444de05 2300 if (!netdev) {
878d9ec7
JB
2301 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
2302 info->attrs);
5fe231e8 2303 if (IS_ERR(rdev))
4c476991 2304 return PTR_ERR(rdev);
f444de05
JB
2305 wdev = NULL;
2306 netdev = NULL;
2307 result = 0;
71fe96bf 2308 } else
f444de05 2309 wdev = netdev->ieee80211_ptr;
f444de05
JB
2310
2311 /*
2312 * end workaround code, by now the rdev is available
2313 * and locked, and wdev may or may not be NULL.
2314 */
4bbf4d56
JB
2315
2316 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
2317 result = cfg80211_dev_rename(
2318 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56 2319
4bbf4d56 2320 if (result)
7f2b8562 2321 return result;
31888487
JM
2322
2323 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
2324 struct ieee80211_txq_params txq_params;
2325 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
2326
7f2b8562
YX
2327 if (!rdev->ops->set_txq_params)
2328 return -EOPNOTSUPP;
31888487 2329
7f2b8562
YX
2330 if (!netdev)
2331 return -EINVAL;
f70f01c2 2332
133a3ff2 2333 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
7f2b8562
YX
2334 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2335 return -EINVAL;
133a3ff2 2336
7f2b8562
YX
2337 if (!netif_running(netdev))
2338 return -ENETDOWN;
2b5f8b0b 2339
31888487
JM
2340 nla_for_each_nested(nl_txq_params,
2341 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
2342 rem_txq_params) {
bfe2c7b1
JB
2343 result = nla_parse_nested(tb, NL80211_TXQ_ATTR_MAX,
2344 nl_txq_params,
fe52145f
JB
2345 txq_params_policy,
2346 info->extack);
ae811e21
JB
2347 if (result)
2348 return result;
31888487
JM
2349 result = parse_txq_params(tb, &txq_params);
2350 if (result)
7f2b8562 2351 return result;
31888487 2352
e35e4d28
HG
2353 result = rdev_set_txq_params(rdev, netdev,
2354 &txq_params);
31888487 2355 if (result)
7f2b8562 2356 return result;
31888487
JM
2357 }
2358 }
55682965 2359
72bdcf34 2360 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
2361 result = __nl80211_set_channel(
2362 rdev,
2363 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
2364 info);
72bdcf34 2365 if (result)
7f2b8562 2366 return result;
72bdcf34
JM
2367 }
2368
98d2ff8b 2369 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 2370 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
2371 enum nl80211_tx_power_setting type;
2372 int idx, mbm = 0;
2373
c8442118
JB
2374 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
2375 txp_wdev = NULL;
2376
7f2b8562
YX
2377 if (!rdev->ops->set_tx_power)
2378 return -EOPNOTSUPP;
98d2ff8b
JO
2379
2380 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
2381 type = nla_get_u32(info->attrs[idx]);
2382
2383 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
7f2b8562
YX
2384 (type != NL80211_TX_POWER_AUTOMATIC))
2385 return -EINVAL;
98d2ff8b
JO
2386
2387 if (type != NL80211_TX_POWER_AUTOMATIC) {
2388 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
2389 mbm = nla_get_u32(info->attrs[idx]);
2390 }
2391
c8442118 2392 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 2393 if (result)
7f2b8562 2394 return result;
98d2ff8b
JO
2395 }
2396
afe0cbf8
BR
2397 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
2398 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
2399 u32 tx_ant, rx_ant;
7a087e74 2400
7f531e03
BR
2401 if ((!rdev->wiphy.available_antennas_tx &&
2402 !rdev->wiphy.available_antennas_rx) ||
7f2b8562
YX
2403 !rdev->ops->set_antenna)
2404 return -EOPNOTSUPP;
afe0cbf8
BR
2405
2406 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
2407 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
2408
a7ffac95 2409 /* reject antenna configurations which don't match the
7f531e03
BR
2410 * available antenna masks, except for the "all" mask */
2411 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
7f2b8562
YX
2412 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
2413 return -EINVAL;
a7ffac95 2414
7f531e03
BR
2415 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
2416 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 2417
e35e4d28 2418 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 2419 if (result)
7f2b8562 2420 return result;
afe0cbf8
BR
2421 }
2422
b9a5f8ca
JM
2423 changed = 0;
2424
2425 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
2426 retry_short = nla_get_u8(
2427 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562
YX
2428 if (retry_short == 0)
2429 return -EINVAL;
2430
b9a5f8ca
JM
2431 changed |= WIPHY_PARAM_RETRY_SHORT;
2432 }
2433
2434 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
2435 retry_long = nla_get_u8(
2436 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562
YX
2437 if (retry_long == 0)
2438 return -EINVAL;
2439
b9a5f8ca
JM
2440 changed |= WIPHY_PARAM_RETRY_LONG;
2441 }
2442
2443 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
2444 frag_threshold = nla_get_u32(
2445 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
7f2b8562
YX
2446 if (frag_threshold < 256)
2447 return -EINVAL;
2448
b9a5f8ca
JM
2449 if (frag_threshold != (u32) -1) {
2450 /*
2451 * Fragments (apart from the last one) are required to
2452 * have even length. Make the fragmentation code
2453 * simpler by stripping LSB should someone try to use
2454 * odd threshold value.
2455 */
2456 frag_threshold &= ~0x1;
2457 }
2458 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
2459 }
2460
2461 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
2462 rts_threshold = nla_get_u32(
2463 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
2464 changed |= WIPHY_PARAM_RTS_THRESHOLD;
2465 }
2466
81077e82 2467 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
3057dbfd
LB
2468 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK])
2469 return -EINVAL;
2470
81077e82
LT
2471 coverage_class = nla_get_u8(
2472 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
2473 changed |= WIPHY_PARAM_COVERAGE_CLASS;
2474 }
2475
3057dbfd
LB
2476 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
2477 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION))
2478 return -EOPNOTSUPP;
2479
2480 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
2481 }
2482
b9a5f8ca
JM
2483 if (changed) {
2484 u8 old_retry_short, old_retry_long;
2485 u32 old_frag_threshold, old_rts_threshold;
81077e82 2486 u8 old_coverage_class;
b9a5f8ca 2487
7f2b8562
YX
2488 if (!rdev->ops->set_wiphy_params)
2489 return -EOPNOTSUPP;
b9a5f8ca
JM
2490
2491 old_retry_short = rdev->wiphy.retry_short;
2492 old_retry_long = rdev->wiphy.retry_long;
2493 old_frag_threshold = rdev->wiphy.frag_threshold;
2494 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 2495 old_coverage_class = rdev->wiphy.coverage_class;
b9a5f8ca
JM
2496
2497 if (changed & WIPHY_PARAM_RETRY_SHORT)
2498 rdev->wiphy.retry_short = retry_short;
2499 if (changed & WIPHY_PARAM_RETRY_LONG)
2500 rdev->wiphy.retry_long = retry_long;
2501 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
2502 rdev->wiphy.frag_threshold = frag_threshold;
2503 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
2504 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
2505 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
2506 rdev->wiphy.coverage_class = coverage_class;
b9a5f8ca 2507
e35e4d28 2508 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
2509 if (result) {
2510 rdev->wiphy.retry_short = old_retry_short;
2511 rdev->wiphy.retry_long = old_retry_long;
2512 rdev->wiphy.frag_threshold = old_frag_threshold;
2513 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 2514 rdev->wiphy.coverage_class = old_coverage_class;
9189ee31 2515 return result;
b9a5f8ca
JM
2516 }
2517 }
7f2b8562 2518 return 0;
55682965
JB
2519}
2520
71bbc994
JB
2521static inline u64 wdev_id(struct wireless_dev *wdev)
2522{
2523 return (u64)wdev->identifier |
f26cbf40 2524 ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32);
71bbc994 2525}
55682965 2526
683b6d3b 2527static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 2528 const struct cfg80211_chan_def *chandef)
683b6d3b 2529{
601555cd
JB
2530 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
2531 return -EINVAL;
3d9d1d66 2532
683b6d3b
JB
2533 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
2534 chandef->chan->center_freq))
2535 return -ENOBUFS;
3d9d1d66
JB
2536 switch (chandef->width) {
2537 case NL80211_CHAN_WIDTH_20_NOHT:
2538 case NL80211_CHAN_WIDTH_20:
2539 case NL80211_CHAN_WIDTH_40:
2540 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2541 cfg80211_get_chandef_type(chandef)))
2542 return -ENOBUFS;
2543 break;
2544 default:
2545 break;
2546 }
2547 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
2548 return -ENOBUFS;
2549 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
2550 return -ENOBUFS;
2551 if (chandef->center_freq2 &&
2552 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
2553 return -ENOBUFS;
2554 return 0;
2555}
2556
15e47304 2557static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 2558 struct cfg80211_registered_device *rdev,
8f894be2 2559 struct wireless_dev *wdev, bool removal)
55682965 2560{
72fb2abc 2561 struct net_device *dev = wdev->netdev;
8f894be2 2562 u8 cmd = NL80211_CMD_NEW_INTERFACE;
55682965
JB
2563 void *hdr;
2564
8f894be2
TB
2565 if (removal)
2566 cmd = NL80211_CMD_DEL_INTERFACE;
2567
2568 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
2569 if (!hdr)
2570 return -1;
2571
72fb2abc
JB
2572 if (dev &&
2573 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 2574 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
2575 goto nla_put_failure;
2576
2577 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2578 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
2579 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
2580 NL80211_ATTR_PAD) ||
98104fde 2581 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
2582 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2583 rdev->devlist_generation ^
2584 (cfg80211_rdev_list_generation << 2)))
2585 goto nla_put_failure;
f5ea9120 2586
5b7ccaf3 2587 if (rdev->ops->get_channel) {
683b6d3b
JB
2588 int ret;
2589 struct cfg80211_chan_def chandef;
2590
2591 ret = rdev_get_channel(rdev, wdev, &chandef);
2592 if (ret == 0) {
2593 if (nl80211_send_chandef(msg, &chandef))
2594 goto nla_put_failure;
2595 }
d91df0e3
PF
2596 }
2597
d55d0d59
RM
2598 if (rdev->ops->get_tx_power) {
2599 int dbm, ret;
2600
2601 ret = rdev_get_tx_power(rdev, wdev, &dbm);
2602 if (ret == 0 &&
2603 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
2604 DBM_TO_MBM(dbm)))
2605 goto nla_put_failure;
2606 }
2607
44905265
JB
2608 wdev_lock(wdev);
2609 switch (wdev->iftype) {
2610 case NL80211_IFTYPE_AP:
2611 if (wdev->ssid_len &&
2612 nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
4564b187 2613 goto nla_put_failure_locked;
44905265
JB
2614 break;
2615 case NL80211_IFTYPE_STATION:
2616 case NL80211_IFTYPE_P2P_CLIENT:
2617 case NL80211_IFTYPE_ADHOC: {
2618 const u8 *ssid_ie;
2619 if (!wdev->current_bss)
2620 break;
2621 ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub,
2622 WLAN_EID_SSID);
2623 if (!ssid_ie)
2624 break;
2625 if (nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2))
4564b187 2626 goto nla_put_failure_locked;
44905265
JB
2627 break;
2628 }
2629 default:
2630 /* nothing */
2631 break;
b84e7a05 2632 }
44905265 2633 wdev_unlock(wdev);
b84e7a05 2634
053c095a
JB
2635 genlmsg_end(msg, hdr);
2636 return 0;
55682965 2637
4564b187
JB
2638 nla_put_failure_locked:
2639 wdev_unlock(wdev);
55682965 2640 nla_put_failure:
bc3ed28c
TG
2641 genlmsg_cancel(msg, hdr);
2642 return -EMSGSIZE;
55682965
JB
2643}
2644
2645static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
2646{
2647 int wp_idx = 0;
2648 int if_idx = 0;
2649 int wp_start = cb->args[0];
2650 int if_start = cb->args[1];
b7fb44da 2651 int filter_wiphy = -1;
f5ea9120 2652 struct cfg80211_registered_device *rdev;
55682965 2653 struct wireless_dev *wdev;
ea90e0dc 2654 int ret;
55682965 2655
5fe231e8 2656 rtnl_lock();
b7fb44da
DK
2657 if (!cb->args[2]) {
2658 struct nl80211_dump_wiphy_state state = {
2659 .filter_wiphy = -1,
2660 };
b7fb44da
DK
2661
2662 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
2663 if (ret)
ea90e0dc 2664 goto out_unlock;
b7fb44da
DK
2665
2666 filter_wiphy = state.filter_wiphy;
2667
2668 /*
2669 * if filtering, set cb->args[2] to +1 since 0 is the default
2670 * value needed to determine that parsing is necessary.
2671 */
2672 if (filter_wiphy >= 0)
2673 cb->args[2] = filter_wiphy + 1;
2674 else
2675 cb->args[2] = -1;
2676 } else if (cb->args[2] > 0) {
2677 filter_wiphy = cb->args[2] - 1;
2678 }
2679
f5ea9120
JB
2680 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2681 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2682 continue;
bba95fef
JB
2683 if (wp_idx < wp_start) {
2684 wp_idx++;
55682965 2685 continue;
bba95fef 2686 }
b7fb44da
DK
2687
2688 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
2689 continue;
2690
55682965
JB
2691 if_idx = 0;
2692
53873f13 2693 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
2694 if (if_idx < if_start) {
2695 if_idx++;
55682965 2696 continue;
bba95fef 2697 }
15e47304 2698 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 2699 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8f894be2 2700 rdev, wdev, false) < 0) {
bba95fef
JB
2701 goto out;
2702 }
2703 if_idx++;
55682965 2704 }
bba95fef
JB
2705
2706 wp_idx++;
55682965 2707 }
bba95fef 2708 out:
55682965
JB
2709 cb->args[0] = wp_idx;
2710 cb->args[1] = if_idx;
2711
ea90e0dc
JB
2712 ret = skb->len;
2713 out_unlock:
2714 rtnl_unlock();
2715
2716 return ret;
55682965
JB
2717}
2718
2719static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
2720{
2721 struct sk_buff *msg;
1b8ec87a 2722 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 2723 struct wireless_dev *wdev = info->user_ptr[1];
55682965 2724
fd2120ca 2725 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 2726 if (!msg)
4c476991 2727 return -ENOMEM;
55682965 2728
15e47304 2729 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 2730 rdev, wdev, false) < 0) {
4c476991
JB
2731 nlmsg_free(msg);
2732 return -ENOBUFS;
2733 }
55682965 2734
134e6375 2735 return genlmsg_reply(msg, info);
55682965
JB
2736}
2737
66f7ac50
MW
2738static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
2739 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
2740 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
2741 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
2742 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
2743 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 2744 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
2745};
2746
2747static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
2748{
2749 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
2750 int flag;
2751
2752 *mntrflags = 0;
2753
2754 if (!nla)
2755 return -EINVAL;
2756
fceb6435
JB
2757 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX, nla,
2758 mntr_flags_policy, NULL))
66f7ac50
MW
2759 return -EINVAL;
2760
2761 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
2762 if (flags[flag])
2763 *mntrflags |= (1<<flag);
2764
818a986e
JB
2765 *mntrflags |= MONITOR_FLAG_CHANGED;
2766
66f7ac50
MW
2767 return 0;
2768}
2769
1db77596
JB
2770static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
2771 enum nl80211_iftype type,
2772 struct genl_info *info,
2773 struct vif_params *params)
2774{
2775 bool change = false;
2776 int err;
2777
2778 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
2779 if (type != NL80211_IFTYPE_MONITOR)
2780 return -EINVAL;
2781
2782 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
2783 &params->flags);
2784 if (err)
2785 return err;
2786
2787 change = true;
2788 }
2789
2790 if (params->flags & MONITOR_FLAG_ACTIVE &&
2791 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2792 return -EOPNOTSUPP;
2793
2794 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
2795 const u8 *mumimo_groups;
2796 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2797
2798 if (type != NL80211_IFTYPE_MONITOR)
2799 return -EINVAL;
2800
2801 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2802 return -EOPNOTSUPP;
2803
2804 mumimo_groups =
2805 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
2806
2807 /* bits 0 and 63 are reserved and must be zero */
4954601f
JB
2808 if ((mumimo_groups[0] & BIT(0)) ||
2809 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(7)))
1db77596
JB
2810 return -EINVAL;
2811
2812 params->vht_mumimo_groups = mumimo_groups;
2813 change = true;
2814 }
2815
2816 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
2817 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2818
2819 if (type != NL80211_IFTYPE_MONITOR)
2820 return -EINVAL;
2821
2822 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2823 return -EOPNOTSUPP;
2824
2825 params->vht_mumimo_follow_addr =
2826 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
2827 change = true;
2828 }
2829
2830 return change ? 1 : 0;
2831}
2832
9bc383de 2833static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
2834 struct net_device *netdev, u8 use_4addr,
2835 enum nl80211_iftype iftype)
9bc383de 2836{
ad4bb6f8 2837 if (!use_4addr) {
f350a0a8 2838 if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT))
ad4bb6f8 2839 return -EBUSY;
9bc383de 2840 return 0;
ad4bb6f8 2841 }
9bc383de
JB
2842
2843 switch (iftype) {
2844 case NL80211_IFTYPE_AP_VLAN:
2845 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
2846 return 0;
2847 break;
2848 case NL80211_IFTYPE_STATION:
2849 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
2850 return 0;
2851 break;
2852 default:
2853 break;
2854 }
2855
2856 return -EOPNOTSUPP;
2857}
2858
55682965
JB
2859static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
2860{
4c476991 2861 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2862 struct vif_params params;
e36d56b6 2863 int err;
04a773ad 2864 enum nl80211_iftype otype, ntype;
4c476991 2865 struct net_device *dev = info->user_ptr[1];
ac7f9cfa 2866 bool change = false;
55682965 2867
2ec600d6
LCC
2868 memset(&params, 0, sizeof(params));
2869
04a773ad 2870 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 2871
723b038d 2872 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 2873 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 2874 if (otype != ntype)
ac7f9cfa 2875 change = true;
4c476991
JB
2876 if (ntype > NL80211_IFTYPE_MAX)
2877 return -EINVAL;
723b038d
JB
2878 }
2879
92ffe055 2880 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
2881 struct wireless_dev *wdev = dev->ieee80211_ptr;
2882
4c476991
JB
2883 if (ntype != NL80211_IFTYPE_MESH_POINT)
2884 return -EINVAL;
29cbe68c
JB
2885 if (netif_running(dev))
2886 return -EBUSY;
2887
2888 wdev_lock(wdev);
2889 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2890 IEEE80211_MAX_MESH_ID_LEN);
2891 wdev->mesh_id_up_len =
2892 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2893 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
2894 wdev->mesh_id_up_len);
2895 wdev_unlock(wdev);
2ec600d6
LCC
2896 }
2897
8b787643
FF
2898 if (info->attrs[NL80211_ATTR_4ADDR]) {
2899 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
2900 change = true;
ad4bb6f8 2901 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 2902 if (err)
4c476991 2903 return err;
8b787643
FF
2904 } else {
2905 params.use_4addr = -1;
2906 }
2907
1db77596
JB
2908 err = nl80211_parse_mon_options(rdev, ntype, info, &params);
2909 if (err < 0)
2910 return err;
2911 if (err > 0)
c6e6a0c8 2912 change = true;
e057d3c3 2913
ac7f9cfa 2914 if (change)
818a986e 2915 err = cfg80211_change_iface(rdev, dev, ntype, &params);
ac7f9cfa
JB
2916 else
2917 err = 0;
60719ffd 2918
9bc383de
JB
2919 if (!err && params.use_4addr != -1)
2920 dev->ieee80211_ptr->use_4addr = params.use_4addr;
2921
55682965
JB
2922 return err;
2923}
2924
2925static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2926{
4c476991 2927 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2928 struct vif_params params;
84efbb84 2929 struct wireless_dev *wdev;
896ff063 2930 struct sk_buff *msg;
55682965
JB
2931 int err;
2932 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
2933
78f22b6a
JB
2934 /* to avoid failing a new interface creation due to pending removal */
2935 cfg80211_destroy_ifaces(rdev);
2936
2ec600d6
LCC
2937 memset(&params, 0, sizeof(params));
2938
55682965
JB
2939 if (!info->attrs[NL80211_ATTR_IFNAME])
2940 return -EINVAL;
2941
2942 if (info->attrs[NL80211_ATTR_IFTYPE]) {
2943 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
2944 if (type > NL80211_IFTYPE_MAX)
2945 return -EINVAL;
2946 }
2947
79c97e97 2948 if (!rdev->ops->add_virtual_intf ||
4c476991
JB
2949 !(rdev->wiphy.interface_modes & (1 << type)))
2950 return -EOPNOTSUPP;
55682965 2951
cb3b7d87 2952 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
2953 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
2954 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
2955 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
2956 ETH_ALEN);
2957 if (!is_valid_ether_addr(params.macaddr))
2958 return -EADDRNOTAVAIL;
2959 }
2960
9bc383de 2961 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 2962 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 2963 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 2964 if (err)
4c476991 2965 return err;
9bc383de 2966 }
8b787643 2967
1db77596
JB
2968 err = nl80211_parse_mon_options(rdev, type, info, &params);
2969 if (err < 0)
2970 return err;
e057d3c3 2971
a18c7192
JB
2972 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2973 if (!msg)
2974 return -ENOMEM;
2975
e35e4d28
HG
2976 wdev = rdev_add_virtual_intf(rdev,
2977 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
818a986e 2978 NET_NAME_USER, type, &params);
d687cbb7
RM
2979 if (WARN_ON(!wdev)) {
2980 nlmsg_free(msg);
2981 return -EPROTO;
2982 } else if (IS_ERR(wdev)) {
1c90f9d4 2983 nlmsg_free(msg);
84efbb84 2984 return PTR_ERR(wdev);
1c90f9d4 2985 }
2ec600d6 2986
18e5ca65 2987 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
2988 wdev->owner_nlportid = info->snd_portid;
2989
98104fde
JB
2990 switch (type) {
2991 case NL80211_IFTYPE_MESH_POINT:
2992 if (!info->attrs[NL80211_ATTR_MESH_ID])
2993 break;
29cbe68c
JB
2994 wdev_lock(wdev);
2995 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2996 IEEE80211_MAX_MESH_ID_LEN);
2997 wdev->mesh_id_up_len =
2998 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2999 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
3000 wdev->mesh_id_up_len);
3001 wdev_unlock(wdev);
98104fde 3002 break;
cb3b7d87 3003 case NL80211_IFTYPE_NAN:
98104fde
JB
3004 case NL80211_IFTYPE_P2P_DEVICE:
3005 /*
cb3b7d87 3006 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
3007 * through the netdev notifier and must be added here
3008 */
3009 mutex_init(&wdev->mtx);
3010 INIT_LIST_HEAD(&wdev->event_list);
3011 spin_lock_init(&wdev->event_lock);
3012 INIT_LIST_HEAD(&wdev->mgmt_registrations);
3013 spin_lock_init(&wdev->mgmt_registrations_lock);
3014
98104fde 3015 wdev->identifier = ++rdev->wdev_id;
53873f13 3016 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
98104fde 3017 rdev->devlist_generation++;
98104fde
JB
3018 break;
3019 default:
3020 break;
29cbe68c
JB
3021 }
3022
15e47304 3023 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 3024 rdev, wdev, false) < 0) {
1c90f9d4
JB
3025 nlmsg_free(msg);
3026 return -ENOBUFS;
3027 }
3028
896ff063
DK
3029 /*
3030 * For wdevs which have no associated netdev object (e.g. of type
3031 * NL80211_IFTYPE_P2P_DEVICE), emit the NEW_INTERFACE event here.
3032 * For all other types, the event will be generated from the
3033 * netdev notifier
3034 */
3035 if (!wdev->netdev)
3036 nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
8f894be2 3037
1c90f9d4 3038 return genlmsg_reply(msg, info);
55682965
JB
3039}
3040
3041static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
3042{
4c476991 3043 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 3044 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3045
4c476991
JB
3046 if (!rdev->ops->del_virtual_intf)
3047 return -EOPNOTSUPP;
55682965 3048
84efbb84
JB
3049 /*
3050 * If we remove a wireless device without a netdev then clear
3051 * user_ptr[1] so that nl80211_post_doit won't dereference it
3052 * to check if it needs to do dev_put(). Otherwise it crashes
3053 * since the wdev has been freed, unlike with a netdev where
3054 * we need the dev_put() for the netdev to really be freed.
3055 */
3056 if (!wdev->netdev)
3057 info->user_ptr[1] = NULL;
3058
7f8ed01e 3059 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
3060}
3061
1d9d9213
SW
3062static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
3063{
3064 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3065 struct net_device *dev = info->user_ptr[1];
3066 u16 noack_map;
3067
3068 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
3069 return -EINVAL;
3070
3071 if (!rdev->ops->set_noack_map)
3072 return -EOPNOTSUPP;
3073
3074 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
3075
e35e4d28 3076 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
3077}
3078
41ade00f
JB
3079struct get_key_cookie {
3080 struct sk_buff *msg;
3081 int error;
b9454e83 3082 int idx;
41ade00f
JB
3083};
3084
3085static void get_key_callback(void *c, struct key_params *params)
3086{
b9454e83 3087 struct nlattr *key;
41ade00f
JB
3088 struct get_key_cookie *cookie = c;
3089
9360ffd1
DM
3090 if ((params->key &&
3091 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
3092 params->key_len, params->key)) ||
3093 (params->seq &&
3094 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
3095 params->seq_len, params->seq)) ||
3096 (params->cipher &&
3097 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
3098 params->cipher)))
3099 goto nla_put_failure;
41ade00f 3100
b9454e83
JB
3101 key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
3102 if (!key)
3103 goto nla_put_failure;
3104
9360ffd1
DM
3105 if ((params->key &&
3106 nla_put(cookie->msg, NL80211_KEY_DATA,
3107 params->key_len, params->key)) ||
3108 (params->seq &&
3109 nla_put(cookie->msg, NL80211_KEY_SEQ,
3110 params->seq_len, params->seq)) ||
3111 (params->cipher &&
3112 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
3113 params->cipher)))
3114 goto nla_put_failure;
b9454e83 3115
9360ffd1
DM
3116 if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx))
3117 goto nla_put_failure;
b9454e83
JB
3118
3119 nla_nest_end(cookie->msg, key);
3120
41ade00f
JB
3121 return;
3122 nla_put_failure:
3123 cookie->error = 1;
3124}
3125
3126static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
3127{
4c476991 3128 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3129 int err;
4c476991 3130 struct net_device *dev = info->user_ptr[1];
41ade00f 3131 u8 key_idx = 0;
e31b8213
JB
3132 const u8 *mac_addr = NULL;
3133 bool pairwise;
41ade00f
JB
3134 struct get_key_cookie cookie = {
3135 .error = 0,
3136 };
3137 void *hdr;
3138 struct sk_buff *msg;
3139
3140 if (info->attrs[NL80211_ATTR_KEY_IDX])
3141 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
3142
3cfcf6ac 3143 if (key_idx > 5)
41ade00f
JB
3144 return -EINVAL;
3145
3146 if (info->attrs[NL80211_ATTR_MAC])
3147 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3148
e31b8213
JB
3149 pairwise = !!mac_addr;
3150 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
3151 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 3152
e31b8213
JB
3153 if (kt >= NUM_NL80211_KEYTYPES)
3154 return -EINVAL;
3155 if (kt != NL80211_KEYTYPE_GROUP &&
3156 kt != NL80211_KEYTYPE_PAIRWISE)
3157 return -EINVAL;
3158 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
3159 }
3160
4c476991
JB
3161 if (!rdev->ops->get_key)
3162 return -EOPNOTSUPP;
41ade00f 3163
0fa7b391
JB
3164 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3165 return -ENOENT;
3166
fd2120ca 3167 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
3168 if (!msg)
3169 return -ENOMEM;
41ade00f 3170
15e47304 3171 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 3172 NL80211_CMD_NEW_KEY);
cb35fba3 3173 if (!hdr)
9fe271af 3174 goto nla_put_failure;
41ade00f
JB
3175
3176 cookie.msg = msg;
b9454e83 3177 cookie.idx = key_idx;
41ade00f 3178
9360ffd1
DM
3179 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3180 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
3181 goto nla_put_failure;
3182 if (mac_addr &&
3183 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
3184 goto nla_put_failure;
41ade00f 3185
e35e4d28
HG
3186 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
3187 get_key_callback);
41ade00f
JB
3188
3189 if (err)
6c95e2a2 3190 goto free_msg;
41ade00f
JB
3191
3192 if (cookie.error)
3193 goto nla_put_failure;
3194
3195 genlmsg_end(msg, hdr);
4c476991 3196 return genlmsg_reply(msg, info);
41ade00f
JB
3197
3198 nla_put_failure:
3199 err = -ENOBUFS;
6c95e2a2 3200 free_msg:
41ade00f 3201 nlmsg_free(msg);
41ade00f
JB
3202 return err;
3203}
3204
3205static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
3206{
4c476991 3207 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 3208 struct key_parse key;
41ade00f 3209 int err;
4c476991 3210 struct net_device *dev = info->user_ptr[1];
41ade00f 3211
b9454e83
JB
3212 err = nl80211_parse_key(info, &key);
3213 if (err)
3214 return err;
41ade00f 3215
b9454e83 3216 if (key.idx < 0)
41ade00f
JB
3217 return -EINVAL;
3218
b9454e83
JB
3219 /* only support setting default key */
3220 if (!key.def && !key.defmgmt)
41ade00f
JB
3221 return -EINVAL;
3222
dbd2fd65 3223 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 3224
dbd2fd65
JB
3225 if (key.def) {
3226 if (!rdev->ops->set_default_key) {
3227 err = -EOPNOTSUPP;
3228 goto out;
3229 }
41ade00f 3230
dbd2fd65
JB
3231 err = nl80211_key_allowed(dev->ieee80211_ptr);
3232 if (err)
3233 goto out;
3234
e35e4d28 3235 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
3236 key.def_uni, key.def_multi);
3237
3238 if (err)
3239 goto out;
fffd0934 3240
3d23e349 3241#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
3242 dev->ieee80211_ptr->wext.default_key = key.idx;
3243#endif
3244 } else {
3245 if (key.def_uni || !key.def_multi) {
3246 err = -EINVAL;
3247 goto out;
3248 }
3249
3250 if (!rdev->ops->set_default_mgmt_key) {
3251 err = -EOPNOTSUPP;
3252 goto out;
3253 }
3254
3255 err = nl80211_key_allowed(dev->ieee80211_ptr);
3256 if (err)
3257 goto out;
3258
e35e4d28 3259 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
3260 if (err)
3261 goto out;
3262
3263#ifdef CONFIG_CFG80211_WEXT
3264 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 3265#endif
dbd2fd65
JB
3266 }
3267
3268 out:
fffd0934 3269 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3270
41ade00f
JB
3271 return err;
3272}
3273
3274static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
3275{
4c476991 3276 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 3277 int err;
4c476991 3278 struct net_device *dev = info->user_ptr[1];
b9454e83 3279 struct key_parse key;
e31b8213 3280 const u8 *mac_addr = NULL;
41ade00f 3281
b9454e83
JB
3282 err = nl80211_parse_key(info, &key);
3283 if (err)
3284 return err;
41ade00f 3285
b9454e83 3286 if (!key.p.key)
41ade00f
JB
3287 return -EINVAL;
3288
41ade00f
JB
3289 if (info->attrs[NL80211_ATTR_MAC])
3290 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3291
e31b8213
JB
3292 if (key.type == -1) {
3293 if (mac_addr)
3294 key.type = NL80211_KEYTYPE_PAIRWISE;
3295 else
3296 key.type = NL80211_KEYTYPE_GROUP;
3297 }
3298
3299 /* for now */
3300 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3301 key.type != NL80211_KEYTYPE_GROUP)
3302 return -EINVAL;
3303
4c476991
JB
3304 if (!rdev->ops->add_key)
3305 return -EOPNOTSUPP;
25e47c18 3306
e31b8213
JB
3307 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
3308 key.type == NL80211_KEYTYPE_PAIRWISE,
3309 mac_addr))
4c476991 3310 return -EINVAL;
41ade00f 3311
fffd0934
JB
3312 wdev_lock(dev->ieee80211_ptr);
3313 err = nl80211_key_allowed(dev->ieee80211_ptr);
3314 if (!err)
e35e4d28
HG
3315 err = rdev_add_key(rdev, dev, key.idx,
3316 key.type == NL80211_KEYTYPE_PAIRWISE,
3317 mac_addr, &key.p);
fffd0934 3318 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3319
41ade00f
JB
3320 return err;
3321}
3322
3323static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
3324{
4c476991 3325 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3326 int err;
4c476991 3327 struct net_device *dev = info->user_ptr[1];
41ade00f 3328 u8 *mac_addr = NULL;
b9454e83 3329 struct key_parse key;
41ade00f 3330
b9454e83
JB
3331 err = nl80211_parse_key(info, &key);
3332 if (err)
3333 return err;
41ade00f
JB
3334
3335 if (info->attrs[NL80211_ATTR_MAC])
3336 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3337
e31b8213
JB
3338 if (key.type == -1) {
3339 if (mac_addr)
3340 key.type = NL80211_KEYTYPE_PAIRWISE;
3341 else
3342 key.type = NL80211_KEYTYPE_GROUP;
3343 }
3344
3345 /* for now */
3346 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3347 key.type != NL80211_KEYTYPE_GROUP)
3348 return -EINVAL;
3349
4c476991
JB
3350 if (!rdev->ops->del_key)
3351 return -EOPNOTSUPP;
41ade00f 3352
fffd0934
JB
3353 wdev_lock(dev->ieee80211_ptr);
3354 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 3355
0fa7b391 3356 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
3357 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3358 err = -ENOENT;
3359
fffd0934 3360 if (!err)
e35e4d28
HG
3361 err = rdev_del_key(rdev, dev, key.idx,
3362 key.type == NL80211_KEYTYPE_PAIRWISE,
3363 mac_addr);
41ade00f 3364
3d23e349 3365#ifdef CONFIG_CFG80211_WEXT
08645126 3366 if (!err) {
b9454e83 3367 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 3368 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 3369 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
3370 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
3371 }
3372#endif
fffd0934 3373 wdev_unlock(dev->ieee80211_ptr);
08645126 3374
41ade00f
JB
3375 return err;
3376}
3377
77765eaf
VT
3378/* This function returns an error or the number of nested attributes */
3379static int validate_acl_mac_addrs(struct nlattr *nl_attr)
3380{
3381 struct nlattr *attr;
3382 int n_entries = 0, tmp;
3383
3384 nla_for_each_nested(attr, nl_attr, tmp) {
3385 if (nla_len(attr) != ETH_ALEN)
3386 return -EINVAL;
3387
3388 n_entries++;
3389 }
3390
3391 return n_entries;
3392}
3393
3394/*
3395 * This function parses ACL information and allocates memory for ACL data.
3396 * On successful return, the calling function is responsible to free the
3397 * ACL buffer returned by this function.
3398 */
3399static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
3400 struct genl_info *info)
3401{
3402 enum nl80211_acl_policy acl_policy;
3403 struct nlattr *attr;
3404 struct cfg80211_acl_data *acl;
3405 int i = 0, n_entries, tmp;
3406
3407 if (!wiphy->max_acl_mac_addrs)
3408 return ERR_PTR(-EOPNOTSUPP);
3409
3410 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
3411 return ERR_PTR(-EINVAL);
3412
3413 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
3414 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
3415 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
3416 return ERR_PTR(-EINVAL);
3417
3418 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
3419 return ERR_PTR(-EINVAL);
3420
3421 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
3422 if (n_entries < 0)
3423 return ERR_PTR(n_entries);
3424
3425 if (n_entries > wiphy->max_acl_mac_addrs)
3426 return ERR_PTR(-ENOTSUPP);
3427
3428 acl = kzalloc(sizeof(*acl) + (sizeof(struct mac_address) * n_entries),
3429 GFP_KERNEL);
3430 if (!acl)
3431 return ERR_PTR(-ENOMEM);
3432
3433 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
3434 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
3435 i++;
3436 }
3437
3438 acl->n_acl_entries = n_entries;
3439 acl->acl_policy = acl_policy;
3440
3441 return acl;
3442}
3443
3444static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
3445{
3446 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3447 struct net_device *dev = info->user_ptr[1];
3448 struct cfg80211_acl_data *acl;
3449 int err;
3450
3451 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3452 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3453 return -EOPNOTSUPP;
3454
3455 if (!dev->ieee80211_ptr->beacon_interval)
3456 return -EINVAL;
3457
3458 acl = parse_acl_data(&rdev->wiphy, info);
3459 if (IS_ERR(acl))
3460 return PTR_ERR(acl);
3461
3462 err = rdev_set_mac_acl(rdev, dev, acl);
3463
3464 kfree(acl);
3465
3466 return err;
3467}
3468
a7c7fbff
PK
3469static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
3470 u8 *rates, u8 rates_len)
3471{
3472 u8 i;
3473 u32 mask = 0;
3474
3475 for (i = 0; i < rates_len; i++) {
3476 int rate = (rates[i] & 0x7f) * 5;
3477 int ridx;
3478
3479 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
3480 struct ieee80211_rate *srate =
3481 &sband->bitrates[ridx];
3482 if (rate == srate->bitrate) {
3483 mask |= 1 << ridx;
3484 break;
3485 }
3486 }
3487 if (ridx == sband->n_bitrates)
3488 return 0; /* rate not found */
3489 }
3490
3491 return mask;
3492}
3493
3494static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
3495 u8 *rates, u8 rates_len,
3496 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
3497{
3498 u8 i;
3499
3500 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
3501
3502 for (i = 0; i < rates_len; i++) {
3503 int ridx, rbit;
3504
3505 ridx = rates[i] / 8;
3506 rbit = BIT(rates[i] % 8);
3507
3508 /* check validity */
3509 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
3510 return false;
3511
3512 /* check availability */
3513 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
3514 mcs[ridx] |= rbit;
3515 else
3516 return false;
3517 }
3518
3519 return true;
3520}
3521
3522static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
3523{
3524 u16 mcs_mask = 0;
3525
3526 switch (vht_mcs_map) {
3527 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
3528 break;
3529 case IEEE80211_VHT_MCS_SUPPORT_0_7:
3530 mcs_mask = 0x00FF;
3531 break;
3532 case IEEE80211_VHT_MCS_SUPPORT_0_8:
3533 mcs_mask = 0x01FF;
3534 break;
3535 case IEEE80211_VHT_MCS_SUPPORT_0_9:
3536 mcs_mask = 0x03FF;
3537 break;
3538 default:
3539 break;
3540 }
3541
3542 return mcs_mask;
3543}
3544
3545static void vht_build_mcs_mask(u16 vht_mcs_map,
3546 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
3547{
3548 u8 nss;
3549
3550 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
3551 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
3552 vht_mcs_map >>= 2;
3553 }
3554}
3555
3556static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
3557 struct nl80211_txrate_vht *txrate,
3558 u16 mcs[NL80211_VHT_NSS_MAX])
3559{
3560 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3561 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
3562 u8 i;
3563
3564 if (!sband->vht_cap.vht_supported)
3565 return false;
3566
3567 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
3568
3569 /* Build vht_mcs_mask from VHT capabilities */
3570 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
3571
3572 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
3573 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
3574 mcs[i] = txrate->mcs[i];
3575 else
3576 return false;
3577 }
3578
3579 return true;
3580}
3581
3582static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
3583 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
3584 .len = NL80211_MAX_SUPP_RATES },
3585 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
3586 .len = NL80211_MAX_SUPP_HT_RATES },
3587 [NL80211_TXRATE_VHT] = { .len = sizeof(struct nl80211_txrate_vht)},
3588 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
3589};
3590
3591static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
3592 struct cfg80211_bitrate_mask *mask)
3593{
3594 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
3595 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3596 int rem, i;
3597 struct nlattr *tx_rates;
3598 struct ieee80211_supported_band *sband;
3599 u16 vht_tx_mcs_map;
3600
3601 memset(mask, 0, sizeof(*mask));
3602 /* Default to all rates enabled */
3603 for (i = 0; i < NUM_NL80211_BANDS; i++) {
3604 sband = rdev->wiphy.bands[i];
3605
3606 if (!sband)
3607 continue;
3608
3609 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
3610 memcpy(mask->control[i].ht_mcs,
3611 sband->ht_cap.mcs.rx_mask,
3612 sizeof(mask->control[i].ht_mcs));
3613
3614 if (!sband->vht_cap.vht_supported)
3615 continue;
3616
3617 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3618 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
3619 }
3620
3621 /* if no rates are given set it back to the defaults */
3622 if (!info->attrs[NL80211_ATTR_TX_RATES])
3623 goto out;
3624
3625 /* The nested attribute uses enum nl80211_band as the index. This maps
3626 * directly to the enum nl80211_band values used in cfg80211.
3627 */
3628 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
3629 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
3630 enum nl80211_band band = nla_type(tx_rates);
3631 int err;
3632
3633 if (band < 0 || band >= NUM_NL80211_BANDS)
3634 return -EINVAL;
3635 sband = rdev->wiphy.bands[band];
3636 if (sband == NULL)
3637 return -EINVAL;
bfe2c7b1 3638 err = nla_parse_nested(tb, NL80211_TXRATE_MAX, tx_rates,
fe52145f 3639 nl80211_txattr_policy, info->extack);
a7c7fbff
PK
3640 if (err)
3641 return err;
3642 if (tb[NL80211_TXRATE_LEGACY]) {
3643 mask->control[band].legacy = rateset_to_mask(
3644 sband,
3645 nla_data(tb[NL80211_TXRATE_LEGACY]),
3646 nla_len(tb[NL80211_TXRATE_LEGACY]));
3647 if ((mask->control[band].legacy == 0) &&
3648 nla_len(tb[NL80211_TXRATE_LEGACY]))
3649 return -EINVAL;
3650 }
3651 if (tb[NL80211_TXRATE_HT]) {
3652 if (!ht_rateset_to_mask(
3653 sband,
3654 nla_data(tb[NL80211_TXRATE_HT]),
3655 nla_len(tb[NL80211_TXRATE_HT]),
3656 mask->control[band].ht_mcs))
3657 return -EINVAL;
3658 }
3659 if (tb[NL80211_TXRATE_VHT]) {
3660 if (!vht_set_mcs_mask(
3661 sband,
3662 nla_data(tb[NL80211_TXRATE_VHT]),
3663 mask->control[band].vht_mcs))
3664 return -EINVAL;
3665 }
3666 if (tb[NL80211_TXRATE_GI]) {
3667 mask->control[band].gi =
3668 nla_get_u8(tb[NL80211_TXRATE_GI]);
3669 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
3670 return -EINVAL;
3671 }
3672
3673 if (mask->control[band].legacy == 0) {
3674 /* don't allow empty legacy rates if HT or VHT
3675 * are not even supported.
3676 */
3677 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
3678 rdev->wiphy.bands[band]->vht_cap.vht_supported))
3679 return -EINVAL;
3680
3681 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
3682 if (mask->control[band].ht_mcs[i])
3683 goto out;
3684
3685 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
3686 if (mask->control[band].vht_mcs[i])
3687 goto out;
3688
3689 /* legacy and mcs rates may not be both empty */
3690 return -EINVAL;
3691 }
3692 }
3693
3694out:
3695 return 0;
3696}
3697
8564e382
JB
3698static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
3699 enum nl80211_band band,
3700 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 3701{
8564e382
JB
3702 u32 count_ht, count_vht, i;
3703 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
3704
3705 /* Allow only one rate */
3706 if (hweight32(rate) > 1)
3707 return -EINVAL;
3708
3709 count_ht = 0;
3710 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 3711 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 3712 return -EINVAL;
8564e382 3713 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
3714 count_ht++;
3715 if (count_ht > 1)
3716 return -EINVAL;
3717 }
3718 if (count_ht && rate)
3719 return -EINVAL;
3720 }
3721
3722 count_vht = 0;
3723 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 3724 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 3725 return -EINVAL;
8564e382 3726 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
3727 count_vht++;
3728 if (count_vht > 1)
3729 return -EINVAL;
3730 }
3731 if (count_vht && rate)
3732 return -EINVAL;
3733 }
3734
3735 if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht))
3736 return -EINVAL;
3737
8564e382
JB
3738 if (rate &&
3739 !wiphy_ext_feature_isset(&rdev->wiphy,
3740 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
3741 return -EINVAL;
3742 if (count_ht &&
3743 !wiphy_ext_feature_isset(&rdev->wiphy,
3744 NL80211_EXT_FEATURE_BEACON_RATE_HT))
3745 return -EINVAL;
3746 if (count_vht &&
3747 !wiphy_ext_feature_isset(&rdev->wiphy,
3748 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
3749 return -EINVAL;
3750
a7c7fbff
PK
3751 return 0;
3752}
3753
a1193be8 3754static int nl80211_parse_beacon(struct nlattr *attrs[],
8860020e 3755 struct cfg80211_beacon_data *bcn)
ed1b6cc7 3756{
8860020e 3757 bool haveinfo = false;
ed1b6cc7 3758
a1193be8
SW
3759 if (!is_valid_ie_attr(attrs[NL80211_ATTR_BEACON_TAIL]) ||
3760 !is_valid_ie_attr(attrs[NL80211_ATTR_IE]) ||
3761 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
3762 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_ASSOC_RESP]))
f4a11bb0
JB
3763 return -EINVAL;
3764
8860020e 3765 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 3766
a1193be8
SW
3767 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
3768 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
3769 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
3770 if (!bcn->head_len)
3771 return -EINVAL;
3772 haveinfo = true;
ed1b6cc7
JB
3773 }
3774
a1193be8
SW
3775 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
3776 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
3777 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 3778 haveinfo = true;
ed1b6cc7
JB
3779 }
3780
4c476991
JB
3781 if (!haveinfo)
3782 return -EINVAL;
3b85875a 3783
a1193be8
SW
3784 if (attrs[NL80211_ATTR_IE]) {
3785 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
3786 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
3787 }
3788
a1193be8 3789 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 3790 bcn->proberesp_ies =
a1193be8 3791 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 3792 bcn->proberesp_ies_len =
a1193be8 3793 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
3794 }
3795
a1193be8 3796 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 3797 bcn->assocresp_ies =
a1193be8 3798 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 3799 bcn->assocresp_ies_len =
a1193be8 3800 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
3801 }
3802
a1193be8
SW
3803 if (attrs[NL80211_ATTR_PROBE_RESP]) {
3804 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
3805 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
3806 }
3807
8860020e
JB
3808 return 0;
3809}
3810
66cd794e
JB
3811static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
3812 const u8 *rates)
3813{
3814 int i;
3815
3816 if (!rates)
3817 return;
3818
3819 for (i = 0; i < rates[1]; i++) {
3820 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
3821 params->ht_required = true;
3822 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
3823 params->vht_required = true;
3824 }
3825}
3826
3827/*
3828 * Since the nl80211 API didn't include, from the beginning, attributes about
3829 * HT/VHT requirements/capabilities, we parse them out of the IEs for the
3830 * benefit of drivers that rebuild IEs in the firmware.
3831 */
3832static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
3833{
3834 const struct cfg80211_beacon_data *bcn = &params->beacon;
ba83bfb1
IM
3835 size_t ies_len = bcn->tail_len;
3836 const u8 *ies = bcn->tail;
66cd794e
JB
3837 const u8 *rates;
3838 const u8 *cap;
3839
3840 rates = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies, ies_len);
3841 nl80211_check_ap_rate_selectors(params, rates);
3842
3843 rates = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
3844 nl80211_check_ap_rate_selectors(params, rates);
3845
3846 cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
3847 if (cap && cap[1] >= sizeof(*params->ht_cap))
3848 params->ht_cap = (void *)(cap + 2);
3849 cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
3850 if (cap && cap[1] >= sizeof(*params->vht_cap))
3851 params->vht_cap = (void *)(cap + 2);
3852}
3853
46c1dd0c
FF
3854static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3855 struct cfg80211_ap_settings *params)
3856{
3857 struct wireless_dev *wdev;
3858 bool ret = false;
3859
53873f13 3860 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
3861 if (wdev->iftype != NL80211_IFTYPE_AP &&
3862 wdev->iftype != NL80211_IFTYPE_P2P_GO)
3863 continue;
3864
683b6d3b 3865 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
3866 continue;
3867
683b6d3b 3868 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
3869 ret = true;
3870 break;
3871 }
3872
46c1dd0c
FF
3873 return ret;
3874}
3875
e39e5b5e
JM
3876static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
3877 enum nl80211_auth_type auth_type,
3878 enum nl80211_commands cmd)
3879{
3880 if (auth_type > NL80211_AUTHTYPE_MAX)
3881 return false;
3882
3883 switch (cmd) {
3884 case NL80211_CMD_AUTHENTICATE:
3885 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
3886 auth_type == NL80211_AUTHTYPE_SAE)
3887 return false;
63181060
JM
3888 if (!wiphy_ext_feature_isset(&rdev->wiphy,
3889 NL80211_EXT_FEATURE_FILS_STA) &&
3890 (auth_type == NL80211_AUTHTYPE_FILS_SK ||
3891 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
3892 auth_type == NL80211_AUTHTYPE_FILS_PK))
3893 return false;
e39e5b5e
JM
3894 return true;
3895 case NL80211_CMD_CONNECT:
a3caf744
VK
3896 /* SAE not supported yet */
3897 if (auth_type == NL80211_AUTHTYPE_SAE)
3898 return false;
3899 /* FILS with SK PFS or PK not supported yet */
3900 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
3901 auth_type == NL80211_AUTHTYPE_FILS_PK)
3902 return false;
3903 if (!wiphy_ext_feature_isset(
3904 &rdev->wiphy,
3905 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
3906 auth_type == NL80211_AUTHTYPE_FILS_SK)
3907 return false;
3908 return true;
e39e5b5e
JM
3909 case NL80211_CMD_START_AP:
3910 /* SAE not supported yet */
3911 if (auth_type == NL80211_AUTHTYPE_SAE)
3912 return false;
63181060
JM
3913 /* FILS not supported yet */
3914 if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
3915 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
3916 auth_type == NL80211_AUTHTYPE_FILS_PK)
3917 return false;
e39e5b5e
JM
3918 return true;
3919 default:
3920 return false;
3921 }
3922}
3923
8860020e
JB
3924static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3925{
3926 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3927 struct net_device *dev = info->user_ptr[1];
3928 struct wireless_dev *wdev = dev->ieee80211_ptr;
3929 struct cfg80211_ap_settings params;
3930 int err;
3931
3932 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3933 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3934 return -EOPNOTSUPP;
3935
3936 if (!rdev->ops->start_ap)
3937 return -EOPNOTSUPP;
3938
3939 if (wdev->beacon_interval)
3940 return -EALREADY;
3941
3942 memset(&params, 0, sizeof(params));
3943
3944 /* these are required for START_AP */
3945 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
3946 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
3947 !info->attrs[NL80211_ATTR_BEACON_HEAD])
3948 return -EINVAL;
3949
a1193be8 3950 err = nl80211_parse_beacon(info->attrs, &params.beacon);
8860020e
JB
3951 if (err)
3952 return err;
3953
3954 params.beacon_interval =
3955 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3956 params.dtim_period =
3957 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
3958
0c317a02
PK
3959 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
3960 params.beacon_interval);
8860020e
JB
3961 if (err)
3962 return err;
3963
3964 /*
3965 * In theory, some of these attributes should be required here
3966 * but since they were not used when the command was originally
3967 * added, keep them optional for old user space programs to let
3968 * them continue to work with drivers that do not need the
3969 * additional information -- drivers must check!
3970 */
3971 if (info->attrs[NL80211_ATTR_SSID]) {
3972 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3973 params.ssid_len =
3974 nla_len(info->attrs[NL80211_ATTR_SSID]);
3975 if (params.ssid_len == 0 ||
3976 params.ssid_len > IEEE80211_MAX_SSID_LEN)
3977 return -EINVAL;
3978 }
3979
3980 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
3981 params.hidden_ssid = nla_get_u32(
3982 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
3983 if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
3984 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
3985 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
3986 return -EINVAL;
3987 }
3988
3989 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
3990
3991 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
3992 params.auth_type = nla_get_u32(
3993 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
3994 if (!nl80211_valid_auth_type(rdev, params.auth_type,
3995 NL80211_CMD_START_AP))
8860020e
JB
3996 return -EINVAL;
3997 } else
3998 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
3999
4000 err = nl80211_crypto_settings(rdev, info, &params.crypto,
4001 NL80211_MAX_NR_CIPHER_SUITES);
4002 if (err)
4003 return err;
4004
1b658f11
VT
4005 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
4006 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
4007 return -EOPNOTSUPP;
4008 params.inactivity_timeout = nla_get_u16(
4009 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
4010 }
4011
53cabad7
JB
4012 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
4013 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4014 return -EINVAL;
4015 params.p2p_ctwindow =
4016 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
4017 if (params.p2p_ctwindow > 127)
4018 return -EINVAL;
4019 if (params.p2p_ctwindow != 0 &&
4020 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
4021 return -EINVAL;
4022 }
4023
4024 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
4025 u8 tmp;
4026
4027 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4028 return -EINVAL;
4029 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
4030 if (tmp > 1)
4031 return -EINVAL;
4032 params.p2p_opp_ps = tmp;
4033 if (params.p2p_opp_ps != 0 &&
4034 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
4035 return -EINVAL;
4036 }
4037
aa430da4 4038 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
4039 err = nl80211_parse_chandef(rdev, info, &params.chandef);
4040 if (err)
4041 return err;
4042 } else if (wdev->preset_chandef.chan) {
4043 params.chandef = wdev->preset_chandef;
46c1dd0c 4044 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
4045 return -EINVAL;
4046
923b352f
AN
4047 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
4048 wdev->iftype))
aa430da4
JB
4049 return -EINVAL;
4050
a7c7fbff
PK
4051 if (info->attrs[NL80211_ATTR_TX_RATES]) {
4052 err = nl80211_parse_tx_bitrate_mask(info, &params.beacon_rate);
4053 if (err)
4054 return err;
4055
8564e382
JB
4056 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
4057 &params.beacon_rate);
a7c7fbff
PK
4058 if (err)
4059 return err;
4060 }
4061
18998c38
EP
4062 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
4063 params.smps_mode =
4064 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
4065 switch (params.smps_mode) {
4066 case NL80211_SMPS_OFF:
4067 break;
4068 case NL80211_SMPS_STATIC:
4069 if (!(rdev->wiphy.features &
4070 NL80211_FEATURE_STATIC_SMPS))
4071 return -EINVAL;
4072 break;
4073 case NL80211_SMPS_DYNAMIC:
4074 if (!(rdev->wiphy.features &
4075 NL80211_FEATURE_DYNAMIC_SMPS))
4076 return -EINVAL;
4077 break;
4078 default:
4079 return -EINVAL;
4080 }
4081 } else {
4082 params.smps_mode = NL80211_SMPS_OFF;
4083 }
4084
6e8ef842
PK
4085 params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
4086 if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
4087 return -EOPNOTSUPP;
4088
4baf6bea
OO
4089 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
4090 params.acl = parse_acl_data(&rdev->wiphy, info);
4091 if (IS_ERR(params.acl))
4092 return PTR_ERR(params.acl);
4093 }
4094
66cd794e
JB
4095 nl80211_calculate_ap_params(&params);
4096
c56589ed 4097 wdev_lock(wdev);
e35e4d28 4098 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 4099 if (!err) {
683b6d3b 4100 wdev->preset_chandef = params.chandef;
8860020e 4101 wdev->beacon_interval = params.beacon_interval;
9e0e2961 4102 wdev->chandef = params.chandef;
06e191e2
AQ
4103 wdev->ssid_len = params.ssid_len;
4104 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
46c1dd0c 4105 }
c56589ed 4106 wdev_unlock(wdev);
77765eaf
VT
4107
4108 kfree(params.acl);
4109
56d1893d 4110 return err;
ed1b6cc7
JB
4111}
4112
8860020e
JB
4113static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
4114{
4115 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4116 struct net_device *dev = info->user_ptr[1];
4117 struct wireless_dev *wdev = dev->ieee80211_ptr;
4118 struct cfg80211_beacon_data params;
4119 int err;
4120
4121 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4122 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4123 return -EOPNOTSUPP;
4124
4125 if (!rdev->ops->change_beacon)
4126 return -EOPNOTSUPP;
4127
4128 if (!wdev->beacon_interval)
4129 return -EINVAL;
4130
a1193be8 4131 err = nl80211_parse_beacon(info->attrs, &params);
8860020e
JB
4132 if (err)
4133 return err;
4134
c56589ed
SW
4135 wdev_lock(wdev);
4136 err = rdev_change_beacon(rdev, dev, &params);
4137 wdev_unlock(wdev);
4138
4139 return err;
8860020e
JB
4140}
4141
4142static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 4143{
4c476991
JB
4144 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4145 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 4146
7c8d5e03 4147 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
4148}
4149
5727ef1b
JB
4150static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
4151 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
4152 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
4153 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 4154 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 4155 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 4156 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
4157};
4158
eccb8e8f 4159static int parse_station_flags(struct genl_info *info,
bdd3ae3d 4160 enum nl80211_iftype iftype,
eccb8e8f 4161 struct station_parameters *params)
5727ef1b
JB
4162{
4163 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 4164 struct nlattr *nla;
5727ef1b
JB
4165 int flag;
4166
eccb8e8f
JB
4167 /*
4168 * Try parsing the new attribute first so userspace
4169 * can specify both for older kernels.
4170 */
4171 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
4172 if (nla) {
4173 struct nl80211_sta_flag_update *sta_flags;
4174
4175 sta_flags = nla_data(nla);
4176 params->sta_flags_mask = sta_flags->mask;
4177 params->sta_flags_set = sta_flags->set;
77ee7c89 4178 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
4179 if ((params->sta_flags_mask |
4180 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
4181 return -EINVAL;
4182 return 0;
4183 }
4184
4185 /* if present, parse the old attribute */
5727ef1b 4186
eccb8e8f 4187 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
4188 if (!nla)
4189 return 0;
4190
fceb6435 4191 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX, nla,
fe52145f 4192 sta_flags_policy, info->extack))
5727ef1b
JB
4193 return -EINVAL;
4194
bdd3ae3d
JB
4195 /*
4196 * Only allow certain flags for interface types so that
4197 * other attributes are silently ignored. Remember that
4198 * this is backward compatibility code with old userspace
4199 * and shouldn't be hit in other cases anyway.
4200 */
4201 switch (iftype) {
4202 case NL80211_IFTYPE_AP:
4203 case NL80211_IFTYPE_AP_VLAN:
4204 case NL80211_IFTYPE_P2P_GO:
4205 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4206 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4207 BIT(NL80211_STA_FLAG_WME) |
4208 BIT(NL80211_STA_FLAG_MFP);
4209 break;
4210 case NL80211_IFTYPE_P2P_CLIENT:
4211 case NL80211_IFTYPE_STATION:
4212 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4213 BIT(NL80211_STA_FLAG_TDLS_PEER);
4214 break;
4215 case NL80211_IFTYPE_MESH_POINT:
4216 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4217 BIT(NL80211_STA_FLAG_MFP) |
4218 BIT(NL80211_STA_FLAG_AUTHORIZED);
4219 default:
4220 return -EINVAL;
4221 }
5727ef1b 4222
3383b5a6
JB
4223 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
4224 if (flags[flag]) {
eccb8e8f 4225 params->sta_flags_set |= (1<<flag);
5727ef1b 4226
3383b5a6
JB
4227 /* no longer support new API additions in old API */
4228 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
4229 return -EINVAL;
4230 }
4231 }
4232
5727ef1b
JB
4233 return 0;
4234}
4235
c8dcfd8a
FF
4236static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
4237 int attr)
4238{
4239 struct nlattr *rate;
8eb41c8d
VK
4240 u32 bitrate;
4241 u16 bitrate_compat;
bbf67e45 4242 enum nl80211_rate_info rate_flg;
c8dcfd8a
FF
4243
4244 rate = nla_nest_start(msg, attr);
4245 if (!rate)
db9c64cf 4246 return false;
c8dcfd8a
FF
4247
4248 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
4249 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
4250 /* report 16-bit bitrate only if we can */
4251 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
4252 if (bitrate > 0 &&
4253 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
4254 return false;
4255 if (bitrate_compat > 0 &&
4256 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
4257 return false;
4258
b51f3bee
JB
4259 switch (info->bw) {
4260 case RATE_INFO_BW_5:
4261 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
4262 break;
4263 case RATE_INFO_BW_10:
4264 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
4265 break;
4266 default:
4267 WARN_ON(1);
4268 /* fall through */
4269 case RATE_INFO_BW_20:
4270 rate_flg = 0;
4271 break;
4272 case RATE_INFO_BW_40:
4273 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
4274 break;
4275 case RATE_INFO_BW_80:
4276 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
4277 break;
4278 case RATE_INFO_BW_160:
4279 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
4280 break;
4281 }
4282
4283 if (rate_flg && nla_put_flag(msg, rate_flg))
4284 return false;
4285
db9c64cf
JB
4286 if (info->flags & RATE_INFO_FLAGS_MCS) {
4287 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
4288 return false;
db9c64cf
JB
4289 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4290 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4291 return false;
4292 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
4293 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
4294 return false;
4295 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
4296 return false;
db9c64cf
JB
4297 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4298 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4299 return false;
4300 }
c8dcfd8a
FF
4301
4302 nla_nest_end(msg, rate);
4303 return true;
c8dcfd8a
FF
4304}
4305
119363c7
FF
4306static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
4307 int id)
4308{
4309 void *attr;
4310 int i = 0;
4311
4312 if (!mask)
4313 return true;
4314
4315 attr = nla_nest_start(msg, id);
4316 if (!attr)
4317 return false;
4318
4319 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
4320 if (!(mask & BIT(i)))
4321 continue;
4322
4323 if (nla_put_u8(msg, i, signal[i]))
4324 return false;
4325 }
4326
4327 nla_nest_end(msg, attr);
4328
4329 return true;
4330}
4331
cf5ead82
JB
4332static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
4333 u32 seq, int flags,
66266b3a
JL
4334 struct cfg80211_registered_device *rdev,
4335 struct net_device *dev,
98b62183 4336 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
4337{
4338 void *hdr;
f4263c98 4339 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 4340
cf5ead82 4341 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
fd5b74dc
JB
4342 if (!hdr)
4343 return -1;
4344
9360ffd1
DM
4345 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4346 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
4347 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
4348 goto nla_put_failure;
f5ea9120 4349
2ec600d6
LCC
4350 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
4351 if (!sinfoattr)
fd5b74dc 4352 goto nla_put_failure;
319090bf
JB
4353
4354#define PUT_SINFO(attr, memb, type) do { \
d686b920 4355 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
739960f1 4356 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
319090bf
JB
4357 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
4358 sinfo->memb)) \
4359 goto nla_put_failure; \
4360 } while (0)
d686b920
JB
4361#define PUT_SINFO_U64(attr, memb) do { \
4362 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
4363 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
4364 sinfo->memb, NL80211_STA_INFO_PAD)) \
4365 goto nla_put_failure; \
4366 } while (0)
319090bf
JB
4367
4368 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
4369 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
4370
4371 if (sinfo->filled & (BIT(NL80211_STA_INFO_RX_BYTES) |
4372 BIT(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 4373 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 4374 (u32)sinfo->rx_bytes))
9360ffd1 4375 goto nla_put_failure;
319090bf
JB
4376
4377 if (sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES) |
4378 BIT(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 4379 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
4380 (u32)sinfo->tx_bytes))
4381 goto nla_put_failure;
319090bf 4382
d686b920
JB
4383 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
4384 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
4385 PUT_SINFO(LLID, llid, u16);
4386 PUT_SINFO(PLID, plid, u16);
4387 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 4388 PUT_SINFO_U64(RX_DURATION, rx_duration);
319090bf 4389
66266b3a
JL
4390 switch (rdev->wiphy.signal_type) {
4391 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
4392 PUT_SINFO(SIGNAL, signal, u8);
4393 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
4394 break;
4395 default:
4396 break;
4397 }
319090bf 4398 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
4399 if (!nl80211_put_signal(msg, sinfo->chains,
4400 sinfo->chain_signal,
4401 NL80211_STA_INFO_CHAIN_SIGNAL))
4402 goto nla_put_failure;
4403 }
319090bf 4404 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
4405 if (!nl80211_put_signal(msg, sinfo->chains,
4406 sinfo->chain_signal_avg,
4407 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
4408 goto nla_put_failure;
4409 }
319090bf 4410 if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
4411 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
4412 NL80211_STA_INFO_TX_BITRATE))
4413 goto nla_put_failure;
4414 }
319090bf 4415 if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
4416 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
4417 NL80211_STA_INFO_RX_BITRATE))
420e7fab 4418 goto nla_put_failure;
420e7fab 4419 }
319090bf
JB
4420
4421 PUT_SINFO(RX_PACKETS, rx_packets, u32);
4422 PUT_SINFO(TX_PACKETS, tx_packets, u32);
4423 PUT_SINFO(TX_RETRIES, tx_retries, u32);
4424 PUT_SINFO(TX_FAILED, tx_failed, u32);
4425 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
4426 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
4427 PUT_SINFO(LOCAL_PM, local_pm, u32);
4428 PUT_SINFO(PEER_PM, peer_pm, u32);
4429 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
4430
4431 if (sinfo->filled & BIT(NL80211_STA_INFO_BSS_PARAM)) {
f4263c98
PS
4432 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
4433 if (!bss_param)
4434 goto nla_put_failure;
4435
9360ffd1
DM
4436 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
4437 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
4438 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
4439 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
4440 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
4441 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
4442 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
4443 sinfo->bss_param.dtim_period) ||
4444 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
4445 sinfo->bss_param.beacon_interval))
4446 goto nla_put_failure;
f4263c98
PS
4447
4448 nla_nest_end(msg, bss_param);
4449 }
319090bf 4450 if ((sinfo->filled & BIT(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
4451 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
4452 sizeof(struct nl80211_sta_flag_update),
4453 &sinfo->sta_flags))
4454 goto nla_put_failure;
319090bf 4455
d686b920
JB
4456 PUT_SINFO_U64(T_OFFSET, t_offset);
4457 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
4458 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 4459 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
319090bf
JB
4460
4461#undef PUT_SINFO
d686b920 4462#undef PUT_SINFO_U64
6de39808
JB
4463
4464 if (sinfo->filled & BIT(NL80211_STA_INFO_TID_STATS)) {
4465 struct nlattr *tidsattr;
4466 int tid;
4467
4468 tidsattr = nla_nest_start(msg, NL80211_STA_INFO_TID_STATS);
4469 if (!tidsattr)
4470 goto nla_put_failure;
4471
4472 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
4473 struct cfg80211_tid_stats *tidstats;
4474 struct nlattr *tidattr;
4475
4476 tidstats = &sinfo->pertid[tid];
4477
4478 if (!tidstats->filled)
4479 continue;
4480
4481 tidattr = nla_nest_start(msg, tid + 1);
4482 if (!tidattr)
4483 goto nla_put_failure;
4484
d686b920 4485#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 4486 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
4487 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
4488 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
4489 goto nla_put_failure; \
4490 } while (0)
4491
d686b920
JB
4492 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
4493 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
4494 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
4495 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 4496
d686b920 4497#undef PUT_TIDVAL_U64
6de39808
JB
4498 nla_nest_end(msg, tidattr);
4499 }
4500
4501 nla_nest_end(msg, tidsattr);
4502 }
4503
2ec600d6 4504 nla_nest_end(msg, sinfoattr);
fd5b74dc 4505
319090bf 4506 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
4507 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
4508 sinfo->assoc_req_ies))
4509 goto nla_put_failure;
50d3dfb7 4510
053c095a
JB
4511 genlmsg_end(msg, hdr);
4512 return 0;
fd5b74dc
JB
4513
4514 nla_put_failure:
bc3ed28c
TG
4515 genlmsg_cancel(msg, hdr);
4516 return -EMSGSIZE;
fd5b74dc
JB
4517}
4518
2ec600d6 4519static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 4520 struct netlink_callback *cb)
2ec600d6 4521{
2ec600d6 4522 struct station_info sinfo;
1b8ec87a 4523 struct cfg80211_registered_device *rdev;
97990a06 4524 struct wireless_dev *wdev;
2ec600d6 4525 u8 mac_addr[ETH_ALEN];
97990a06 4526 int sta_idx = cb->args[2];
2ec600d6 4527 int err;
2ec600d6 4528
ea90e0dc 4529 rtnl_lock();
1b8ec87a 4530 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893 4531 if (err)
ea90e0dc 4532 goto out_err;
bba95fef 4533
97990a06
JB
4534 if (!wdev->netdev) {
4535 err = -EINVAL;
4536 goto out_err;
4537 }
4538
1b8ec87a 4539 if (!rdev->ops->dump_station) {
eec60b03 4540 err = -EOPNOTSUPP;
bba95fef
JB
4541 goto out_err;
4542 }
4543
bba95fef 4544 while (1) {
f612cedf 4545 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 4546 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
e35e4d28 4547 mac_addr, &sinfo);
bba95fef
JB
4548 if (err == -ENOENT)
4549 break;
4550 if (err)
3b85875a 4551 goto out_err;
bba95fef 4552
cf5ead82 4553 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 4554 NETLINK_CB(cb->skb).portid,
bba95fef 4555 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 4556 rdev, wdev->netdev, mac_addr,
bba95fef
JB
4557 &sinfo) < 0)
4558 goto out;
4559
4560 sta_idx++;
4561 }
4562
bba95fef 4563 out:
97990a06 4564 cb->args[2] = sta_idx;
bba95fef 4565 err = skb->len;
bba95fef 4566 out_err:
ea90e0dc 4567 rtnl_unlock();
bba95fef
JB
4568
4569 return err;
2ec600d6 4570}
fd5b74dc 4571
5727ef1b
JB
4572static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
4573{
4c476991
JB
4574 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4575 struct net_device *dev = info->user_ptr[1];
2ec600d6 4576 struct station_info sinfo;
fd5b74dc
JB
4577 struct sk_buff *msg;
4578 u8 *mac_addr = NULL;
4c476991 4579 int err;
fd5b74dc 4580
2ec600d6 4581 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc
JB
4582
4583 if (!info->attrs[NL80211_ATTR_MAC])
4584 return -EINVAL;
4585
4586 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4587
4c476991
JB
4588 if (!rdev->ops->get_station)
4589 return -EOPNOTSUPP;
3b85875a 4590
e35e4d28 4591 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 4592 if (err)
4c476991 4593 return err;
2ec600d6 4594
fd2120ca 4595 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
fd5b74dc 4596 if (!msg)
4c476991 4597 return -ENOMEM;
fd5b74dc 4598
cf5ead82
JB
4599 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
4600 info->snd_portid, info->snd_seq, 0,
66266b3a 4601 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991
JB
4602 nlmsg_free(msg);
4603 return -ENOBUFS;
4604 }
3b85875a 4605
4c476991 4606 return genlmsg_reply(msg, info);
5727ef1b
JB
4607}
4608
77ee7c89
JB
4609int cfg80211_check_station_change(struct wiphy *wiphy,
4610 struct station_parameters *params,
4611 enum cfg80211_station_type statype)
4612{
e4208427
AB
4613 if (params->listen_interval != -1 &&
4614 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 4615 return -EINVAL;
e4208427 4616
17b94247
AB
4617 if (params->support_p2p_ps != -1 &&
4618 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
4619 return -EINVAL;
4620
c72e1140 4621 if (params->aid &&
e4208427
AB
4622 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
4623 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
4624 return -EINVAL;
4625
4626 /* When you run into this, adjust the code below for the new flag */
4627 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
4628
4629 switch (statype) {
eef941e6
TP
4630 case CFG80211_STA_MESH_PEER_KERNEL:
4631 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
4632 /*
4633 * No ignoring the TDLS flag here -- the userspace mesh
4634 * code doesn't have the bug of including TDLS in the
4635 * mask everywhere.
4636 */
4637 if (params->sta_flags_mask &
4638 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4639 BIT(NL80211_STA_FLAG_MFP) |
4640 BIT(NL80211_STA_FLAG_AUTHORIZED)))
4641 return -EINVAL;
4642 break;
4643 case CFG80211_STA_TDLS_PEER_SETUP:
4644 case CFG80211_STA_TDLS_PEER_ACTIVE:
4645 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
4646 return -EINVAL;
4647 /* ignore since it can't change */
4648 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
4649 break;
4650 default:
4651 /* disallow mesh-specific things */
4652 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
4653 return -EINVAL;
4654 if (params->local_pm)
4655 return -EINVAL;
4656 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
4657 return -EINVAL;
4658 }
4659
4660 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
4661 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
4662 /* TDLS can't be set, ... */
4663 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
4664 return -EINVAL;
4665 /*
4666 * ... but don't bother the driver with it. This works around
4667 * a hostapd/wpa_supplicant issue -- it always includes the
4668 * TLDS_PEER flag in the mask even for AP mode.
4669 */
4670 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
4671 }
4672
47edb11b
AB
4673 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
4674 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
4675 /* reject other things that can't change */
4676 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
4677 return -EINVAL;
4678 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
4679 return -EINVAL;
4680 if (params->supported_rates)
4681 return -EINVAL;
4682 if (params->ext_capab || params->ht_capa || params->vht_capa)
4683 return -EINVAL;
4684 }
4685
47edb11b
AB
4686 if (statype != CFG80211_STA_AP_CLIENT &&
4687 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
4688 if (params->vlan)
4689 return -EINVAL;
4690 }
4691
4692 switch (statype) {
4693 case CFG80211_STA_AP_MLME_CLIENT:
4694 /* Use this only for authorizing/unauthorizing a station */
4695 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4696 return -EOPNOTSUPP;
4697 break;
4698 case CFG80211_STA_AP_CLIENT:
47edb11b 4699 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
4700 /* accept only the listed bits */
4701 if (params->sta_flags_mask &
4702 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
4703 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4704 BIT(NL80211_STA_FLAG_ASSOCIATED) |
4705 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4706 BIT(NL80211_STA_FLAG_WME) |
4707 BIT(NL80211_STA_FLAG_MFP)))
4708 return -EINVAL;
4709
4710 /* but authenticated/associated only if driver handles it */
4711 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
4712 params->sta_flags_mask &
4713 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4714 BIT(NL80211_STA_FLAG_ASSOCIATED)))
4715 return -EINVAL;
4716 break;
4717 case CFG80211_STA_IBSS:
4718 case CFG80211_STA_AP_STA:
4719 /* reject any changes other than AUTHORIZED */
4720 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
4721 return -EINVAL;
4722 break;
4723 case CFG80211_STA_TDLS_PEER_SETUP:
4724 /* reject any changes other than AUTHORIZED or WME */
4725 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
4726 BIT(NL80211_STA_FLAG_WME)))
4727 return -EINVAL;
4728 /* force (at least) rates when authorizing */
4729 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
4730 !params->supported_rates)
4731 return -EINVAL;
4732 break;
4733 case CFG80211_STA_TDLS_PEER_ACTIVE:
4734 /* reject any changes */
4735 return -EINVAL;
eef941e6 4736 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
4737 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
4738 return -EINVAL;
4739 break;
eef941e6 4740 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
4741 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
4742 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
4743 return -EINVAL;
4744 break;
4745 }
4746
06f7c88c
BL
4747 /*
4748 * Older kernel versions ignored this attribute entirely, so don't
4749 * reject attempts to update it but mark it as unused instead so the
4750 * driver won't look at the data.
4751 */
4752 if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
4753 statype != CFG80211_STA_TDLS_PEER_SETUP)
4754 params->opmode_notif_used = false;
4755
77ee7c89
JB
4756 return 0;
4757}
4758EXPORT_SYMBOL(cfg80211_check_station_change);
4759
5727ef1b 4760/*
c258d2de 4761 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 4762 */
80b99899
JB
4763static struct net_device *get_vlan(struct genl_info *info,
4764 struct cfg80211_registered_device *rdev)
5727ef1b 4765{
463d0183 4766 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
4767 struct net_device *v;
4768 int ret;
4769
4770 if (!vlanattr)
4771 return NULL;
4772
4773 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
4774 if (!v)
4775 return ERR_PTR(-ENODEV);
4776
4777 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
4778 ret = -EINVAL;
4779 goto error;
5727ef1b 4780 }
80b99899 4781
77ee7c89
JB
4782 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4783 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4784 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
4785 ret = -EINVAL;
4786 goto error;
4787 }
4788
80b99899
JB
4789 if (!netif_running(v)) {
4790 ret = -ENETDOWN;
4791 goto error;
4792 }
4793
4794 return v;
4795 error:
4796 dev_put(v);
4797 return ERR_PTR(ret);
5727ef1b
JB
4798}
4799
94e860f1
JB
4800static const struct nla_policy
4801nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
4802 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
4803 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
4804};
4805
ff276691
JB
4806static int nl80211_parse_sta_wme(struct genl_info *info,
4807 struct station_parameters *params)
df881293 4808{
df881293
JM
4809 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
4810 struct nlattr *nla;
4811 int err;
4812
df881293
JM
4813 /* parse WME attributes if present */
4814 if (!info->attrs[NL80211_ATTR_STA_WME])
4815 return 0;
4816
4817 nla = info->attrs[NL80211_ATTR_STA_WME];
4818 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
fe52145f 4819 nl80211_sta_wme_policy, info->extack);
df881293
JM
4820 if (err)
4821 return err;
4822
4823 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
4824 params->uapsd_queues = nla_get_u8(
4825 tb[NL80211_STA_WME_UAPSD_QUEUES]);
4826 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
4827 return -EINVAL;
4828
4829 if (tb[NL80211_STA_WME_MAX_SP])
4830 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
4831
4832 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
4833 return -EINVAL;
4834
4835 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
4836
4837 return 0;
4838}
4839
c01fc9ad
SD
4840static int nl80211_parse_sta_channel_info(struct genl_info *info,
4841 struct station_parameters *params)
4842{
4843 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
4844 params->supported_channels =
4845 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
4846 params->supported_channels_len =
4847 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
4848 /*
4849 * Need to include at least one (first channel, number of
4850 * channels) tuple for each subband, and must have proper
4851 * tuples for the rest of the data as well.
4852 */
4853 if (params->supported_channels_len < 2)
4854 return -EINVAL;
4855 if (params->supported_channels_len % 2)
4856 return -EINVAL;
4857 }
4858
4859 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
4860 params->supported_oper_classes =
4861 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
4862 params->supported_oper_classes_len =
4863 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
4864 /*
4865 * The value of the Length field of the Supported Operating
4866 * Classes element is between 2 and 253.
4867 */
4868 if (params->supported_oper_classes_len < 2 ||
4869 params->supported_oper_classes_len > 253)
4870 return -EINVAL;
4871 }
4872 return 0;
4873}
4874
ff276691
JB
4875static int nl80211_set_station_tdls(struct genl_info *info,
4876 struct station_parameters *params)
4877{
c01fc9ad 4878 int err;
ff276691 4879 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
4880 if (info->attrs[NL80211_ATTR_PEER_AID])
4881 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
4882 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
4883 params->ht_capa =
4884 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
4885 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
4886 params->vht_capa =
4887 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
4888
c01fc9ad
SD
4889 err = nl80211_parse_sta_channel_info(info, params);
4890 if (err)
4891 return err;
4892
ff276691
JB
4893 return nl80211_parse_sta_wme(info, params);
4894}
4895
5727ef1b
JB
4896static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
4897{
4c476991 4898 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 4899 struct net_device *dev = info->user_ptr[1];
5727ef1b 4900 struct station_parameters params;
77ee7c89
JB
4901 u8 *mac_addr;
4902 int err;
5727ef1b
JB
4903
4904 memset(&params, 0, sizeof(params));
4905
77ee7c89
JB
4906 if (!rdev->ops->change_station)
4907 return -EOPNOTSUPP;
4908
e4208427
AB
4909 /*
4910 * AID and listen_interval properties can be set only for unassociated
4911 * station. Include these parameters here and will check them in
4912 * cfg80211_check_station_change().
4913 */
a9bc31e4
AB
4914 if (info->attrs[NL80211_ATTR_STA_AID])
4915 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427
AB
4916
4917 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
4918 params.listen_interval =
4919 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
4920 else
4921 params.listen_interval = -1;
5727ef1b 4922
17b94247
AB
4923 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
4924 u8 tmp;
4925
4926 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
4927 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
4928 return -EINVAL;
4929
4930 params.support_p2p_ps = tmp;
4931 } else {
4932 params.support_p2p_ps = -1;
4933 }
4934
5727ef1b
JB
4935 if (!info->attrs[NL80211_ATTR_MAC])
4936 return -EINVAL;
4937
4938 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4939
4940 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
4941 params.supported_rates =
4942 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4943 params.supported_rates_len =
4944 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4945 }
4946
9d62a986
JM
4947 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
4948 params.capability =
4949 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
4950 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
4951 }
4952
4953 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
4954 params.ext_capab =
4955 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4956 params.ext_capab_len =
4957 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4958 }
4959
bdd3ae3d 4960 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
4961 return -EINVAL;
4962
f8bacc21 4963 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
2ec600d6 4964 params.plink_action =
f8bacc21
JB
4965 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
4966 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
4967 return -EINVAL;
4968 }
2ec600d6 4969
f8bacc21 4970 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 4971 params.plink_state =
f8bacc21
JB
4972 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
4973 if (params.plink_state >= NUM_NL80211_PLINK_STATES)
4974 return -EINVAL;
7d27a0ba
MH
4975 if (info->attrs[NL80211_ATTR_MESH_PEER_AID]) {
4976 params.peer_aid = nla_get_u16(
4977 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
4978 if (params.peer_aid > IEEE80211_MAX_AID)
4979 return -EINVAL;
4980 }
f8bacc21
JB
4981 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
4982 }
9c3990aa 4983
3b1c5a53
MP
4984 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) {
4985 enum nl80211_mesh_power_mode pm = nla_get_u32(
4986 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
4987
4988 if (pm <= NL80211_MESH_POWER_UNKNOWN ||
4989 pm > NL80211_MESH_POWER_MAX)
4990 return -EINVAL;
4991
4992 params.local_pm = pm;
4993 }
4994
06f7c88c
BL
4995 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
4996 params.opmode_notif_used = true;
4997 params.opmode_notif =
4998 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
4999 }
5000
77ee7c89
JB
5001 /* Include parameters for TDLS peer (will check later) */
5002 err = nl80211_set_station_tdls(info, &params);
5003 if (err)
5004 return err;
5005
5006 params.vlan = get_vlan(info, rdev);
5007 if (IS_ERR(params.vlan))
5008 return PTR_ERR(params.vlan);
5009
a97f4424
JB
5010 switch (dev->ieee80211_ptr->iftype) {
5011 case NL80211_IFTYPE_AP:
5012 case NL80211_IFTYPE_AP_VLAN:
074ac8df 5013 case NL80211_IFTYPE_P2P_GO:
074ac8df 5014 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 5015 case NL80211_IFTYPE_STATION:
267335d6 5016 case NL80211_IFTYPE_ADHOC:
a97f4424 5017 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
5018 break;
5019 default:
77ee7c89
JB
5020 err = -EOPNOTSUPP;
5021 goto out_put_vlan;
034d655e
JB
5022 }
5023
77ee7c89 5024 /* driver will call cfg80211_check_station_change() */
e35e4d28 5025 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 5026
77ee7c89 5027 out_put_vlan:
5727ef1b
JB
5028 if (params.vlan)
5029 dev_put(params.vlan);
3b85875a 5030
5727ef1b
JB
5031 return err;
5032}
5033
5034static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
5035{
4c476991 5036 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 5037 int err;
4c476991 5038 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
5039 struct station_parameters params;
5040 u8 *mac_addr = NULL;
bda95eb1
JB
5041 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5042 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
5043
5044 memset(&params, 0, sizeof(params));
5045
984c311b
JB
5046 if (!rdev->ops->add_station)
5047 return -EOPNOTSUPP;
5048
5727ef1b
JB
5049 if (!info->attrs[NL80211_ATTR_MAC])
5050 return -EINVAL;
5051
5727ef1b
JB
5052 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
5053 return -EINVAL;
5054
5055 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
5056 return -EINVAL;
5057
5e4b6f56
JM
5058 if (!info->attrs[NL80211_ATTR_STA_AID] &&
5059 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
5060 return -EINVAL;
5061
5727ef1b
JB
5062 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
5063 params.supported_rates =
5064 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5065 params.supported_rates_len =
5066 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5067 params.listen_interval =
5068 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 5069
17b94247
AB
5070 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
5071 u8 tmp;
5072
5073 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
5074 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
5075 return -EINVAL;
5076
5077 params.support_p2p_ps = tmp;
5078 } else {
5079 /*
5080 * if not specified, assume it's supported for P2P GO interface,
5081 * and is NOT supported for AP interface
5082 */
5083 params.support_p2p_ps =
5084 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
5085 }
5086
3d124ea2 5087 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 5088 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
5089 else
5090 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
0e956c13
TLSC
5091 if (!params.aid || params.aid > IEEE80211_MAX_AID)
5092 return -EINVAL;
51b50fbe 5093
9d62a986
JM
5094 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
5095 params.capability =
5096 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
5097 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
5098 }
5099
5100 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
5101 params.ext_capab =
5102 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5103 params.ext_capab_len =
5104 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5105 }
5106
36aedc90
JM
5107 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
5108 params.ht_capa =
5109 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 5110
f461be3e
MP
5111 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
5112 params.vht_capa =
5113 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
5114
60f4a7b1
MK
5115 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
5116 params.opmode_notif_used = true;
5117 params.opmode_notif =
5118 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
5119 }
5120
f8bacc21 5121 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
96b78dff 5122 params.plink_action =
f8bacc21
JB
5123 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
5124 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
5125 return -EINVAL;
5126 }
96b78dff 5127
c01fc9ad
SD
5128 err = nl80211_parse_sta_channel_info(info, &params);
5129 if (err)
5130 return err;
5131
ff276691
JB
5132 err = nl80211_parse_sta_wme(info, &params);
5133 if (err)
5134 return err;
bdd90d5e 5135
bdd3ae3d 5136 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
5137 return -EINVAL;
5138
496fcc29
JB
5139 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
5140 * as userspace might just pass through the capabilities from the IEs
5141 * directly, rather than enforcing this restriction and returning an
5142 * error in this case.
5143 */
5144 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
5145 params.ht_capa = NULL;
5146 params.vht_capa = NULL;
5147 }
5148
77ee7c89
JB
5149 /* When you run into this, adjust the code below for the new flag */
5150 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
5151
bdd90d5e
JB
5152 switch (dev->ieee80211_ptr->iftype) {
5153 case NL80211_IFTYPE_AP:
5154 case NL80211_IFTYPE_AP_VLAN:
5155 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
5156 /* ignore WME attributes if iface/sta is not capable */
5157 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
5158 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
5159 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 5160
bdd90d5e 5161 /* TDLS peers cannot be added */
3d124ea2
JM
5162 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5163 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 5164 return -EINVAL;
bdd90d5e
JB
5165 /* but don't bother the driver with it */
5166 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 5167
d582cffb
JB
5168 /* allow authenticated/associated only if driver handles it */
5169 if (!(rdev->wiphy.features &
5170 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 5171 params.sta_flags_mask & auth_assoc)
d582cffb
JB
5172 return -EINVAL;
5173
bda95eb1
JB
5174 /* Older userspace, or userspace wanting to be compatible with
5175 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
5176 * and assoc flags in the mask, but assumes the station will be
5177 * added as associated anyway since this was the required driver
5178 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
5179 * introduced.
5180 * In order to not bother drivers with this quirk in the API
5181 * set the flags in both the mask and set for new stations in
5182 * this case.
5183 */
5184 if (!(params.sta_flags_mask & auth_assoc)) {
5185 params.sta_flags_mask |= auth_assoc;
5186 params.sta_flags_set |= auth_assoc;
5187 }
5188
bdd90d5e
JB
5189 /* must be last in here for error handling */
5190 params.vlan = get_vlan(info, rdev);
5191 if (IS_ERR(params.vlan))
5192 return PTR_ERR(params.vlan);
5193 break;
5194 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
5195 /* ignore uAPSD data */
5196 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5197
d582cffb
JB
5198 /* associated is disallowed */
5199 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
5200 return -EINVAL;
bdd90d5e 5201 /* TDLS peers cannot be added */
3d124ea2
JM
5202 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5203 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
5204 return -EINVAL;
5205 break;
5206 case NL80211_IFTYPE_STATION:
93d08f0b 5207 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
5208 /* ignore uAPSD data */
5209 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5210
77ee7c89
JB
5211 /* these are disallowed */
5212 if (params.sta_flags_mask &
5213 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
5214 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 5215 return -EINVAL;
bdd90d5e
JB
5216 /* Only TDLS peers can be added */
5217 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
5218 return -EINVAL;
5219 /* Can only add if TDLS ... */
5220 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
5221 return -EOPNOTSUPP;
5222 /* ... with external setup is supported */
5223 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
5224 return -EOPNOTSUPP;
77ee7c89
JB
5225 /*
5226 * Older wpa_supplicant versions always mark the TDLS peer
5227 * as authorized, but it shouldn't yet be.
5228 */
5229 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
5230 break;
5231 default:
5232 return -EOPNOTSUPP;
c75786c9
EP
5233 }
5234
bdd90d5e 5235 /* be aware of params.vlan when changing code here */
5727ef1b 5236
e35e4d28 5237 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 5238
5727ef1b
JB
5239 if (params.vlan)
5240 dev_put(params.vlan);
5727ef1b
JB
5241 return err;
5242}
5243
5244static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
5245{
4c476991
JB
5246 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5247 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
5248 struct station_del_parameters params;
5249
5250 memset(&params, 0, sizeof(params));
5727ef1b
JB
5251
5252 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 5253 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 5254
e80cf853 5255 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
d5d9de02 5256 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
074ac8df 5257 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
5258 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5259 return -EINVAL;
5727ef1b 5260
4c476991
JB
5261 if (!rdev->ops->del_station)
5262 return -EOPNOTSUPP;
3b85875a 5263
98856866
JM
5264 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
5265 params.subtype =
5266 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
5267 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
5268 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
5269 return -EINVAL;
5270 } else {
5271 /* Default to Deauthentication frame */
5272 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
5273 }
5274
5275 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
5276 params.reason_code =
5277 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
5278 if (params.reason_code == 0)
5279 return -EINVAL; /* 0 is reserved */
5280 } else {
5281 /* Default to reason code 2 */
5282 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
5283 }
5284
89c771e5 5285 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
5286}
5287
15e47304 5288static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
5289 int flags, struct net_device *dev,
5290 u8 *dst, u8 *next_hop,
5291 struct mpath_info *pinfo)
5292{
5293 void *hdr;
5294 struct nlattr *pinfoattr;
5295
1ef4c850 5296 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
5297 if (!hdr)
5298 return -1;
5299
9360ffd1
DM
5300 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5301 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
5302 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
5303 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
5304 goto nla_put_failure;
f5ea9120 5305
2ec600d6
LCC
5306 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
5307 if (!pinfoattr)
5308 goto nla_put_failure;
9360ffd1
DM
5309 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
5310 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
5311 pinfo->frame_qlen))
5312 goto nla_put_failure;
5313 if (((pinfo->filled & MPATH_INFO_SN) &&
5314 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
5315 ((pinfo->filled & MPATH_INFO_METRIC) &&
5316 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
5317 pinfo->metric)) ||
5318 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
5319 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
5320 pinfo->exptime)) ||
5321 ((pinfo->filled & MPATH_INFO_FLAGS) &&
5322 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
5323 pinfo->flags)) ||
5324 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
5325 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
5326 pinfo->discovery_timeout)) ||
5327 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
5328 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
5329 pinfo->discovery_retries)))
5330 goto nla_put_failure;
2ec600d6
LCC
5331
5332 nla_nest_end(msg, pinfoattr);
5333
053c095a
JB
5334 genlmsg_end(msg, hdr);
5335 return 0;
2ec600d6
LCC
5336
5337 nla_put_failure:
bc3ed28c
TG
5338 genlmsg_cancel(msg, hdr);
5339 return -EMSGSIZE;
2ec600d6
LCC
5340}
5341
5342static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 5343 struct netlink_callback *cb)
2ec600d6 5344{
2ec600d6 5345 struct mpath_info pinfo;
1b8ec87a 5346 struct cfg80211_registered_device *rdev;
97990a06 5347 struct wireless_dev *wdev;
2ec600d6
LCC
5348 u8 dst[ETH_ALEN];
5349 u8 next_hop[ETH_ALEN];
97990a06 5350 int path_idx = cb->args[2];
2ec600d6 5351 int err;
2ec600d6 5352
ea90e0dc 5353 rtnl_lock();
1b8ec87a 5354 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893 5355 if (err)
ea90e0dc 5356 goto out_err;
bba95fef 5357
1b8ec87a 5358 if (!rdev->ops->dump_mpath) {
eec60b03 5359 err = -EOPNOTSUPP;
bba95fef
JB
5360 goto out_err;
5361 }
5362
97990a06 5363 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 5364 err = -EOPNOTSUPP;
0448b5fc 5365 goto out_err;
eec60b03
JM
5366 }
5367
bba95fef 5368 while (1) {
1b8ec87a 5369 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 5370 next_hop, &pinfo);
bba95fef 5371 if (err == -ENOENT)
2ec600d6 5372 break;
bba95fef 5373 if (err)
3b85875a 5374 goto out_err;
2ec600d6 5375
15e47304 5376 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 5377 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 5378 wdev->netdev, dst, next_hop,
bba95fef
JB
5379 &pinfo) < 0)
5380 goto out;
2ec600d6 5381
bba95fef 5382 path_idx++;
2ec600d6 5383 }
2ec600d6 5384
bba95fef 5385 out:
97990a06 5386 cb->args[2] = path_idx;
bba95fef 5387 err = skb->len;
bba95fef 5388 out_err:
ea90e0dc 5389 rtnl_unlock();
bba95fef 5390 return err;
2ec600d6
LCC
5391}
5392
5393static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
5394{
4c476991 5395 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 5396 int err;
4c476991 5397 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5398 struct mpath_info pinfo;
5399 struct sk_buff *msg;
5400 u8 *dst = NULL;
5401 u8 next_hop[ETH_ALEN];
5402
5403 memset(&pinfo, 0, sizeof(pinfo));
5404
5405 if (!info->attrs[NL80211_ATTR_MAC])
5406 return -EINVAL;
5407
5408 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5409
4c476991
JB
5410 if (!rdev->ops->get_mpath)
5411 return -EOPNOTSUPP;
2ec600d6 5412
4c476991
JB
5413 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5414 return -EOPNOTSUPP;
eec60b03 5415
e35e4d28 5416 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 5417 if (err)
4c476991 5418 return err;
2ec600d6 5419
fd2120ca 5420 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 5421 if (!msg)
4c476991 5422 return -ENOMEM;
2ec600d6 5423
15e47304 5424 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
5425 dev, dst, next_hop, &pinfo) < 0) {
5426 nlmsg_free(msg);
5427 return -ENOBUFS;
5428 }
3b85875a 5429
4c476991 5430 return genlmsg_reply(msg, info);
2ec600d6
LCC
5431}
5432
5433static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
5434{
4c476991
JB
5435 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5436 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5437 u8 *dst = NULL;
5438 u8 *next_hop = NULL;
5439
5440 if (!info->attrs[NL80211_ATTR_MAC])
5441 return -EINVAL;
5442
5443 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5444 return -EINVAL;
5445
5446 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5447 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5448
4c476991
JB
5449 if (!rdev->ops->change_mpath)
5450 return -EOPNOTSUPP;
35a8efe1 5451
4c476991
JB
5452 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5453 return -EOPNOTSUPP;
2ec600d6 5454
e35e4d28 5455 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 5456}
4c476991 5457
2ec600d6
LCC
5458static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
5459{
4c476991
JB
5460 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5461 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5462 u8 *dst = NULL;
5463 u8 *next_hop = NULL;
5464
5465 if (!info->attrs[NL80211_ATTR_MAC])
5466 return -EINVAL;
5467
5468 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5469 return -EINVAL;
5470
5471 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5472 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5473
4c476991
JB
5474 if (!rdev->ops->add_mpath)
5475 return -EOPNOTSUPP;
35a8efe1 5476
4c476991
JB
5477 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5478 return -EOPNOTSUPP;
2ec600d6 5479
e35e4d28 5480 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
5481}
5482
5483static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
5484{
4c476991
JB
5485 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5486 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5487 u8 *dst = NULL;
5488
5489 if (info->attrs[NL80211_ATTR_MAC])
5490 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5491
4c476991
JB
5492 if (!rdev->ops->del_mpath)
5493 return -EOPNOTSUPP;
3b85875a 5494
e35e4d28 5495 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
5496}
5497
66be7d2b
HR
5498static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
5499{
5500 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5501 int err;
5502 struct net_device *dev = info->user_ptr[1];
5503 struct mpath_info pinfo;
5504 struct sk_buff *msg;
5505 u8 *dst = NULL;
5506 u8 mpp[ETH_ALEN];
5507
5508 memset(&pinfo, 0, sizeof(pinfo));
5509
5510 if (!info->attrs[NL80211_ATTR_MAC])
5511 return -EINVAL;
5512
5513 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5514
5515 if (!rdev->ops->get_mpp)
5516 return -EOPNOTSUPP;
5517
5518 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5519 return -EOPNOTSUPP;
5520
5521 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
5522 if (err)
5523 return err;
5524
5525 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5526 if (!msg)
5527 return -ENOMEM;
5528
5529 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
5530 dev, dst, mpp, &pinfo) < 0) {
5531 nlmsg_free(msg);
5532 return -ENOBUFS;
5533 }
5534
5535 return genlmsg_reply(msg, info);
5536}
5537
5538static int nl80211_dump_mpp(struct sk_buff *skb,
5539 struct netlink_callback *cb)
5540{
5541 struct mpath_info pinfo;
5542 struct cfg80211_registered_device *rdev;
5543 struct wireless_dev *wdev;
5544 u8 dst[ETH_ALEN];
5545 u8 mpp[ETH_ALEN];
5546 int path_idx = cb->args[2];
5547 int err;
5548
ea90e0dc 5549 rtnl_lock();
66be7d2b
HR
5550 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
5551 if (err)
ea90e0dc 5552 goto out_err;
66be7d2b
HR
5553
5554 if (!rdev->ops->dump_mpp) {
5555 err = -EOPNOTSUPP;
5556 goto out_err;
5557 }
5558
5559 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
5560 err = -EOPNOTSUPP;
5561 goto out_err;
5562 }
5563
5564 while (1) {
5565 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
5566 mpp, &pinfo);
5567 if (err == -ENOENT)
5568 break;
5569 if (err)
5570 goto out_err;
5571
5572 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
5573 cb->nlh->nlmsg_seq, NLM_F_MULTI,
5574 wdev->netdev, dst, mpp,
5575 &pinfo) < 0)
5576 goto out;
5577
5578 path_idx++;
5579 }
5580
5581 out:
5582 cb->args[2] = path_idx;
5583 err = skb->len;
5584 out_err:
ea90e0dc 5585 rtnl_unlock();
66be7d2b
HR
5586 return err;
5587}
5588
9f1ba906
JM
5589static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
5590{
4c476991
JB
5591 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5592 struct net_device *dev = info->user_ptr[1];
c56589ed 5593 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 5594 struct bss_parameters params;
c56589ed 5595 int err;
9f1ba906
JM
5596
5597 memset(&params, 0, sizeof(params));
5598 /* default to not changing parameters */
5599 params.use_cts_prot = -1;
5600 params.use_short_preamble = -1;
5601 params.use_short_slot_time = -1;
fd8aaaf3 5602 params.ap_isolate = -1;
50b12f59 5603 params.ht_opmode = -1;
53cabad7
JB
5604 params.p2p_ctwindow = -1;
5605 params.p2p_opp_ps = -1;
9f1ba906
JM
5606
5607 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
5608 params.use_cts_prot =
5609 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
5610 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
5611 params.use_short_preamble =
5612 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
5613 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
5614 params.use_short_slot_time =
5615 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
5616 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
5617 params.basic_rates =
5618 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5619 params.basic_rates_len =
5620 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5621 }
fd8aaaf3
FF
5622 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
5623 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
5624 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
5625 params.ht_opmode =
5626 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 5627
53cabad7
JB
5628 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
5629 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5630 return -EINVAL;
5631 params.p2p_ctwindow =
5632 nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
5633 if (params.p2p_ctwindow < 0)
5634 return -EINVAL;
5635 if (params.p2p_ctwindow != 0 &&
5636 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
5637 return -EINVAL;
5638 }
5639
5640 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
5641 u8 tmp;
5642
5643 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5644 return -EINVAL;
5645 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
5646 if (tmp > 1)
5647 return -EINVAL;
5648 params.p2p_opp_ps = tmp;
5649 if (params.p2p_opp_ps &&
5650 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
5651 return -EINVAL;
5652 }
5653
4c476991
JB
5654 if (!rdev->ops->change_bss)
5655 return -EOPNOTSUPP;
9f1ba906 5656
074ac8df 5657 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
5658 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5659 return -EOPNOTSUPP;
3b85875a 5660
c56589ed
SW
5661 wdev_lock(wdev);
5662 err = rdev_change_bss(rdev, dev, &params);
5663 wdev_unlock(wdev);
5664
5665 return err;
9f1ba906
JM
5666}
5667
b2e1b302
LR
5668static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
5669{
b2e1b302 5670 char *data = NULL;
05050753 5671 bool is_indoor;
57b5ce07 5672 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
5673 u32 owner_nlportid;
5674
80778f18
LR
5675 /*
5676 * You should only get this when cfg80211 hasn't yet initialized
5677 * completely when built-in to the kernel right between the time
5678 * window between nl80211_init() and regulatory_init(), if that is
5679 * even possible.
5680 */
458f4f9e 5681 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 5682 return -EINPROGRESS;
80778f18 5683
57b5ce07
LR
5684 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
5685 user_reg_hint_type =
5686 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
5687 else
5688 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
5689
5690 switch (user_reg_hint_type) {
5691 case NL80211_USER_REG_HINT_USER:
5692 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
5693 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
5694 return -EINVAL;
5695
5696 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
5697 return regulatory_hint_user(data, user_reg_hint_type);
5698 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
5699 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
5700 owner_nlportid = info->snd_portid;
5701 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
5702 } else {
5703 owner_nlportid = 0;
5704 is_indoor = true;
5705 }
5706
5707 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
5708 default:
5709 return -EINVAL;
5710 }
b2e1b302
LR
5711}
5712
1ea4ff3e
JB
5713static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
5714{
5715 return reg_reload_regdb();
5716}
5717
24bdd9f4 5718static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 5719 struct genl_info *info)
93da9cc1 5720{
4c476991 5721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 5722 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
5723 struct wireless_dev *wdev = dev->ieee80211_ptr;
5724 struct mesh_config cur_params;
5725 int err = 0;
93da9cc1 5726 void *hdr;
5727 struct nlattr *pinfoattr;
5728 struct sk_buff *msg;
5729
29cbe68c
JB
5730 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
5731 return -EOPNOTSUPP;
5732
24bdd9f4 5733 if (!rdev->ops->get_mesh_config)
4c476991 5734 return -EOPNOTSUPP;
f3f92586 5735
29cbe68c
JB
5736 wdev_lock(wdev);
5737 /* If not connected, get default parameters */
5738 if (!wdev->mesh_id_len)
5739 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
5740 else
e35e4d28 5741 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
5742 wdev_unlock(wdev);
5743
93da9cc1 5744 if (err)
4c476991 5745 return err;
93da9cc1 5746
5747 /* Draw up a netlink message to send back */
fd2120ca 5748 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
5749 if (!msg)
5750 return -ENOMEM;
15e47304 5751 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 5752 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 5753 if (!hdr)
efe1cf0c 5754 goto out;
24bdd9f4 5755 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 5756 if (!pinfoattr)
5757 goto nla_put_failure;
9360ffd1
DM
5758 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5759 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
5760 cur_params.dot11MeshRetryTimeout) ||
5761 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
5762 cur_params.dot11MeshConfirmTimeout) ||
5763 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
5764 cur_params.dot11MeshHoldingTimeout) ||
5765 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
5766 cur_params.dot11MeshMaxPeerLinks) ||
5767 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
5768 cur_params.dot11MeshMaxRetries) ||
5769 nla_put_u8(msg, NL80211_MESHCONF_TTL,
5770 cur_params.dot11MeshTTL) ||
5771 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
5772 cur_params.element_ttl) ||
5773 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
5774 cur_params.auto_open_plinks) ||
7eab0f64
JL
5775 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
5776 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
5777 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
5778 cur_params.dot11MeshHWMPmaxPREQretries) ||
5779 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
5780 cur_params.path_refresh_time) ||
5781 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
5782 cur_params.min_discovery_timeout) ||
5783 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
5784 cur_params.dot11MeshHWMPactivePathTimeout) ||
5785 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
5786 cur_params.dot11MeshHWMPpreqMinInterval) ||
5787 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
5788 cur_params.dot11MeshHWMPperrMinInterval) ||
5789 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
5790 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
5791 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
5792 cur_params.dot11MeshHWMPRootMode) ||
5793 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
5794 cur_params.dot11MeshHWMPRannInterval) ||
5795 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
5796 cur_params.dot11MeshGateAnnouncementProtocol) ||
5797 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
5798 cur_params.dot11MeshForwarding) ||
335d5349 5799 nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
5800 cur_params.rssi_threshold) ||
5801 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
5802 cur_params.ht_opmode) ||
5803 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
5804 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
5805 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
5806 cur_params.dot11MeshHWMProotInterval) ||
5807 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
5808 cur_params.dot11MeshHWMPconfirmationInterval) ||
5809 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
5810 cur_params.power_mode) ||
5811 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
5812 cur_params.dot11MeshAwakeWindowDuration) ||
5813 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
5814 cur_params.plink_timeout))
9360ffd1 5815 goto nla_put_failure;
93da9cc1 5816 nla_nest_end(msg, pinfoattr);
5817 genlmsg_end(msg, hdr);
4c476991 5818 return genlmsg_reply(msg, info);
93da9cc1 5819
3b85875a 5820 nla_put_failure:
93da9cc1 5821 genlmsg_cancel(msg, hdr);
efe1cf0c 5822 out:
d080e275 5823 nlmsg_free(msg);
4c476991 5824 return -ENOBUFS;
93da9cc1 5825}
5826
b54452b0 5827static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
93da9cc1 5828 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
5829 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
5830 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
5831 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
5832 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
5833 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
45904f21 5834 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
93da9cc1 5835 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
d299a1f2 5836 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
93da9cc1 5837 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
5838 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
5839 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
5840 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
5841 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
dca7e943 5842 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 },
93da9cc1 5843 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
699403db 5844 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
0507e159 5845 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
16dd7267 5846 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
94f90656 5847 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
a4f606ea
CYY
5848 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
5849 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6
CYY
5850 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
5851 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
728b19e5 5852 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
3b1c5a53
MP
5853 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 },
5854 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 5855 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
93da9cc1 5856};
5857
c80d545d
JC
5858static const struct nla_policy
5859 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 5860 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
5861 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
5862 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 5863 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 5864 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 5865 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
581a8b0f 5866 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
a4f606ea 5867 .len = IEEE80211_MAX_DATA_LEN },
b130e5ce 5868 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
5869};
5870
f151d9db
AB
5871static int nl80211_check_bool(const struct nlattr *nla, u8 min, u8 max, bool *out)
5872{
5873 u8 val = nla_get_u8(nla);
5874 if (val < min || val > max)
5875 return -EINVAL;
5876 *out = val;
5877 return 0;
5878}
5879
5880static int nl80211_check_u8(const struct nlattr *nla, u8 min, u8 max, u8 *out)
5881{
5882 u8 val = nla_get_u8(nla);
5883 if (val < min || val > max)
5884 return -EINVAL;
5885 *out = val;
5886 return 0;
5887}
5888
5889static int nl80211_check_u16(const struct nlattr *nla, u16 min, u16 max, u16 *out)
5890{
5891 u16 val = nla_get_u16(nla);
5892 if (val < min || val > max)
5893 return -EINVAL;
5894 *out = val;
5895 return 0;
5896}
5897
5898static int nl80211_check_u32(const struct nlattr *nla, u32 min, u32 max, u32 *out)
5899{
5900 u32 val = nla_get_u32(nla);
5901 if (val < min || val > max)
5902 return -EINVAL;
5903 *out = val;
5904 return 0;
5905}
5906
5907static int nl80211_check_s32(const struct nlattr *nla, s32 min, s32 max, s32 *out)
5908{
5909 s32 val = nla_get_s32(nla);
5910 if (val < min || val > max)
5911 return -EINVAL;
5912 *out = val;
5913 return 0;
5914}
5915
ff9a71af
JB
5916static int nl80211_check_power_mode(const struct nlattr *nla,
5917 enum nl80211_mesh_power_mode min,
5918 enum nl80211_mesh_power_mode max,
5919 enum nl80211_mesh_power_mode *out)
5920{
5921 u32 val = nla_get_u32(nla);
5922 if (val < min || val > max)
5923 return -EINVAL;
5924 *out = val;
5925 return 0;
5926}
5927
24bdd9f4 5928static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
5929 struct mesh_config *cfg,
5930 u32 *mask_out)
93da9cc1 5931{
93da9cc1 5932 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 5933 u32 mask = 0;
9757235f 5934 u16 ht_opmode;
93da9cc1 5935
ea54fba2
MP
5936#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \
5937do { \
5938 if (tb[attr]) { \
f151d9db 5939 if (fn(tb[attr], min, max, &cfg->param)) \
ea54fba2 5940 return -EINVAL; \
ea54fba2
MP
5941 mask |= (1 << (attr - 1)); \
5942 } \
5943} while (0)
bd90fdcc 5944
24bdd9f4 5945 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 5946 return -EINVAL;
5947 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
24bdd9f4 5948 info->attrs[NL80211_ATTR_MESH_CONFIG],
fe52145f 5949 nl80211_meshconf_params_policy, info->extack))
93da9cc1 5950 return -EINVAL;
5951
93da9cc1 5952 /* This makes sure that there aren't more than 32 mesh config
5953 * parameters (otherwise our bitfield scheme would not work.) */
5954 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
5955
5956 /* Fill in the params struct */
ea54fba2 5957 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255,
a4f606ea 5958 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
f151d9db 5959 nl80211_check_u16);
ea54fba2 5960 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255,
a4f606ea 5961 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
f151d9db 5962 nl80211_check_u16);
ea54fba2 5963 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255,
a4f606ea 5964 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
f151d9db 5965 nl80211_check_u16);
ea54fba2 5966 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255,
a4f606ea 5967 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
f151d9db 5968 nl80211_check_u16);
ea54fba2 5969 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16,
a4f606ea 5970 mask, NL80211_MESHCONF_MAX_RETRIES,
f151d9db 5971 nl80211_check_u8);
ea54fba2 5972 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255,
f151d9db 5973 mask, NL80211_MESHCONF_TTL, nl80211_check_u8);
ea54fba2 5974 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255,
a4f606ea 5975 mask, NL80211_MESHCONF_ELEMENT_TTL,
f151d9db 5976 nl80211_check_u8);
ea54fba2 5977 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1,
a4f606ea 5978 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
f151d9db 5979 nl80211_check_bool);
ea54fba2
MP
5980 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
5981 1, 255, mask,
a4f606ea 5982 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
f151d9db 5983 nl80211_check_u32);
ea54fba2 5984 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255,
a4f606ea 5985 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
f151d9db 5986 nl80211_check_u8);
ea54fba2 5987 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535,
a4f606ea 5988 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
f151d9db 5989 nl80211_check_u32);
ea54fba2 5990 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535,
a4f606ea 5991 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
f151d9db 5992 nl80211_check_u16);
ea54fba2
MP
5993 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
5994 1, 65535, mask,
a4f606ea 5995 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
f151d9db 5996 nl80211_check_u32);
93da9cc1 5997 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
ea54fba2
MP
5998 1, 65535, mask,
5999 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
f151d9db 6000 nl80211_check_u16);
dca7e943 6001 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
ea54fba2
MP
6002 1, 65535, mask,
6003 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
f151d9db 6004 nl80211_check_u16);
93da9cc1 6005 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
6006 dot11MeshHWMPnetDiameterTraversalTime,
6007 1, 65535, mask,
a4f606ea 6008 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
f151d9db 6009 nl80211_check_u16);
ea54fba2
MP
6010 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4,
6011 mask, NL80211_MESHCONF_HWMP_ROOTMODE,
f151d9db 6012 nl80211_check_u8);
ea54fba2
MP
6013 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535,
6014 mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
f151d9db 6015 nl80211_check_u16);
63c5723b 6016 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
6017 dot11MeshGateAnnouncementProtocol, 0, 1,
6018 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
f151d9db 6019 nl80211_check_bool);
ea54fba2 6020 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1,
a4f606ea 6021 mask, NL80211_MESHCONF_FORWARDING,
f151d9db 6022 nl80211_check_bool);
83374fe9 6023 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
a4f606ea 6024 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
f151d9db 6025 nl80211_check_s32);
9757235f
MH
6026 /*
6027 * Check HT operation mode based on
6028 * IEEE 802.11 2012 8.4.2.59 HT Operation element.
6029 */
6030 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
6031 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
6032
6033 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
6034 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
6035 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
6036 return -EINVAL;
6037
6038 if ((ht_opmode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) &&
6039 (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
6040 return -EINVAL;
6041
6042 switch (ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION) {
6043 case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
6044 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
6045 if (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)
6046 return -EINVAL;
6047 break;
6048 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
6049 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
6050 if (!(ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
6051 return -EINVAL;
6052 break;
6053 }
6054 cfg->ht_opmode = ht_opmode;
fd551bac 6055 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
9757235f 6056 }
ac1073a6 6057 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
ea54fba2 6058 1, 65535, mask,
ac1073a6 6059 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
f151d9db 6060 nl80211_check_u32);
ea54fba2 6061 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535,
ac1073a6 6062 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
f151d9db 6063 nl80211_check_u16);
728b19e5 6064 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
6065 dot11MeshHWMPconfirmationInterval,
6066 1, 65535, mask,
728b19e5 6067 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
f151d9db 6068 nl80211_check_u16);
3b1c5a53
MP
6069 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode,
6070 NL80211_MESH_POWER_ACTIVE,
6071 NL80211_MESH_POWER_MAX,
6072 mask, NL80211_MESHCONF_POWER_MODE,
ff9a71af 6073 nl80211_check_power_mode);
3b1c5a53
MP
6074 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration,
6075 0, 65535, mask,
f151d9db 6076 NL80211_MESHCONF_AWAKE_WINDOW, nl80211_check_u16);
31f909a2 6077 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 0, 0xffffffff,
8e7c0538 6078 mask, NL80211_MESHCONF_PLINK_TIMEOUT,
f151d9db 6079 nl80211_check_u32);
bd90fdcc
JB
6080 if (mask_out)
6081 *mask_out = mask;
c80d545d 6082
bd90fdcc
JB
6083 return 0;
6084
6085#undef FILL_IN_MESH_PARAM_IF_SET
6086}
6087
c80d545d
JC
6088static int nl80211_parse_mesh_setup(struct genl_info *info,
6089 struct mesh_setup *setup)
6090{
bb2798d4 6091 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
6092 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
6093
6094 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
6095 return -EINVAL;
6096 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
6097 info->attrs[NL80211_ATTR_MESH_SETUP],
fe52145f 6098 nl80211_mesh_setup_params_policy, info->extack))
c80d545d
JC
6099 return -EINVAL;
6100
d299a1f2
JC
6101 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
6102 setup->sync_method =
6103 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
6104 IEEE80211_SYNC_METHOD_VENDOR :
6105 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
6106
c80d545d
JC
6107 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
6108 setup->path_sel_proto =
6109 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
6110 IEEE80211_PATH_PROTOCOL_VENDOR :
6111 IEEE80211_PATH_PROTOCOL_HWMP;
6112
6113 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
6114 setup->path_metric =
6115 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
6116 IEEE80211_PATH_METRIC_VENDOR :
6117 IEEE80211_PATH_METRIC_AIRTIME;
6118
581a8b0f 6119 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 6120 struct nlattr *ieattr =
581a8b0f 6121 tb[NL80211_MESH_SETUP_IE];
c80d545d
JC
6122 if (!is_valid_ie_attr(ieattr))
6123 return -EINVAL;
581a8b0f
JC
6124 setup->ie = nla_data(ieattr);
6125 setup->ie_len = nla_len(ieattr);
c80d545d 6126 }
bb2798d4
TP
6127 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
6128 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
6129 return -EINVAL;
6130 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
6131 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
6132 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
6133 if (setup->is_secure)
6134 setup->user_mpm = true;
c80d545d 6135
6e16d90b
CT
6136 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
6137 if (!setup->user_mpm)
6138 return -EINVAL;
6139 setup->auth_id =
6140 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
6141 }
6142
c80d545d
JC
6143 return 0;
6144}
6145
24bdd9f4 6146static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 6147 struct genl_info *info)
bd90fdcc
JB
6148{
6149 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6150 struct net_device *dev = info->user_ptr[1];
29cbe68c 6151 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
6152 struct mesh_config cfg;
6153 u32 mask;
6154 int err;
6155
29cbe68c
JB
6156 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
6157 return -EOPNOTSUPP;
6158
24bdd9f4 6159 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
6160 return -EOPNOTSUPP;
6161
24bdd9f4 6162 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
6163 if (err)
6164 return err;
6165
29cbe68c
JB
6166 wdev_lock(wdev);
6167 if (!wdev->mesh_id_len)
6168 err = -ENOLINK;
6169
6170 if (!err)
e35e4d28 6171 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
6172
6173 wdev_unlock(wdev);
6174
6175 return err;
93da9cc1 6176}
6177
ad30ca2c
AN
6178static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
6179 struct sk_buff *msg)
f130347c 6180{
f130347c
LR
6181 struct nlattr *nl_reg_rules;
6182 unsigned int i;
f130347c 6183
458f4f9e
JB
6184 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
6185 (regdom->dfs_region &&
6186 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 6187 goto nla_put_failure;
458f4f9e 6188
f130347c
LR
6189 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
6190 if (!nl_reg_rules)
ad30ca2c 6191 goto nla_put_failure;
f130347c 6192
458f4f9e 6193 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
6194 struct nlattr *nl_reg_rule;
6195 const struct ieee80211_reg_rule *reg_rule;
6196 const struct ieee80211_freq_range *freq_range;
6197 const struct ieee80211_power_rule *power_rule;
97524820 6198 unsigned int max_bandwidth_khz;
f130347c 6199
458f4f9e 6200 reg_rule = &regdom->reg_rules[i];
f130347c
LR
6201 freq_range = &reg_rule->freq_range;
6202 power_rule = &reg_rule->power_rule;
6203
6204 nl_reg_rule = nla_nest_start(msg, i);
6205 if (!nl_reg_rule)
ad30ca2c 6206 goto nla_put_failure;
f130347c 6207
97524820
JD
6208 max_bandwidth_khz = freq_range->max_bandwidth_khz;
6209 if (!max_bandwidth_khz)
6210 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
6211 reg_rule);
6212
9360ffd1
DM
6213 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
6214 reg_rule->flags) ||
6215 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
6216 freq_range->start_freq_khz) ||
6217 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
6218 freq_range->end_freq_khz) ||
6219 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 6220 max_bandwidth_khz) ||
9360ffd1
DM
6221 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
6222 power_rule->max_antenna_gain) ||
6223 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
6224 power_rule->max_eirp) ||
6225 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
6226 reg_rule->dfs_cac_ms))
ad30ca2c 6227 goto nla_put_failure;
f130347c
LR
6228
6229 nla_nest_end(msg, nl_reg_rule);
6230 }
6231
6232 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
6233 return 0;
6234
6235nla_put_failure:
6236 return -EMSGSIZE;
6237}
6238
6239static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
6240{
6241 const struct ieee80211_regdomain *regdom = NULL;
6242 struct cfg80211_registered_device *rdev;
6243 struct wiphy *wiphy = NULL;
6244 struct sk_buff *msg;
6245 void *hdr;
6246
6247 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6248 if (!msg)
6249 return -ENOBUFS;
6250
6251 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
6252 NL80211_CMD_GET_REG);
6253 if (!hdr)
6254 goto put_failure;
6255
6256 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
6257 bool self_managed;
6258
ad30ca2c
AN
6259 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
6260 if (IS_ERR(rdev)) {
6261 nlmsg_free(msg);
6262 return PTR_ERR(rdev);
6263 }
6264
6265 wiphy = &rdev->wiphy;
1bdd716c
AN
6266 self_managed = wiphy->regulatory_flags &
6267 REGULATORY_WIPHY_SELF_MANAGED;
ad30ca2c
AN
6268 regdom = get_wiphy_regdom(wiphy);
6269
1bdd716c
AN
6270 /* a self-managed-reg device must have a private regdom */
6271 if (WARN_ON(!regdom && self_managed)) {
6272 nlmsg_free(msg);
6273 return -EINVAL;
6274 }
6275
ad30ca2c
AN
6276 if (regdom &&
6277 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6278 goto nla_put_failure;
6279 }
6280
6281 if (!wiphy && reg_last_request_cell_base() &&
6282 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6283 NL80211_USER_REG_HINT_CELL_BASE))
6284 goto nla_put_failure;
6285
6286 rcu_read_lock();
6287
6288 if (!regdom)
6289 regdom = rcu_dereference(cfg80211_regdomain);
6290
6291 if (nl80211_put_regdom(regdom, msg))
6292 goto nla_put_failure_rcu;
6293
6294 rcu_read_unlock();
f130347c
LR
6295
6296 genlmsg_end(msg, hdr);
5fe231e8 6297 return genlmsg_reply(msg, info);
f130347c 6298
458f4f9e
JB
6299nla_put_failure_rcu:
6300 rcu_read_unlock();
f130347c
LR
6301nla_put_failure:
6302 genlmsg_cancel(msg, hdr);
efe1cf0c 6303put_failure:
d080e275 6304 nlmsg_free(msg);
5fe231e8 6305 return -EMSGSIZE;
f130347c
LR
6306}
6307
ad30ca2c
AN
6308static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
6309 u32 seq, int flags, struct wiphy *wiphy,
6310 const struct ieee80211_regdomain *regdom)
6311{
6312 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
6313 NL80211_CMD_GET_REG);
6314
6315 if (!hdr)
6316 return -1;
6317
0a833c29 6318 genl_dump_check_consistent(cb, hdr);
ad30ca2c
AN
6319
6320 if (nl80211_put_regdom(regdom, msg))
6321 goto nla_put_failure;
6322
6323 if (!wiphy && reg_last_request_cell_base() &&
6324 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6325 NL80211_USER_REG_HINT_CELL_BASE))
6326 goto nla_put_failure;
6327
6328 if (wiphy &&
6329 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6330 goto nla_put_failure;
6331
1bdd716c
AN
6332 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
6333 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
6334 goto nla_put_failure;
6335
053c095a
JB
6336 genlmsg_end(msg, hdr);
6337 return 0;
ad30ca2c
AN
6338
6339nla_put_failure:
6340 genlmsg_cancel(msg, hdr);
6341 return -EMSGSIZE;
6342}
6343
6344static int nl80211_get_reg_dump(struct sk_buff *skb,
6345 struct netlink_callback *cb)
6346{
6347 const struct ieee80211_regdomain *regdom = NULL;
6348 struct cfg80211_registered_device *rdev;
6349 int err, reg_idx, start = cb->args[2];
6350
6351 rtnl_lock();
6352
6353 if (cfg80211_regdomain && start == 0) {
6354 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6355 NLM_F_MULTI, NULL,
6356 rtnl_dereference(cfg80211_regdomain));
6357 if (err < 0)
6358 goto out_err;
6359 }
6360
6361 /* the global regdom is idx 0 */
6362 reg_idx = 1;
6363 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
6364 regdom = get_wiphy_regdom(&rdev->wiphy);
6365 if (!regdom)
6366 continue;
6367
6368 if (++reg_idx <= start)
6369 continue;
6370
6371 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6372 NLM_F_MULTI, &rdev->wiphy, regdom);
6373 if (err < 0) {
6374 reg_idx--;
6375 break;
6376 }
6377 }
6378
6379 cb->args[2] = reg_idx;
6380 err = skb->len;
6381out_err:
6382 rtnl_unlock();
6383 return err;
6384}
6385
b6863036
JB
6386#ifdef CONFIG_CFG80211_CRDA_SUPPORT
6387static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
6388 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
6389 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
6390 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
6391 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
6392 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
6393 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
6394 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
6395};
6396
6397static int parse_reg_rule(struct nlattr *tb[],
6398 struct ieee80211_reg_rule *reg_rule)
6399{
6400 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
6401 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
6402
6403 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
6404 return -EINVAL;
6405 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
6406 return -EINVAL;
6407 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
6408 return -EINVAL;
6409 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
6410 return -EINVAL;
6411 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6412 return -EINVAL;
6413
6414 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
6415
6416 freq_range->start_freq_khz =
6417 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
6418 freq_range->end_freq_khz =
6419 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
6420 freq_range->max_bandwidth_khz =
6421 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
6422
6423 power_rule->max_eirp =
6424 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
6425
6426 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
6427 power_rule->max_antenna_gain =
6428 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
6429
6430 if (tb[NL80211_ATTR_DFS_CAC_TIME])
6431 reg_rule->dfs_cac_ms =
6432 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
6433
6434 return 0;
6435}
6436
b2e1b302
LR
6437static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
6438{
6439 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
6440 struct nlattr *nl_reg_rule;
ea372c54
JB
6441 char *alpha2;
6442 int rem_reg_rules, r;
b2e1b302 6443 u32 num_rules = 0, rule_idx = 0, size_of_regd;
4c7d3982 6444 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 6445 struct ieee80211_regdomain *rd;
b2e1b302
LR
6446
6447 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
6448 return -EINVAL;
6449
6450 if (!info->attrs[NL80211_ATTR_REG_RULES])
6451 return -EINVAL;
6452
6453 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
6454
8b60b078
LR
6455 if (info->attrs[NL80211_ATTR_DFS_REGION])
6456 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
6457
b2e1b302 6458 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6459 rem_reg_rules) {
b2e1b302
LR
6460 num_rules++;
6461 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 6462 return -EINVAL;
b2e1b302
LR
6463 }
6464
e438768f
LR
6465 if (!reg_is_valid_request(alpha2))
6466 return -EINVAL;
6467
b2e1b302 6468 size_of_regd = sizeof(struct ieee80211_regdomain) +
1a919318 6469 num_rules * sizeof(struct ieee80211_reg_rule);
b2e1b302
LR
6470
6471 rd = kzalloc(size_of_regd, GFP_KERNEL);
6913b49a
JB
6472 if (!rd)
6473 return -ENOMEM;
b2e1b302
LR
6474
6475 rd->n_reg_rules = num_rules;
6476 rd->alpha2[0] = alpha2[0];
6477 rd->alpha2[1] = alpha2[1];
6478
8b60b078
LR
6479 /*
6480 * Disable DFS master mode if the DFS region was
6481 * not supported or known on this kernel.
6482 */
6483 if (reg_supported_dfs_region(dfs_region))
6484 rd->dfs_region = dfs_region;
6485
b2e1b302 6486 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6487 rem_reg_rules) {
bfe2c7b1 6488 r = nla_parse_nested(tb, NL80211_REG_RULE_ATTR_MAX,
fe52145f
JB
6489 nl_reg_rule, reg_rule_policy,
6490 info->extack);
ae811e21
JB
6491 if (r)
6492 goto bad_reg;
b2e1b302
LR
6493 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
6494 if (r)
6495 goto bad_reg;
6496
6497 rule_idx++;
6498
d0e18f83
LR
6499 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
6500 r = -EINVAL;
b2e1b302 6501 goto bad_reg;
d0e18f83 6502 }
b2e1b302
LR
6503 }
6504
06627990
JB
6505 /* set_regdom takes ownership of rd */
6506 return set_regdom(rd, REGD_SOURCE_CRDA);
d2372b31 6507 bad_reg:
b2e1b302 6508 kfree(rd);
d0e18f83 6509 return r;
b2e1b302 6510}
b6863036 6511#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 6512
83f5e2cf
JB
6513static int validate_scan_freqs(struct nlattr *freqs)
6514{
6515 struct nlattr *attr1, *attr2;
6516 int n_channels = 0, tmp1, tmp2;
6517
d7f13f74
SD
6518 nla_for_each_nested(attr1, freqs, tmp1)
6519 if (nla_len(attr1) != sizeof(u32))
6520 return 0;
6521
83f5e2cf
JB
6522 nla_for_each_nested(attr1, freqs, tmp1) {
6523 n_channels++;
6524 /*
6525 * Some hardware has a limited channel list for
6526 * scanning, and it is pretty much nonsensical
6527 * to scan for a channel twice, so disallow that
6528 * and don't require drivers to check that the
6529 * channel list they get isn't longer than what
6530 * they can scan, as long as they can scan all
6531 * the channels they registered at once.
6532 */
6533 nla_for_each_nested(attr2, freqs, tmp2)
6534 if (attr1 != attr2 &&
6535 nla_get_u32(attr1) == nla_get_u32(attr2))
6536 return 0;
6537 }
6538
6539 return n_channels;
6540}
6541
57fbcce3 6542static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 6543{
57fbcce3 6544 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
6545}
6546
6547static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
6548 struct cfg80211_bss_selection *bss_select)
6549{
6550 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
6551 struct nlattr *nest;
6552 int err;
6553 bool found = false;
6554 int i;
6555
6556 /* only process one nested attribute */
6557 nest = nla_data(nla);
6558 if (!nla_ok(nest, nla_len(nest)))
6559 return -EINVAL;
6560
bfe2c7b1 6561 err = nla_parse_nested(attr, NL80211_BSS_SELECT_ATTR_MAX, nest,
fceb6435 6562 nl80211_bss_select_policy, NULL);
38de03d2
AS
6563 if (err)
6564 return err;
6565
6566 /* only one attribute may be given */
6567 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
6568 if (attr[i]) {
6569 if (found)
6570 return -EINVAL;
6571 found = true;
6572 }
6573 }
6574
6575 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
6576
6577 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
6578 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
6579
6580 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
6581 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
6582 bss_select->param.band_pref =
6583 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
6584 if (!is_band_valid(wiphy, bss_select->param.band_pref))
6585 return -EINVAL;
6586 }
6587
6588 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
6589 struct nl80211_bss_select_rssi_adjust *adj_param;
6590
6591 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
6592 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
6593 bss_select->param.adjust.band = adj_param->band;
6594 bss_select->param.adjust.delta = adj_param->delta;
6595 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
6596 return -EINVAL;
6597 }
6598
6599 /* user-space did not provide behaviour attribute */
6600 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
6601 return -EINVAL;
6602
6603 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
6604 return -EINVAL;
6605
6606 return 0;
6607}
6608
ad2b26ab
JB
6609static int nl80211_parse_random_mac(struct nlattr **attrs,
6610 u8 *mac_addr, u8 *mac_addr_mask)
6611{
6612 int i;
6613
6614 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
6615 eth_zero_addr(mac_addr);
6616 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
6617 mac_addr[0] = 0x2;
6618 mac_addr_mask[0] = 0x3;
6619
6620 return 0;
6621 }
6622
6623 /* need both or none */
6624 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
6625 return -EINVAL;
6626
6627 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
6628 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
6629
6630 /* don't allow or configure an mcast address */
6631 if (!is_multicast_ether_addr(mac_addr_mask) ||
6632 is_multicast_ether_addr(mac_addr))
6633 return -EINVAL;
6634
6635 /*
6636 * allow users to pass a MAC address that has bits set outside
6637 * of the mask, but don't bother drivers with having to deal
6638 * with such bits
6639 */
6640 for (i = 0; i < ETH_ALEN; i++)
6641 mac_addr[i] &= mac_addr_mask[i];
6642
6643 return 0;
6644}
6645
34373d12
VT
6646static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
6647{
6648 ASSERT_WDEV_LOCK(wdev);
6649
6650 if (!cfg80211_beaconing_iface_active(wdev))
6651 return true;
6652
6653 if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
6654 return true;
6655
6656 return regulatory_pre_cac_allowed(wdev->wiphy);
6657}
6658
2d23d073
RZ
6659static int
6660nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
6661 void *request, struct nlattr **attrs,
6662 bool is_sched_scan)
6663{
6664 u8 *mac_addr, *mac_addr_mask;
6665 u32 *flags;
6666 enum nl80211_feature_flags randomness_flag;
6667
6668 if (!attrs[NL80211_ATTR_SCAN_FLAGS])
6669 return 0;
6670
6671 if (is_sched_scan) {
6672 struct cfg80211_sched_scan_request *req = request;
6673
6674 randomness_flag = wdev ?
6675 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
6676 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
6677 flags = &req->flags;
6678 mac_addr = req->mac_addr;
6679 mac_addr_mask = req->mac_addr_mask;
6680 } else {
6681 struct cfg80211_scan_request *req = request;
6682
6683 randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
6684 flags = &req->flags;
6685 mac_addr = req->mac_addr;
6686 mac_addr_mask = req->mac_addr_mask;
6687 }
6688
6689 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
6690
6691 if ((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
6692 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN))
6693 return -EOPNOTSUPP;
6694
6695 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
6696 int err;
6697
6698 if (!(wiphy->features & randomness_flag) ||
6699 (wdev && wdev->current_bss))
6700 return -EOPNOTSUPP;
6701
6702 err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
6703 if (err)
6704 return err;
6705 }
6706
6707 if ((*flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME) &&
6708 !wiphy_ext_feature_isset(wiphy,
6709 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME))
6710 return -EOPNOTSUPP;
6711
6712 if ((*flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP) &&
6713 !wiphy_ext_feature_isset(wiphy,
6714 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP))
6715 return -EOPNOTSUPP;
6716
6717 if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) &&
6718 !wiphy_ext_feature_isset(wiphy,
6719 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION))
6720 return -EOPNOTSUPP;
6721
6722 if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE) &&
6723 !wiphy_ext_feature_isset(wiphy,
6724 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE))
6725 return -EOPNOTSUPP;
6726
6727 return 0;
6728}
6729
2a519311
JB
6730static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
6731{
4c476991 6732 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 6733 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 6734 struct cfg80211_scan_request *request;
2a519311
JB
6735 struct nlattr *attr;
6736 struct wiphy *wiphy;
83f5e2cf 6737 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 6738 size_t ie_len;
2a519311 6739
f4a11bb0
JB
6740 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
6741 return -EINVAL;
6742
79c97e97 6743 wiphy = &rdev->wiphy;
2a519311 6744
cb3b7d87
AB
6745 if (wdev->iftype == NL80211_IFTYPE_NAN)
6746 return -EOPNOTSUPP;
6747
4c476991
JB
6748 if (!rdev->ops->scan)
6749 return -EOPNOTSUPP;
2a519311 6750
f9d15d16 6751 if (rdev->scan_req || rdev->scan_msg) {
f9f47529
JB
6752 err = -EBUSY;
6753 goto unlock;
6754 }
2a519311
JB
6755
6756 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
6757 n_channels = validate_scan_freqs(
6758 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
f9f47529
JB
6759 if (!n_channels) {
6760 err = -EINVAL;
6761 goto unlock;
6762 }
2a519311 6763 } else {
bdfbec2d 6764 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
6765 }
6766
6767 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
6768 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
6769 n_ssids++;
6770
f9f47529
JB
6771 if (n_ssids > wiphy->max_scan_ssids) {
6772 err = -EINVAL;
6773 goto unlock;
6774 }
2a519311 6775
70692ad2
JM
6776 if (info->attrs[NL80211_ATTR_IE])
6777 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
6778 else
6779 ie_len = 0;
6780
f9f47529
JB
6781 if (ie_len > wiphy->max_scan_ie_len) {
6782 err = -EINVAL;
6783 goto unlock;
6784 }
18a83659 6785
2a519311 6786 request = kzalloc(sizeof(*request)
a2cd43c5
LC
6787 + sizeof(*request->ssids) * n_ssids
6788 + sizeof(*request->channels) * n_channels
70692ad2 6789 + ie_len, GFP_KERNEL);
f9f47529
JB
6790 if (!request) {
6791 err = -ENOMEM;
6792 goto unlock;
6793 }
2a519311 6794
2a519311 6795 if (n_ssids)
5ba63533 6796 request->ssids = (void *)&request->channels[n_channels];
2a519311 6797 request->n_ssids = n_ssids;
70692ad2 6798 if (ie_len) {
13874e4b 6799 if (n_ssids)
70692ad2
JM
6800 request->ie = (void *)(request->ssids + n_ssids);
6801 else
6802 request->ie = (void *)(request->channels + n_channels);
6803 }
2a519311 6804
584991dc 6805 i = 0;
2a519311
JB
6806 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
6807 /* user specified, bail out if channel not found */
2a519311 6808 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
6809 struct ieee80211_channel *chan;
6810
6811 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
6812
6813 if (!chan) {
2a519311
JB
6814 err = -EINVAL;
6815 goto out_free;
6816 }
584991dc
JB
6817
6818 /* ignore disabled channels */
6819 if (chan->flags & IEEE80211_CHAN_DISABLED)
6820 continue;
6821
6822 request->channels[i] = chan;
2a519311
JB
6823 i++;
6824 }
6825 } else {
57fbcce3 6826 enum nl80211_band band;
34850ab2 6827
2a519311 6828 /* all channels */
57fbcce3 6829 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 6830 int j;
7a087e74 6831
2a519311
JB
6832 if (!wiphy->bands[band])
6833 continue;
6834 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
6835 struct ieee80211_channel *chan;
6836
6837 chan = &wiphy->bands[band]->channels[j];
6838
6839 if (chan->flags & IEEE80211_CHAN_DISABLED)
6840 continue;
6841
6842 request->channels[i] = chan;
2a519311
JB
6843 i++;
6844 }
6845 }
6846 }
6847
584991dc
JB
6848 if (!i) {
6849 err = -EINVAL;
6850 goto out_free;
6851 }
6852
6853 request->n_channels = i;
6854
34373d12
VT
6855 wdev_lock(wdev);
6856 if (!cfg80211_off_channel_oper_allowed(wdev)) {
6857 struct ieee80211_channel *chan;
6858
6859 if (request->n_channels != 1) {
6860 wdev_unlock(wdev);
6861 err = -EBUSY;
6862 goto out_free;
6863 }
6864
6865 chan = request->channels[0];
6866 if (chan->center_freq != wdev->chandef.chan->center_freq) {
6867 wdev_unlock(wdev);
6868 err = -EBUSY;
6869 goto out_free;
6870 }
6871 }
6872 wdev_unlock(wdev);
6873
2a519311 6874 i = 0;
13874e4b 6875 if (n_ssids) {
2a519311 6876 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 6877 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
6878 err = -EINVAL;
6879 goto out_free;
6880 }
57a27e1d 6881 request->ssids[i].ssid_len = nla_len(attr);
2a519311 6882 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
6883 i++;
6884 }
6885 }
6886
70692ad2
JM
6887 if (info->attrs[NL80211_ATTR_IE]) {
6888 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
6889 memcpy((void *)request->ie,
6890 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
6891 request->ie_len);
6892 }
6893
57fbcce3 6894 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
6895 if (wiphy->bands[i])
6896 request->rates[i] =
6897 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
6898
6899 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
6900 nla_for_each_nested(attr,
6901 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
6902 tmp) {
57fbcce3 6903 enum nl80211_band band = nla_type(attr);
34850ab2 6904
57fbcce3 6905 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
6906 err = -EINVAL;
6907 goto out_free;
6908 }
1b09cd82
FF
6909
6910 if (!wiphy->bands[band])
6911 continue;
6912
34850ab2
JB
6913 err = ieee80211_get_ratemask(wiphy->bands[band],
6914 nla_data(attr),
6915 nla_len(attr),
6916 &request->rates[band]);
6917 if (err)
6918 goto out_free;
6919 }
6920 }
6921
1d76250b
AS
6922 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
6923 if (!wiphy_ext_feature_isset(wiphy,
6924 NL80211_EXT_FEATURE_SET_SCAN_DWELL)) {
6925 err = -EOPNOTSUPP;
6926 goto out_free;
6927 }
6928
6929 request->duration =
6930 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
6931 request->duration_mandatory =
6932 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
6933 }
6934
2d23d073
RZ
6935 err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
6936 false);
6937 if (err)
6938 goto out_free;
ed473771 6939
e9f935e3
RM
6940 request->no_cck =
6941 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
6942
2fa436b3
VK
6943 /* Initial implementation used NL80211_ATTR_MAC to set the specific
6944 * BSSID to scan for. This was problematic because that same attribute
6945 * was already used for another purpose (local random MAC address). The
6946 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
6947 * compatibility with older userspace components, also use the
6948 * NL80211_ATTR_MAC value here if it can be determined to be used for
6949 * the specific BSSID use case instead of the random MAC address
6950 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
6951 */
6952 if (info->attrs[NL80211_ATTR_BSSID])
6953 memcpy(request->bssid,
6954 nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
6955 else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
6956 info->attrs[NL80211_ATTR_MAC])
818965d3
JM
6957 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
6958 ETH_ALEN);
6959 else
6960 eth_broadcast_addr(request->bssid);
6961
fd014284 6962 request->wdev = wdev;
79c97e97 6963 request->wiphy = &rdev->wiphy;
15d6030b 6964 request->scan_start = jiffies;
2a519311 6965
79c97e97 6966 rdev->scan_req = request;
e35e4d28 6967 err = rdev_scan(rdev, request);
2a519311 6968
463d0183 6969 if (!err) {
fd014284
JB
6970 nl80211_send_scan_start(rdev, wdev);
6971 if (wdev->netdev)
6972 dev_hold(wdev->netdev);
4c476991 6973 } else {
2a519311 6974 out_free:
79c97e97 6975 rdev->scan_req = NULL;
2a519311
JB
6976 kfree(request);
6977 }
3b85875a 6978
f9f47529 6979 unlock:
2a519311
JB
6980 return err;
6981}
6982
91d3ab46
VK
6983static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
6984{
6985 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6986 struct wireless_dev *wdev = info->user_ptr[1];
6987
6988 if (!rdev->ops->abort_scan)
6989 return -EOPNOTSUPP;
6990
6991 if (rdev->scan_msg)
6992 return 0;
6993
6994 if (!rdev->scan_req)
6995 return -ENOENT;
6996
6997 rdev_abort_scan(rdev, wdev);
6998 return 0;
6999}
7000
3b06d277
AS
7001static int
7002nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
7003 struct cfg80211_sched_scan_request *request,
7004 struct nlattr **attrs)
7005{
7006 int tmp, err, i = 0;
7007 struct nlattr *attr;
7008
7009 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
7010 u32 interval;
7011
7012 /*
7013 * If scan plans are not specified,
5a88de53 7014 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
3b06d277
AS
7015 * case one scan plan will be set with the specified scan
7016 * interval and infinite number of iterations.
7017 */
3b06d277
AS
7018 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
7019 if (!interval)
7020 return -EINVAL;
7021
7022 request->scan_plans[0].interval =
7023 DIV_ROUND_UP(interval, MSEC_PER_SEC);
7024 if (!request->scan_plans[0].interval)
7025 return -EINVAL;
7026
7027 if (request->scan_plans[0].interval >
7028 wiphy->max_sched_scan_plan_interval)
7029 request->scan_plans[0].interval =
7030 wiphy->max_sched_scan_plan_interval;
7031
7032 return 0;
7033 }
7034
7035 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
7036 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
7037
7038 if (WARN_ON(i >= n_plans))
7039 return -EINVAL;
7040
bfe2c7b1 7041 err = nla_parse_nested(plan, NL80211_SCHED_SCAN_PLAN_MAX,
fceb6435 7042 attr, nl80211_plan_policy, NULL);
3b06d277
AS
7043 if (err)
7044 return err;
7045
7046 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
7047 return -EINVAL;
7048
7049 request->scan_plans[i].interval =
7050 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
7051 if (!request->scan_plans[i].interval ||
7052 request->scan_plans[i].interval >
7053 wiphy->max_sched_scan_plan_interval)
7054 return -EINVAL;
7055
7056 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
7057 request->scan_plans[i].iterations =
7058 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
7059 if (!request->scan_plans[i].iterations ||
7060 (request->scan_plans[i].iterations >
7061 wiphy->max_sched_scan_plan_iterations))
7062 return -EINVAL;
7063 } else if (i < n_plans - 1) {
7064 /*
7065 * All scan plans but the last one must specify
7066 * a finite number of iterations
7067 */
7068 return -EINVAL;
7069 }
7070
7071 i++;
7072 }
7073
7074 /*
7075 * The last scan plan must not specify the number of
7076 * iterations, it is supposed to run infinitely
7077 */
7078 if (request->scan_plans[n_plans - 1].iterations)
7079 return -EINVAL;
7080
7081 return 0;
7082}
7083
256da02d 7084static struct cfg80211_sched_scan_request *
ad2b26ab 7085nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
aad1e812 7086 struct nlattr **attrs, int max_match_sets)
807f8a8c
LC
7087{
7088 struct cfg80211_sched_scan_request *request;
807f8a8c 7089 struct nlattr *attr;
3b06d277 7090 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 7091 enum nl80211_band band;
807f8a8c 7092 size_t ie_len;
a1f1c21c 7093 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 7094 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 7095
256da02d
LC
7096 if (!is_valid_ie_attr(attrs[NL80211_ATTR_IE]))
7097 return ERR_PTR(-EINVAL);
807f8a8c 7098
256da02d 7099 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 7100 n_channels = validate_scan_freqs(
256da02d 7101 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 7102 if (!n_channels)
256da02d 7103 return ERR_PTR(-EINVAL);
807f8a8c 7104 } else {
bdfbec2d 7105 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
7106 }
7107
256da02d
LC
7108 if (attrs[NL80211_ATTR_SCAN_SSIDS])
7109 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
7110 tmp)
7111 n_ssids++;
7112
93b6aa69 7113 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 7114 return ERR_PTR(-EINVAL);
807f8a8c 7115
ea73cbce
JB
7116 /*
7117 * First, count the number of 'real' matchsets. Due to an issue with
7118 * the old implementation, matchsets containing only the RSSI attribute
7119 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
7120 * RSSI for all matchsets, rather than their own matchset for reporting
7121 * all APs with a strong RSSI. This is needed to be compatible with
7122 * older userspace that treated a matchset with only the RSSI as the
7123 * global RSSI for all other matchsets - if there are other matchsets.
7124 */
256da02d 7125 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 7126 nla_for_each_nested(attr,
256da02d 7127 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
7128 tmp) {
7129 struct nlattr *rssi;
7130
bfe2c7b1
JB
7131 err = nla_parse_nested(tb,
7132 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
fceb6435
JB
7133 attr, nl80211_match_policy,
7134 NULL);
ea73cbce 7135 if (err)
256da02d 7136 return ERR_PTR(err);
3007e352
AVS
7137
7138 /* SSID and BSSID are mutually exclusive */
7139 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
7140 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
7141 return ERR_PTR(-EINVAL);
7142
ea73cbce 7143 /* add other standalone attributes here */
3007e352
AVS
7144 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
7145 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
ea73cbce
JB
7146 n_match_sets++;
7147 continue;
7148 }
7149 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
7150 if (rssi)
7151 default_match_rssi = nla_get_s32(rssi);
7152 }
7153 }
7154
7155 /* However, if there's no other matchset, add the RSSI one */
7156 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
7157 n_match_sets = 1;
a1f1c21c 7158
aad1e812 7159 if (n_match_sets > max_match_sets)
256da02d 7160 return ERR_PTR(-EINVAL);
a1f1c21c 7161
256da02d
LC
7162 if (attrs[NL80211_ATTR_IE])
7163 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
7164 else
7165 ie_len = 0;
7166
5a865bad 7167 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 7168 return ERR_PTR(-EINVAL);
c10841ca 7169
3b06d277
AS
7170 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
7171 /*
7172 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
7173 * each scan plan already specifies its own interval
7174 */
7175 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
7176 return ERR_PTR(-EINVAL);
7177
7178 nla_for_each_nested(attr,
7179 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
7180 n_plans++;
7181 } else {
7182 /*
7183 * The scan interval attribute is kept for backward
7184 * compatibility. If no scan plans are specified and sched scan
7185 * interval is specified, one scan plan will be set with this
7186 * scan interval and infinite number of iterations.
7187 */
7188 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
7189 return ERR_PTR(-EINVAL);
7190
7191 n_plans = 1;
7192 }
7193
7194 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
7195 return ERR_PTR(-EINVAL);
7196
bf95ecdb 7197 if (!wiphy_ext_feature_isset(
7198 wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
7199 (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
7200 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
7201 return ERR_PTR(-EINVAL);
7202
807f8a8c 7203 request = kzalloc(sizeof(*request)
a2cd43c5 7204 + sizeof(*request->ssids) * n_ssids
a1f1c21c 7205 + sizeof(*request->match_sets) * n_match_sets
3b06d277 7206 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 7207 + sizeof(*request->channels) * n_channels
807f8a8c 7208 + ie_len, GFP_KERNEL);
256da02d
LC
7209 if (!request)
7210 return ERR_PTR(-ENOMEM);
807f8a8c
LC
7211
7212 if (n_ssids)
7213 request->ssids = (void *)&request->channels[n_channels];
7214 request->n_ssids = n_ssids;
7215 if (ie_len) {
13874e4b 7216 if (n_ssids)
807f8a8c
LC
7217 request->ie = (void *)(request->ssids + n_ssids);
7218 else
7219 request->ie = (void *)(request->channels + n_channels);
7220 }
7221
a1f1c21c
LC
7222 if (n_match_sets) {
7223 if (request->ie)
7224 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 7225 else if (n_ssids)
a1f1c21c
LC
7226 request->match_sets =
7227 (void *)(request->ssids + n_ssids);
7228 else
7229 request->match_sets =
7230 (void *)(request->channels + n_channels);
7231 }
7232 request->n_match_sets = n_match_sets;
7233
3b06d277
AS
7234 if (n_match_sets)
7235 request->scan_plans = (void *)(request->match_sets +
7236 n_match_sets);
7237 else if (request->ie)
7238 request->scan_plans = (void *)(request->ie + ie_len);
7239 else if (n_ssids)
7240 request->scan_plans = (void *)(request->ssids + n_ssids);
7241 else
7242 request->scan_plans = (void *)(request->channels + n_channels);
7243
7244 request->n_scan_plans = n_plans;
7245
807f8a8c 7246 i = 0;
256da02d 7247 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
7248 /* user specified, bail out if channel not found */
7249 nla_for_each_nested(attr,
256da02d 7250 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
7251 tmp) {
7252 struct ieee80211_channel *chan;
7253
7254 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
7255
7256 if (!chan) {
7257 err = -EINVAL;
7258 goto out_free;
7259 }
7260
7261 /* ignore disabled channels */
7262 if (chan->flags & IEEE80211_CHAN_DISABLED)
7263 continue;
7264
7265 request->channels[i] = chan;
7266 i++;
7267 }
7268 } else {
7269 /* all channels */
57fbcce3 7270 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 7271 int j;
7a087e74 7272
807f8a8c
LC
7273 if (!wiphy->bands[band])
7274 continue;
7275 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
7276 struct ieee80211_channel *chan;
7277
7278 chan = &wiphy->bands[band]->channels[j];
7279
7280 if (chan->flags & IEEE80211_CHAN_DISABLED)
7281 continue;
7282
7283 request->channels[i] = chan;
7284 i++;
7285 }
7286 }
7287 }
7288
7289 if (!i) {
7290 err = -EINVAL;
7291 goto out_free;
7292 }
7293
7294 request->n_channels = i;
7295
7296 i = 0;
13874e4b 7297 if (n_ssids) {
256da02d 7298 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 7299 tmp) {
57a27e1d 7300 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
7301 err = -EINVAL;
7302 goto out_free;
7303 }
57a27e1d 7304 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
7305 memcpy(request->ssids[i].ssid, nla_data(attr),
7306 nla_len(attr));
807f8a8c
LC
7307 i++;
7308 }
7309 }
7310
a1f1c21c 7311 i = 0;
256da02d 7312 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 7313 nla_for_each_nested(attr,
256da02d 7314 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 7315 tmp) {
3007e352 7316 struct nlattr *ssid, *bssid, *rssi;
a1f1c21c 7317
bfe2c7b1
JB
7318 err = nla_parse_nested(tb,
7319 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
fceb6435
JB
7320 attr, nl80211_match_policy,
7321 NULL);
ae811e21
JB
7322 if (err)
7323 goto out_free;
4a4ab0d7 7324 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
3007e352
AVS
7325 bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
7326 if (ssid || bssid) {
ea73cbce
JB
7327 if (WARN_ON(i >= n_match_sets)) {
7328 /* this indicates a programming error,
7329 * the loop above should have verified
7330 * things properly
7331 */
7332 err = -EINVAL;
7333 goto out_free;
7334 }
7335
3007e352
AVS
7336 if (ssid) {
7337 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
7338 err = -EINVAL;
7339 goto out_free;
7340 }
7341 memcpy(request->match_sets[i].ssid.ssid,
7342 nla_data(ssid), nla_len(ssid));
7343 request->match_sets[i].ssid.ssid_len =
7344 nla_len(ssid);
7345 }
7346 if (bssid) {
7347 if (nla_len(bssid) != ETH_ALEN) {
7348 err = -EINVAL;
7349 goto out_free;
7350 }
7351 memcpy(request->match_sets[i].bssid,
7352 nla_data(bssid), ETH_ALEN);
a1f1c21c 7353 }
3007e352 7354
56ab364f 7355 /* special attribute - old implementation w/a */
ea73cbce
JB
7356 request->match_sets[i].rssi_thold =
7357 default_match_rssi;
7358 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
7359 if (rssi)
7360 request->match_sets[i].rssi_thold =
7361 nla_get_s32(rssi);
a1f1c21c
LC
7362 }
7363 i++;
7364 }
ea73cbce
JB
7365
7366 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 7367 if (i == 0 && n_match_sets)
ea73cbce
JB
7368 request->match_sets[0].rssi_thold = default_match_rssi;
7369
7370 request->min_rssi_thold = INT_MAX;
7371 for (i = 0; i < n_match_sets; i++)
7372 request->min_rssi_thold =
7373 min(request->match_sets[i].rssi_thold,
7374 request->min_rssi_thold);
7375 } else {
7376 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
7377 }
7378
9900e484
JB
7379 if (ie_len) {
7380 request->ie_len = ie_len;
807f8a8c 7381 memcpy((void *)request->ie,
256da02d 7382 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
7383 request->ie_len);
7384 }
7385
2d23d073
RZ
7386 err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
7387 if (err)
7388 goto out_free;
ed473771 7389
9c748934
LC
7390 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
7391 request->delay =
7392 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
7393
bf95ecdb 7394 if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
7395 request->relative_rssi = nla_get_s8(
7396 attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
7397 request->relative_rssi_set = true;
7398 }
7399
7400 if (request->relative_rssi_set &&
7401 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
7402 struct nl80211_bss_select_rssi_adjust *rssi_adjust;
7403
7404 rssi_adjust = nla_data(
7405 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
7406 request->rssi_adjust.band = rssi_adjust->band;
7407 request->rssi_adjust.delta = rssi_adjust->delta;
7408 if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
7409 err = -EINVAL;
7410 goto out_free;
7411 }
7412 }
7413
3b06d277
AS
7414 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
7415 if (err)
7416 goto out_free;
7417
15d6030b 7418 request->scan_start = jiffies;
807f8a8c 7419
256da02d 7420 return request;
807f8a8c
LC
7421
7422out_free:
7423 kfree(request);
256da02d
LC
7424 return ERR_PTR(err);
7425}
7426
7427static int nl80211_start_sched_scan(struct sk_buff *skb,
7428 struct genl_info *info)
7429{
7430 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7431 struct net_device *dev = info->user_ptr[1];
ad2b26ab 7432 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 7433 struct cfg80211_sched_scan_request *sched_scan_req;
ca986ad9 7434 bool want_multi;
256da02d
LC
7435 int err;
7436
ca986ad9 7437 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
256da02d
LC
7438 return -EOPNOTSUPP;
7439
ca986ad9
AVS
7440 want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
7441 err = cfg80211_sched_scan_req_possible(rdev, want_multi);
7442 if (err)
7443 return err;
256da02d 7444
31a60ed1 7445 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
aad1e812
AVS
7446 info->attrs,
7447 rdev->wiphy.max_match_sets);
31a60ed1
JR
7448
7449 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
7450 if (err)
7451 goto out_err;
7452
ca986ad9
AVS
7453 /* leave request id zero for legacy request
7454 * or if driver does not support multi-scheduled scan
7455 */
7456 if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1) {
7457 while (!sched_scan_req->reqid)
7458 sched_scan_req->reqid = rdev->wiphy.cookie_counter++;
7459 }
7460
31a60ed1 7461 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
7462 if (err)
7463 goto out_free;
7464
31a60ed1
JR
7465 sched_scan_req->dev = dev;
7466 sched_scan_req->wiphy = &rdev->wiphy;
7467
93a1e86c
JR
7468 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
7469 sched_scan_req->owner_nlportid = info->snd_portid;
7470
ca986ad9 7471 cfg80211_add_sched_scan_req(rdev, sched_scan_req);
256da02d 7472
96b08fd6 7473 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
256da02d
LC
7474 return 0;
7475
7476out_free:
31a60ed1 7477 kfree(sched_scan_req);
256da02d 7478out_err:
807f8a8c
LC
7479 return err;
7480}
7481
7482static int nl80211_stop_sched_scan(struct sk_buff *skb,
7483 struct genl_info *info)
7484{
ca986ad9 7485 struct cfg80211_sched_scan_request *req;
807f8a8c 7486 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ca986ad9 7487 u64 cookie;
807f8a8c 7488
ca986ad9 7489 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
807f8a8c
LC
7490 return -EOPNOTSUPP;
7491
ca986ad9
AVS
7492 if (info->attrs[NL80211_ATTR_COOKIE]) {
7493 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
7494 return __cfg80211_stop_sched_scan(rdev, cookie, false);
7495 }
7496
7497 req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
7498 struct cfg80211_sched_scan_request,
7499 list);
7500 if (!req || req->reqid ||
7501 (req->owner_nlportid &&
7502 req->owner_nlportid != info->snd_portid))
7503 return -ENOENT;
7504
7505 return cfg80211_stop_sched_scan_req(rdev, req, false);
807f8a8c
LC
7506}
7507
04f39047
SW
7508static int nl80211_start_radar_detection(struct sk_buff *skb,
7509 struct genl_info *info)
7510{
7511 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7512 struct net_device *dev = info->user_ptr[1];
7513 struct wireless_dev *wdev = dev->ieee80211_ptr;
7514 struct cfg80211_chan_def chandef;
55f7435c 7515 enum nl80211_dfs_regions dfs_region;
31559f35 7516 unsigned int cac_time_ms;
04f39047
SW
7517 int err;
7518
55f7435c
LR
7519 dfs_region = reg_get_dfs_region(wdev->wiphy);
7520 if (dfs_region == NL80211_DFS_UNSET)
7521 return -EINVAL;
7522
04f39047
SW
7523 err = nl80211_parse_chandef(rdev, info, &chandef);
7524 if (err)
7525 return err;
7526
ff311bc1
SW
7527 if (netif_carrier_ok(dev))
7528 return -EBUSY;
7529
04f39047
SW
7530 if (wdev->cac_started)
7531 return -EBUSY;
7532
2beb6dab 7533 err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef,
00ec75fc 7534 wdev->iftype);
04f39047
SW
7535 if (err < 0)
7536 return err;
7537
7538 if (err == 0)
7539 return -EINVAL;
7540
fe7c3a1f 7541 if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef))
04f39047
SW
7542 return -EINVAL;
7543
7544 if (!rdev->ops->start_radar_detection)
7545 return -EOPNOTSUPP;
7546
31559f35
JD
7547 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
7548 if (WARN_ON(!cac_time_ms))
7549 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
7550
a1056b1b 7551 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 7552 if (!err) {
9e0e2961 7553 wdev->chandef = chandef;
04f39047
SW
7554 wdev->cac_started = true;
7555 wdev->cac_start_time = jiffies;
31559f35 7556 wdev->cac_time_ms = cac_time_ms;
04f39047 7557 }
04f39047
SW
7558 return err;
7559}
7560
16ef1fe2
SW
7561static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
7562{
7563 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7564 struct net_device *dev = info->user_ptr[1];
7565 struct wireless_dev *wdev = dev->ieee80211_ptr;
7566 struct cfg80211_csa_settings params;
7567 /* csa_attrs is defined static to avoid waste of stack size - this
7568 * function is called under RTNL lock, so this should not be a problem.
7569 */
7570 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
16ef1fe2 7571 int err;
ee4bc9e7 7572 bool need_new_beacon = false;
8d9de16f 7573 bool need_handle_dfs_flag = true;
9a774c78 7574 int len, i;
252e07ca 7575 u32 cs_count;
16ef1fe2
SW
7576
7577 if (!rdev->ops->channel_switch ||
7578 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
7579 return -EOPNOTSUPP;
7580
ee4bc9e7
SW
7581 switch (dev->ieee80211_ptr->iftype) {
7582 case NL80211_IFTYPE_AP:
7583 case NL80211_IFTYPE_P2P_GO:
7584 need_new_beacon = true;
8d9de16f
BB
7585 /* For all modes except AP the handle_dfs flag needs to be
7586 * supplied to tell the kernel that userspace will handle radar
7587 * events when they happen. Otherwise a switch to a channel
7588 * requiring DFS will be rejected.
7589 */
7590 need_handle_dfs_flag = false;
ee4bc9e7
SW
7591
7592 /* useless if AP is not running */
7593 if (!wdev->beacon_interval)
1ff79dfa 7594 return -ENOTCONN;
ee4bc9e7
SW
7595 break;
7596 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
7597 if (!wdev->ssid_len)
7598 return -ENOTCONN;
7599 break;
c6da674a 7600 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
7601 if (!wdev->mesh_id_len)
7602 return -ENOTCONN;
ee4bc9e7
SW
7603 break;
7604 default:
16ef1fe2 7605 return -EOPNOTSUPP;
ee4bc9e7 7606 }
16ef1fe2
SW
7607
7608 memset(&params, 0, sizeof(params));
7609
7610 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
7611 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
7612 return -EINVAL;
7613
7614 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 7615 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
7616 return -EINVAL;
7617
252e07ca
LC
7618 /* Even though the attribute is u32, the specification says
7619 * u8, so let's make sure we don't overflow.
7620 */
7621 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
7622 if (cs_count > 255)
7623 return -EINVAL;
7624
7625 params.count = cs_count;
16ef1fe2 7626
ee4bc9e7
SW
7627 if (!need_new_beacon)
7628 goto skip_beacons;
7629
16ef1fe2
SW
7630 err = nl80211_parse_beacon(info->attrs, &params.beacon_after);
7631 if (err)
7632 return err;
7633
7634 err = nla_parse_nested(csa_attrs, NL80211_ATTR_MAX,
7635 info->attrs[NL80211_ATTR_CSA_IES],
fe52145f 7636 nl80211_policy, info->extack);
16ef1fe2
SW
7637 if (err)
7638 return err;
7639
7640 err = nl80211_parse_beacon(csa_attrs, &params.beacon_csa);
7641 if (err)
7642 return err;
7643
7644 if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON])
7645 return -EINVAL;
7646
9a774c78
AO
7647 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
7648 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
7649 return -EINVAL;
7650
9a774c78
AO
7651 params.n_counter_offsets_beacon = len / sizeof(u16);
7652 if (rdev->wiphy.max_num_csa_counters &&
7653 (params.n_counter_offsets_beacon >
7654 rdev->wiphy.max_num_csa_counters))
16ef1fe2
SW
7655 return -EINVAL;
7656
9a774c78
AO
7657 params.counter_offsets_beacon =
7658 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
7659
7660 /* sanity checks - counters should fit and be the same */
7661 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
7662 u16 offset = params.counter_offsets_beacon[i];
7663
7664 if (offset >= params.beacon_csa.tail_len)
7665 return -EINVAL;
7666
7667 if (params.beacon_csa.tail[offset] != params.count)
7668 return -EINVAL;
7669 }
7670
16ef1fe2 7671 if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) {
9a774c78
AO
7672 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
7673 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
7674 return -EINVAL;
7675
9a774c78
AO
7676 params.n_counter_offsets_presp = len / sizeof(u16);
7677 if (rdev->wiphy.max_num_csa_counters &&
ad5987b4 7678 (params.n_counter_offsets_presp >
9a774c78 7679 rdev->wiphy.max_num_csa_counters))
16ef1fe2 7680 return -EINVAL;
9a774c78
AO
7681
7682 params.counter_offsets_presp =
7683 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
7684
7685 /* sanity checks - counters should fit and be the same */
7686 for (i = 0; i < params.n_counter_offsets_presp; i++) {
7687 u16 offset = params.counter_offsets_presp[i];
7688
7689 if (offset >= params.beacon_csa.probe_resp_len)
7690 return -EINVAL;
7691
7692 if (params.beacon_csa.probe_resp[offset] !=
7693 params.count)
7694 return -EINVAL;
7695 }
16ef1fe2
SW
7696 }
7697
ee4bc9e7 7698skip_beacons:
16ef1fe2
SW
7699 err = nl80211_parse_chandef(rdev, info, &params.chandef);
7700 if (err)
7701 return err;
7702
923b352f
AN
7703 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
7704 wdev->iftype))
16ef1fe2
SW
7705 return -EINVAL;
7706
2beb6dab
LC
7707 err = cfg80211_chandef_dfs_required(wdev->wiphy,
7708 &params.chandef,
7709 wdev->iftype);
7710 if (err < 0)
7711 return err;
7712
8d9de16f 7713 if (err > 0) {
2beb6dab 7714 params.radar_required = true;
8d9de16f
BB
7715 if (need_handle_dfs_flag &&
7716 !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
7717 return -EINVAL;
7718 }
7719 }
16ef1fe2 7720
16ef1fe2
SW
7721 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
7722 params.block_tx = true;
7723
c56589ed
SW
7724 wdev_lock(wdev);
7725 err = rdev_channel_switch(rdev, dev, &params);
7726 wdev_unlock(wdev);
7727
7728 return err;
16ef1fe2
SW
7729}
7730
9720bb3a
JB
7731static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
7732 u32 seq, int flags,
2a519311 7733 struct cfg80211_registered_device *rdev,
48ab905d
JB
7734 struct wireless_dev *wdev,
7735 struct cfg80211_internal_bss *intbss)
2a519311 7736{
48ab905d 7737 struct cfg80211_bss *res = &intbss->pub;
9caf0364 7738 const struct cfg80211_bss_ies *ies;
2a519311
JB
7739 void *hdr;
7740 struct nlattr *bss;
48ab905d
JB
7741
7742 ASSERT_WDEV_LOCK(wdev);
2a519311 7743
15e47304 7744 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
7745 NL80211_CMD_NEW_SCAN_RESULTS);
7746 if (!hdr)
7747 return -1;
7748
0a833c29 7749 genl_dump_check_consistent(cb, hdr);
9720bb3a 7750
97990a06
JB
7751 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
7752 goto nla_put_failure;
7753 if (wdev->netdev &&
9360ffd1
DM
7754 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
7755 goto nla_put_failure;
2dad624e
ND
7756 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
7757 NL80211_ATTR_PAD))
97990a06 7758 goto nla_put_failure;
2a519311
JB
7759
7760 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
7761 if (!bss)
7762 goto nla_put_failure;
9360ffd1 7763 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 7764 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 7765 goto nla_put_failure;
9caf0364
JB
7766
7767 rcu_read_lock();
0e227084
JB
7768 /* indicate whether we have probe response data or not */
7769 if (rcu_access_pointer(res->proberesp_ies) &&
7770 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
7771 goto fail_unlock_rcu;
7772
7773 /* this pointer prefers to be pointed to probe response data
7774 * but is always valid
7775 */
9caf0364 7776 ies = rcu_dereference(res->ies);
8cef2c9d 7777 if (ies) {
2dad624e
ND
7778 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
7779 NL80211_BSS_PAD))
8cef2c9d 7780 goto fail_unlock_rcu;
8cef2c9d
JB
7781 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
7782 ies->len, ies->data))
7783 goto fail_unlock_rcu;
9caf0364 7784 }
0e227084
JB
7785
7786 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 7787 ies = rcu_dereference(res->beacon_ies);
0e227084 7788 if (ies && ies->from_beacon) {
2dad624e
ND
7789 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
7790 NL80211_BSS_PAD))
8cef2c9d
JB
7791 goto fail_unlock_rcu;
7792 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
7793 ies->len, ies->data))
7794 goto fail_unlock_rcu;
9caf0364
JB
7795 }
7796 rcu_read_unlock();
7797
9360ffd1
DM
7798 if (res->beacon_interval &&
7799 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
7800 goto nla_put_failure;
7801 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
7802 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
dcd6eac1 7803 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
7804 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
7805 jiffies_to_msecs(jiffies - intbss->ts)))
7806 goto nla_put_failure;
2a519311 7807
1d76250b
AS
7808 if (intbss->parent_tsf &&
7809 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
7810 intbss->parent_tsf, NL80211_BSS_PAD) ||
7811 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
7812 intbss->parent_bssid)))
7813 goto nla_put_failure;
7814
6e19bc4b 7815 if (intbss->ts_boottime &&
2dad624e
ND
7816 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
7817 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
7818 goto nla_put_failure;
7819
77965c97 7820 switch (rdev->wiphy.signal_type) {
2a519311 7821 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
7822 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
7823 goto nla_put_failure;
2a519311
JB
7824 break;
7825 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
7826 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
7827 goto nla_put_failure;
2a519311
JB
7828 break;
7829 default:
7830 break;
7831 }
7832
48ab905d 7833 switch (wdev->iftype) {
074ac8df 7834 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 7835 case NL80211_IFTYPE_STATION:
9360ffd1
DM
7836 if (intbss == wdev->current_bss &&
7837 nla_put_u32(msg, NL80211_BSS_STATUS,
7838 NL80211_BSS_STATUS_ASSOCIATED))
7839 goto nla_put_failure;
48ab905d
JB
7840 break;
7841 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
7842 if (intbss == wdev->current_bss &&
7843 nla_put_u32(msg, NL80211_BSS_STATUS,
7844 NL80211_BSS_STATUS_IBSS_JOINED))
7845 goto nla_put_failure;
48ab905d
JB
7846 break;
7847 default:
7848 break;
7849 }
7850
2a519311
JB
7851 nla_nest_end(msg, bss);
7852
053c095a
JB
7853 genlmsg_end(msg, hdr);
7854 return 0;
2a519311 7855
8cef2c9d
JB
7856 fail_unlock_rcu:
7857 rcu_read_unlock();
2a519311
JB
7858 nla_put_failure:
7859 genlmsg_cancel(msg, hdr);
7860 return -EMSGSIZE;
7861}
7862
97990a06 7863static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 7864{
48ab905d 7865 struct cfg80211_registered_device *rdev;
2a519311 7866 struct cfg80211_internal_bss *scan;
48ab905d 7867 struct wireless_dev *wdev;
97990a06 7868 int start = cb->args[2], idx = 0;
2a519311
JB
7869 int err;
7870
ea90e0dc 7871 rtnl_lock();
97990a06 7872 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
ea90e0dc
JB
7873 if (err) {
7874 rtnl_unlock();
67748893 7875 return err;
ea90e0dc 7876 }
2a519311 7877
48ab905d
JB
7878 wdev_lock(wdev);
7879 spin_lock_bh(&rdev->bss_lock);
7880 cfg80211_bss_expire(rdev);
7881
9720bb3a
JB
7882 cb->seq = rdev->bss_generation;
7883
48ab905d 7884 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
7885 if (++idx <= start)
7886 continue;
9720bb3a 7887 if (nl80211_send_bss(skb, cb,
2a519311 7888 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 7889 rdev, wdev, scan) < 0) {
2a519311 7890 idx--;
67748893 7891 break;
2a519311
JB
7892 }
7893 }
7894
48ab905d
JB
7895 spin_unlock_bh(&rdev->bss_lock);
7896 wdev_unlock(wdev);
2a519311 7897
97990a06 7898 cb->args[2] = idx;
ea90e0dc 7899 rtnl_unlock();
2a519311 7900
67748893 7901 return skb->len;
2a519311
JB
7902}
7903
15e47304 7904static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
7905 int flags, struct net_device *dev,
7906 bool allow_radio_stats,
7907 struct survey_info *survey)
61fa713c
HS
7908{
7909 void *hdr;
7910 struct nlattr *infoattr;
7911
11f78ac3
JB
7912 /* skip radio stats if userspace didn't request them */
7913 if (!survey->channel && !allow_radio_stats)
7914 return 0;
7915
15e47304 7916 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
7917 NL80211_CMD_NEW_SURVEY_RESULTS);
7918 if (!hdr)
7919 return -ENOMEM;
7920
9360ffd1
DM
7921 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
7922 goto nla_put_failure;
61fa713c
HS
7923
7924 infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
7925 if (!infoattr)
7926 goto nla_put_failure;
7927
11f78ac3
JB
7928 if (survey->channel &&
7929 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
7930 survey->channel->center_freq))
7931 goto nla_put_failure;
7932
7933 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
7934 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
7935 goto nla_put_failure;
7936 if ((survey->filled & SURVEY_INFO_IN_USE) &&
7937 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
7938 goto nla_put_failure;
4ed20beb 7939 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
7940 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
7941 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 7942 goto nla_put_failure;
4ed20beb 7943 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
7944 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
7945 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 7946 goto nla_put_failure;
4ed20beb 7947 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
7948 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
7949 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 7950 goto nla_put_failure;
4ed20beb 7951 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
7952 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
7953 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 7954 goto nla_put_failure;
4ed20beb 7955 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
7956 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
7957 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 7958 goto nla_put_failure;
052536ab 7959 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
7960 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
7961 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 7962 goto nla_put_failure;
61fa713c
HS
7963
7964 nla_nest_end(msg, infoattr);
7965
053c095a
JB
7966 genlmsg_end(msg, hdr);
7967 return 0;
61fa713c
HS
7968
7969 nla_put_failure:
7970 genlmsg_cancel(msg, hdr);
7971 return -EMSGSIZE;
7972}
7973
11f78ac3 7974static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c 7975{
c90c39da 7976 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
61fa713c 7977 struct survey_info survey;
1b8ec87a 7978 struct cfg80211_registered_device *rdev;
97990a06
JB
7979 struct wireless_dev *wdev;
7980 int survey_idx = cb->args[2];
61fa713c 7981 int res;
11f78ac3 7982 bool radio_stats;
61fa713c 7983
ea90e0dc 7984 rtnl_lock();
1b8ec87a 7985 res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893 7986 if (res)
ea90e0dc 7987 goto out_err;
61fa713c 7988
11f78ac3 7989 /* prepare_wdev_dump parsed the attributes */
c90c39da 7990 radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
11f78ac3 7991
97990a06
JB
7992 if (!wdev->netdev) {
7993 res = -EINVAL;
7994 goto out_err;
7995 }
7996
1b8ec87a 7997 if (!rdev->ops->dump_survey) {
61fa713c
HS
7998 res = -EOPNOTSUPP;
7999 goto out_err;
8000 }
8001
8002 while (1) {
1b8ec87a 8003 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
8004 if (res == -ENOENT)
8005 break;
8006 if (res)
8007 goto out_err;
8008
11f78ac3
JB
8009 /* don't send disabled channels, but do send non-channel data */
8010 if (survey.channel &&
8011 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
8012 survey_idx++;
8013 continue;
8014 }
8015
61fa713c 8016 if (nl80211_send_survey(skb,
15e47304 8017 NETLINK_CB(cb->skb).portid,
61fa713c 8018 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 8019 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
8020 goto out;
8021 survey_idx++;
8022 }
8023
8024 out:
97990a06 8025 cb->args[2] = survey_idx;
61fa713c
HS
8026 res = skb->len;
8027 out_err:
ea90e0dc 8028 rtnl_unlock();
61fa713c
HS
8029 return res;
8030}
8031
b23aa676
SO
8032static bool nl80211_valid_wpa_versions(u32 wpa_versions)
8033{
8034 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
8035 NL80211_WPA_VERSION_2));
8036}
8037
636a5d36
JM
8038static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
8039{
4c476991
JB
8040 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8041 struct net_device *dev = info->user_ptr[1];
19957bb3 8042 struct ieee80211_channel *chan;
11b6b5a4
JM
8043 const u8 *bssid, *ssid, *ie = NULL, *auth_data = NULL;
8044 int err, ssid_len, ie_len = 0, auth_data_len = 0;
19957bb3 8045 enum nl80211_auth_type auth_type;
fffd0934 8046 struct key_parse key;
d5cdfacb 8047 bool local_state_change;
636a5d36 8048
f4a11bb0
JB
8049 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8050 return -EINVAL;
8051
8052 if (!info->attrs[NL80211_ATTR_MAC])
8053 return -EINVAL;
8054
1778092e
JM
8055 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
8056 return -EINVAL;
8057
19957bb3
JB
8058 if (!info->attrs[NL80211_ATTR_SSID])
8059 return -EINVAL;
8060
8061 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
8062 return -EINVAL;
8063
fffd0934
JB
8064 err = nl80211_parse_key(info, &key);
8065 if (err)
8066 return err;
8067
8068 if (key.idx >= 0) {
e31b8213
JB
8069 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
8070 return -EINVAL;
fffd0934
JB
8071 if (!key.p.key || !key.p.key_len)
8072 return -EINVAL;
8073 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
8074 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
8075 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
8076 key.p.key_len != WLAN_KEY_LEN_WEP104))
8077 return -EINVAL;
b6b5555b 8078 if (key.idx > 3)
fffd0934
JB
8079 return -EINVAL;
8080 } else {
8081 key.p.key_len = 0;
8082 key.p.key = NULL;
8083 }
8084
afea0b7a
JB
8085 if (key.idx >= 0) {
8086 int i;
8087 bool ok = false;
7a087e74 8088
afea0b7a
JB
8089 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
8090 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
8091 ok = true;
8092 break;
8093 }
8094 }
4c476991
JB
8095 if (!ok)
8096 return -EINVAL;
afea0b7a
JB
8097 }
8098
4c476991
JB
8099 if (!rdev->ops->auth)
8100 return -EOPNOTSUPP;
636a5d36 8101
074ac8df 8102 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8103 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8104 return -EOPNOTSUPP;
eec60b03 8105
19957bb3 8106 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
664834de
JM
8107 chan = nl80211_get_valid_chan(&rdev->wiphy,
8108 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8109 if (!chan)
4c476991 8110 return -EINVAL;
636a5d36 8111
19957bb3
JB
8112 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8113 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
8114
8115 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8116 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8117 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8118 }
8119
19957bb3 8120 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 8121 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 8122 return -EINVAL;
636a5d36 8123
63181060
JM
8124 if ((auth_type == NL80211_AUTHTYPE_SAE ||
8125 auth_type == NL80211_AUTHTYPE_FILS_SK ||
8126 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
8127 auth_type == NL80211_AUTHTYPE_FILS_PK) &&
11b6b5a4 8128 !info->attrs[NL80211_ATTR_AUTH_DATA])
e39e5b5e
JM
8129 return -EINVAL;
8130
11b6b5a4 8131 if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
63181060
JM
8132 if (auth_type != NL80211_AUTHTYPE_SAE &&
8133 auth_type != NL80211_AUTHTYPE_FILS_SK &&
8134 auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
8135 auth_type != NL80211_AUTHTYPE_FILS_PK)
e39e5b5e 8136 return -EINVAL;
11b6b5a4
JM
8137 auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
8138 auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
e39e5b5e 8139 /* need to include at least Auth Transaction and Status Code */
11b6b5a4 8140 if (auth_data_len < 4)
e39e5b5e
JM
8141 return -EINVAL;
8142 }
8143
d5cdfacb
JM
8144 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8145
95de817b
JB
8146 /*
8147 * Since we no longer track auth state, ignore
8148 * requests to only change local state.
8149 */
8150 if (local_state_change)
8151 return 0;
8152
91bf9b26
JB
8153 wdev_lock(dev->ieee80211_ptr);
8154 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
8155 ssid, ssid_len, ie, ie_len,
8156 key.p.key, key.p.key_len, key.idx,
11b6b5a4 8157 auth_data, auth_data_len);
91bf9b26
JB
8158 wdev_unlock(dev->ieee80211_ptr);
8159 return err;
636a5d36
JM
8160}
8161
c0692b8f
JB
8162static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
8163 struct genl_info *info,
3dc27d25
JB
8164 struct cfg80211_crypto_settings *settings,
8165 int cipher_limit)
b23aa676 8166{
c0b2bbd8
JB
8167 memset(settings, 0, sizeof(*settings));
8168
b23aa676
SO
8169 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
8170
c0692b8f
JB
8171 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
8172 u16 proto;
7a087e74 8173
c0692b8f
JB
8174 proto = nla_get_u16(
8175 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
8176 settings->control_port_ethertype = cpu_to_be16(proto);
8177 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
8178 proto != ETH_P_PAE)
8179 return -EINVAL;
8180 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
8181 settings->control_port_no_encrypt = true;
8182 } else
8183 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
8184
b23aa676
SO
8185 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
8186 void *data;
8187 int len, i;
8188
8189 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
8190 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
8191 settings->n_ciphers_pairwise = len / sizeof(u32);
8192
8193 if (len % sizeof(u32))
8194 return -EINVAL;
8195
3dc27d25 8196 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
8197 return -EINVAL;
8198
8199 memcpy(settings->ciphers_pairwise, data, len);
8200
8201 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
8202 if (!cfg80211_supported_cipher_suite(
8203 &rdev->wiphy,
b23aa676
SO
8204 settings->ciphers_pairwise[i]))
8205 return -EINVAL;
8206 }
8207
8208 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
8209 settings->cipher_group =
8210 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
8211 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
8212 settings->cipher_group))
b23aa676
SO
8213 return -EINVAL;
8214 }
8215
8216 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
8217 settings->wpa_versions =
8218 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
8219 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
8220 return -EINVAL;
8221 }
8222
8223 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
8224 void *data;
6d30240e 8225 int len;
b23aa676
SO
8226
8227 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
8228 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
8229 settings->n_akm_suites = len / sizeof(u32);
8230
8231 if (len % sizeof(u32))
8232 return -EINVAL;
8233
1b9ca027
JM
8234 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
8235 return -EINVAL;
8236
b23aa676 8237 memcpy(settings->akm_suites, data, len);
b23aa676
SO
8238 }
8239
91b5ab62
EP
8240 if (info->attrs[NL80211_ATTR_PMK]) {
8241 if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
8242 return -EINVAL;
8243 if (!wiphy_ext_feature_isset(&rdev->wiphy,
8244 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
8245 return -EINVAL;
8246 settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
8247 }
8248
b23aa676
SO
8249 return 0;
8250}
8251
636a5d36
JM
8252static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
8253{
4c476991
JB
8254 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8255 struct net_device *dev = info->user_ptr[1];
f444de05 8256 struct ieee80211_channel *chan;
f62fab73
JB
8257 struct cfg80211_assoc_request req = {};
8258 const u8 *bssid, *ssid;
8259 int err, ssid_len = 0;
636a5d36 8260
f4a11bb0
JB
8261 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8262 return -EINVAL;
8263
8264 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
8265 !info->attrs[NL80211_ATTR_SSID] ||
8266 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
8267 return -EINVAL;
8268
4c476991
JB
8269 if (!rdev->ops->assoc)
8270 return -EOPNOTSUPP;
636a5d36 8271
074ac8df 8272 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8273 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8274 return -EOPNOTSUPP;
eec60b03 8275
19957bb3 8276 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8277
664834de
JM
8278 chan = nl80211_get_valid_chan(&rdev->wiphy,
8279 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8280 if (!chan)
4c476991 8281 return -EINVAL;
636a5d36 8282
19957bb3
JB
8283 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8284 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
8285
8286 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
8287 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8288 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8289 }
8290
dc6382ce 8291 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 8292 enum nl80211_mfp mfp =
dc6382ce 8293 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 8294 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 8295 req.use_mfp = true;
4c476991
JB
8296 else if (mfp != NL80211_MFP_NO)
8297 return -EINVAL;
dc6382ce
JM
8298 }
8299
3e5d7649 8300 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 8301 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 8302
7e7c8926 8303 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 8304 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
8305
8306 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
8307 memcpy(&req.ht_capa_mask,
8308 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8309 sizeof(req.ht_capa_mask));
7e7c8926
BG
8310
8311 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 8312 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 8313 return -EINVAL;
f62fab73
JB
8314 memcpy(&req.ht_capa,
8315 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8316 sizeof(req.ht_capa));
7e7c8926
BG
8317 }
8318
ee2aca34 8319 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 8320 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34
JB
8321
8322 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
8323 memcpy(&req.vht_capa_mask,
8324 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
8325 sizeof(req.vht_capa_mask));
ee2aca34
JB
8326
8327 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 8328 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 8329 return -EINVAL;
f62fab73
JB
8330 memcpy(&req.vht_capa,
8331 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
8332 sizeof(req.vht_capa));
ee2aca34
JB
8333 }
8334
bab5ab7d 8335 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
8336 if (!((rdev->wiphy.features &
8337 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
8338 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
8339 !wiphy_ext_feature_isset(&rdev->wiphy,
8340 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
8341 return -EINVAL;
8342 req.flags |= ASSOC_REQ_USE_RRM;
8343 }
8344
348bd456
JM
8345 if (info->attrs[NL80211_ATTR_FILS_KEK]) {
8346 req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
8347 req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
8348 if (!info->attrs[NL80211_ATTR_FILS_NONCES])
8349 return -EINVAL;
8350 req.fils_nonces =
8351 nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
8352 }
8353
f62fab73 8354 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
8355 if (!err) {
8356 wdev_lock(dev->ieee80211_ptr);
bd2522b1 8357
f62fab73
JB
8358 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
8359 ssid, ssid_len, &req);
bd2522b1
AZ
8360
8361 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
8362 dev->ieee80211_ptr->conn_owner_nlportid =
8363 info->snd_portid;
8364 memcpy(dev->ieee80211_ptr->disconnect_bssid,
8365 bssid, ETH_ALEN);
8366 }
8367
91bf9b26
JB
8368 wdev_unlock(dev->ieee80211_ptr);
8369 }
636a5d36 8370
636a5d36
JM
8371 return err;
8372}
8373
8374static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
8375{
4c476991
JB
8376 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8377 struct net_device *dev = info->user_ptr[1];
19957bb3 8378 const u8 *ie = NULL, *bssid;
91bf9b26 8379 int ie_len = 0, err;
19957bb3 8380 u16 reason_code;
d5cdfacb 8381 bool local_state_change;
636a5d36 8382
f4a11bb0
JB
8383 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8384 return -EINVAL;
8385
8386 if (!info->attrs[NL80211_ATTR_MAC])
8387 return -EINVAL;
8388
8389 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8390 return -EINVAL;
8391
4c476991
JB
8392 if (!rdev->ops->deauth)
8393 return -EOPNOTSUPP;
636a5d36 8394
074ac8df 8395 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8396 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8397 return -EOPNOTSUPP;
eec60b03 8398
19957bb3 8399 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8400
19957bb3
JB
8401 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8402 if (reason_code == 0) {
f4a11bb0 8403 /* Reason Code 0 is reserved */
4c476991 8404 return -EINVAL;
255e737e 8405 }
636a5d36
JM
8406
8407 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8408 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8409 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8410 }
8411
d5cdfacb
JM
8412 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8413
91bf9b26
JB
8414 wdev_lock(dev->ieee80211_ptr);
8415 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
8416 local_state_change);
8417 wdev_unlock(dev->ieee80211_ptr);
8418 return err;
636a5d36
JM
8419}
8420
8421static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
8422{
4c476991
JB
8423 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8424 struct net_device *dev = info->user_ptr[1];
19957bb3 8425 const u8 *ie = NULL, *bssid;
91bf9b26 8426 int ie_len = 0, err;
19957bb3 8427 u16 reason_code;
d5cdfacb 8428 bool local_state_change;
636a5d36 8429
f4a11bb0
JB
8430 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8431 return -EINVAL;
8432
8433 if (!info->attrs[NL80211_ATTR_MAC])
8434 return -EINVAL;
8435
8436 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8437 return -EINVAL;
8438
4c476991
JB
8439 if (!rdev->ops->disassoc)
8440 return -EOPNOTSUPP;
636a5d36 8441
074ac8df 8442 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8443 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8444 return -EOPNOTSUPP;
eec60b03 8445
19957bb3 8446 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8447
19957bb3
JB
8448 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8449 if (reason_code == 0) {
f4a11bb0 8450 /* Reason Code 0 is reserved */
4c476991 8451 return -EINVAL;
255e737e 8452 }
636a5d36
JM
8453
8454 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8455 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8456 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8457 }
8458
d5cdfacb
JM
8459 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8460
91bf9b26
JB
8461 wdev_lock(dev->ieee80211_ptr);
8462 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
8463 local_state_change);
8464 wdev_unlock(dev->ieee80211_ptr);
8465 return err;
636a5d36
JM
8466}
8467
dd5b4cc7
FF
8468static bool
8469nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 8470 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
8471 int rateval)
8472{
8473 struct wiphy *wiphy = &rdev->wiphy;
8474 bool found = false;
8475 int band, i;
8476
57fbcce3 8477 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
8478 struct ieee80211_supported_band *sband;
8479
8480 sband = wiphy->bands[band];
8481 if (!sband)
8482 continue;
8483
8484 for (i = 0; i < sband->n_bitrates; i++) {
8485 if (sband->bitrates[i].bitrate == rateval) {
8486 mcast_rate[band] = i + 1;
8487 found = true;
8488 break;
8489 }
8490 }
8491 }
8492
8493 return found;
8494}
8495
04a773ad
JB
8496static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
8497{
4c476991
JB
8498 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8499 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
8500 struct cfg80211_ibss_params ibss;
8501 struct wiphy *wiphy;
fffd0934 8502 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
8503 int err;
8504
8e30bc55
JB
8505 memset(&ibss, 0, sizeof(ibss));
8506
04a773ad
JB
8507 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8508 return -EINVAL;
8509
683b6d3b 8510 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
8511 !nla_len(info->attrs[NL80211_ATTR_SSID]))
8512 return -EINVAL;
8513
8e30bc55
JB
8514 ibss.beacon_interval = 100;
8515
12d20fc9 8516 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
8517 ibss.beacon_interval =
8518 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 8519
0c317a02
PK
8520 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
8521 ibss.beacon_interval);
12d20fc9
PK
8522 if (err)
8523 return err;
8e30bc55 8524
4c476991
JB
8525 if (!rdev->ops->join_ibss)
8526 return -EOPNOTSUPP;
04a773ad 8527
4c476991
JB
8528 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
8529 return -EOPNOTSUPP;
04a773ad 8530
79c97e97 8531 wiphy = &rdev->wiphy;
04a773ad 8532
39193498 8533 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 8534 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
8535
8536 if (!is_valid_ether_addr(ibss.bssid))
8537 return -EINVAL;
8538 }
04a773ad
JB
8539 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8540 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
8541
8542 if (info->attrs[NL80211_ATTR_IE]) {
8543 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8544 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8545 }
8546
683b6d3b
JB
8547 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
8548 if (err)
8549 return err;
04a773ad 8550
174e0cd2
IP
8551 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
8552 NL80211_IFTYPE_ADHOC))
54858ee5
AS
8553 return -EINVAL;
8554
2f301ab2 8555 switch (ibss.chandef.width) {
bf372645
SW
8556 case NL80211_CHAN_WIDTH_5:
8557 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
8558 case NL80211_CHAN_WIDTH_20_NOHT:
8559 break;
8560 case NL80211_CHAN_WIDTH_20:
8561 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
8562 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8563 return -EINVAL;
8564 break;
8565 case NL80211_CHAN_WIDTH_80:
8566 case NL80211_CHAN_WIDTH_80P80:
8567 case NL80211_CHAN_WIDTH_160:
8568 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8569 return -EINVAL;
8570 if (!wiphy_ext_feature_isset(&rdev->wiphy,
8571 NL80211_EXT_FEATURE_VHT_IBSS))
8572 return -EINVAL;
8573 break;
2f301ab2 8574 default:
c04d6150 8575 return -EINVAL;
2f301ab2 8576 }
db9c64cf 8577
04a773ad 8578 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
8579 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
8580
fbd2c8dc
TP
8581 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
8582 u8 *rates =
8583 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8584 int n_rates =
8585 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8586 struct ieee80211_supported_band *sband =
683b6d3b 8587 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 8588
34850ab2
JB
8589 err = ieee80211_get_ratemask(sband, rates, n_rates,
8590 &ibss.basic_rates);
8591 if (err)
8592 return err;
fbd2c8dc 8593 }
dd5b4cc7 8594
803768f5
SW
8595 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8596 memcpy(&ibss.ht_capa_mask,
8597 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8598 sizeof(ibss.ht_capa_mask));
8599
8600 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
8601 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8602 return -EINVAL;
8603 memcpy(&ibss.ht_capa,
8604 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8605 sizeof(ibss.ht_capa));
8606 }
8607
dd5b4cc7
FF
8608 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
8609 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
8610 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
8611 return -EINVAL;
fbd2c8dc 8612
4c476991 8613 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
8614 bool no_ht = false;
8615
4c476991 8616 connkeys = nl80211_parse_connkeys(rdev,
de7044ee
SM
8617 info->attrs[NL80211_ATTR_KEYS],
8618 &no_ht);
4c476991
JB
8619 if (IS_ERR(connkeys))
8620 return PTR_ERR(connkeys);
de7044ee 8621
3d9d1d66
JB
8622 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
8623 no_ht) {
5e950a78 8624 kzfree(connkeys);
de7044ee
SM
8625 return -EINVAL;
8626 }
4c476991 8627 }
04a773ad 8628
267335d6
AQ
8629 ibss.control_port =
8630 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
8631
5336fa88
SW
8632 ibss.userspace_handles_dfs =
8633 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
8634
4c476991 8635 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 8636 if (err)
b47f610b 8637 kzfree(connkeys);
04a773ad
JB
8638 return err;
8639}
8640
8641static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
8642{
4c476991
JB
8643 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8644 struct net_device *dev = info->user_ptr[1];
04a773ad 8645
4c476991
JB
8646 if (!rdev->ops->leave_ibss)
8647 return -EOPNOTSUPP;
04a773ad 8648
4c476991
JB
8649 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
8650 return -EOPNOTSUPP;
04a773ad 8651
4c476991 8652 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
8653}
8654
f4e583c8
AQ
8655static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
8656{
8657 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8658 struct net_device *dev = info->user_ptr[1];
57fbcce3 8659 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
8660 u32 nla_rate;
8661 int err;
8662
8663 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
8664 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
8665 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
8666 return -EOPNOTSUPP;
8667
8668 if (!rdev->ops->set_mcast_rate)
8669 return -EOPNOTSUPP;
8670
8671 memset(mcast_rate, 0, sizeof(mcast_rate));
8672
8673 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
8674 return -EINVAL;
8675
8676 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
8677 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
8678 return -EINVAL;
8679
a1056b1b 8680 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
8681
8682 return err;
8683}
8684
ad7e718c
JB
8685static struct sk_buff *
8686__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
8687 struct wireless_dev *wdev, int approxlen,
8688 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
8689 enum nl80211_attrs attr,
8690 const struct nl80211_vendor_cmd_info *info,
8691 gfp_t gfp)
ad7e718c
JB
8692{
8693 struct sk_buff *skb;
8694 void *hdr;
8695 struct nlattr *data;
8696
8697 skb = nlmsg_new(approxlen + 100, gfp);
8698 if (!skb)
8699 return NULL;
8700
8701 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
8702 if (!hdr) {
8703 kfree_skb(skb);
8704 return NULL;
8705 }
8706
8707 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
8708 goto nla_put_failure;
567ffc35
JB
8709
8710 if (info) {
8711 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
8712 info->vendor_id))
8713 goto nla_put_failure;
8714 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
8715 info->subcmd))
8716 goto nla_put_failure;
8717 }
8718
6c09e791 8719 if (wdev) {
2dad624e
ND
8720 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
8721 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
8722 goto nla_put_failure;
8723 if (wdev->netdev &&
8724 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
8725 wdev->netdev->ifindex))
8726 goto nla_put_failure;
8727 }
8728
ad7e718c 8729 data = nla_nest_start(skb, attr);
76e1fb4b
JB
8730 if (!data)
8731 goto nla_put_failure;
ad7e718c
JB
8732
8733 ((void **)skb->cb)[0] = rdev;
8734 ((void **)skb->cb)[1] = hdr;
8735 ((void **)skb->cb)[2] = data;
8736
8737 return skb;
8738
8739 nla_put_failure:
8740 kfree_skb(skb);
8741 return NULL;
8742}
f4e583c8 8743
e03ad6ea 8744struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 8745 struct wireless_dev *wdev,
e03ad6ea
JB
8746 enum nl80211_commands cmd,
8747 enum nl80211_attrs attr,
8748 int vendor_event_idx,
8749 int approxlen, gfp_t gfp)
8750{
f26cbf40 8751 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
8752 const struct nl80211_vendor_cmd_info *info;
8753
8754 switch (cmd) {
8755 case NL80211_CMD_TESTMODE:
8756 if (WARN_ON(vendor_event_idx != -1))
8757 return NULL;
8758 info = NULL;
8759 break;
8760 case NL80211_CMD_VENDOR:
8761 if (WARN_ON(vendor_event_idx < 0 ||
8762 vendor_event_idx >= wiphy->n_vendor_events))
8763 return NULL;
8764 info = &wiphy->vendor_events[vendor_event_idx];
8765 break;
8766 default:
8767 WARN_ON(1);
8768 return NULL;
8769 }
8770
6c09e791 8771 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, 0, 0,
e03ad6ea
JB
8772 cmd, attr, info, gfp);
8773}
8774EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
8775
8776void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
8777{
8778 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
8779 void *hdr = ((void **)skb->cb)[1];
8780 struct nlattr *data = ((void **)skb->cb)[2];
8781 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
8782
bd8c78e7
JB
8783 /* clear CB data for netlink core to own from now on */
8784 memset(skb->cb, 0, sizeof(skb->cb));
8785
e03ad6ea
JB
8786 nla_nest_end(skb, data);
8787 genlmsg_end(skb, hdr);
8788
8789 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
8790 mcgrp = NL80211_MCGRP_VENDOR;
8791
8792 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0,
8793 mcgrp, gfp);
8794}
8795EXPORT_SYMBOL(__cfg80211_send_event_skb);
8796
aff89a9b 8797#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
8798static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
8799{
4c476991 8800 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fc73f11f
DS
8801 struct wireless_dev *wdev =
8802 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
aff89a9b
JB
8803 int err;
8804
fc73f11f
DS
8805 if (!rdev->ops->testmode_cmd)
8806 return -EOPNOTSUPP;
8807
8808 if (IS_ERR(wdev)) {
8809 err = PTR_ERR(wdev);
8810 if (err != -EINVAL)
8811 return err;
8812 wdev = NULL;
8813 } else if (wdev->wiphy != &rdev->wiphy) {
8814 return -EINVAL;
8815 }
8816
aff89a9b
JB
8817 if (!info->attrs[NL80211_ATTR_TESTDATA])
8818 return -EINVAL;
8819
ad7e718c 8820 rdev->cur_cmd_info = info;
fc73f11f 8821 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
8822 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
8823 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 8824 rdev->cur_cmd_info = NULL;
aff89a9b 8825
aff89a9b
JB
8826 return err;
8827}
8828
71063f0e
WYG
8829static int nl80211_testmode_dump(struct sk_buff *skb,
8830 struct netlink_callback *cb)
8831{
00918d33 8832 struct cfg80211_registered_device *rdev;
71063f0e
WYG
8833 int err;
8834 long phy_idx;
8835 void *data = NULL;
8836 int data_len = 0;
8837
5fe231e8
JB
8838 rtnl_lock();
8839
71063f0e
WYG
8840 if (cb->args[0]) {
8841 /*
8842 * 0 is a valid index, but not valid for args[0],
8843 * so we need to offset by 1.
8844 */
8845 phy_idx = cb->args[0] - 1;
a4956dca
LC
8846
8847 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
8848 if (!rdev) {
8849 err = -ENOENT;
8850 goto out_err;
8851 }
71063f0e 8852 } else {
c90c39da
JB
8853 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
8854
71063f0e 8855 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
fceb6435
JB
8856 attrbuf, nl80211_fam.maxattr,
8857 nl80211_policy, NULL);
71063f0e 8858 if (err)
5fe231e8 8859 goto out_err;
00918d33 8860
c90c39da 8861 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
2bd7e35d 8862 if (IS_ERR(rdev)) {
5fe231e8
JB
8863 err = PTR_ERR(rdev);
8864 goto out_err;
00918d33 8865 }
2bd7e35d 8866 phy_idx = rdev->wiphy_idx;
2bd7e35d 8867
c90c39da
JB
8868 if (attrbuf[NL80211_ATTR_TESTDATA])
8869 cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
71063f0e
WYG
8870 }
8871
8872 if (cb->args[1]) {
8873 data = nla_data((void *)cb->args[1]);
8874 data_len = nla_len((void *)cb->args[1]);
8875 }
8876
00918d33 8877 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
8878 err = -EOPNOTSUPP;
8879 goto out_err;
8880 }
8881
8882 while (1) {
15e47304 8883 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
8884 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8885 NL80211_CMD_TESTMODE);
8886 struct nlattr *tmdata;
8887
cb35fba3
DC
8888 if (!hdr)
8889 break;
8890
9360ffd1 8891 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
8892 genlmsg_cancel(skb, hdr);
8893 break;
8894 }
8895
8896 tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
8897 if (!tmdata) {
8898 genlmsg_cancel(skb, hdr);
8899 break;
8900 }
e35e4d28 8901 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
8902 nla_nest_end(skb, tmdata);
8903
8904 if (err == -ENOBUFS || err == -ENOENT) {
8905 genlmsg_cancel(skb, hdr);
8906 break;
8907 } else if (err) {
8908 genlmsg_cancel(skb, hdr);
8909 goto out_err;
8910 }
8911
8912 genlmsg_end(skb, hdr);
8913 }
8914
8915 err = skb->len;
8916 /* see above */
8917 cb->args[0] = phy_idx + 1;
8918 out_err:
5fe231e8 8919 rtnl_unlock();
71063f0e
WYG
8920 return err;
8921}
aff89a9b
JB
8922#endif
8923
b23aa676
SO
8924static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
8925{
4c476991
JB
8926 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8927 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
8928 struct cfg80211_connect_params connect;
8929 struct wiphy *wiphy;
fffd0934 8930 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
8931 int err;
8932
8933 memset(&connect, 0, sizeof(connect));
8934
8935 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8936 return -EINVAL;
8937
8938 if (!info->attrs[NL80211_ATTR_SSID] ||
8939 !nla_len(info->attrs[NL80211_ATTR_SSID]))
8940 return -EINVAL;
8941
8942 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
8943 connect.auth_type =
8944 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
8945 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
8946 NL80211_CMD_CONNECT))
b23aa676
SO
8947 return -EINVAL;
8948 } else
8949 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
8950
8951 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
8952
3a00df57
AS
8953 if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
8954 !wiphy_ext_feature_isset(&rdev->wiphy,
8955 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
8956 return -EINVAL;
8957 connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
8958
c0692b8f 8959 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 8960 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
8961 if (err)
8962 return err;
b23aa676 8963
074ac8df 8964 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8965 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8966 return -EOPNOTSUPP;
b23aa676 8967
79c97e97 8968 wiphy = &rdev->wiphy;
b23aa676 8969
4486ea98
BS
8970 connect.bg_scan_period = -1;
8971 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
8972 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
8973 connect.bg_scan_period =
8974 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
8975 }
8976
b23aa676
SO
8977 if (info->attrs[NL80211_ATTR_MAC])
8978 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
8979 else if (info->attrs[NL80211_ATTR_MAC_HINT])
8980 connect.bssid_hint =
8981 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
8982 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8983 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
8984
8985 if (info->attrs[NL80211_ATTR_IE]) {
8986 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8987 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8988 }
8989
cee00a95
JM
8990 if (info->attrs[NL80211_ATTR_USE_MFP]) {
8991 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
65026002
EG
8992 if (connect.mfp == NL80211_MFP_OPTIONAL &&
8993 !wiphy_ext_feature_isset(&rdev->wiphy,
8994 NL80211_EXT_FEATURE_MFP_OPTIONAL))
8995 return -EOPNOTSUPP;
8996
cee00a95 8997 if (connect.mfp != NL80211_MFP_REQUIRED &&
65026002
EG
8998 connect.mfp != NL80211_MFP_NO &&
8999 connect.mfp != NL80211_MFP_OPTIONAL)
cee00a95
JM
9000 return -EINVAL;
9001 } else {
9002 connect.mfp = NL80211_MFP_NO;
9003 }
9004
ba6fbacf
JM
9005 if (info->attrs[NL80211_ATTR_PREV_BSSID])
9006 connect.prev_bssid =
9007 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
9008
b23aa676 9009 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
664834de
JM
9010 connect.channel = nl80211_get_valid_chan(
9011 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
9012 if (!connect.channel)
1df4a510
JM
9013 return -EINVAL;
9014 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
664834de
JM
9015 connect.channel_hint = nl80211_get_valid_chan(
9016 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
9017 if (!connect.channel_hint)
4c476991 9018 return -EINVAL;
b23aa676
SO
9019 }
9020
fffd0934
JB
9021 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
9022 connkeys = nl80211_parse_connkeys(rdev,
de7044ee 9023 info->attrs[NL80211_ATTR_KEYS], NULL);
4c476991
JB
9024 if (IS_ERR(connkeys))
9025 return PTR_ERR(connkeys);
fffd0934
JB
9026 }
9027
7e7c8926
BG
9028 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
9029 connect.flags |= ASSOC_REQ_DISABLE_HT;
9030
9031 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
9032 memcpy(&connect.ht_capa_mask,
9033 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
9034 sizeof(connect.ht_capa_mask));
9035
9036 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 9037 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
b47f610b 9038 kzfree(connkeys);
7e7c8926 9039 return -EINVAL;
b4e4f47e 9040 }
7e7c8926
BG
9041 memcpy(&connect.ht_capa,
9042 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
9043 sizeof(connect.ht_capa));
9044 }
9045
ee2aca34
JB
9046 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
9047 connect.flags |= ASSOC_REQ_DISABLE_VHT;
9048
9049 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
9050 memcpy(&connect.vht_capa_mask,
9051 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
9052 sizeof(connect.vht_capa_mask));
9053
9054 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
9055 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
b47f610b 9056 kzfree(connkeys);
ee2aca34
JB
9057 return -EINVAL;
9058 }
9059 memcpy(&connect.vht_capa,
9060 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
9061 sizeof(connect.vht_capa));
9062 }
9063
bab5ab7d 9064 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
9065 if (!((rdev->wiphy.features &
9066 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
9067 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
9068 !wiphy_ext_feature_isset(&rdev->wiphy,
9069 NL80211_EXT_FEATURE_RRM)) {
707554b4 9070 kzfree(connkeys);
bab5ab7d 9071 return -EINVAL;
707554b4 9072 }
bab5ab7d
AK
9073 connect.flags |= ASSOC_REQ_USE_RRM;
9074 }
9075
34d50519 9076 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 9077 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
34d50519
LD
9078 kzfree(connkeys);
9079 return -EOPNOTSUPP;
9080 }
9081
38de03d2
AS
9082 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
9083 /* bss selection makes no sense if bssid is set */
9084 if (connect.bssid) {
9085 kzfree(connkeys);
9086 return -EINVAL;
9087 }
9088
9089 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
9090 wiphy, &connect.bss_select);
9091 if (err) {
9092 kzfree(connkeys);
9093 return err;
9094 }
9095 }
9096
a3caf744
VK
9097 if (wiphy_ext_feature_isset(&rdev->wiphy,
9098 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
9099 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
9100 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
9101 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
9102 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9103 connect.fils_erp_username =
9104 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9105 connect.fils_erp_username_len =
9106 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9107 connect.fils_erp_realm =
9108 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9109 connect.fils_erp_realm_len =
9110 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9111 connect.fils_erp_next_seq_num =
9112 nla_get_u16(
9113 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
9114 connect.fils_erp_rrk =
9115 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9116 connect.fils_erp_rrk_len =
9117 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9118 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
9119 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
9120 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
9121 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9122 kzfree(connkeys);
9123 return -EINVAL;
9124 }
9125
83739b03 9126 wdev_lock(dev->ieee80211_ptr);
bd2522b1 9127
4ce2bd9c
JM
9128 err = cfg80211_connect(rdev, dev, &connect, connkeys,
9129 connect.prev_bssid);
fffd0934 9130 if (err)
b47f610b 9131 kzfree(connkeys);
bd2522b1
AZ
9132
9133 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
9134 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
9135 if (connect.bssid)
9136 memcpy(dev->ieee80211_ptr->disconnect_bssid,
9137 connect.bssid, ETH_ALEN);
9138 else
9139 memset(dev->ieee80211_ptr->disconnect_bssid,
9140 0, ETH_ALEN);
9141 }
9142
9143 wdev_unlock(dev->ieee80211_ptr);
9144
b23aa676
SO
9145 return err;
9146}
9147
088e8df8 9148static int nl80211_update_connect_params(struct sk_buff *skb,
9149 struct genl_info *info)
9150{
9151 struct cfg80211_connect_params connect = {};
9152 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9153 struct net_device *dev = info->user_ptr[1];
9154 struct wireless_dev *wdev = dev->ieee80211_ptr;
9155 u32 changed = 0;
9156 int ret;
9157
9158 if (!rdev->ops->update_connect_params)
9159 return -EOPNOTSUPP;
9160
9161 if (info->attrs[NL80211_ATTR_IE]) {
9162 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
9163 return -EINVAL;
9164 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9165 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9166 changed |= UPDATE_ASSOC_IES;
9167 }
9168
9169 wdev_lock(dev->ieee80211_ptr);
9170 if (!wdev->current_bss)
9171 ret = -ENOLINK;
9172 else
9173 ret = rdev_update_connect_params(rdev, dev, &connect, changed);
9174 wdev_unlock(dev->ieee80211_ptr);
9175
9176 return ret;
9177}
9178
b23aa676
SO
9179static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
9180{
4c476991
JB
9181 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9182 struct net_device *dev = info->user_ptr[1];
b23aa676 9183 u16 reason;
83739b03 9184 int ret;
b23aa676
SO
9185
9186 if (!info->attrs[NL80211_ATTR_REASON_CODE])
9187 reason = WLAN_REASON_DEAUTH_LEAVING;
9188 else
9189 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
9190
9191 if (reason == 0)
9192 return -EINVAL;
9193
074ac8df 9194 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9195 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9196 return -EOPNOTSUPP;
b23aa676 9197
83739b03
JB
9198 wdev_lock(dev->ieee80211_ptr);
9199 ret = cfg80211_disconnect(rdev, dev, reason, true);
9200 wdev_unlock(dev->ieee80211_ptr);
9201 return ret;
b23aa676
SO
9202}
9203
463d0183
JB
9204static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
9205{
4c476991 9206 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
9207 struct net *net;
9208 int err;
463d0183 9209
4b681c82
VK
9210 if (info->attrs[NL80211_ATTR_PID]) {
9211 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
9212
9213 net = get_net_ns_by_pid(pid);
9214 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
9215 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 9216
4b681c82
VK
9217 net = get_net_ns_by_fd(fd);
9218 } else {
9219 return -EINVAL;
9220 }
463d0183 9221
4c476991
JB
9222 if (IS_ERR(net))
9223 return PTR_ERR(net);
463d0183
JB
9224
9225 err = 0;
9226
9227 /* check if anything to do */
4c476991
JB
9228 if (!net_eq(wiphy_net(&rdev->wiphy), net))
9229 err = cfg80211_switch_netns(rdev, net);
463d0183 9230
463d0183 9231 put_net(net);
463d0183
JB
9232 return err;
9233}
9234
67fbb16b
SO
9235static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
9236{
4c476991 9237 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
9238 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
9239 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 9240 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
9241 struct cfg80211_pmksa pmksa;
9242
9243 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
9244
67fbb16b
SO
9245 if (!info->attrs[NL80211_ATTR_PMKID])
9246 return -EINVAL;
9247
67fbb16b 9248 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
a3caf744
VK
9249
9250 if (info->attrs[NL80211_ATTR_MAC]) {
9251 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
9252 } else if (info->attrs[NL80211_ATTR_SSID] &&
9253 info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
9254 (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
9255 info->attrs[NL80211_ATTR_PMK])) {
9256 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9257 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
9258 pmksa.cache_id =
9259 nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
9260 } else {
9261 return -EINVAL;
9262 }
9263 if (info->attrs[NL80211_ATTR_PMK]) {
9264 pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
9265 pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
9266 }
67fbb16b 9267
074ac8df 9268 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9269 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9270 return -EOPNOTSUPP;
67fbb16b
SO
9271
9272 switch (info->genlhdr->cmd) {
9273 case NL80211_CMD_SET_PMKSA:
9274 rdev_ops = rdev->ops->set_pmksa;
9275 break;
9276 case NL80211_CMD_DEL_PMKSA:
9277 rdev_ops = rdev->ops->del_pmksa;
9278 break;
9279 default:
9280 WARN_ON(1);
9281 break;
9282 }
9283
4c476991
JB
9284 if (!rdev_ops)
9285 return -EOPNOTSUPP;
67fbb16b 9286
4c476991 9287 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
9288}
9289
9290static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
9291{
4c476991
JB
9292 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9293 struct net_device *dev = info->user_ptr[1];
67fbb16b 9294
074ac8df 9295 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9296 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9297 return -EOPNOTSUPP;
67fbb16b 9298
4c476991
JB
9299 if (!rdev->ops->flush_pmksa)
9300 return -EOPNOTSUPP;
67fbb16b 9301
e35e4d28 9302 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
9303}
9304
109086ce
AN
9305static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
9306{
9307 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9308 struct net_device *dev = info->user_ptr[1];
9309 u8 action_code, dialog_token;
df942e7b 9310 u32 peer_capability = 0;
109086ce
AN
9311 u16 status_code;
9312 u8 *peer;
31fa97c5 9313 bool initiator;
109086ce
AN
9314
9315 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
9316 !rdev->ops->tdls_mgmt)
9317 return -EOPNOTSUPP;
9318
9319 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
9320 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
9321 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
9322 !info->attrs[NL80211_ATTR_IE] ||
9323 !info->attrs[NL80211_ATTR_MAC])
9324 return -EINVAL;
9325
9326 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
9327 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
9328 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
9329 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 9330 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
9331 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
9332 peer_capability =
9333 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 9334
e35e4d28 9335 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 9336 dialog_token, status_code, peer_capability,
31fa97c5 9337 initiator,
e35e4d28
HG
9338 nla_data(info->attrs[NL80211_ATTR_IE]),
9339 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
9340}
9341
9342static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
9343{
9344 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9345 struct net_device *dev = info->user_ptr[1];
9346 enum nl80211_tdls_operation operation;
9347 u8 *peer;
9348
9349 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
9350 !rdev->ops->tdls_oper)
9351 return -EOPNOTSUPP;
9352
9353 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
9354 !info->attrs[NL80211_ATTR_MAC])
9355 return -EINVAL;
9356
9357 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
9358 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
9359
e35e4d28 9360 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
9361}
9362
9588bbd5
JM
9363static int nl80211_remain_on_channel(struct sk_buff *skb,
9364 struct genl_info *info)
9365{
4c476991 9366 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9367 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 9368 struct cfg80211_chan_def chandef;
34373d12 9369 const struct cfg80211_chan_def *compat_chandef;
9588bbd5
JM
9370 struct sk_buff *msg;
9371 void *hdr;
9372 u64 cookie;
683b6d3b 9373 u32 duration;
9588bbd5
JM
9374 int err;
9375
9376 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
9377 !info->attrs[NL80211_ATTR_DURATION])
9378 return -EINVAL;
9379
9380 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
9381
ebf348fc
JB
9382 if (!rdev->ops->remain_on_channel ||
9383 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
9384 return -EOPNOTSUPP;
9385
9588bbd5 9386 /*
ebf348fc
JB
9387 * We should be on that channel for at least a minimum amount of
9388 * time (10ms) but no longer than the driver supports.
9588bbd5 9389 */
ebf348fc 9390 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 9391 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
9392 return -EINVAL;
9393
683b6d3b
JB
9394 err = nl80211_parse_chandef(rdev, info, &chandef);
9395 if (err)
9396 return err;
9588bbd5 9397
34373d12
VT
9398 wdev_lock(wdev);
9399 if (!cfg80211_off_channel_oper_allowed(wdev) &&
9400 !cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
9401 compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
9402 &chandef);
9403 if (compat_chandef != &chandef) {
9404 wdev_unlock(wdev);
9405 return -EBUSY;
9406 }
9407 }
9408 wdev_unlock(wdev);
9409
9588bbd5 9410 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
9411 if (!msg)
9412 return -ENOMEM;
9588bbd5 9413
15e47304 9414 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 9415 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
9416 if (!hdr) {
9417 err = -ENOBUFS;
9588bbd5
JM
9418 goto free_msg;
9419 }
9420
683b6d3b
JB
9421 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
9422 duration, &cookie);
9588bbd5
JM
9423
9424 if (err)
9425 goto free_msg;
9426
2dad624e
ND
9427 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
9428 NL80211_ATTR_PAD))
9360ffd1 9429 goto nla_put_failure;
9588bbd5
JM
9430
9431 genlmsg_end(msg, hdr);
4c476991
JB
9432
9433 return genlmsg_reply(msg, info);
9588bbd5
JM
9434
9435 nla_put_failure:
9436 err = -ENOBUFS;
9437 free_msg:
9438 nlmsg_free(msg);
9588bbd5
JM
9439 return err;
9440}
9441
9442static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
9443 struct genl_info *info)
9444{
4c476991 9445 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9446 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 9447 u64 cookie;
9588bbd5
JM
9448
9449 if (!info->attrs[NL80211_ATTR_COOKIE])
9450 return -EINVAL;
9451
4c476991
JB
9452 if (!rdev->ops->cancel_remain_on_channel)
9453 return -EOPNOTSUPP;
9588bbd5 9454
9588bbd5
JM
9455 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9456
e35e4d28 9457 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
9458}
9459
13ae75b1
JM
9460static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
9461 struct genl_info *info)
9462{
13ae75b1 9463 struct cfg80211_bitrate_mask mask;
a7c7fbff 9464 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 9465 struct net_device *dev = info->user_ptr[1];
a7c7fbff 9466 int err;
13ae75b1 9467
4c476991
JB
9468 if (!rdev->ops->set_bitrate_mask)
9469 return -EOPNOTSUPP;
13ae75b1 9470
a7c7fbff
PK
9471 err = nl80211_parse_tx_bitrate_mask(info, &mask);
9472 if (err)
9473 return err;
13ae75b1 9474
e35e4d28 9475 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
9476}
9477
2e161f78 9478static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 9479{
4c476991 9480 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9481 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 9482 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
9483
9484 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
9485 return -EINVAL;
9486
2e161f78
JB
9487 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
9488 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 9489
71bbc994
JB
9490 switch (wdev->iftype) {
9491 case NL80211_IFTYPE_STATION:
9492 case NL80211_IFTYPE_ADHOC:
9493 case NL80211_IFTYPE_P2P_CLIENT:
9494 case NL80211_IFTYPE_AP:
9495 case NL80211_IFTYPE_AP_VLAN:
9496 case NL80211_IFTYPE_MESH_POINT:
9497 case NL80211_IFTYPE_P2P_GO:
98104fde 9498 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 9499 break;
cb3b7d87 9500 case NL80211_IFTYPE_NAN:
71bbc994 9501 default:
4c476991 9502 return -EOPNOTSUPP;
71bbc994 9503 }
026331c4
JM
9504
9505 /* not much point in registering if we can't reply */
4c476991
JB
9506 if (!rdev->ops->mgmt_tx)
9507 return -EOPNOTSUPP;
026331c4 9508
15e47304 9509 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
026331c4
JM
9510 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
9511 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
026331c4
JM
9512}
9513
2e161f78 9514static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 9515{
4c476991 9516 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9517 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 9518 struct cfg80211_chan_def chandef;
026331c4 9519 int err;
d64d373f 9520 void *hdr = NULL;
026331c4 9521 u64 cookie;
e247bd90 9522 struct sk_buff *msg = NULL;
b176e629
AO
9523 struct cfg80211_mgmt_tx_params params = {
9524 .dont_wait_for_ack =
9525 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
9526 };
026331c4 9527
683b6d3b 9528 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
9529 return -EINVAL;
9530
4c476991
JB
9531 if (!rdev->ops->mgmt_tx)
9532 return -EOPNOTSUPP;
026331c4 9533
71bbc994 9534 switch (wdev->iftype) {
ea141b75
AQ
9535 case NL80211_IFTYPE_P2P_DEVICE:
9536 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
9537 return -EINVAL;
71bbc994
JB
9538 case NL80211_IFTYPE_STATION:
9539 case NL80211_IFTYPE_ADHOC:
9540 case NL80211_IFTYPE_P2P_CLIENT:
9541 case NL80211_IFTYPE_AP:
9542 case NL80211_IFTYPE_AP_VLAN:
9543 case NL80211_IFTYPE_MESH_POINT:
9544 case NL80211_IFTYPE_P2P_GO:
9545 break;
cb3b7d87 9546 case NL80211_IFTYPE_NAN:
71bbc994 9547 default:
4c476991 9548 return -EOPNOTSUPP;
71bbc994 9549 }
026331c4 9550
f7ca38df 9551 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 9552 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 9553 return -EINVAL;
b176e629 9554 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
9555
9556 /*
9557 * We should wait on the channel for at least a minimum amount
9558 * of time (10ms) but no longer than the driver supports.
9559 */
b176e629
AO
9560 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
9561 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 9562 return -EINVAL;
f7ca38df
JB
9563 }
9564
b176e629 9565 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 9566
b176e629 9567 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
9568 return -EINVAL;
9569
b176e629 9570 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 9571
ea141b75
AQ
9572 /* get the channel if any has been specified, otherwise pass NULL to
9573 * the driver. The latter will use the current one
9574 */
9575 chandef.chan = NULL;
9576 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
9577 err = nl80211_parse_chandef(rdev, info, &chandef);
9578 if (err)
9579 return err;
9580 }
9581
b176e629 9582 if (!chandef.chan && params.offchan)
ea141b75 9583 return -EINVAL;
026331c4 9584
34373d12
VT
9585 wdev_lock(wdev);
9586 if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
9587 wdev_unlock(wdev);
9588 return -EBUSY;
9589 }
9590 wdev_unlock(wdev);
9591
34d22ce2
AO
9592 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
9593 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
9594
9595 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
9596 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
9597 int i;
9598
9599 if (len % sizeof(u16))
9600 return -EINVAL;
9601
9602 params.n_csa_offsets = len / sizeof(u16);
9603 params.csa_offsets =
9604 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
9605
9606 /* check that all the offsets fit the frame */
9607 for (i = 0; i < params.n_csa_offsets; i++) {
9608 if (params.csa_offsets[i] >= params.len)
9609 return -EINVAL;
9610 }
9611 }
9612
b176e629 9613 if (!params.dont_wait_for_ack) {
e247bd90
JB
9614 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9615 if (!msg)
9616 return -ENOMEM;
026331c4 9617
15e47304 9618 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 9619 NL80211_CMD_FRAME);
cb35fba3
DC
9620 if (!hdr) {
9621 err = -ENOBUFS;
e247bd90
JB
9622 goto free_msg;
9623 }
026331c4 9624 }
e247bd90 9625
b176e629
AO
9626 params.chan = chandef.chan;
9627 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
9628 if (err)
9629 goto free_msg;
9630
e247bd90 9631 if (msg) {
2dad624e
ND
9632 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
9633 NL80211_ATTR_PAD))
9360ffd1 9634 goto nla_put_failure;
026331c4 9635
e247bd90
JB
9636 genlmsg_end(msg, hdr);
9637 return genlmsg_reply(msg, info);
9638 }
9639
9640 return 0;
026331c4
JM
9641
9642 nla_put_failure:
9643 err = -ENOBUFS;
9644 free_msg:
9645 nlmsg_free(msg);
026331c4
JM
9646 return err;
9647}
9648
f7ca38df
JB
9649static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
9650{
9651 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9652 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
9653 u64 cookie;
9654
9655 if (!info->attrs[NL80211_ATTR_COOKIE])
9656 return -EINVAL;
9657
9658 if (!rdev->ops->mgmt_tx_cancel_wait)
9659 return -EOPNOTSUPP;
9660
71bbc994
JB
9661 switch (wdev->iftype) {
9662 case NL80211_IFTYPE_STATION:
9663 case NL80211_IFTYPE_ADHOC:
9664 case NL80211_IFTYPE_P2P_CLIENT:
9665 case NL80211_IFTYPE_AP:
9666 case NL80211_IFTYPE_AP_VLAN:
9667 case NL80211_IFTYPE_P2P_GO:
98104fde 9668 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 9669 break;
cb3b7d87 9670 case NL80211_IFTYPE_NAN:
71bbc994 9671 default:
f7ca38df 9672 return -EOPNOTSUPP;
71bbc994 9673 }
f7ca38df
JB
9674
9675 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9676
e35e4d28 9677 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
9678}
9679
ffb9eb3d
KV
9680static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
9681{
4c476991 9682 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 9683 struct wireless_dev *wdev;
4c476991 9684 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
9685 u8 ps_state;
9686 bool state;
9687 int err;
9688
4c476991
JB
9689 if (!info->attrs[NL80211_ATTR_PS_STATE])
9690 return -EINVAL;
ffb9eb3d
KV
9691
9692 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
9693
4c476991
JB
9694 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
9695 return -EINVAL;
ffb9eb3d
KV
9696
9697 wdev = dev->ieee80211_ptr;
9698
4c476991
JB
9699 if (!rdev->ops->set_power_mgmt)
9700 return -EOPNOTSUPP;
ffb9eb3d
KV
9701
9702 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
9703
9704 if (state == wdev->ps)
4c476991 9705 return 0;
ffb9eb3d 9706
e35e4d28 9707 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
9708 if (!err)
9709 wdev->ps = state;
ffb9eb3d
KV
9710 return err;
9711}
9712
9713static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
9714{
4c476991 9715 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
9716 enum nl80211_ps_state ps_state;
9717 struct wireless_dev *wdev;
4c476991 9718 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
9719 struct sk_buff *msg;
9720 void *hdr;
9721 int err;
9722
ffb9eb3d
KV
9723 wdev = dev->ieee80211_ptr;
9724
4c476991
JB
9725 if (!rdev->ops->set_power_mgmt)
9726 return -EOPNOTSUPP;
ffb9eb3d
KV
9727
9728 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
9729 if (!msg)
9730 return -ENOMEM;
ffb9eb3d 9731
15e47304 9732 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
9733 NL80211_CMD_GET_POWER_SAVE);
9734 if (!hdr) {
4c476991 9735 err = -ENOBUFS;
ffb9eb3d
KV
9736 goto free_msg;
9737 }
9738
9739 if (wdev->ps)
9740 ps_state = NL80211_PS_ENABLED;
9741 else
9742 ps_state = NL80211_PS_DISABLED;
9743
9360ffd1
DM
9744 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
9745 goto nla_put_failure;
ffb9eb3d
KV
9746
9747 genlmsg_end(msg, hdr);
4c476991 9748 return genlmsg_reply(msg, info);
ffb9eb3d 9749
4c476991 9750 nla_put_failure:
ffb9eb3d 9751 err = -ENOBUFS;
4c476991 9752 free_msg:
ffb9eb3d 9753 nlmsg_free(msg);
ffb9eb3d
KV
9754 return err;
9755}
9756
94e860f1
JB
9757static const struct nla_policy
9758nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
4a4b8169 9759 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
d6dc1a38
JO
9760 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
9761 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
9762 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
9763 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
9764 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
bee427b8 9765 [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 },
d6dc1a38
JO
9766};
9767
84f10708 9768static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 9769 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
9770{
9771 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 9772 struct net_device *dev = info->user_ptr[1];
1da5fcc8 9773 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 9774
d9d8b019 9775 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
9776 return -EINVAL;
9777
84f10708
TP
9778 if (!rdev->ops->set_cqm_txe_config)
9779 return -EOPNOTSUPP;
9780
9781 if (wdev->iftype != NL80211_IFTYPE_STATION &&
9782 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
9783 return -EOPNOTSUPP;
9784
e35e4d28 9785 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
9786}
9787
4a4b8169
AZ
9788static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
9789 struct net_device *dev)
9790{
9791 struct wireless_dev *wdev = dev->ieee80211_ptr;
9792 s32 last, low, high;
9793 u32 hyst;
9794 int i, n;
9795 int err;
9796
9797 /* RSSI reporting disabled? */
9798 if (!wdev->cqm_config)
9799 return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
9800
9801 /*
9802 * Obtain current RSSI value if possible, if not and no RSSI threshold
9803 * event has been received yet, we should receive an event after a
9804 * connection is established and enough beacons received to calculate
9805 * the average.
9806 */
9807 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
9808 rdev->ops->get_station) {
9809 struct station_info sinfo;
9810 u8 *mac_addr;
9811
9812 mac_addr = wdev->current_bss->pub.bssid;
9813
9814 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
9815 if (err)
9816 return err;
9817
9818 if (sinfo.filled & BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
9819 wdev->cqm_config->last_rssi_event_value =
9820 (s8) sinfo.rx_beacon_signal_avg;
9821 }
9822
9823 last = wdev->cqm_config->last_rssi_event_value;
9824 hyst = wdev->cqm_config->rssi_hyst;
9825 n = wdev->cqm_config->n_rssi_thresholds;
9826
9827 for (i = 0; i < n; i++)
9828 if (last < wdev->cqm_config->rssi_thresholds[i])
9829 break;
9830
9831 low = i > 0 ?
9832 (wdev->cqm_config->rssi_thresholds[i - 1] - hyst) : S32_MIN;
9833 high = i < n ?
9834 (wdev->cqm_config->rssi_thresholds[i] + hyst - 1) : S32_MAX;
9835
9836 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
9837}
9838
d6dc1a38 9839static int nl80211_set_cqm_rssi(struct genl_info *info,
4a4b8169
AZ
9840 const s32 *thresholds, int n_thresholds,
9841 u32 hysteresis)
d6dc1a38 9842{
4c476991 9843 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 9844 struct net_device *dev = info->user_ptr[1];
1da5fcc8 9845 struct wireless_dev *wdev = dev->ieee80211_ptr;
4a4b8169
AZ
9846 int i, err;
9847 s32 prev = S32_MIN;
d6dc1a38 9848
4a4b8169
AZ
9849 /* Check all values negative and sorted */
9850 for (i = 0; i < n_thresholds; i++) {
9851 if (thresholds[i] > 0 || thresholds[i] <= prev)
9852 return -EINVAL;
d6dc1a38 9853
4a4b8169
AZ
9854 prev = thresholds[i];
9855 }
d6dc1a38 9856
074ac8df 9857 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9858 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
9859 return -EOPNOTSUPP;
d6dc1a38 9860
4a4b8169
AZ
9861 wdev_lock(wdev);
9862 cfg80211_cqm_config_free(wdev);
9863 wdev_unlock(wdev);
9864
9865 if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
9866 if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
9867 return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
9868
9869 return rdev_set_cqm_rssi_config(rdev, dev,
9870 thresholds[0], hysteresis);
9871 }
9872
9873 if (!wiphy_ext_feature_isset(&rdev->wiphy,
9874 NL80211_EXT_FEATURE_CQM_RSSI_LIST))
9875 return -EOPNOTSUPP;
9876
9877 if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
9878 n_thresholds = 0;
9879
9880 wdev_lock(wdev);
9881 if (n_thresholds) {
9882 struct cfg80211_cqm_config *cqm_config;
9883
9884 cqm_config = kzalloc(sizeof(struct cfg80211_cqm_config) +
9885 n_thresholds * sizeof(s32), GFP_KERNEL);
9886 if (!cqm_config) {
9887 err = -ENOMEM;
9888 goto unlock;
9889 }
9890
9891 cqm_config->rssi_hyst = hysteresis;
9892 cqm_config->n_rssi_thresholds = n_thresholds;
9893 memcpy(cqm_config->rssi_thresholds, thresholds,
9894 n_thresholds * sizeof(s32));
9895
9896 wdev->cqm_config = cqm_config;
9897 }
9898
9899 err = cfg80211_cqm_rssi_update(rdev, dev);
9900
9901unlock:
9902 wdev_unlock(wdev);
9903
9904 return err;
d6dc1a38
JO
9905}
9906
9907static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
9908{
9909 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
9910 struct nlattr *cqm;
9911 int err;
9912
9913 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
9914 if (!cqm)
9915 return -EINVAL;
d6dc1a38
JO
9916
9917 err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
fe52145f 9918 nl80211_attr_cqm_policy, info->extack);
d6dc1a38 9919 if (err)
1da5fcc8 9920 return err;
d6dc1a38
JO
9921
9922 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
9923 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
4a4b8169
AZ
9924 const s32 *thresholds =
9925 nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
9926 int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
1da5fcc8 9927 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 9928
4a4b8169
AZ
9929 if (len % 4)
9930 return -EINVAL;
9931
9932 return nl80211_set_cqm_rssi(info, thresholds, len / 4,
9933 hysteresis);
1da5fcc8
JB
9934 }
9935
9936 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
9937 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
9938 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
9939 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
9940 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
9941 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
9942
9943 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
9944 }
9945
9946 return -EINVAL;
d6dc1a38
JO
9947}
9948
6e0bd6c3
RL
9949static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
9950{
9951 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9952 struct net_device *dev = info->user_ptr[1];
9953 struct ocb_setup setup = {};
9954 int err;
9955
9956 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
9957 if (err)
9958 return err;
9959
9960 return cfg80211_join_ocb(rdev, dev, &setup);
9961}
9962
9963static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
9964{
9965 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9966 struct net_device *dev = info->user_ptr[1];
9967
9968 return cfg80211_leave_ocb(rdev, dev);
9969}
9970
29cbe68c
JB
9971static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
9972{
9973 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9974 struct net_device *dev = info->user_ptr[1];
9975 struct mesh_config cfg;
c80d545d 9976 struct mesh_setup setup;
29cbe68c
JB
9977 int err;
9978
9979 /* start with default */
9980 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 9981 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 9982
24bdd9f4 9983 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 9984 /* and parse parameters if given */
24bdd9f4 9985 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
9986 if (err)
9987 return err;
9988 }
9989
9990 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
9991 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
9992 return -EINVAL;
9993
c80d545d
JC
9994 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
9995 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
9996
4bb62344
CYY
9997 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
9998 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
9999 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
10000 return -EINVAL;
10001
9bdbf04d
MP
10002 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
10003 setup.beacon_interval =
10004 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 10005
0c317a02
PK
10006 err = cfg80211_validate_beacon_int(rdev,
10007 NL80211_IFTYPE_MESH_POINT,
10008 setup.beacon_interval);
12d20fc9
PK
10009 if (err)
10010 return err;
9bdbf04d
MP
10011 }
10012
10013 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
10014 setup.dtim_period =
10015 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
10016 if (setup.dtim_period < 1 || setup.dtim_period > 100)
10017 return -EINVAL;
10018 }
10019
c80d545d
JC
10020 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
10021 /* parse additional setup parameters if given */
10022 err = nl80211_parse_mesh_setup(info, &setup);
10023 if (err)
10024 return err;
10025 }
10026
d37bb18a
TP
10027 if (setup.user_mpm)
10028 cfg.auto_open_plinks = false;
10029
cc1d2806 10030 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
10031 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
10032 if (err)
10033 return err;
cc1d2806
JB
10034 } else {
10035 /* cfg80211_join_mesh() will sort it out */
683b6d3b 10036 setup.chandef.chan = NULL;
cc1d2806
JB
10037 }
10038
ffb3cf30
AN
10039 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
10040 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10041 int n_rates =
10042 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10043 struct ieee80211_supported_band *sband;
10044
10045 if (!setup.chandef.chan)
10046 return -EINVAL;
10047
10048 sband = rdev->wiphy.bands[setup.chandef.chan->band];
10049
10050 err = ieee80211_get_ratemask(sband, rates, n_rates,
10051 &setup.basic_rates);
10052 if (err)
10053 return err;
10054 }
10055
8564e382
JB
10056 if (info->attrs[NL80211_ATTR_TX_RATES]) {
10057 err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate);
10058 if (err)
10059 return err;
10060
265698d7
JB
10061 if (!setup.chandef.chan)
10062 return -EINVAL;
10063
8564e382
JB
10064 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
10065 &setup.beacon_rate);
10066 if (err)
10067 return err;
10068 }
10069
d37d49c2
BB
10070 setup.userspace_handles_dfs =
10071 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
10072
c80d545d 10073 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
29cbe68c
JB
10074}
10075
10076static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
10077{
10078 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10079 struct net_device *dev = info->user_ptr[1];
10080
10081 return cfg80211_leave_mesh(rdev, dev);
10082}
10083
dfb89c56 10084#ifdef CONFIG_PM
bb92d199
AK
10085static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
10086 struct cfg80211_registered_device *rdev)
10087{
6abb9cb9 10088 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
10089 struct nlattr *nl_pats, *nl_pat;
10090 int i, pat_len;
10091
6abb9cb9 10092 if (!wowlan->n_patterns)
bb92d199
AK
10093 return 0;
10094
10095 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
10096 if (!nl_pats)
10097 return -ENOBUFS;
10098
6abb9cb9 10099 for (i = 0; i < wowlan->n_patterns; i++) {
bb92d199
AK
10100 nl_pat = nla_nest_start(msg, i + 1);
10101 if (!nl_pat)
10102 return -ENOBUFS;
6abb9cb9 10103 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 10104 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 10105 wowlan->patterns[i].mask) ||
50ac6607
AK
10106 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
10107 wowlan->patterns[i].pattern) ||
10108 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 10109 wowlan->patterns[i].pkt_offset))
bb92d199
AK
10110 return -ENOBUFS;
10111 nla_nest_end(msg, nl_pat);
10112 }
10113 nla_nest_end(msg, nl_pats);
10114
10115 return 0;
10116}
10117
2a0e047e
JB
10118static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
10119 struct cfg80211_wowlan_tcp *tcp)
10120{
10121 struct nlattr *nl_tcp;
10122
10123 if (!tcp)
10124 return 0;
10125
10126 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
10127 if (!nl_tcp)
10128 return -ENOBUFS;
10129
930345ea
JB
10130 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
10131 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
10132 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
10133 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
10134 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
10135 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
10136 tcp->payload_len, tcp->payload) ||
10137 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
10138 tcp->data_interval) ||
10139 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
10140 tcp->wake_len, tcp->wake_data) ||
10141 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
10142 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
10143 return -ENOBUFS;
10144
10145 if (tcp->payload_seq.len &&
10146 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
10147 sizeof(tcp->payload_seq), &tcp->payload_seq))
10148 return -ENOBUFS;
10149
10150 if (tcp->payload_tok.len &&
10151 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
10152 sizeof(tcp->payload_tok) + tcp->tokens_size,
10153 &tcp->payload_tok))
10154 return -ENOBUFS;
10155
e248ad30
JB
10156 nla_nest_end(msg, nl_tcp);
10157
2a0e047e
JB
10158 return 0;
10159}
10160
75453ccb
LC
10161static int nl80211_send_wowlan_nd(struct sk_buff *msg,
10162 struct cfg80211_sched_scan_request *req)
10163{
3b06d277 10164 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
10165 int i;
10166
10167 if (!req)
10168 return 0;
10169
10170 nd = nla_nest_start(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
10171 if (!nd)
10172 return -ENOBUFS;
10173
3b06d277
AS
10174 if (req->n_scan_plans == 1 &&
10175 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
10176 req->scan_plans[0].interval * 1000))
75453ccb
LC
10177 return -ENOBUFS;
10178
21fea567
LC
10179 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
10180 return -ENOBUFS;
10181
bf95ecdb 10182 if (req->relative_rssi_set) {
10183 struct nl80211_bss_select_rssi_adjust rssi_adjust;
10184
10185 if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
10186 req->relative_rssi))
10187 return -ENOBUFS;
10188
10189 rssi_adjust.band = req->rssi_adjust.band;
10190 rssi_adjust.delta = req->rssi_adjust.delta;
10191 if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
10192 sizeof(rssi_adjust), &rssi_adjust))
10193 return -ENOBUFS;
10194 }
10195
75453ccb
LC
10196 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
10197 if (!freqs)
10198 return -ENOBUFS;
10199
53b18980
JB
10200 for (i = 0; i < req->n_channels; i++) {
10201 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
10202 return -ENOBUFS;
10203 }
75453ccb
LC
10204
10205 nla_nest_end(msg, freqs);
10206
10207 if (req->n_match_sets) {
10208 matches = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
10209 if (!matches)
10210 return -ENOBUFS;
10211
75453ccb
LC
10212 for (i = 0; i < req->n_match_sets; i++) {
10213 match = nla_nest_start(msg, i);
76e1fb4b
JB
10214 if (!match)
10215 return -ENOBUFS;
10216
53b18980
JB
10217 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
10218 req->match_sets[i].ssid.ssid_len,
10219 req->match_sets[i].ssid.ssid))
10220 return -ENOBUFS;
75453ccb
LC
10221 nla_nest_end(msg, match);
10222 }
10223 nla_nest_end(msg, matches);
10224 }
10225
3b06d277
AS
10226 scan_plans = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
10227 if (!scan_plans)
10228 return -ENOBUFS;
10229
10230 for (i = 0; i < req->n_scan_plans; i++) {
10231 scan_plan = nla_nest_start(msg, i + 1);
76e1fb4b
JB
10232 if (!scan_plan)
10233 return -ENOBUFS;
10234
3b06d277
AS
10235 if (!scan_plan ||
10236 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
10237 req->scan_plans[i].interval) ||
10238 (req->scan_plans[i].iterations &&
10239 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
10240 req->scan_plans[i].iterations)))
10241 return -ENOBUFS;
10242 nla_nest_end(msg, scan_plan);
10243 }
10244 nla_nest_end(msg, scan_plans);
10245
75453ccb
LC
10246 nla_nest_end(msg, nd);
10247
10248 return 0;
10249}
10250
ff1b6e69
JB
10251static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
10252{
10253 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10254 struct sk_buff *msg;
10255 void *hdr;
2a0e047e 10256 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 10257
964dc9e2 10258 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
10259 return -EOPNOTSUPP;
10260
6abb9cb9 10261 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 10262 /* adjust size to have room for all the data */
6abb9cb9
JB
10263 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
10264 rdev->wiphy.wowlan_config->tcp->payload_len +
10265 rdev->wiphy.wowlan_config->tcp->wake_len +
10266 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
10267 }
10268
10269 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
10270 if (!msg)
10271 return -ENOMEM;
10272
15e47304 10273 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
10274 NL80211_CMD_GET_WOWLAN);
10275 if (!hdr)
10276 goto nla_put_failure;
10277
6abb9cb9 10278 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
10279 struct nlattr *nl_wowlan;
10280
10281 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
10282 if (!nl_wowlan)
10283 goto nla_put_failure;
10284
6abb9cb9 10285 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 10286 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 10287 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 10288 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 10289 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 10290 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 10291 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 10292 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 10293 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 10294 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 10295 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 10296 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 10297 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
10298 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
10299 goto nla_put_failure;
2a0e047e 10300
bb92d199
AK
10301 if (nl80211_send_wowlan_patterns(msg, rdev))
10302 goto nla_put_failure;
2a0e047e 10303
6abb9cb9
JB
10304 if (nl80211_send_wowlan_tcp(msg,
10305 rdev->wiphy.wowlan_config->tcp))
2a0e047e 10306 goto nla_put_failure;
75453ccb
LC
10307
10308 if (nl80211_send_wowlan_nd(
10309 msg,
10310 rdev->wiphy.wowlan_config->nd_config))
10311 goto nla_put_failure;
2a0e047e 10312
ff1b6e69
JB
10313 nla_nest_end(msg, nl_wowlan);
10314 }
10315
10316 genlmsg_end(msg, hdr);
10317 return genlmsg_reply(msg, info);
10318
10319nla_put_failure:
10320 nlmsg_free(msg);
10321 return -ENOBUFS;
10322}
10323
2a0e047e
JB
10324static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
10325 struct nlattr *attr,
10326 struct cfg80211_wowlan *trig)
10327{
10328 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
10329 struct cfg80211_wowlan_tcp *cfg;
10330 struct nl80211_wowlan_tcp_data_token *tok = NULL;
10331 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
10332 u32 size;
10333 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
10334 int err, port;
10335
964dc9e2 10336 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
10337 return -EINVAL;
10338
bfe2c7b1 10339 err = nla_parse_nested(tb, MAX_NL80211_WOWLAN_TCP, attr,
fceb6435 10340 nl80211_wowlan_tcp_policy, NULL);
2a0e047e
JB
10341 if (err)
10342 return err;
10343
10344 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
10345 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
10346 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
10347 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
10348 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
10349 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
10350 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
10351 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
10352 return -EINVAL;
10353
10354 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 10355 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
10356 return -EINVAL;
10357
10358 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 10359 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 10360 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
10361 return -EINVAL;
10362
10363 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 10364 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
10365 return -EINVAL;
10366
10367 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
10368 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
10369 return -EINVAL;
10370
10371 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
10372 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
10373
10374 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
10375 tokens_size = tokln - sizeof(*tok);
10376
10377 if (!tok->len || tokens_size % tok->len)
10378 return -EINVAL;
964dc9e2 10379 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 10380 return -EINVAL;
964dc9e2 10381 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 10382 return -EINVAL;
964dc9e2 10383 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 10384 return -EINVAL;
964dc9e2 10385 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
10386 return -EINVAL;
10387 if (tok->offset + tok->len > data_size)
10388 return -EINVAL;
10389 }
10390
10391 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
10392 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 10393 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
10394 return -EINVAL;
10395 if (seq->len == 0 || seq->len > 4)
10396 return -EINVAL;
10397 if (seq->len + seq->offset > data_size)
10398 return -EINVAL;
10399 }
10400
10401 size = sizeof(*cfg);
10402 size += data_size;
10403 size += wake_size + wake_mask_size;
10404 size += tokens_size;
10405
10406 cfg = kzalloc(size, GFP_KERNEL);
10407 if (!cfg)
10408 return -ENOMEM;
67b61f6c
JB
10409 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
10410 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
10411 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
10412 ETH_ALEN);
10413 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
10414 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
10415 else
10416 port = 0;
10417#ifdef CONFIG_INET
10418 /* allocate a socket and port for it and use it */
10419 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
10420 IPPROTO_TCP, &cfg->sock, 1);
10421 if (err) {
10422 kfree(cfg);
10423 return err;
10424 }
10425 if (inet_csk_get_port(cfg->sock->sk, port)) {
10426 sock_release(cfg->sock);
10427 kfree(cfg);
10428 return -EADDRINUSE;
10429 }
10430 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
10431#else
10432 if (!port) {
10433 kfree(cfg);
10434 return -EINVAL;
10435 }
10436 cfg->src_port = port;
10437#endif
10438
10439 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
10440 cfg->payload_len = data_size;
10441 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
10442 memcpy((void *)cfg->payload,
10443 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
10444 data_size);
10445 if (seq)
10446 cfg->payload_seq = *seq;
10447 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
10448 cfg->wake_len = wake_size;
10449 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
10450 memcpy((void *)cfg->wake_data,
10451 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
10452 wake_size);
10453 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
10454 data_size + wake_size;
10455 memcpy((void *)cfg->wake_mask,
10456 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
10457 wake_mask_size);
10458 if (tok) {
10459 cfg->tokens_size = tokens_size;
10460 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
10461 }
10462
10463 trig->tcp = cfg;
10464
10465 return 0;
10466}
10467
8cd4d456
LC
10468static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
10469 const struct wiphy_wowlan_support *wowlan,
10470 struct nlattr *attr,
10471 struct cfg80211_wowlan *trig)
10472{
10473 struct nlattr **tb;
10474 int err;
10475
10476 tb = kzalloc(NUM_NL80211_ATTR * sizeof(*tb), GFP_KERNEL);
10477 if (!tb)
10478 return -ENOMEM;
10479
10480 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
10481 err = -EOPNOTSUPP;
10482 goto out;
10483 }
10484
fceb6435
JB
10485 err = nla_parse_nested(tb, NL80211_ATTR_MAX, attr, nl80211_policy,
10486 NULL);
8cd4d456
LC
10487 if (err)
10488 goto out;
10489
aad1e812
AVS
10490 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb,
10491 wowlan->max_nd_match_sets);
8cd4d456
LC
10492 err = PTR_ERR_OR_ZERO(trig->nd_config);
10493 if (err)
10494 trig->nd_config = NULL;
10495
10496out:
10497 kfree(tb);
10498 return err;
10499}
10500
ff1b6e69
JB
10501static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
10502{
10503 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10504 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 10505 struct cfg80211_wowlan new_triggers = {};
ae33bd81 10506 struct cfg80211_wowlan *ntrig;
964dc9e2 10507 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 10508 int err, i;
6abb9cb9 10509 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 10510 bool regular = false;
ff1b6e69 10511
964dc9e2 10512 if (!wowlan)
ff1b6e69
JB
10513 return -EOPNOTSUPP;
10514
ae33bd81
JB
10515 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
10516 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 10517 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
10518 goto set_wakeup;
10519 }
ff1b6e69 10520
bfe2c7b1
JB
10521 err = nla_parse_nested(tb, MAX_NL80211_WOWLAN_TRIG,
10522 info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
fe52145f 10523 nl80211_wowlan_policy, info->extack);
ff1b6e69
JB
10524 if (err)
10525 return err;
10526
10527 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
10528 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
10529 return -EINVAL;
10530 new_triggers.any = true;
10531 }
10532
10533 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
10534 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
10535 return -EINVAL;
10536 new_triggers.disconnect = true;
98fc4386 10537 regular = true;
ff1b6e69
JB
10538 }
10539
10540 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
10541 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
10542 return -EINVAL;
10543 new_triggers.magic_pkt = true;
98fc4386 10544 regular = true;
ff1b6e69
JB
10545 }
10546
77dbbb13
JB
10547 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
10548 return -EINVAL;
10549
10550 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
10551 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
10552 return -EINVAL;
10553 new_triggers.gtk_rekey_failure = true;
98fc4386 10554 regular = true;
77dbbb13
JB
10555 }
10556
10557 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
10558 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
10559 return -EINVAL;
10560 new_triggers.eap_identity_req = true;
98fc4386 10561 regular = true;
77dbbb13
JB
10562 }
10563
10564 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
10565 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
10566 return -EINVAL;
10567 new_triggers.four_way_handshake = true;
98fc4386 10568 regular = true;
77dbbb13
JB
10569 }
10570
10571 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
10572 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
10573 return -EINVAL;
10574 new_triggers.rfkill_release = true;
98fc4386 10575 regular = true;
77dbbb13
JB
10576 }
10577
ff1b6e69
JB
10578 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
10579 struct nlattr *pat;
10580 int n_patterns = 0;
bb92d199 10581 int rem, pat_len, mask_len, pkt_offset;
50ac6607 10582 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 10583
98fc4386
JB
10584 regular = true;
10585
ff1b6e69
JB
10586 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
10587 rem)
10588 n_patterns++;
10589 if (n_patterns > wowlan->n_patterns)
10590 return -EINVAL;
10591
10592 new_triggers.patterns = kcalloc(n_patterns,
10593 sizeof(new_triggers.patterns[0]),
10594 GFP_KERNEL);
10595 if (!new_triggers.patterns)
10596 return -ENOMEM;
10597
10598 new_triggers.n_patterns = n_patterns;
10599 i = 0;
10600
10601 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
10602 rem) {
922bd80f
JB
10603 u8 *mask_pat;
10604
bfe2c7b1 10605 nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat,
ad670233
PX
10606 nl80211_packet_pattern_policy,
10607 info->extack);
ff1b6e69 10608 err = -EINVAL;
50ac6607
AK
10609 if (!pat_tb[NL80211_PKTPAT_MASK] ||
10610 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 10611 goto error;
50ac6607 10612 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 10613 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 10614 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
10615 goto error;
10616 if (pat_len > wowlan->pattern_max_len ||
10617 pat_len < wowlan->pattern_min_len)
10618 goto error;
10619
50ac6607 10620 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
10621 pkt_offset = 0;
10622 else
10623 pkt_offset = nla_get_u32(
50ac6607 10624 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
10625 if (pkt_offset > wowlan->max_pkt_offset)
10626 goto error;
10627 new_triggers.patterns[i].pkt_offset = pkt_offset;
10628
922bd80f
JB
10629 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
10630 if (!mask_pat) {
ff1b6e69
JB
10631 err = -ENOMEM;
10632 goto error;
10633 }
922bd80f
JB
10634 new_triggers.patterns[i].mask = mask_pat;
10635 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 10636 mask_len);
922bd80f
JB
10637 mask_pat += mask_len;
10638 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 10639 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 10640 memcpy(mask_pat,
50ac6607 10641 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
10642 pat_len);
10643 i++;
10644 }
10645 }
10646
2a0e047e 10647 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 10648 regular = true;
2a0e047e
JB
10649 err = nl80211_parse_wowlan_tcp(
10650 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
10651 &new_triggers);
10652 if (err)
10653 goto error;
10654 }
10655
8cd4d456 10656 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 10657 regular = true;
8cd4d456
LC
10658 err = nl80211_parse_wowlan_nd(
10659 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
10660 &new_triggers);
10661 if (err)
10662 goto error;
10663 }
10664
98fc4386
JB
10665 /* The 'any' trigger means the device continues operating more or less
10666 * as in its normal operation mode and wakes up the host on most of the
10667 * normal interrupts (like packet RX, ...)
10668 * It therefore makes little sense to combine with the more constrained
10669 * wakeup trigger modes.
10670 */
10671 if (new_triggers.any && regular) {
10672 err = -EINVAL;
10673 goto error;
10674 }
10675
ae33bd81
JB
10676 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
10677 if (!ntrig) {
10678 err = -ENOMEM;
10679 goto error;
ff1b6e69 10680 }
ae33bd81 10681 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 10682 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 10683
ae33bd81 10684 set_wakeup:
6abb9cb9
JB
10685 if (rdev->ops->set_wakeup &&
10686 prev_enabled != !!rdev->wiphy.wowlan_config)
10687 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 10688
ff1b6e69
JB
10689 return 0;
10690 error:
10691 for (i = 0; i < new_triggers.n_patterns; i++)
10692 kfree(new_triggers.patterns[i].mask);
10693 kfree(new_triggers.patterns);
2a0e047e
JB
10694 if (new_triggers.tcp && new_triggers.tcp->sock)
10695 sock_release(new_triggers.tcp->sock);
10696 kfree(new_triggers.tcp);
e5dbe070 10697 kfree(new_triggers.nd_config);
ff1b6e69
JB
10698 return err;
10699}
dfb89c56 10700#endif
ff1b6e69 10701
be29b99a
AK
10702static int nl80211_send_coalesce_rules(struct sk_buff *msg,
10703 struct cfg80211_registered_device *rdev)
10704{
10705 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
10706 int i, j, pat_len;
10707 struct cfg80211_coalesce_rules *rule;
10708
10709 if (!rdev->coalesce->n_rules)
10710 return 0;
10711
10712 nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
10713 if (!nl_rules)
10714 return -ENOBUFS;
10715
10716 for (i = 0; i < rdev->coalesce->n_rules; i++) {
10717 nl_rule = nla_nest_start(msg, i + 1);
10718 if (!nl_rule)
10719 return -ENOBUFS;
10720
10721 rule = &rdev->coalesce->rules[i];
10722 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
10723 rule->delay))
10724 return -ENOBUFS;
10725
10726 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
10727 rule->condition))
10728 return -ENOBUFS;
10729
10730 nl_pats = nla_nest_start(msg,
10731 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
10732 if (!nl_pats)
10733 return -ENOBUFS;
10734
10735 for (j = 0; j < rule->n_patterns; j++) {
10736 nl_pat = nla_nest_start(msg, j + 1);
10737 if (!nl_pat)
10738 return -ENOBUFS;
10739 pat_len = rule->patterns[j].pattern_len;
10740 if (nla_put(msg, NL80211_PKTPAT_MASK,
10741 DIV_ROUND_UP(pat_len, 8),
10742 rule->patterns[j].mask) ||
10743 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
10744 rule->patterns[j].pattern) ||
10745 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
10746 rule->patterns[j].pkt_offset))
10747 return -ENOBUFS;
10748 nla_nest_end(msg, nl_pat);
10749 }
10750 nla_nest_end(msg, nl_pats);
10751 nla_nest_end(msg, nl_rule);
10752 }
10753 nla_nest_end(msg, nl_rules);
10754
10755 return 0;
10756}
10757
10758static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
10759{
10760 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10761 struct sk_buff *msg;
10762 void *hdr;
10763
10764 if (!rdev->wiphy.coalesce)
10765 return -EOPNOTSUPP;
10766
10767 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10768 if (!msg)
10769 return -ENOMEM;
10770
10771 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
10772 NL80211_CMD_GET_COALESCE);
10773 if (!hdr)
10774 goto nla_put_failure;
10775
10776 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
10777 goto nla_put_failure;
10778
10779 genlmsg_end(msg, hdr);
10780 return genlmsg_reply(msg, info);
10781
10782nla_put_failure:
10783 nlmsg_free(msg);
10784 return -ENOBUFS;
10785}
10786
10787void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
10788{
10789 struct cfg80211_coalesce *coalesce = rdev->coalesce;
10790 int i, j;
10791 struct cfg80211_coalesce_rules *rule;
10792
10793 if (!coalesce)
10794 return;
10795
10796 for (i = 0; i < coalesce->n_rules; i++) {
10797 rule = &coalesce->rules[i];
10798 for (j = 0; j < rule->n_patterns; j++)
10799 kfree(rule->patterns[j].mask);
10800 kfree(rule->patterns);
10801 }
10802 kfree(coalesce->rules);
10803 kfree(coalesce);
10804 rdev->coalesce = NULL;
10805}
10806
10807static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
10808 struct nlattr *rule,
10809 struct cfg80211_coalesce_rules *new_rule)
10810{
10811 int err, i;
10812 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
10813 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
10814 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
10815 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
10816
bfe2c7b1 10817 err = nla_parse_nested(tb, NL80211_ATTR_COALESCE_RULE_MAX, rule,
fceb6435 10818 nl80211_coalesce_policy, NULL);
be29b99a
AK
10819 if (err)
10820 return err;
10821
10822 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
10823 new_rule->delay =
10824 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
10825 if (new_rule->delay > coalesce->max_delay)
10826 return -EINVAL;
10827
10828 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
10829 new_rule->condition =
10830 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
10831 if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH &&
10832 new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH)
10833 return -EINVAL;
10834
10835 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
10836 return -EINVAL;
10837
10838 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
10839 rem)
10840 n_patterns++;
10841 if (n_patterns > coalesce->n_patterns)
10842 return -EINVAL;
10843
10844 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
10845 GFP_KERNEL);
10846 if (!new_rule->patterns)
10847 return -ENOMEM;
10848
10849 new_rule->n_patterns = n_patterns;
10850 i = 0;
10851
10852 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
10853 rem) {
922bd80f
JB
10854 u8 *mask_pat;
10855
ad670233
PX
10856 nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat,
10857 nl80211_packet_pattern_policy, NULL);
be29b99a
AK
10858 if (!pat_tb[NL80211_PKTPAT_MASK] ||
10859 !pat_tb[NL80211_PKTPAT_PATTERN])
10860 return -EINVAL;
10861 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
10862 mask_len = DIV_ROUND_UP(pat_len, 8);
10863 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
10864 return -EINVAL;
10865 if (pat_len > coalesce->pattern_max_len ||
10866 pat_len < coalesce->pattern_min_len)
10867 return -EINVAL;
10868
10869 if (!pat_tb[NL80211_PKTPAT_OFFSET])
10870 pkt_offset = 0;
10871 else
10872 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
10873 if (pkt_offset > coalesce->max_pkt_offset)
10874 return -EINVAL;
10875 new_rule->patterns[i].pkt_offset = pkt_offset;
10876
922bd80f
JB
10877 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
10878 if (!mask_pat)
be29b99a 10879 return -ENOMEM;
922bd80f
JB
10880
10881 new_rule->patterns[i].mask = mask_pat;
10882 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
10883 mask_len);
10884
10885 mask_pat += mask_len;
10886 new_rule->patterns[i].pattern = mask_pat;
be29b99a 10887 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
10888 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
10889 pat_len);
be29b99a
AK
10890 i++;
10891 }
10892
10893 return 0;
10894}
10895
10896static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
10897{
10898 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10899 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
10900 struct cfg80211_coalesce new_coalesce = {};
10901 struct cfg80211_coalesce *n_coalesce;
10902 int err, rem_rule, n_rules = 0, i, j;
10903 struct nlattr *rule;
10904 struct cfg80211_coalesce_rules *tmp_rule;
10905
10906 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
10907 return -EOPNOTSUPP;
10908
10909 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
10910 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 10911 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
10912 return 0;
10913 }
10914
10915 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
10916 rem_rule)
10917 n_rules++;
10918 if (n_rules > coalesce->n_rules)
10919 return -EINVAL;
10920
10921 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
10922 GFP_KERNEL);
10923 if (!new_coalesce.rules)
10924 return -ENOMEM;
10925
10926 new_coalesce.n_rules = n_rules;
10927 i = 0;
10928
10929 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
10930 rem_rule) {
10931 err = nl80211_parse_coalesce_rule(rdev, rule,
10932 &new_coalesce.rules[i]);
10933 if (err)
10934 goto error;
10935
10936 i++;
10937 }
10938
a1056b1b 10939 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
10940 if (err)
10941 goto error;
10942
10943 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
10944 if (!n_coalesce) {
10945 err = -ENOMEM;
10946 goto error;
10947 }
10948 cfg80211_rdev_free_coalesce(rdev);
10949 rdev->coalesce = n_coalesce;
10950
10951 return 0;
10952error:
10953 for (i = 0; i < new_coalesce.n_rules; i++) {
10954 tmp_rule = &new_coalesce.rules[i];
10955 for (j = 0; j < tmp_rule->n_patterns; j++)
10956 kfree(tmp_rule->patterns[j].mask);
10957 kfree(tmp_rule->patterns);
10958 }
10959 kfree(new_coalesce.rules);
10960
10961 return err;
10962}
10963
e5497d76
JB
10964static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
10965{
10966 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10967 struct net_device *dev = info->user_ptr[1];
10968 struct wireless_dev *wdev = dev->ieee80211_ptr;
10969 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
10970 struct cfg80211_gtk_rekey_data rekey_data;
10971 int err;
10972
10973 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
10974 return -EINVAL;
10975
bfe2c7b1
JB
10976 err = nla_parse_nested(tb, MAX_NL80211_REKEY_DATA,
10977 info->attrs[NL80211_ATTR_REKEY_DATA],
fe52145f 10978 nl80211_rekey_policy, info->extack);
e5497d76
JB
10979 if (err)
10980 return err;
10981
e785fa0a
VD
10982 if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
10983 !tb[NL80211_REKEY_DATA_KCK])
10984 return -EINVAL;
e5497d76
JB
10985 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
10986 return -ERANGE;
10987 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
10988 return -ERANGE;
10989 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
10990 return -ERANGE;
10991
78f686ca
JB
10992 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
10993 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
10994 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
e5497d76
JB
10995
10996 wdev_lock(wdev);
10997 if (!wdev->current_bss) {
10998 err = -ENOTCONN;
10999 goto out;
11000 }
11001
11002 if (!rdev->ops->set_rekey_data) {
11003 err = -EOPNOTSUPP;
11004 goto out;
11005 }
11006
e35e4d28 11007 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
11008 out:
11009 wdev_unlock(wdev);
11010 return err;
11011}
11012
28946da7
JB
11013static int nl80211_register_unexpected_frame(struct sk_buff *skb,
11014 struct genl_info *info)
11015{
11016 struct net_device *dev = info->user_ptr[1];
11017 struct wireless_dev *wdev = dev->ieee80211_ptr;
11018
11019 if (wdev->iftype != NL80211_IFTYPE_AP &&
11020 wdev->iftype != NL80211_IFTYPE_P2P_GO)
11021 return -EINVAL;
11022
15e47304 11023 if (wdev->ap_unexpected_nlportid)
28946da7
JB
11024 return -EBUSY;
11025
15e47304 11026 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
11027 return 0;
11028}
11029
7f6cf311
JB
11030static int nl80211_probe_client(struct sk_buff *skb,
11031 struct genl_info *info)
11032{
11033 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11034 struct net_device *dev = info->user_ptr[1];
11035 struct wireless_dev *wdev = dev->ieee80211_ptr;
11036 struct sk_buff *msg;
11037 void *hdr;
11038 const u8 *addr;
11039 u64 cookie;
11040 int err;
11041
11042 if (wdev->iftype != NL80211_IFTYPE_AP &&
11043 wdev->iftype != NL80211_IFTYPE_P2P_GO)
11044 return -EOPNOTSUPP;
11045
11046 if (!info->attrs[NL80211_ATTR_MAC])
11047 return -EINVAL;
11048
11049 if (!rdev->ops->probe_client)
11050 return -EOPNOTSUPP;
11051
11052 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11053 if (!msg)
11054 return -ENOMEM;
11055
15e47304 11056 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 11057 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
11058 if (!hdr) {
11059 err = -ENOBUFS;
7f6cf311
JB
11060 goto free_msg;
11061 }
11062
11063 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11064
e35e4d28 11065 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
11066 if (err)
11067 goto free_msg;
11068
2dad624e
ND
11069 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11070 NL80211_ATTR_PAD))
9360ffd1 11071 goto nla_put_failure;
7f6cf311
JB
11072
11073 genlmsg_end(msg, hdr);
11074
11075 return genlmsg_reply(msg, info);
11076
11077 nla_put_failure:
11078 err = -ENOBUFS;
11079 free_msg:
11080 nlmsg_free(msg);
11081 return err;
11082}
11083
5e760230
JB
11084static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
11085{
11086 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
11087 struct cfg80211_beacon_registration *reg, *nreg;
11088 int rv;
5e760230
JB
11089
11090 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
11091 return -EOPNOTSUPP;
11092
37c73b5f
BG
11093 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
11094 if (!nreg)
11095 return -ENOMEM;
11096
11097 /* First, check if already registered. */
11098 spin_lock_bh(&rdev->beacon_registrations_lock);
11099 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
11100 if (reg->nlportid == info->snd_portid) {
11101 rv = -EALREADY;
11102 goto out_err;
11103 }
11104 }
11105 /* Add it to the list */
11106 nreg->nlportid = info->snd_portid;
11107 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 11108
37c73b5f 11109 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
11110
11111 return 0;
37c73b5f
BG
11112out_err:
11113 spin_unlock_bh(&rdev->beacon_registrations_lock);
11114 kfree(nreg);
11115 return rv;
5e760230
JB
11116}
11117
98104fde
JB
11118static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
11119{
11120 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11121 struct wireless_dev *wdev = info->user_ptr[1];
11122 int err;
11123
11124 if (!rdev->ops->start_p2p_device)
11125 return -EOPNOTSUPP;
11126
11127 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
11128 return -EOPNOTSUPP;
11129
73c7da3d 11130 if (wdev_running(wdev))
98104fde
JB
11131 return 0;
11132
b6a55015
LC
11133 if (rfkill_blocked(rdev->rfkill))
11134 return -ERFKILL;
98104fde 11135
eeb126e9 11136 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
11137 if (err)
11138 return err;
11139
73c7da3d 11140 wdev->is_running = true;
98104fde 11141 rdev->opencount++;
98104fde
JB
11142
11143 return 0;
11144}
11145
11146static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
11147{
11148 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11149 struct wireless_dev *wdev = info->user_ptr[1];
11150
11151 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
11152 return -EOPNOTSUPP;
11153
11154 if (!rdev->ops->stop_p2p_device)
11155 return -EOPNOTSUPP;
11156
f9f47529 11157 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
11158
11159 return 0;
11160}
11161
cb3b7d87
AB
11162static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
11163{
11164 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11165 struct wireless_dev *wdev = info->user_ptr[1];
11166 struct cfg80211_nan_conf conf = {};
11167 int err;
11168
11169 if (wdev->iftype != NL80211_IFTYPE_NAN)
11170 return -EOPNOTSUPP;
11171
eeb04a96 11172 if (wdev_running(wdev))
cb3b7d87
AB
11173 return -EEXIST;
11174
11175 if (rfkill_blocked(rdev->rfkill))
11176 return -ERFKILL;
11177
11178 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
11179 return -EINVAL;
11180
cb3b7d87
AB
11181 conf.master_pref =
11182 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
11183 if (!conf.master_pref)
11184 return -EINVAL;
11185
8585989d
LC
11186 if (info->attrs[NL80211_ATTR_BANDS]) {
11187 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
11188
11189 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
11190 return -EOPNOTSUPP;
11191
11192 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
11193 return -EINVAL;
11194
11195 conf.bands = bands;
11196 }
cb3b7d87
AB
11197
11198 err = rdev_start_nan(rdev, wdev, &conf);
11199 if (err)
11200 return err;
11201
73c7da3d 11202 wdev->is_running = true;
cb3b7d87
AB
11203 rdev->opencount++;
11204
11205 return 0;
11206}
11207
11208static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
11209{
11210 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11211 struct wireless_dev *wdev = info->user_ptr[1];
11212
11213 if (wdev->iftype != NL80211_IFTYPE_NAN)
11214 return -EOPNOTSUPP;
11215
11216 cfg80211_stop_nan(rdev, wdev);
11217
11218 return 0;
11219}
11220
a442b761
AB
11221static int validate_nan_filter(struct nlattr *filter_attr)
11222{
11223 struct nlattr *attr;
11224 int len = 0, n_entries = 0, rem;
11225
11226 nla_for_each_nested(attr, filter_attr, rem) {
11227 len += nla_len(attr);
11228 n_entries++;
11229 }
11230
11231 if (len >= U8_MAX)
11232 return -EINVAL;
11233
11234 return n_entries;
11235}
11236
11237static int handle_nan_filter(struct nlattr *attr_filter,
11238 struct cfg80211_nan_func *func,
11239 bool tx)
11240{
11241 struct nlattr *attr;
11242 int n_entries, rem, i;
11243 struct cfg80211_nan_func_filter *filter;
11244
11245 n_entries = validate_nan_filter(attr_filter);
11246 if (n_entries < 0)
11247 return n_entries;
11248
11249 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
11250
11251 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
11252 if (!filter)
11253 return -ENOMEM;
11254
11255 i = 0;
11256 nla_for_each_nested(attr, attr_filter, rem) {
b15ca182 11257 filter[i].filter = nla_memdup(attr, GFP_KERNEL);
a442b761
AB
11258 filter[i].len = nla_len(attr);
11259 i++;
11260 }
11261 if (tx) {
11262 func->num_tx_filters = n_entries;
11263 func->tx_filters = filter;
11264 } else {
11265 func->num_rx_filters = n_entries;
11266 func->rx_filters = filter;
11267 }
11268
11269 return 0;
11270}
11271
11272static int nl80211_nan_add_func(struct sk_buff *skb,
11273 struct genl_info *info)
11274{
11275 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11276 struct wireless_dev *wdev = info->user_ptr[1];
11277 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
11278 struct cfg80211_nan_func *func;
11279 struct sk_buff *msg = NULL;
11280 void *hdr = NULL;
11281 int err = 0;
11282
11283 if (wdev->iftype != NL80211_IFTYPE_NAN)
11284 return -EOPNOTSUPP;
11285
73c7da3d 11286 if (!wdev_running(wdev))
a442b761
AB
11287 return -ENOTCONN;
11288
11289 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
11290 return -EINVAL;
11291
bfe2c7b1
JB
11292 err = nla_parse_nested(tb, NL80211_NAN_FUNC_ATTR_MAX,
11293 info->attrs[NL80211_ATTR_NAN_FUNC],
fe52145f 11294 nl80211_nan_func_policy, info->extack);
a442b761
AB
11295 if (err)
11296 return err;
11297
11298 func = kzalloc(sizeof(*func), GFP_KERNEL);
11299 if (!func)
11300 return -ENOMEM;
11301
11302 func->cookie = wdev->wiphy->cookie_counter++;
11303
11304 if (!tb[NL80211_NAN_FUNC_TYPE] ||
11305 nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
11306 err = -EINVAL;
11307 goto out;
11308 }
11309
11310
11311 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
11312
11313 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
11314 err = -EINVAL;
11315 goto out;
11316 }
11317
11318 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
11319 sizeof(func->service_id));
11320
11321 func->close_range =
11322 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
11323
11324 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
11325 func->serv_spec_info_len =
11326 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
11327 func->serv_spec_info =
11328 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
11329 func->serv_spec_info_len,
11330 GFP_KERNEL);
11331 if (!func->serv_spec_info) {
11332 err = -ENOMEM;
11333 goto out;
11334 }
11335 }
11336
11337 if (tb[NL80211_NAN_FUNC_TTL])
11338 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
11339
11340 switch (func->type) {
11341 case NL80211_NAN_FUNC_PUBLISH:
11342 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
11343 err = -EINVAL;
11344 goto out;
11345 }
11346
11347 func->publish_type =
11348 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
11349 func->publish_bcast =
11350 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
11351
11352 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
11353 func->publish_bcast) {
11354 err = -EINVAL;
11355 goto out;
11356 }
11357 break;
11358 case NL80211_NAN_FUNC_SUBSCRIBE:
11359 func->subscribe_active =
11360 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
11361 break;
11362 case NL80211_NAN_FUNC_FOLLOW_UP:
11363 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
11364 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]) {
11365 err = -EINVAL;
11366 goto out;
11367 }
11368
11369 func->followup_id =
11370 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
11371 func->followup_reqid =
11372 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
11373 memcpy(func->followup_dest.addr,
11374 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
11375 sizeof(func->followup_dest.addr));
11376 if (func->ttl) {
11377 err = -EINVAL;
11378 goto out;
11379 }
11380 break;
11381 default:
11382 err = -EINVAL;
11383 goto out;
11384 }
11385
11386 if (tb[NL80211_NAN_FUNC_SRF]) {
11387 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
11388
bfe2c7b1
JB
11389 err = nla_parse_nested(srf_tb, NL80211_NAN_SRF_ATTR_MAX,
11390 tb[NL80211_NAN_FUNC_SRF],
fe52145f 11391 nl80211_nan_srf_policy, info->extack);
a442b761
AB
11392 if (err)
11393 goto out;
11394
11395 func->srf_include =
11396 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
11397
11398 if (srf_tb[NL80211_NAN_SRF_BF]) {
11399 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
11400 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
11401 err = -EINVAL;
11402 goto out;
11403 }
11404
11405 func->srf_bf_len =
11406 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
11407 func->srf_bf =
11408 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
11409 func->srf_bf_len, GFP_KERNEL);
11410 if (!func->srf_bf) {
11411 err = -ENOMEM;
11412 goto out;
11413 }
11414
11415 func->srf_bf_idx =
11416 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
11417 } else {
11418 struct nlattr *attr, *mac_attr =
11419 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
11420 int n_entries, rem, i = 0;
11421
11422 if (!mac_attr) {
11423 err = -EINVAL;
11424 goto out;
11425 }
11426
11427 n_entries = validate_acl_mac_addrs(mac_attr);
11428 if (n_entries <= 0) {
11429 err = -EINVAL;
11430 goto out;
11431 }
11432
11433 func->srf_num_macs = n_entries;
11434 func->srf_macs =
11435 kzalloc(sizeof(*func->srf_macs) * n_entries,
11436 GFP_KERNEL);
11437 if (!func->srf_macs) {
11438 err = -ENOMEM;
11439 goto out;
11440 }
11441
11442 nla_for_each_nested(attr, mac_attr, rem)
11443 memcpy(func->srf_macs[i++].addr, nla_data(attr),
11444 sizeof(*func->srf_macs));
11445 }
11446 }
11447
11448 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
11449 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
11450 func, true);
11451 if (err)
11452 goto out;
11453 }
11454
11455 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
11456 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
11457 func, false);
11458 if (err)
11459 goto out;
11460 }
11461
11462 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11463 if (!msg) {
11464 err = -ENOMEM;
11465 goto out;
11466 }
11467
11468 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11469 NL80211_CMD_ADD_NAN_FUNCTION);
11470 /* This can't really happen - we just allocated 4KB */
11471 if (WARN_ON(!hdr)) {
11472 err = -ENOMEM;
11473 goto out;
11474 }
11475
11476 err = rdev_add_nan_func(rdev, wdev, func);
11477out:
11478 if (err < 0) {
11479 cfg80211_free_nan_func(func);
11480 nlmsg_free(msg);
11481 return err;
11482 }
11483
11484 /* propagate the instance id and cookie to userspace */
11485 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
11486 NL80211_ATTR_PAD))
11487 goto nla_put_failure;
11488
11489 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
11490 if (!func_attr)
11491 goto nla_put_failure;
11492
11493 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
11494 func->instance_id))
11495 goto nla_put_failure;
11496
11497 nla_nest_end(msg, func_attr);
11498
11499 genlmsg_end(msg, hdr);
11500 return genlmsg_reply(msg, info);
11501
11502nla_put_failure:
11503 nlmsg_free(msg);
11504 return -ENOBUFS;
11505}
11506
11507static int nl80211_nan_del_func(struct sk_buff *skb,
11508 struct genl_info *info)
11509{
11510 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11511 struct wireless_dev *wdev = info->user_ptr[1];
11512 u64 cookie;
11513
11514 if (wdev->iftype != NL80211_IFTYPE_NAN)
11515 return -EOPNOTSUPP;
11516
73c7da3d 11517 if (!wdev_running(wdev))
a442b761
AB
11518 return -ENOTCONN;
11519
11520 if (!info->attrs[NL80211_ATTR_COOKIE])
11521 return -EINVAL;
11522
a442b761
AB
11523 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
11524
11525 rdev_del_nan_func(rdev, wdev, cookie);
11526
11527 return 0;
11528}
11529
a5a9dcf2
AB
11530static int nl80211_nan_change_config(struct sk_buff *skb,
11531 struct genl_info *info)
11532{
11533 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11534 struct wireless_dev *wdev = info->user_ptr[1];
11535 struct cfg80211_nan_conf conf = {};
11536 u32 changed = 0;
11537
11538 if (wdev->iftype != NL80211_IFTYPE_NAN)
11539 return -EOPNOTSUPP;
11540
73c7da3d 11541 if (!wdev_running(wdev))
a5a9dcf2
AB
11542 return -ENOTCONN;
11543
11544 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
11545 conf.master_pref =
11546 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
11547 if (conf.master_pref <= 1 || conf.master_pref == 255)
11548 return -EINVAL;
11549
11550 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
11551 }
11552
8585989d
LC
11553 if (info->attrs[NL80211_ATTR_BANDS]) {
11554 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
11555
11556 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
11557 return -EOPNOTSUPP;
11558
11559 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
11560 return -EINVAL;
11561
11562 conf.bands = bands;
11563 changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
a5a9dcf2
AB
11564 }
11565
11566 if (!changed)
11567 return -EINVAL;
11568
11569 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
11570}
11571
50bcd31d
AB
11572void cfg80211_nan_match(struct wireless_dev *wdev,
11573 struct cfg80211_nan_match_params *match, gfp_t gfp)
11574{
11575 struct wiphy *wiphy = wdev->wiphy;
11576 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11577 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
11578 struct sk_buff *msg;
11579 void *hdr;
11580
11581 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
11582 return;
11583
11584 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11585 if (!msg)
11586 return;
11587
11588 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
11589 if (!hdr) {
11590 nlmsg_free(msg);
11591 return;
11592 }
11593
11594 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11595 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
11596 wdev->netdev->ifindex)) ||
11597 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
11598 NL80211_ATTR_PAD))
11599 goto nla_put_failure;
11600
11601 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
11602 NL80211_ATTR_PAD) ||
11603 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
11604 goto nla_put_failure;
11605
11606 match_attr = nla_nest_start(msg, NL80211_ATTR_NAN_MATCH);
11607 if (!match_attr)
11608 goto nla_put_failure;
11609
11610 local_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_LOCAL);
11611 if (!local_func_attr)
11612 goto nla_put_failure;
11613
11614 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
11615 goto nla_put_failure;
11616
11617 nla_nest_end(msg, local_func_attr);
11618
11619 peer_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_PEER);
11620 if (!peer_func_attr)
11621 goto nla_put_failure;
11622
11623 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
11624 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
11625 goto nla_put_failure;
11626
11627 if (match->info && match->info_len &&
11628 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
11629 match->info))
11630 goto nla_put_failure;
11631
11632 nla_nest_end(msg, peer_func_attr);
11633 nla_nest_end(msg, match_attr);
11634 genlmsg_end(msg, hdr);
11635
11636 if (!wdev->owner_nlportid)
11637 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11638 msg, 0, NL80211_MCGRP_NAN, gfp);
11639 else
11640 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
11641 wdev->owner_nlportid);
11642
11643 return;
11644
11645nla_put_failure:
11646 nlmsg_free(msg);
11647}
11648EXPORT_SYMBOL(cfg80211_nan_match);
11649
368e5a7b
AB
11650void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
11651 u8 inst_id,
11652 enum nl80211_nan_func_term_reason reason,
11653 u64 cookie, gfp_t gfp)
11654{
11655 struct wiphy *wiphy = wdev->wiphy;
11656 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11657 struct sk_buff *msg;
11658 struct nlattr *func_attr;
11659 void *hdr;
11660
11661 if (WARN_ON(!inst_id))
11662 return;
11663
11664 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11665 if (!msg)
11666 return;
11667
11668 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
11669 if (!hdr) {
11670 nlmsg_free(msg);
11671 return;
11672 }
11673
11674 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11675 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
11676 wdev->netdev->ifindex)) ||
11677 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
11678 NL80211_ATTR_PAD))
11679 goto nla_put_failure;
11680
11681 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11682 NL80211_ATTR_PAD))
11683 goto nla_put_failure;
11684
11685 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
11686 if (!func_attr)
11687 goto nla_put_failure;
11688
11689 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
11690 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
11691 goto nla_put_failure;
11692
11693 nla_nest_end(msg, func_attr);
11694 genlmsg_end(msg, hdr);
11695
11696 if (!wdev->owner_nlportid)
11697 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11698 msg, 0, NL80211_MCGRP_NAN, gfp);
11699 else
11700 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
11701 wdev->owner_nlportid);
11702
11703 return;
11704
11705nla_put_failure:
11706 nlmsg_free(msg);
11707}
11708EXPORT_SYMBOL(cfg80211_nan_func_terminated);
11709
3713b4e3
JB
11710static int nl80211_get_protocol_features(struct sk_buff *skb,
11711 struct genl_info *info)
11712{
11713 void *hdr;
11714 struct sk_buff *msg;
11715
11716 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11717 if (!msg)
11718 return -ENOMEM;
11719
11720 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11721 NL80211_CMD_GET_PROTOCOL_FEATURES);
11722 if (!hdr)
11723 goto nla_put_failure;
11724
11725 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
11726 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
11727 goto nla_put_failure;
11728
11729 genlmsg_end(msg, hdr);
11730 return genlmsg_reply(msg, info);
11731
11732 nla_put_failure:
11733 kfree_skb(msg);
11734 return -ENOBUFS;
11735}
11736
355199e0
JM
11737static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
11738{
11739 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11740 struct cfg80211_update_ft_ies_params ft_params;
11741 struct net_device *dev = info->user_ptr[1];
11742
11743 if (!rdev->ops->update_ft_ies)
11744 return -EOPNOTSUPP;
11745
11746 if (!info->attrs[NL80211_ATTR_MDID] ||
11747 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
11748 return -EINVAL;
11749
11750 memset(&ft_params, 0, sizeof(ft_params));
11751 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
11752 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11753 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11754
11755 return rdev_update_ft_ies(rdev, dev, &ft_params);
11756}
11757
5de17984
AS
11758static int nl80211_crit_protocol_start(struct sk_buff *skb,
11759 struct genl_info *info)
11760{
11761 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11762 struct wireless_dev *wdev = info->user_ptr[1];
11763 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
11764 u16 duration;
11765 int ret;
11766
11767 if (!rdev->ops->crit_proto_start)
11768 return -EOPNOTSUPP;
11769
11770 if (WARN_ON(!rdev->ops->crit_proto_stop))
11771 return -EINVAL;
11772
11773 if (rdev->crit_proto_nlportid)
11774 return -EBUSY;
11775
11776 /* determine protocol if provided */
11777 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
11778 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
11779
11780 if (proto >= NUM_NL80211_CRIT_PROTO)
11781 return -EINVAL;
11782
11783 /* timeout must be provided */
11784 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
11785 return -EINVAL;
11786
11787 duration =
11788 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
11789
11790 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
11791 return -ERANGE;
11792
11793 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
11794 if (!ret)
11795 rdev->crit_proto_nlportid = info->snd_portid;
11796
11797 return ret;
11798}
11799
11800static int nl80211_crit_protocol_stop(struct sk_buff *skb,
11801 struct genl_info *info)
11802{
11803 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11804 struct wireless_dev *wdev = info->user_ptr[1];
11805
11806 if (!rdev->ops->crit_proto_stop)
11807 return -EOPNOTSUPP;
11808
11809 if (rdev->crit_proto_nlportid) {
11810 rdev->crit_proto_nlportid = 0;
11811 rdev_crit_proto_stop(rdev, wdev);
11812 }
11813 return 0;
11814}
11815
ad7e718c
JB
11816static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
11817{
11818 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11819 struct wireless_dev *wdev =
11820 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
11821 int i, err;
11822 u32 vid, subcmd;
11823
11824 if (!rdev->wiphy.vendor_commands)
11825 return -EOPNOTSUPP;
11826
11827 if (IS_ERR(wdev)) {
11828 err = PTR_ERR(wdev);
11829 if (err != -EINVAL)
11830 return err;
11831 wdev = NULL;
11832 } else if (wdev->wiphy != &rdev->wiphy) {
11833 return -EINVAL;
11834 }
11835
11836 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
11837 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
11838 return -EINVAL;
11839
11840 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
11841 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
11842 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
11843 const struct wiphy_vendor_command *vcmd;
11844 void *data = NULL;
11845 int len = 0;
11846
11847 vcmd = &rdev->wiphy.vendor_commands[i];
11848
11849 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11850 continue;
11851
11852 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11853 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11854 if (!wdev)
11855 return -EINVAL;
11856 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11857 !wdev->netdev)
11858 return -EINVAL;
11859
11860 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 11861 if (!wdev_running(wdev))
ad7e718c
JB
11862 return -ENETDOWN;
11863 }
7bdbe400
JB
11864
11865 if (!vcmd->doit)
11866 return -EOPNOTSUPP;
ad7e718c
JB
11867 } else {
11868 wdev = NULL;
11869 }
11870
11871 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
11872 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11873 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11874 }
11875
11876 rdev->cur_cmd_info = info;
11877 err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
11878 data, len);
11879 rdev->cur_cmd_info = NULL;
11880 return err;
11881 }
11882
11883 return -EOPNOTSUPP;
11884}
11885
7bdbe400
JB
11886static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
11887 struct netlink_callback *cb,
11888 struct cfg80211_registered_device **rdev,
11889 struct wireless_dev **wdev)
11890{
c90c39da 11891 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
7bdbe400
JB
11892 u32 vid, subcmd;
11893 unsigned int i;
11894 int vcmd_idx = -1;
11895 int err;
11896 void *data = NULL;
11897 unsigned int data_len = 0;
11898
7bdbe400
JB
11899 if (cb->args[0]) {
11900 /* subtract the 1 again here */
11901 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
11902 struct wireless_dev *tmp;
11903
ea90e0dc
JB
11904 if (!wiphy)
11905 return -ENODEV;
7bdbe400
JB
11906 *rdev = wiphy_to_rdev(wiphy);
11907 *wdev = NULL;
11908
11909 if (cb->args[1]) {
53873f13 11910 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
11911 if (tmp->identifier == cb->args[1] - 1) {
11912 *wdev = tmp;
11913 break;
11914 }
11915 }
11916 }
11917
11918 /* keep rtnl locked in successful case */
11919 return 0;
11920 }
11921
fceb6435
JB
11922 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, attrbuf,
11923 nl80211_fam.maxattr, nl80211_policy, NULL);
7bdbe400 11924 if (err)
ea90e0dc 11925 return err;
7bdbe400 11926
c90c39da 11927 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
ea90e0dc
JB
11928 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD])
11929 return -EINVAL;
7bdbe400 11930
c90c39da 11931 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
7bdbe400
JB
11932 if (IS_ERR(*wdev))
11933 *wdev = NULL;
11934
c90c39da 11935 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
ea90e0dc
JB
11936 if (IS_ERR(*rdev))
11937 return PTR_ERR(*rdev);
7bdbe400 11938
c90c39da
JB
11939 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
11940 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
7bdbe400
JB
11941
11942 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
11943 const struct wiphy_vendor_command *vcmd;
11944
11945 vcmd = &(*rdev)->wiphy.vendor_commands[i];
11946
11947 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11948 continue;
11949
ea90e0dc
JB
11950 if (!vcmd->dumpit)
11951 return -EOPNOTSUPP;
7bdbe400
JB
11952
11953 vcmd_idx = i;
11954 break;
11955 }
11956
ea90e0dc
JB
11957 if (vcmd_idx < 0)
11958 return -EOPNOTSUPP;
7bdbe400 11959
c90c39da
JB
11960 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
11961 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
11962 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
7bdbe400
JB
11963 }
11964
11965 /* 0 is the first index - add 1 to parse only once */
11966 cb->args[0] = (*rdev)->wiphy_idx + 1;
11967 /* add 1 to know if it was NULL */
11968 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
11969 cb->args[2] = vcmd_idx;
11970 cb->args[3] = (unsigned long)data;
11971 cb->args[4] = data_len;
11972
11973 /* keep rtnl locked in successful case */
11974 return 0;
7bdbe400
JB
11975}
11976
11977static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
11978 struct netlink_callback *cb)
11979{
11980 struct cfg80211_registered_device *rdev;
11981 struct wireless_dev *wdev;
11982 unsigned int vcmd_idx;
11983 const struct wiphy_vendor_command *vcmd;
11984 void *data;
11985 int data_len;
11986 int err;
11987 struct nlattr *vendor_data;
11988
ea90e0dc 11989 rtnl_lock();
7bdbe400
JB
11990 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
11991 if (err)
ea90e0dc 11992 goto out;
7bdbe400
JB
11993
11994 vcmd_idx = cb->args[2];
11995 data = (void *)cb->args[3];
11996 data_len = cb->args[4];
11997 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
11998
11999 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
12000 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
ea90e0dc
JB
12001 if (!wdev) {
12002 err = -EINVAL;
12003 goto out;
12004 }
7bdbe400 12005 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
ea90e0dc
JB
12006 !wdev->netdev) {
12007 err = -EINVAL;
12008 goto out;
12009 }
7bdbe400
JB
12010
12011 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
ea90e0dc
JB
12012 if (!wdev_running(wdev)) {
12013 err = -ENETDOWN;
12014 goto out;
12015 }
7bdbe400
JB
12016 }
12017 }
12018
12019 while (1) {
12020 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
12021 cb->nlh->nlmsg_seq, NLM_F_MULTI,
12022 NL80211_CMD_VENDOR);
12023 if (!hdr)
12024 break;
12025
12026 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
12027 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
12028 wdev_id(wdev),
12029 NL80211_ATTR_PAD))) {
7bdbe400
JB
12030 genlmsg_cancel(skb, hdr);
12031 break;
12032 }
12033
12034 vendor_data = nla_nest_start(skb, NL80211_ATTR_VENDOR_DATA);
12035 if (!vendor_data) {
12036 genlmsg_cancel(skb, hdr);
12037 break;
12038 }
12039
12040 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
12041 (unsigned long *)&cb->args[5]);
12042 nla_nest_end(skb, vendor_data);
12043
12044 if (err == -ENOBUFS || err == -ENOENT) {
12045 genlmsg_cancel(skb, hdr);
12046 break;
12047 } else if (err) {
12048 genlmsg_cancel(skb, hdr);
12049 goto out;
12050 }
12051
12052 genlmsg_end(skb, hdr);
12053 }
12054
12055 err = skb->len;
12056 out:
12057 rtnl_unlock();
12058 return err;
12059}
12060
ad7e718c
JB
12061struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
12062 enum nl80211_commands cmd,
12063 enum nl80211_attrs attr,
12064 int approxlen)
12065{
f26cbf40 12066 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
12067
12068 if (WARN_ON(!rdev->cur_cmd_info))
12069 return NULL;
12070
6c09e791 12071 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
12072 rdev->cur_cmd_info->snd_portid,
12073 rdev->cur_cmd_info->snd_seq,
567ffc35 12074 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
12075}
12076EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
12077
12078int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
12079{
12080 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
12081 void *hdr = ((void **)skb->cb)[1];
12082 struct nlattr *data = ((void **)skb->cb)[2];
12083
bd8c78e7
JB
12084 /* clear CB data for netlink core to own from now on */
12085 memset(skb->cb, 0, sizeof(skb->cb));
12086
ad7e718c
JB
12087 if (WARN_ON(!rdev->cur_cmd_info)) {
12088 kfree_skb(skb);
12089 return -EINVAL;
12090 }
12091
12092 nla_nest_end(skb, data);
12093 genlmsg_end(skb, hdr);
12094 return genlmsg_reply(skb, rdev->cur_cmd_info);
12095}
12096EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
12097
fa9ffc74
KP
12098static int nl80211_set_qos_map(struct sk_buff *skb,
12099 struct genl_info *info)
12100{
12101 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12102 struct cfg80211_qos_map *qos_map = NULL;
12103 struct net_device *dev = info->user_ptr[1];
12104 u8 *pos, len, num_des, des_len, des;
12105 int ret;
12106
12107 if (!rdev->ops->set_qos_map)
12108 return -EOPNOTSUPP;
12109
12110 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
12111 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
12112 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
12113
12114 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
12115 len > IEEE80211_QOS_MAP_LEN_MAX)
12116 return -EINVAL;
12117
12118 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
12119 if (!qos_map)
12120 return -ENOMEM;
12121
12122 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
12123 if (num_des) {
12124 des_len = num_des *
12125 sizeof(struct cfg80211_dscp_exception);
12126 memcpy(qos_map->dscp_exception, pos, des_len);
12127 qos_map->num_des = num_des;
12128 for (des = 0; des < num_des; des++) {
12129 if (qos_map->dscp_exception[des].up > 7) {
12130 kfree(qos_map);
12131 return -EINVAL;
12132 }
12133 }
12134 pos += des_len;
12135 }
12136 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
12137 }
12138
12139 wdev_lock(dev->ieee80211_ptr);
12140 ret = nl80211_key_allowed(dev->ieee80211_ptr);
12141 if (!ret)
12142 ret = rdev_set_qos_map(rdev, dev, qos_map);
12143 wdev_unlock(dev->ieee80211_ptr);
12144
12145 kfree(qos_map);
12146 return ret;
12147}
12148
960d01ac
JB
12149static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
12150{
12151 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12152 struct net_device *dev = info->user_ptr[1];
12153 struct wireless_dev *wdev = dev->ieee80211_ptr;
12154 const u8 *peer;
12155 u8 tsid, up;
12156 u16 admitted_time = 0;
12157 int err;
12158
723e73ac 12159 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
12160 return -EOPNOTSUPP;
12161
12162 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
12163 !info->attrs[NL80211_ATTR_USER_PRIO])
12164 return -EINVAL;
12165
12166 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
12167 if (tsid >= IEEE80211_NUM_TIDS)
12168 return -EINVAL;
12169
12170 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
12171 if (up >= IEEE80211_NUM_UPS)
12172 return -EINVAL;
12173
12174 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 12175 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 12176 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
12177 * need more attributes for that (e.g. BA session requirement);
12178 * change the WMM adminssion test above to allow both then
960d01ac
JB
12179 */
12180 return -EINVAL;
12181 }
12182
12183 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
12184
12185 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
12186 admitted_time =
12187 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
12188 if (!admitted_time)
12189 return -EINVAL;
12190 }
12191
12192 wdev_lock(wdev);
12193 switch (wdev->iftype) {
12194 case NL80211_IFTYPE_STATION:
12195 case NL80211_IFTYPE_P2P_CLIENT:
12196 if (wdev->current_bss)
12197 break;
12198 err = -ENOTCONN;
12199 goto out;
12200 default:
12201 err = -EOPNOTSUPP;
12202 goto out;
12203 }
12204
12205 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
12206
12207 out:
12208 wdev_unlock(wdev);
12209 return err;
12210}
12211
12212static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
12213{
12214 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12215 struct net_device *dev = info->user_ptr[1];
12216 struct wireless_dev *wdev = dev->ieee80211_ptr;
12217 const u8 *peer;
12218 u8 tsid;
12219 int err;
12220
12221 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
12222 return -EINVAL;
12223
12224 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
12225 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
12226
12227 wdev_lock(wdev);
12228 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
12229 wdev_unlock(wdev);
12230
12231 return err;
12232}
12233
1057d35e
AN
12234static int nl80211_tdls_channel_switch(struct sk_buff *skb,
12235 struct genl_info *info)
12236{
12237 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12238 struct net_device *dev = info->user_ptr[1];
12239 struct wireless_dev *wdev = dev->ieee80211_ptr;
12240 struct cfg80211_chan_def chandef = {};
12241 const u8 *addr;
12242 u8 oper_class;
12243 int err;
12244
12245 if (!rdev->ops->tdls_channel_switch ||
12246 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
12247 return -EOPNOTSUPP;
12248
12249 switch (dev->ieee80211_ptr->iftype) {
12250 case NL80211_IFTYPE_STATION:
12251 case NL80211_IFTYPE_P2P_CLIENT:
12252 break;
12253 default:
12254 return -EOPNOTSUPP;
12255 }
12256
12257 if (!info->attrs[NL80211_ATTR_MAC] ||
12258 !info->attrs[NL80211_ATTR_OPER_CLASS])
12259 return -EINVAL;
12260
12261 err = nl80211_parse_chandef(rdev, info, &chandef);
12262 if (err)
12263 return err;
12264
12265 /*
12266 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
12267 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
12268 * specification is not defined for them.
12269 */
57fbcce3 12270 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
12271 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
12272 chandef.width != NL80211_CHAN_WIDTH_20)
12273 return -EINVAL;
12274
12275 /* we will be active on the TDLS link */
923b352f
AN
12276 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
12277 wdev->iftype))
1057d35e
AN
12278 return -EINVAL;
12279
12280 /* don't allow switching to DFS channels */
12281 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
12282 return -EINVAL;
12283
12284 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
12285 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
12286
12287 wdev_lock(wdev);
12288 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
12289 wdev_unlock(wdev);
12290
12291 return err;
12292}
12293
12294static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
12295 struct genl_info *info)
12296{
12297 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12298 struct net_device *dev = info->user_ptr[1];
12299 struct wireless_dev *wdev = dev->ieee80211_ptr;
12300 const u8 *addr;
12301
12302 if (!rdev->ops->tdls_channel_switch ||
12303 !rdev->ops->tdls_cancel_channel_switch ||
12304 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
12305 return -EOPNOTSUPP;
12306
12307 switch (dev->ieee80211_ptr->iftype) {
12308 case NL80211_IFTYPE_STATION:
12309 case NL80211_IFTYPE_P2P_CLIENT:
12310 break;
12311 default:
12312 return -EOPNOTSUPP;
12313 }
12314
12315 if (!info->attrs[NL80211_ATTR_MAC])
12316 return -EINVAL;
12317
12318 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
12319
12320 wdev_lock(wdev);
12321 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
12322 wdev_unlock(wdev);
12323
12324 return 0;
12325}
12326
ce0ce13a
MB
12327static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
12328 struct genl_info *info)
12329{
12330 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12331 struct net_device *dev = info->user_ptr[1];
12332 struct wireless_dev *wdev = dev->ieee80211_ptr;
12333 const struct nlattr *nla;
12334 bool enabled;
12335
ce0ce13a
MB
12336 if (!rdev->ops->set_multicast_to_unicast)
12337 return -EOPNOTSUPP;
12338
12339 if (wdev->iftype != NL80211_IFTYPE_AP &&
12340 wdev->iftype != NL80211_IFTYPE_P2P_GO)
12341 return -EOPNOTSUPP;
12342
12343 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
12344 enabled = nla_get_flag(nla);
12345
12346 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
12347}
12348
3a00df57
AS
12349static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
12350{
12351 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12352 struct net_device *dev = info->user_ptr[1];
12353 struct wireless_dev *wdev = dev->ieee80211_ptr;
12354 struct cfg80211_pmk_conf pmk_conf = {};
12355 int ret;
12356
12357 if (wdev->iftype != NL80211_IFTYPE_STATION &&
12358 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
12359 return -EOPNOTSUPP;
12360
12361 if (!wiphy_ext_feature_isset(&rdev->wiphy,
12362 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
12363 return -EOPNOTSUPP;
12364
12365 if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
12366 return -EINVAL;
12367
12368 wdev_lock(wdev);
12369 if (!wdev->current_bss) {
12370 ret = -ENOTCONN;
12371 goto out;
12372 }
12373
12374 pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
12375 if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
12376 ret = -EINVAL;
12377 goto out;
12378 }
12379
12380 pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
12381 pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
12382 if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
12383 pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
12384 ret = -EINVAL;
12385 goto out;
12386 }
12387
12388 if (info->attrs[NL80211_ATTR_PMKR0_NAME]) {
12389 int r0_name_len = nla_len(info->attrs[NL80211_ATTR_PMKR0_NAME]);
12390
12391 if (r0_name_len != WLAN_PMK_NAME_LEN) {
12392 ret = -EINVAL;
12393 goto out;
12394 }
12395
12396 pmk_conf.pmk_r0_name =
12397 nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
12398 }
12399
12400 ret = rdev_set_pmk(rdev, dev, &pmk_conf);
12401out:
12402 wdev_unlock(wdev);
12403 return ret;
12404}
12405
12406static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
12407{
12408 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12409 struct net_device *dev = info->user_ptr[1];
12410 struct wireless_dev *wdev = dev->ieee80211_ptr;
12411 const u8 *aa;
12412 int ret;
12413
12414 if (wdev->iftype != NL80211_IFTYPE_STATION &&
12415 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
12416 return -EOPNOTSUPP;
12417
12418 if (!wiphy_ext_feature_isset(&rdev->wiphy,
12419 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
12420 return -EOPNOTSUPP;
12421
12422 if (!info->attrs[NL80211_ATTR_MAC])
12423 return -EINVAL;
12424
12425 wdev_lock(wdev);
12426 aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
12427 ret = rdev_del_pmk(rdev, dev, aa);
12428 wdev_unlock(wdev);
12429
12430 return ret;
12431}
12432
4c476991
JB
12433#define NL80211_FLAG_NEED_WIPHY 0x01
12434#define NL80211_FLAG_NEED_NETDEV 0x02
12435#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
12436#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
12437#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
12438 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 12439#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 12440/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
12441#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
12442 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 12443#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 12444
f84f771d 12445static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
12446 struct genl_info *info)
12447{
12448 struct cfg80211_registered_device *rdev;
89a54e48 12449 struct wireless_dev *wdev;
4c476991 12450 struct net_device *dev;
4c476991
JB
12451 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
12452
12453 if (rtnl)
12454 rtnl_lock();
12455
12456 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 12457 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
12458 if (IS_ERR(rdev)) {
12459 if (rtnl)
12460 rtnl_unlock();
12461 return PTR_ERR(rdev);
12462 }
12463 info->user_ptr[0] = rdev;
1bf614ef
JB
12464 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
12465 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
12466 ASSERT_RTNL();
12467
89a54e48
JB
12468 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
12469 info->attrs);
12470 if (IS_ERR(wdev)) {
4c476991
JB
12471 if (rtnl)
12472 rtnl_unlock();
89a54e48 12473 return PTR_ERR(wdev);
4c476991 12474 }
89a54e48 12475
89a54e48 12476 dev = wdev->netdev;
f26cbf40 12477 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 12478
1bf614ef
JB
12479 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
12480 if (!dev) {
1bf614ef
JB
12481 if (rtnl)
12482 rtnl_unlock();
12483 return -EINVAL;
12484 }
12485
12486 info->user_ptr[1] = dev;
12487 } else {
12488 info->user_ptr[1] = wdev;
41265714 12489 }
1bf614ef 12490
73c7da3d
AVS
12491 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
12492 !wdev_running(wdev)) {
12493 if (rtnl)
12494 rtnl_unlock();
12495 return -ENETDOWN;
12496 }
1bf614ef 12497
73c7da3d 12498 if (dev)
1bf614ef 12499 dev_hold(dev);
89a54e48 12500
4c476991 12501 info->user_ptr[0] = rdev;
4c476991
JB
12502 }
12503
12504 return 0;
12505}
12506
f84f771d 12507static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
12508 struct genl_info *info)
12509{
1bf614ef
JB
12510 if (info->user_ptr[1]) {
12511 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
12512 struct wireless_dev *wdev = info->user_ptr[1];
12513
12514 if (wdev->netdev)
12515 dev_put(wdev->netdev);
12516 } else {
12517 dev_put(info->user_ptr[1]);
12518 }
12519 }
5393b917 12520
4c476991
JB
12521 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
12522 rtnl_unlock();
5393b917
JB
12523
12524 /* If needed, clear the netlink message payload from the SKB
12525 * as it might contain key data that shouldn't stick around on
12526 * the heap after the SKB is freed. The netlink message header
12527 * is still needed for further processing, so leave it intact.
12528 */
12529 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
12530 struct nlmsghdr *nlh = nlmsg_hdr(skb);
12531
12532 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
12533 }
4c476991
JB
12534}
12535
4534de83 12536static const struct genl_ops nl80211_ops[] = {
55682965
JB
12537 {
12538 .cmd = NL80211_CMD_GET_WIPHY,
12539 .doit = nl80211_get_wiphy,
12540 .dumpit = nl80211_dump_wiphy,
86e8cf98 12541 .done = nl80211_dump_wiphy_done,
55682965
JB
12542 .policy = nl80211_policy,
12543 /* can be retrieved by unprivileged users */
5fe231e8
JB
12544 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12545 NL80211_FLAG_NEED_RTNL,
55682965
JB
12546 },
12547 {
12548 .cmd = NL80211_CMD_SET_WIPHY,
12549 .doit = nl80211_set_wiphy,
12550 .policy = nl80211_policy,
5617c6cd 12551 .flags = GENL_UNS_ADMIN_PERM,
4c476991 12552 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
12553 },
12554 {
12555 .cmd = NL80211_CMD_GET_INTERFACE,
12556 .doit = nl80211_get_interface,
12557 .dumpit = nl80211_dump_interface,
12558 .policy = nl80211_policy,
12559 /* can be retrieved by unprivileged users */
5fe231e8
JB
12560 .internal_flags = NL80211_FLAG_NEED_WDEV |
12561 NL80211_FLAG_NEED_RTNL,
55682965
JB
12562 },
12563 {
12564 .cmd = NL80211_CMD_SET_INTERFACE,
12565 .doit = nl80211_set_interface,
12566 .policy = nl80211_policy,
5617c6cd 12567 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12568 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12569 NL80211_FLAG_NEED_RTNL,
55682965
JB
12570 },
12571 {
12572 .cmd = NL80211_CMD_NEW_INTERFACE,
12573 .doit = nl80211_new_interface,
12574 .policy = nl80211_policy,
5617c6cd 12575 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12576 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12577 NL80211_FLAG_NEED_RTNL,
55682965
JB
12578 },
12579 {
12580 .cmd = NL80211_CMD_DEL_INTERFACE,
12581 .doit = nl80211_del_interface,
12582 .policy = nl80211_policy,
5617c6cd 12583 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 12584 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 12585 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
12586 },
12587 {
12588 .cmd = NL80211_CMD_GET_KEY,
12589 .doit = nl80211_get_key,
12590 .policy = nl80211_policy,
5617c6cd 12591 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12592 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12593 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
12594 },
12595 {
12596 .cmd = NL80211_CMD_SET_KEY,
12597 .doit = nl80211_set_key,
12598 .policy = nl80211_policy,
5617c6cd 12599 .flags = GENL_UNS_ADMIN_PERM,
41265714 12600 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12601 NL80211_FLAG_NEED_RTNL |
12602 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
12603 },
12604 {
12605 .cmd = NL80211_CMD_NEW_KEY,
12606 .doit = nl80211_new_key,
12607 .policy = nl80211_policy,
5617c6cd 12608 .flags = GENL_UNS_ADMIN_PERM,
41265714 12609 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12610 NL80211_FLAG_NEED_RTNL |
12611 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
12612 },
12613 {
12614 .cmd = NL80211_CMD_DEL_KEY,
12615 .doit = nl80211_del_key,
12616 .policy = nl80211_policy,
5617c6cd 12617 .flags = GENL_UNS_ADMIN_PERM,
41265714 12618 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12619 NL80211_FLAG_NEED_RTNL,
55682965 12620 },
ed1b6cc7
JB
12621 {
12622 .cmd = NL80211_CMD_SET_BEACON,
12623 .policy = nl80211_policy,
5617c6cd 12624 .flags = GENL_UNS_ADMIN_PERM,
8860020e 12625 .doit = nl80211_set_beacon,
2b5f8b0b 12626 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12627 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
12628 },
12629 {
8860020e 12630 .cmd = NL80211_CMD_START_AP,
ed1b6cc7 12631 .policy = nl80211_policy,
5617c6cd 12632 .flags = GENL_UNS_ADMIN_PERM,
8860020e 12633 .doit = nl80211_start_ap,
2b5f8b0b 12634 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12635 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
12636 },
12637 {
8860020e 12638 .cmd = NL80211_CMD_STOP_AP,
ed1b6cc7 12639 .policy = nl80211_policy,
5617c6cd 12640 .flags = GENL_UNS_ADMIN_PERM,
8860020e 12641 .doit = nl80211_stop_ap,
2b5f8b0b 12642 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12643 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 12644 },
5727ef1b
JB
12645 {
12646 .cmd = NL80211_CMD_GET_STATION,
12647 .doit = nl80211_get_station,
2ec600d6 12648 .dumpit = nl80211_dump_station,
5727ef1b 12649 .policy = nl80211_policy,
4c476991
JB
12650 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12651 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
12652 },
12653 {
12654 .cmd = NL80211_CMD_SET_STATION,
12655 .doit = nl80211_set_station,
12656 .policy = nl80211_policy,
5617c6cd 12657 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12658 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12659 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
12660 },
12661 {
12662 .cmd = NL80211_CMD_NEW_STATION,
12663 .doit = nl80211_new_station,
12664 .policy = nl80211_policy,
5617c6cd 12665 .flags = GENL_UNS_ADMIN_PERM,
41265714 12666 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12667 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
12668 },
12669 {
12670 .cmd = NL80211_CMD_DEL_STATION,
12671 .doit = nl80211_del_station,
12672 .policy = nl80211_policy,
5617c6cd 12673 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12674 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12675 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12676 },
12677 {
12678 .cmd = NL80211_CMD_GET_MPATH,
12679 .doit = nl80211_get_mpath,
12680 .dumpit = nl80211_dump_mpath,
12681 .policy = nl80211_policy,
5617c6cd 12682 .flags = GENL_UNS_ADMIN_PERM,
41265714 12683 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12684 NL80211_FLAG_NEED_RTNL,
2ec600d6 12685 },
66be7d2b
HR
12686 {
12687 .cmd = NL80211_CMD_GET_MPP,
12688 .doit = nl80211_get_mpp,
12689 .dumpit = nl80211_dump_mpp,
12690 .policy = nl80211_policy,
5617c6cd 12691 .flags = GENL_UNS_ADMIN_PERM,
66be7d2b
HR
12692 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12693 NL80211_FLAG_NEED_RTNL,
12694 },
2ec600d6
LCC
12695 {
12696 .cmd = NL80211_CMD_SET_MPATH,
12697 .doit = nl80211_set_mpath,
12698 .policy = nl80211_policy,
5617c6cd 12699 .flags = GENL_UNS_ADMIN_PERM,
41265714 12700 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12701 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12702 },
12703 {
12704 .cmd = NL80211_CMD_NEW_MPATH,
12705 .doit = nl80211_new_mpath,
12706 .policy = nl80211_policy,
5617c6cd 12707 .flags = GENL_UNS_ADMIN_PERM,
41265714 12708 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12709 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12710 },
12711 {
12712 .cmd = NL80211_CMD_DEL_MPATH,
12713 .doit = nl80211_del_mpath,
12714 .policy = nl80211_policy,
5617c6cd 12715 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12716 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12717 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
12718 },
12719 {
12720 .cmd = NL80211_CMD_SET_BSS,
12721 .doit = nl80211_set_bss,
12722 .policy = nl80211_policy,
5617c6cd 12723 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12724 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12725 NL80211_FLAG_NEED_RTNL,
b2e1b302 12726 },
f130347c
LR
12727 {
12728 .cmd = NL80211_CMD_GET_REG,
ad30ca2c
AN
12729 .doit = nl80211_get_reg_do,
12730 .dumpit = nl80211_get_reg_dump,
f130347c 12731 .policy = nl80211_policy,
5fe231e8 12732 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
12733 /* can be retrieved by unprivileged users */
12734 },
b6863036 12735#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
12736 {
12737 .cmd = NL80211_CMD_SET_REG,
12738 .doit = nl80211_set_reg,
12739 .policy = nl80211_policy,
12740 .flags = GENL_ADMIN_PERM,
5fe231e8 12741 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302 12742 },
b6863036 12743#endif
b2e1b302
LR
12744 {
12745 .cmd = NL80211_CMD_REQ_SET_REG,
12746 .doit = nl80211_req_set_reg,
12747 .policy = nl80211_policy,
93da9cc1 12748 .flags = GENL_ADMIN_PERM,
12749 },
1ea4ff3e
JB
12750 {
12751 .cmd = NL80211_CMD_RELOAD_REGDB,
12752 .doit = nl80211_reload_regdb,
12753 .policy = nl80211_policy,
12754 .flags = GENL_ADMIN_PERM,
12755 },
93da9cc1 12756 {
24bdd9f4
JC
12757 .cmd = NL80211_CMD_GET_MESH_CONFIG,
12758 .doit = nl80211_get_mesh_config,
93da9cc1 12759 .policy = nl80211_policy,
12760 /* can be retrieved by unprivileged users */
2b5f8b0b 12761 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12762 NL80211_FLAG_NEED_RTNL,
93da9cc1 12763 },
12764 {
24bdd9f4
JC
12765 .cmd = NL80211_CMD_SET_MESH_CONFIG,
12766 .doit = nl80211_update_mesh_config,
93da9cc1 12767 .policy = nl80211_policy,
5617c6cd 12768 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c 12769 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12770 NL80211_FLAG_NEED_RTNL,
9aed3cc1 12771 },
2a519311
JB
12772 {
12773 .cmd = NL80211_CMD_TRIGGER_SCAN,
12774 .doit = nl80211_trigger_scan,
12775 .policy = nl80211_policy,
5617c6cd 12776 .flags = GENL_UNS_ADMIN_PERM,
fd014284 12777 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12778 NL80211_FLAG_NEED_RTNL,
2a519311 12779 },
91d3ab46
VK
12780 {
12781 .cmd = NL80211_CMD_ABORT_SCAN,
12782 .doit = nl80211_abort_scan,
12783 .policy = nl80211_policy,
5617c6cd 12784 .flags = GENL_UNS_ADMIN_PERM,
91d3ab46
VK
12785 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12786 NL80211_FLAG_NEED_RTNL,
12787 },
2a519311
JB
12788 {
12789 .cmd = NL80211_CMD_GET_SCAN,
12790 .policy = nl80211_policy,
12791 .dumpit = nl80211_dump_scan,
12792 },
807f8a8c
LC
12793 {
12794 .cmd = NL80211_CMD_START_SCHED_SCAN,
12795 .doit = nl80211_start_sched_scan,
12796 .policy = nl80211_policy,
5617c6cd 12797 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
12798 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12799 NL80211_FLAG_NEED_RTNL,
12800 },
12801 {
12802 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
12803 .doit = nl80211_stop_sched_scan,
12804 .policy = nl80211_policy,
5617c6cd 12805 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
12806 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12807 NL80211_FLAG_NEED_RTNL,
12808 },
636a5d36
JM
12809 {
12810 .cmd = NL80211_CMD_AUTHENTICATE,
12811 .doit = nl80211_authenticate,
12812 .policy = nl80211_policy,
5617c6cd 12813 .flags = GENL_UNS_ADMIN_PERM,
41265714 12814 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12815 NL80211_FLAG_NEED_RTNL |
12816 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
12817 },
12818 {
12819 .cmd = NL80211_CMD_ASSOCIATE,
12820 .doit = nl80211_associate,
12821 .policy = nl80211_policy,
5617c6cd 12822 .flags = GENL_UNS_ADMIN_PERM,
41265714 12823 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12824 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
12825 },
12826 {
12827 .cmd = NL80211_CMD_DEAUTHENTICATE,
12828 .doit = nl80211_deauthenticate,
12829 .policy = nl80211_policy,
5617c6cd 12830 .flags = GENL_UNS_ADMIN_PERM,
41265714 12831 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12832 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
12833 },
12834 {
12835 .cmd = NL80211_CMD_DISASSOCIATE,
12836 .doit = nl80211_disassociate,
12837 .policy = nl80211_policy,
5617c6cd 12838 .flags = GENL_UNS_ADMIN_PERM,
41265714 12839 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12840 NL80211_FLAG_NEED_RTNL,
636a5d36 12841 },
04a773ad
JB
12842 {
12843 .cmd = NL80211_CMD_JOIN_IBSS,
12844 .doit = nl80211_join_ibss,
12845 .policy = nl80211_policy,
5617c6cd 12846 .flags = GENL_UNS_ADMIN_PERM,
41265714 12847 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12848 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
12849 },
12850 {
12851 .cmd = NL80211_CMD_LEAVE_IBSS,
12852 .doit = nl80211_leave_ibss,
12853 .policy = nl80211_policy,
5617c6cd 12854 .flags = GENL_UNS_ADMIN_PERM,
41265714 12855 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12856 NL80211_FLAG_NEED_RTNL,
04a773ad 12857 },
aff89a9b
JB
12858#ifdef CONFIG_NL80211_TESTMODE
12859 {
12860 .cmd = NL80211_CMD_TESTMODE,
12861 .doit = nl80211_testmode_do,
71063f0e 12862 .dumpit = nl80211_testmode_dump,
aff89a9b 12863 .policy = nl80211_policy,
5617c6cd 12864 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12865 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12866 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
12867 },
12868#endif
b23aa676
SO
12869 {
12870 .cmd = NL80211_CMD_CONNECT,
12871 .doit = nl80211_connect,
12872 .policy = nl80211_policy,
5617c6cd 12873 .flags = GENL_UNS_ADMIN_PERM,
41265714 12874 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12875 NL80211_FLAG_NEED_RTNL,
b23aa676 12876 },
088e8df8 12877 {
12878 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
12879 .doit = nl80211_update_connect_params,
12880 .policy = nl80211_policy,
12881 .flags = GENL_ADMIN_PERM,
12882 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12883 NL80211_FLAG_NEED_RTNL,
12884 },
b23aa676
SO
12885 {
12886 .cmd = NL80211_CMD_DISCONNECT,
12887 .doit = nl80211_disconnect,
12888 .policy = nl80211_policy,
5617c6cd 12889 .flags = GENL_UNS_ADMIN_PERM,
41265714 12890 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12891 NL80211_FLAG_NEED_RTNL,
b23aa676 12892 },
463d0183
JB
12893 {
12894 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
12895 .doit = nl80211_wiphy_netns,
12896 .policy = nl80211_policy,
5617c6cd 12897 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12898 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12899 NL80211_FLAG_NEED_RTNL,
463d0183 12900 },
61fa713c
HS
12901 {
12902 .cmd = NL80211_CMD_GET_SURVEY,
12903 .policy = nl80211_policy,
12904 .dumpit = nl80211_dump_survey,
12905 },
67fbb16b
SO
12906 {
12907 .cmd = NL80211_CMD_SET_PMKSA,
12908 .doit = nl80211_setdel_pmksa,
12909 .policy = nl80211_policy,
5617c6cd 12910 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12911 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12912 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12913 },
12914 {
12915 .cmd = NL80211_CMD_DEL_PMKSA,
12916 .doit = nl80211_setdel_pmksa,
12917 .policy = nl80211_policy,
5617c6cd 12918 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12919 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12920 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12921 },
12922 {
12923 .cmd = NL80211_CMD_FLUSH_PMKSA,
12924 .doit = nl80211_flush_pmksa,
12925 .policy = nl80211_policy,
5617c6cd 12926 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12927 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12928 NL80211_FLAG_NEED_RTNL,
67fbb16b 12929 },
9588bbd5
JM
12930 {
12931 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
12932 .doit = nl80211_remain_on_channel,
12933 .policy = nl80211_policy,
5617c6cd 12934 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12935 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12936 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
12937 },
12938 {
12939 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
12940 .doit = nl80211_cancel_remain_on_channel,
12941 .policy = nl80211_policy,
5617c6cd 12942 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12943 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12944 NL80211_FLAG_NEED_RTNL,
9588bbd5 12945 },
13ae75b1
JM
12946 {
12947 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
12948 .doit = nl80211_set_tx_bitrate_mask,
12949 .policy = nl80211_policy,
5617c6cd 12950 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12951 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12952 NL80211_FLAG_NEED_RTNL,
13ae75b1 12953 },
026331c4 12954 {
2e161f78
JB
12955 .cmd = NL80211_CMD_REGISTER_FRAME,
12956 .doit = nl80211_register_mgmt,
026331c4 12957 .policy = nl80211_policy,
5617c6cd 12958 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12959 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 12960 NL80211_FLAG_NEED_RTNL,
026331c4
JM
12961 },
12962 {
2e161f78
JB
12963 .cmd = NL80211_CMD_FRAME,
12964 .doit = nl80211_tx_mgmt,
026331c4 12965 .policy = nl80211_policy,
5617c6cd 12966 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12967 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
12968 NL80211_FLAG_NEED_RTNL,
12969 },
12970 {
12971 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
12972 .doit = nl80211_tx_mgmt_cancel_wait,
12973 .policy = nl80211_policy,
5617c6cd 12974 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12975 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12976 NL80211_FLAG_NEED_RTNL,
026331c4 12977 },
ffb9eb3d
KV
12978 {
12979 .cmd = NL80211_CMD_SET_POWER_SAVE,
12980 .doit = nl80211_set_power_save,
12981 .policy = nl80211_policy,
5617c6cd 12982 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12983 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12984 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
12985 },
12986 {
12987 .cmd = NL80211_CMD_GET_POWER_SAVE,
12988 .doit = nl80211_get_power_save,
12989 .policy = nl80211_policy,
12990 /* can be retrieved by unprivileged users */
4c476991
JB
12991 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12992 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 12993 },
d6dc1a38
JO
12994 {
12995 .cmd = NL80211_CMD_SET_CQM,
12996 .doit = nl80211_set_cqm,
12997 .policy = nl80211_policy,
5617c6cd 12998 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12999 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13000 NL80211_FLAG_NEED_RTNL,
d6dc1a38 13001 },
f444de05
JB
13002 {
13003 .cmd = NL80211_CMD_SET_CHANNEL,
13004 .doit = nl80211_set_channel,
13005 .policy = nl80211_policy,
5617c6cd 13006 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13007 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13008 NL80211_FLAG_NEED_RTNL,
f444de05 13009 },
e8347eba
BJ
13010 {
13011 .cmd = NL80211_CMD_SET_WDS_PEER,
13012 .doit = nl80211_set_wds_peer,
13013 .policy = nl80211_policy,
5617c6cd 13014 .flags = GENL_UNS_ADMIN_PERM,
43b19952
JB
13015 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13016 NL80211_FLAG_NEED_RTNL,
e8347eba 13017 },
29cbe68c
JB
13018 {
13019 .cmd = NL80211_CMD_JOIN_MESH,
13020 .doit = nl80211_join_mesh,
13021 .policy = nl80211_policy,
5617c6cd 13022 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
13023 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13024 NL80211_FLAG_NEED_RTNL,
13025 },
13026 {
13027 .cmd = NL80211_CMD_LEAVE_MESH,
13028 .doit = nl80211_leave_mesh,
13029 .policy = nl80211_policy,
5617c6cd 13030 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
13031 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13032 NL80211_FLAG_NEED_RTNL,
13033 },
6e0bd6c3
RL
13034 {
13035 .cmd = NL80211_CMD_JOIN_OCB,
13036 .doit = nl80211_join_ocb,
13037 .policy = nl80211_policy,
5617c6cd 13038 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
13039 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13040 NL80211_FLAG_NEED_RTNL,
13041 },
13042 {
13043 .cmd = NL80211_CMD_LEAVE_OCB,
13044 .doit = nl80211_leave_ocb,
13045 .policy = nl80211_policy,
5617c6cd 13046 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
13047 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13048 NL80211_FLAG_NEED_RTNL,
13049 },
dfb89c56 13050#ifdef CONFIG_PM
ff1b6e69
JB
13051 {
13052 .cmd = NL80211_CMD_GET_WOWLAN,
13053 .doit = nl80211_get_wowlan,
13054 .policy = nl80211_policy,
13055 /* can be retrieved by unprivileged users */
13056 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13057 NL80211_FLAG_NEED_RTNL,
13058 },
13059 {
13060 .cmd = NL80211_CMD_SET_WOWLAN,
13061 .doit = nl80211_set_wowlan,
13062 .policy = nl80211_policy,
5617c6cd 13063 .flags = GENL_UNS_ADMIN_PERM,
ff1b6e69
JB
13064 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13065 NL80211_FLAG_NEED_RTNL,
13066 },
dfb89c56 13067#endif
e5497d76
JB
13068 {
13069 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
13070 .doit = nl80211_set_rekey_data,
13071 .policy = nl80211_policy,
5617c6cd 13072 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 13073 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
13074 NL80211_FLAG_NEED_RTNL |
13075 NL80211_FLAG_CLEAR_SKB,
e5497d76 13076 },
109086ce
AN
13077 {
13078 .cmd = NL80211_CMD_TDLS_MGMT,
13079 .doit = nl80211_tdls_mgmt,
13080 .policy = nl80211_policy,
5617c6cd 13081 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
13082 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13083 NL80211_FLAG_NEED_RTNL,
13084 },
13085 {
13086 .cmd = NL80211_CMD_TDLS_OPER,
13087 .doit = nl80211_tdls_oper,
13088 .policy = nl80211_policy,
5617c6cd 13089 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
13090 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13091 NL80211_FLAG_NEED_RTNL,
13092 },
28946da7
JB
13093 {
13094 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
13095 .doit = nl80211_register_unexpected_frame,
13096 .policy = nl80211_policy,
5617c6cd 13097 .flags = GENL_UNS_ADMIN_PERM,
28946da7
JB
13098 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13099 NL80211_FLAG_NEED_RTNL,
13100 },
7f6cf311
JB
13101 {
13102 .cmd = NL80211_CMD_PROBE_CLIENT,
13103 .doit = nl80211_probe_client,
13104 .policy = nl80211_policy,
5617c6cd 13105 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13106 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
13107 NL80211_FLAG_NEED_RTNL,
13108 },
5e760230
JB
13109 {
13110 .cmd = NL80211_CMD_REGISTER_BEACONS,
13111 .doit = nl80211_register_beacons,
13112 .policy = nl80211_policy,
5617c6cd 13113 .flags = GENL_UNS_ADMIN_PERM,
5e760230
JB
13114 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13115 NL80211_FLAG_NEED_RTNL,
13116 },
1d9d9213
SW
13117 {
13118 .cmd = NL80211_CMD_SET_NOACK_MAP,
13119 .doit = nl80211_set_noack_map,
13120 .policy = nl80211_policy,
5617c6cd 13121 .flags = GENL_UNS_ADMIN_PERM,
1d9d9213
SW
13122 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13123 NL80211_FLAG_NEED_RTNL,
13124 },
98104fde
JB
13125 {
13126 .cmd = NL80211_CMD_START_P2P_DEVICE,
13127 .doit = nl80211_start_p2p_device,
13128 .policy = nl80211_policy,
5617c6cd 13129 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
13130 .internal_flags = NL80211_FLAG_NEED_WDEV |
13131 NL80211_FLAG_NEED_RTNL,
13132 },
13133 {
13134 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
13135 .doit = nl80211_stop_p2p_device,
13136 .policy = nl80211_policy,
5617c6cd 13137 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
13138 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13139 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
13140 },
13141 {
13142 .cmd = NL80211_CMD_START_NAN,
13143 .doit = nl80211_start_nan,
13144 .policy = nl80211_policy,
13145 .flags = GENL_ADMIN_PERM,
13146 .internal_flags = NL80211_FLAG_NEED_WDEV |
13147 NL80211_FLAG_NEED_RTNL,
13148 },
13149 {
13150 .cmd = NL80211_CMD_STOP_NAN,
13151 .doit = nl80211_stop_nan,
13152 .policy = nl80211_policy,
13153 .flags = GENL_ADMIN_PERM,
13154 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13155 NL80211_FLAG_NEED_RTNL,
a442b761
AB
13156 },
13157 {
13158 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
13159 .doit = nl80211_nan_add_func,
13160 .policy = nl80211_policy,
13161 .flags = GENL_ADMIN_PERM,
13162 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13163 NL80211_FLAG_NEED_RTNL,
13164 },
13165 {
13166 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
13167 .doit = nl80211_nan_del_func,
13168 .policy = nl80211_policy,
13169 .flags = GENL_ADMIN_PERM,
13170 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13171 NL80211_FLAG_NEED_RTNL,
a5a9dcf2
AB
13172 },
13173 {
13174 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
13175 .doit = nl80211_nan_change_config,
13176 .policy = nl80211_policy,
13177 .flags = GENL_ADMIN_PERM,
13178 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13179 NL80211_FLAG_NEED_RTNL,
98104fde 13180 },
f4e583c8
AQ
13181 {
13182 .cmd = NL80211_CMD_SET_MCAST_RATE,
13183 .doit = nl80211_set_mcast_rate,
77765eaf 13184 .policy = nl80211_policy,
5617c6cd 13185 .flags = GENL_UNS_ADMIN_PERM,
77765eaf
VT
13186 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13187 NL80211_FLAG_NEED_RTNL,
13188 },
13189 {
13190 .cmd = NL80211_CMD_SET_MAC_ACL,
13191 .doit = nl80211_set_mac_acl,
f4e583c8 13192 .policy = nl80211_policy,
5617c6cd 13193 .flags = GENL_UNS_ADMIN_PERM,
f4e583c8
AQ
13194 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13195 NL80211_FLAG_NEED_RTNL,
13196 },
04f39047
SW
13197 {
13198 .cmd = NL80211_CMD_RADAR_DETECT,
13199 .doit = nl80211_start_radar_detection,
13200 .policy = nl80211_policy,
5617c6cd 13201 .flags = GENL_UNS_ADMIN_PERM,
04f39047
SW
13202 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13203 NL80211_FLAG_NEED_RTNL,
13204 },
3713b4e3
JB
13205 {
13206 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
13207 .doit = nl80211_get_protocol_features,
13208 .policy = nl80211_policy,
13209 },
355199e0
JM
13210 {
13211 .cmd = NL80211_CMD_UPDATE_FT_IES,
13212 .doit = nl80211_update_ft_ies,
13213 .policy = nl80211_policy,
5617c6cd 13214 .flags = GENL_UNS_ADMIN_PERM,
355199e0
JM
13215 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13216 NL80211_FLAG_NEED_RTNL,
13217 },
5de17984
AS
13218 {
13219 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
13220 .doit = nl80211_crit_protocol_start,
13221 .policy = nl80211_policy,
5617c6cd 13222 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
13223 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13224 NL80211_FLAG_NEED_RTNL,
13225 },
13226 {
13227 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
13228 .doit = nl80211_crit_protocol_stop,
13229 .policy = nl80211_policy,
5617c6cd 13230 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
13231 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13232 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
13233 },
13234 {
13235 .cmd = NL80211_CMD_GET_COALESCE,
13236 .doit = nl80211_get_coalesce,
13237 .policy = nl80211_policy,
13238 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13239 NL80211_FLAG_NEED_RTNL,
13240 },
13241 {
13242 .cmd = NL80211_CMD_SET_COALESCE,
13243 .doit = nl80211_set_coalesce,
13244 .policy = nl80211_policy,
5617c6cd 13245 .flags = GENL_UNS_ADMIN_PERM,
be29b99a
AK
13246 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13247 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
13248 },
13249 {
13250 .cmd = NL80211_CMD_CHANNEL_SWITCH,
13251 .doit = nl80211_channel_switch,
13252 .policy = nl80211_policy,
5617c6cd 13253 .flags = GENL_UNS_ADMIN_PERM,
16ef1fe2
SW
13254 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13255 NL80211_FLAG_NEED_RTNL,
13256 },
ad7e718c
JB
13257 {
13258 .cmd = NL80211_CMD_VENDOR,
13259 .doit = nl80211_vendor_cmd,
7bdbe400 13260 .dumpit = nl80211_vendor_cmd_dump,
ad7e718c 13261 .policy = nl80211_policy,
5617c6cd 13262 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c
JB
13263 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13264 NL80211_FLAG_NEED_RTNL,
13265 },
fa9ffc74
KP
13266 {
13267 .cmd = NL80211_CMD_SET_QOS_MAP,
13268 .doit = nl80211_set_qos_map,
13269 .policy = nl80211_policy,
5617c6cd 13270 .flags = GENL_UNS_ADMIN_PERM,
fa9ffc74
KP
13271 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13272 NL80211_FLAG_NEED_RTNL,
13273 },
960d01ac
JB
13274 {
13275 .cmd = NL80211_CMD_ADD_TX_TS,
13276 .doit = nl80211_add_tx_ts,
13277 .policy = nl80211_policy,
5617c6cd 13278 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
13279 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13280 NL80211_FLAG_NEED_RTNL,
13281 },
13282 {
13283 .cmd = NL80211_CMD_DEL_TX_TS,
13284 .doit = nl80211_del_tx_ts,
13285 .policy = nl80211_policy,
5617c6cd 13286 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
13287 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13288 NL80211_FLAG_NEED_RTNL,
13289 },
1057d35e
AN
13290 {
13291 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
13292 .doit = nl80211_tdls_channel_switch,
13293 .policy = nl80211_policy,
5617c6cd 13294 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
13295 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13296 NL80211_FLAG_NEED_RTNL,
13297 },
13298 {
13299 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
13300 .doit = nl80211_tdls_cancel_channel_switch,
13301 .policy = nl80211_policy,
5617c6cd 13302 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
13303 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13304 NL80211_FLAG_NEED_RTNL,
13305 },
ce0ce13a
MB
13306 {
13307 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
13308 .doit = nl80211_set_multicast_to_unicast,
13309 .policy = nl80211_policy,
13310 .flags = GENL_UNS_ADMIN_PERM,
13311 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13312 NL80211_FLAG_NEED_RTNL,
13313 },
3a00df57
AS
13314 {
13315 .cmd = NL80211_CMD_SET_PMK,
13316 .doit = nl80211_set_pmk,
13317 .policy = nl80211_policy,
13318 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13319 NL80211_FLAG_NEED_RTNL,
13320 },
13321 {
13322 .cmd = NL80211_CMD_DEL_PMK,
13323 .doit = nl80211_del_pmk,
13324 .policy = nl80211_policy,
13325 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13326 NL80211_FLAG_NEED_RTNL,
13327 },
13328
55682965 13329};
9588bbd5 13330
56989f6d 13331static struct genl_family nl80211_fam __ro_after_init = {
489111e5
JB
13332 .name = NL80211_GENL_NAME, /* have users key off the name instead */
13333 .hdrsize = 0, /* no private header */
13334 .version = 1, /* no particular meaning now */
13335 .maxattr = NL80211_ATTR_MAX,
13336 .netnsok = true,
13337 .pre_doit = nl80211_pre_doit,
13338 .post_doit = nl80211_post_doit,
13339 .module = THIS_MODULE,
13340 .ops = nl80211_ops,
13341 .n_ops = ARRAY_SIZE(nl80211_ops),
13342 .mcgrps = nl80211_mcgrps,
13343 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
13344};
13345
55682965
JB
13346/* notification functions */
13347
3bb20556
JB
13348void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
13349 enum nl80211_commands cmd)
55682965
JB
13350{
13351 struct sk_buff *msg;
86e8cf98 13352 struct nl80211_dump_wiphy_state state = {};
55682965 13353
3bb20556
JB
13354 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
13355 cmd != NL80211_CMD_DEL_WIPHY);
13356
fd2120ca 13357 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
13358 if (!msg)
13359 return;
13360
3bb20556 13361 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
13362 nlmsg_free(msg);
13363 return;
13364 }
13365
68eb5503 13366 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13367 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
13368}
13369
896ff063
DK
13370void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
13371 struct wireless_dev *wdev,
13372 enum nl80211_commands cmd)
13373{
13374 struct sk_buff *msg;
13375
13376 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
13377 cmd != NL80211_CMD_DEL_INTERFACE);
13378
13379 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13380 if (!msg)
13381 return;
13382
13383 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev,
13384 cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
13385 nlmsg_free(msg);
13386 return;
13387 }
13388
13389 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
13390 NL80211_MCGRP_CONFIG, GFP_KERNEL);
13391}
13392
362a415d
JB
13393static int nl80211_add_scan_req(struct sk_buff *msg,
13394 struct cfg80211_registered_device *rdev)
13395{
13396 struct cfg80211_scan_request *req = rdev->scan_req;
13397 struct nlattr *nest;
13398 int i;
13399
13400 if (WARN_ON(!req))
13401 return 0;
13402
13403 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
13404 if (!nest)
13405 goto nla_put_failure;
9360ffd1
DM
13406 for (i = 0; i < req->n_ssids; i++) {
13407 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
13408 goto nla_put_failure;
13409 }
362a415d
JB
13410 nla_nest_end(msg, nest);
13411
13412 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
13413 if (!nest)
13414 goto nla_put_failure;
9360ffd1
DM
13415 for (i = 0; i < req->n_channels; i++) {
13416 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
13417 goto nla_put_failure;
13418 }
362a415d
JB
13419 nla_nest_end(msg, nest);
13420
9360ffd1
DM
13421 if (req->ie &&
13422 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
13423 goto nla_put_failure;
362a415d 13424
ae917c9f
JB
13425 if (req->flags &&
13426 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
13427 goto nla_put_failure;
ed473771 13428
1d76250b
AS
13429 if (req->info.scan_start_tsf &&
13430 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
13431 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
13432 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
13433 req->info.tsf_bssid)))
13434 goto nla_put_failure;
13435
362a415d
JB
13436 return 0;
13437 nla_put_failure:
13438 return -ENOBUFS;
13439}
13440
505a2e88 13441static int nl80211_prep_scan_msg(struct sk_buff *msg,
a538e2d5 13442 struct cfg80211_registered_device *rdev,
fd014284 13443 struct wireless_dev *wdev,
15e47304 13444 u32 portid, u32 seq, int flags,
a538e2d5 13445 u32 cmd)
2a519311
JB
13446{
13447 void *hdr;
13448
15e47304 13449 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
13450 if (!hdr)
13451 return -1;
13452
9360ffd1 13453 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
13454 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13455 wdev->netdev->ifindex)) ||
2dad624e
ND
13456 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13457 NL80211_ATTR_PAD))
9360ffd1 13458 goto nla_put_failure;
2a519311 13459
362a415d
JB
13460 /* ignore errors and send incomplete event anyway */
13461 nl80211_add_scan_req(msg, rdev);
2a519311 13462
053c095a
JB
13463 genlmsg_end(msg, hdr);
13464 return 0;
2a519311
JB
13465
13466 nla_put_failure:
13467 genlmsg_cancel(msg, hdr);
13468 return -EMSGSIZE;
13469}
13470
807f8a8c 13471static int
505a2e88 13472nl80211_prep_sched_scan_msg(struct sk_buff *msg,
96b08fd6 13473 struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
13474{
13475 void *hdr;
13476
96b08fd6 13477 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
807f8a8c
LC
13478 if (!hdr)
13479 return -1;
13480
96b08fd6
AVS
13481 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
13482 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
13483 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
13484 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
13485 NL80211_ATTR_PAD))
9360ffd1 13486 goto nla_put_failure;
807f8a8c 13487
053c095a
JB
13488 genlmsg_end(msg, hdr);
13489 return 0;
807f8a8c
LC
13490
13491 nla_put_failure:
13492 genlmsg_cancel(msg, hdr);
13493 return -EMSGSIZE;
13494}
13495
a538e2d5 13496void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 13497 struct wireless_dev *wdev)
a538e2d5
JB
13498{
13499 struct sk_buff *msg;
13500
58050fce 13501 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
13502 if (!msg)
13503 return;
13504
505a2e88 13505 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
13506 NL80211_CMD_TRIGGER_SCAN) < 0) {
13507 nlmsg_free(msg);
13508 return;
13509 }
13510
68eb5503 13511 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13512 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
13513}
13514
f9d15d16
JB
13515struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
13516 struct wireless_dev *wdev, bool aborted)
2a519311
JB
13517{
13518 struct sk_buff *msg;
13519
fd2120ca 13520 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 13521 if (!msg)
f9d15d16 13522 return NULL;
2a519311 13523
505a2e88 13524 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
13525 aborted ? NL80211_CMD_SCAN_ABORTED :
13526 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 13527 nlmsg_free(msg);
f9d15d16 13528 return NULL;
2a519311
JB
13529 }
13530
f9d15d16 13531 return msg;
2a519311
JB
13532}
13533
505a2e88
AVS
13534/* send message created by nl80211_build_scan_msg() */
13535void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
13536 struct sk_buff *msg)
807f8a8c 13537{
807f8a8c
LC
13538 if (!msg)
13539 return;
13540
68eb5503 13541 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13542 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
13543}
13544
96b08fd6 13545void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
13546{
13547 struct sk_buff *msg;
13548
58050fce 13549 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
13550 if (!msg)
13551 return;
13552
96b08fd6 13553 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
807f8a8c
LC
13554 nlmsg_free(msg);
13555 return;
13556 }
13557
96b08fd6 13558 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
2a94fe48 13559 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
13560}
13561
b0d7aa59
JD
13562static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
13563 struct regulatory_request *request)
73d54c9e 13564{
73d54c9e 13565 /* Userspace can always count this one always being set */
9360ffd1
DM
13566 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
13567 goto nla_put_failure;
13568
13569 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
13570 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13571 NL80211_REGDOM_TYPE_WORLD))
13572 goto nla_put_failure;
13573 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
13574 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13575 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
13576 goto nla_put_failure;
13577 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
13578 request->intersect) {
13579 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13580 NL80211_REGDOM_TYPE_INTERSECTION))
13581 goto nla_put_failure;
13582 } else {
13583 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13584 NL80211_REGDOM_TYPE_COUNTRY) ||
13585 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
13586 request->alpha2))
13587 goto nla_put_failure;
13588 }
13589
ad30ca2c
AN
13590 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
13591 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
13592
13593 if (wiphy &&
13594 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
13595 goto nla_put_failure;
1bdd716c
AN
13596
13597 if (wiphy &&
13598 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
13599 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
13600 goto nla_put_failure;
ad30ca2c 13601 }
73d54c9e 13602
b0d7aa59
JD
13603 return true;
13604
13605nla_put_failure:
13606 return false;
13607}
13608
13609/*
13610 * This can happen on global regulatory changes or device specific settings
13611 * based on custom regulatory domains.
13612 */
13613void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
13614 struct regulatory_request *request)
13615{
13616 struct sk_buff *msg;
13617 void *hdr;
13618
13619 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13620 if (!msg)
13621 return;
13622
13623 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
13624 if (!hdr) {
13625 nlmsg_free(msg);
13626 return;
13627 }
13628
13629 if (nl80211_reg_change_event_fill(msg, request) == false)
13630 goto nla_put_failure;
13631
3b7b72ee 13632 genlmsg_end(msg, hdr);
73d54c9e 13633
bc43b28c 13634 rcu_read_lock();
68eb5503 13635 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 13636 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 13637 rcu_read_unlock();
73d54c9e
LR
13638
13639 return;
13640
13641nla_put_failure:
13642 genlmsg_cancel(msg, hdr);
13643 nlmsg_free(msg);
13644}
13645
6039f6d2
JM
13646static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
13647 struct net_device *netdev,
13648 const u8 *buf, size_t len,
b0b6aa2c
EP
13649 enum nl80211_commands cmd, gfp_t gfp,
13650 int uapsd_queues)
6039f6d2
JM
13651{
13652 struct sk_buff *msg;
13653 void *hdr;
13654
4ef8c1c9 13655 msg = nlmsg_new(100 + len, gfp);
6039f6d2
JM
13656 if (!msg)
13657 return;
13658
13659 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13660 if (!hdr) {
13661 nlmsg_free(msg);
13662 return;
13663 }
13664
9360ffd1
DM
13665 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13666 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13667 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
13668 goto nla_put_failure;
6039f6d2 13669
b0b6aa2c
EP
13670 if (uapsd_queues >= 0) {
13671 struct nlattr *nla_wmm =
13672 nla_nest_start(msg, NL80211_ATTR_STA_WME);
13673 if (!nla_wmm)
13674 goto nla_put_failure;
13675
13676 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
13677 uapsd_queues))
13678 goto nla_put_failure;
13679
13680 nla_nest_end(msg, nla_wmm);
13681 }
13682
3b7b72ee 13683 genlmsg_end(msg, hdr);
6039f6d2 13684
68eb5503 13685 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13686 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
13687 return;
13688
13689 nla_put_failure:
13690 genlmsg_cancel(msg, hdr);
13691 nlmsg_free(msg);
13692}
13693
13694void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13695 struct net_device *netdev, const u8 *buf,
13696 size_t len, gfp_t gfp)
6039f6d2
JM
13697{
13698 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13699 NL80211_CMD_AUTHENTICATE, gfp, -1);
6039f6d2
JM
13700}
13701
13702void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
13703 struct net_device *netdev, const u8 *buf,
b0b6aa2c 13704 size_t len, gfp_t gfp, int uapsd_queues)
6039f6d2 13705{
e6d6e342 13706 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13707 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues);
6039f6d2
JM
13708}
13709
53b46b84 13710void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13711 struct net_device *netdev, const u8 *buf,
13712 size_t len, gfp_t gfp)
6039f6d2
JM
13713{
13714 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13715 NL80211_CMD_DEAUTHENTICATE, gfp, -1);
6039f6d2
JM
13716}
13717
53b46b84
JM
13718void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
13719 struct net_device *netdev, const u8 *buf,
e6d6e342 13720 size_t len, gfp_t gfp)
6039f6d2
JM
13721{
13722 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13723 NL80211_CMD_DISASSOCIATE, gfp, -1);
6039f6d2
JM
13724}
13725
6ff57cf8
JB
13726void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
13727 size_t len)
cf4e594e 13728{
947add36
JB
13729 struct wireless_dev *wdev = dev->ieee80211_ptr;
13730 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13731 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
13732 const struct ieee80211_mgmt *mgmt = (void *)buf;
13733 u32 cmd;
947add36 13734
6ff57cf8
JB
13735 if (WARN_ON(len < 2))
13736 return;
cf4e594e 13737
6ff57cf8
JB
13738 if (ieee80211_is_deauth(mgmt->frame_control))
13739 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
13740 else
13741 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 13742
6ff57cf8 13743 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
b0b6aa2c 13744 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1);
cf4e594e 13745}
6ff57cf8 13746EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 13747
1b06bb40
LR
13748static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
13749 struct net_device *netdev, int cmd,
e6d6e342 13750 const u8 *addr, gfp_t gfp)
1965c853
JM
13751{
13752 struct sk_buff *msg;
13753 void *hdr;
13754
e6d6e342 13755 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
13756 if (!msg)
13757 return;
13758
13759 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13760 if (!hdr) {
13761 nlmsg_free(msg);
13762 return;
13763 }
13764
9360ffd1
DM
13765 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13766 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13767 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
13768 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
13769 goto nla_put_failure;
1965c853 13770
3b7b72ee 13771 genlmsg_end(msg, hdr);
1965c853 13772
68eb5503 13773 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13774 NL80211_MCGRP_MLME, gfp);
1965c853
JM
13775 return;
13776
13777 nla_put_failure:
13778 genlmsg_cancel(msg, hdr);
13779 nlmsg_free(msg);
13780}
13781
13782void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13783 struct net_device *netdev, const u8 *addr,
13784 gfp_t gfp)
1965c853
JM
13785{
13786 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 13787 addr, gfp);
1965c853
JM
13788}
13789
13790void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13791 struct net_device *netdev, const u8 *addr,
13792 gfp_t gfp)
1965c853 13793{
e6d6e342
JB
13794 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
13795 addr, gfp);
1965c853
JM
13796}
13797
b23aa676 13798void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
5349a0f7
VK
13799 struct net_device *netdev,
13800 struct cfg80211_connect_resp_params *cr,
3093ebbe 13801 gfp_t gfp)
b23aa676
SO
13802{
13803 struct sk_buff *msg;
13804 void *hdr;
13805
a3caf744
VK
13806 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
13807 cr->fils_kek_len + cr->pmk_len +
13808 (cr->pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
13809 if (!msg)
13810 return;
13811
13812 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
13813 if (!hdr) {
13814 nlmsg_free(msg);
13815 return;
13816 }
13817
9360ffd1
DM
13818 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13819 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
5349a0f7
VK
13820 (cr->bssid &&
13821 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
bf1ecd21 13822 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
5349a0f7
VK
13823 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
13824 cr->status) ||
13825 (cr->status < 0 &&
3093ebbe 13826 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
5349a0f7
VK
13827 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
13828 cr->timeout_reason))) ||
13829 (cr->req_ie &&
13830 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
13831 (cr->resp_ie &&
13832 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
a3caf744
VK
13833 cr->resp_ie)) ||
13834 (cr->update_erp_next_seq_num &&
13835 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
13836 cr->fils_erp_next_seq_num)) ||
13837 (cr->status == WLAN_STATUS_SUCCESS &&
13838 ((cr->fils_kek &&
13839 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils_kek_len,
13840 cr->fils_kek)) ||
13841 (cr->pmk &&
13842 nla_put(msg, NL80211_ATTR_PMK, cr->pmk_len, cr->pmk)) ||
13843 (cr->pmkid &&
13844 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->pmkid)))))
9360ffd1 13845 goto nla_put_failure;
b23aa676 13846
3b7b72ee 13847 genlmsg_end(msg, hdr);
b23aa676 13848
68eb5503 13849 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13850 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
13851 return;
13852
13853 nla_put_failure:
13854 genlmsg_cancel(msg, hdr);
13855 nlmsg_free(msg);
b23aa676
SO
13856}
13857
13858void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
29ce6ecb
AS
13859 struct net_device *netdev,
13860 struct cfg80211_roam_info *info, gfp_t gfp)
b23aa676
SO
13861{
13862 struct sk_buff *msg;
13863 void *hdr;
29ce6ecb 13864 const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
b23aa676 13865
29ce6ecb 13866 msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len, gfp);
b23aa676
SO
13867 if (!msg)
13868 return;
13869
13870 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
13871 if (!hdr) {
13872 nlmsg_free(msg);
13873 return;
13874 }
13875
9360ffd1
DM
13876 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13877 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13878 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
29ce6ecb
AS
13879 (info->req_ie &&
13880 nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
13881 info->req_ie)) ||
13882 (info->resp_ie &&
13883 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
503c1fb9 13884 info->resp_ie)))
9360ffd1 13885 goto nla_put_failure;
b23aa676 13886
3b7b72ee 13887 genlmsg_end(msg, hdr);
b23aa676 13888
68eb5503 13889 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13890 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
13891 return;
13892
503c1fb9
AS
13893 nla_put_failure:
13894 genlmsg_cancel(msg, hdr);
13895 nlmsg_free(msg);
13896}
13897
13898void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
13899 struct net_device *netdev, const u8 *bssid)
13900{
13901 struct sk_buff *msg;
13902 void *hdr;
13903
13904 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13905 if (!msg)
13906 return;
13907
13908 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
13909 if (!hdr) {
13910 nlmsg_free(msg);
13911 return;
13912 }
13913
13914 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13915 goto nla_put_failure;
13916
13917 genlmsg_end(msg, hdr);
13918
13919 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
13920 NL80211_MCGRP_MLME, GFP_KERNEL);
13921 return;
13922
b23aa676
SO
13923 nla_put_failure:
13924 genlmsg_cancel(msg, hdr);
13925 nlmsg_free(msg);
b23aa676
SO
13926}
13927
13928void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
13929 struct net_device *netdev, u16 reason,
667503dd 13930 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
13931{
13932 struct sk_buff *msg;
13933 void *hdr;
13934
4ef8c1c9 13935 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
b23aa676
SO
13936 if (!msg)
13937 return;
13938
13939 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
13940 if (!hdr) {
13941 nlmsg_free(msg);
13942 return;
13943 }
13944
9360ffd1
DM
13945 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13946 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13947 (from_ap && reason &&
13948 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
13949 (from_ap &&
13950 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
13951 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
13952 goto nla_put_failure;
b23aa676 13953
3b7b72ee 13954 genlmsg_end(msg, hdr);
b23aa676 13955
68eb5503 13956 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13957 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
13958 return;
13959
13960 nla_put_failure:
13961 genlmsg_cancel(msg, hdr);
13962 nlmsg_free(msg);
b23aa676
SO
13963}
13964
04a773ad
JB
13965void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
13966 struct net_device *netdev, const u8 *bssid,
13967 gfp_t gfp)
13968{
13969 struct sk_buff *msg;
13970 void *hdr;
13971
fd2120ca 13972 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
13973 if (!msg)
13974 return;
13975
13976 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
13977 if (!hdr) {
13978 nlmsg_free(msg);
13979 return;
13980 }
13981
9360ffd1
DM
13982 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13983 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13984 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13985 goto nla_put_failure;
04a773ad 13986
3b7b72ee 13987 genlmsg_end(msg, hdr);
04a773ad 13988
68eb5503 13989 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13990 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
13991 return;
13992
13993 nla_put_failure:
13994 genlmsg_cancel(msg, hdr);
13995 nlmsg_free(msg);
13996}
13997
947add36
JB
13998void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
13999 const u8* ie, u8 ie_len, gfp_t gfp)
c93b5e71 14000{
947add36 14001 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14002 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
14003 struct sk_buff *msg;
14004 void *hdr;
14005
947add36
JB
14006 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
14007 return;
14008
14009 trace_cfg80211_notify_new_peer_candidate(dev, addr);
14010
4ef8c1c9 14011 msg = nlmsg_new(100 + ie_len, gfp);
c93b5e71
JC
14012 if (!msg)
14013 return;
14014
14015 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
14016 if (!hdr) {
14017 nlmsg_free(msg);
14018 return;
14019 }
14020
9360ffd1 14021 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
14022 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14023 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1
DM
14024 (ie_len && ie &&
14025 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
14026 goto nla_put_failure;
c93b5e71 14027
3b7b72ee 14028 genlmsg_end(msg, hdr);
c93b5e71 14029
68eb5503 14030 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14031 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
14032 return;
14033
14034 nla_put_failure:
14035 genlmsg_cancel(msg, hdr);
14036 nlmsg_free(msg);
14037}
947add36 14038EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 14039
a3b8b056
JM
14040void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
14041 struct net_device *netdev, const u8 *addr,
14042 enum nl80211_key_type key_type, int key_id,
e6d6e342 14043 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
14044{
14045 struct sk_buff *msg;
14046 void *hdr;
14047
e6d6e342 14048 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
14049 if (!msg)
14050 return;
14051
14052 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
14053 if (!hdr) {
14054 nlmsg_free(msg);
14055 return;
14056 }
14057
9360ffd1
DM
14058 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14059 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14060 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
14061 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
14062 (key_id != -1 &&
14063 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
14064 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
14065 goto nla_put_failure;
a3b8b056 14066
3b7b72ee 14067 genlmsg_end(msg, hdr);
a3b8b056 14068
68eb5503 14069 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14070 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
14071 return;
14072
14073 nla_put_failure:
14074 genlmsg_cancel(msg, hdr);
14075 nlmsg_free(msg);
14076}
14077
6bad8766
LR
14078void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
14079 struct ieee80211_channel *channel_before,
14080 struct ieee80211_channel *channel_after)
14081{
14082 struct sk_buff *msg;
14083 void *hdr;
14084 struct nlattr *nl_freq;
14085
fd2120ca 14086 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
14087 if (!msg)
14088 return;
14089
14090 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
14091 if (!hdr) {
14092 nlmsg_free(msg);
14093 return;
14094 }
14095
14096 /*
14097 * Since we are applying the beacon hint to a wiphy we know its
14098 * wiphy_idx is valid
14099 */
9360ffd1
DM
14100 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
14101 goto nla_put_failure;
6bad8766
LR
14102
14103 /* Before */
14104 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
14105 if (!nl_freq)
14106 goto nla_put_failure;
cdc89b97 14107 if (nl80211_msg_put_channel(msg, channel_before, false))
6bad8766
LR
14108 goto nla_put_failure;
14109 nla_nest_end(msg, nl_freq);
14110
14111 /* After */
14112 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
14113 if (!nl_freq)
14114 goto nla_put_failure;
cdc89b97 14115 if (nl80211_msg_put_channel(msg, channel_after, false))
6bad8766
LR
14116 goto nla_put_failure;
14117 nla_nest_end(msg, nl_freq);
14118
3b7b72ee 14119 genlmsg_end(msg, hdr);
6bad8766 14120
463d0183 14121 rcu_read_lock();
68eb5503 14122 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 14123 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 14124 rcu_read_unlock();
6bad8766
LR
14125
14126 return;
14127
14128nla_put_failure:
14129 genlmsg_cancel(msg, hdr);
14130 nlmsg_free(msg);
14131}
14132
9588bbd5
JM
14133static void nl80211_send_remain_on_chan_event(
14134 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 14135 struct wireless_dev *wdev, u64 cookie,
9588bbd5 14136 struct ieee80211_channel *chan,
9588bbd5
JM
14137 unsigned int duration, gfp_t gfp)
14138{
14139 struct sk_buff *msg;
14140 void *hdr;
14141
14142 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14143 if (!msg)
14144 return;
14145
14146 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
14147 if (!hdr) {
14148 nlmsg_free(msg);
14149 return;
14150 }
14151
9360ffd1 14152 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
14153 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14154 wdev->netdev->ifindex)) ||
2dad624e
ND
14155 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14156 NL80211_ATTR_PAD) ||
9360ffd1 14157 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
14158 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
14159 NL80211_CHAN_NO_HT) ||
2dad624e
ND
14160 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14161 NL80211_ATTR_PAD))
9360ffd1 14162 goto nla_put_failure;
9588bbd5 14163
9360ffd1
DM
14164 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
14165 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
14166 goto nla_put_failure;
9588bbd5 14167
3b7b72ee 14168 genlmsg_end(msg, hdr);
9588bbd5 14169
68eb5503 14170 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14171 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
14172 return;
14173
14174 nla_put_failure:
14175 genlmsg_cancel(msg, hdr);
14176 nlmsg_free(msg);
14177}
14178
947add36
JB
14179void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
14180 struct ieee80211_channel *chan,
14181 unsigned int duration, gfp_t gfp)
9588bbd5 14182{
947add36 14183 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14184 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14185
14186 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 14187 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 14188 rdev, wdev, cookie, chan,
42d97a59 14189 duration, gfp);
9588bbd5 14190}
947add36 14191EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 14192
947add36
JB
14193void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
14194 struct ieee80211_channel *chan,
14195 gfp_t gfp)
9588bbd5 14196{
947add36 14197 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14198 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14199
14200 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 14201 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 14202 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 14203}
947add36 14204EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 14205
947add36
JB
14206void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
14207 struct station_info *sinfo, gfp_t gfp)
98b62183 14208{
947add36 14209 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 14210 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
14211 struct sk_buff *msg;
14212
947add36
JB
14213 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
14214
58050fce 14215 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
14216 if (!msg)
14217 return;
14218
cf5ead82 14219 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 14220 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
14221 nlmsg_free(msg);
14222 return;
14223 }
14224
68eb5503 14225 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14226 NL80211_MCGRP_MLME, gfp);
98b62183 14227}
947add36 14228EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 14229
cf5ead82
JB
14230void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
14231 struct station_info *sinfo, gfp_t gfp)
ec15e68b 14232{
947add36 14233 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 14234 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 14235 struct sk_buff *msg;
cf5ead82
JB
14236 struct station_info empty_sinfo = {};
14237
14238 if (!sinfo)
14239 sinfo = &empty_sinfo;
ec15e68b 14240
947add36
JB
14241 trace_cfg80211_del_sta(dev, mac_addr);
14242
58050fce 14243 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
ec15e68b
JM
14244 if (!msg)
14245 return;
14246
cf5ead82 14247 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 14248 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b
JM
14249 nlmsg_free(msg);
14250 return;
14251 }
14252
68eb5503 14253 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14254 NL80211_MCGRP_MLME, gfp);
ec15e68b 14255}
cf5ead82 14256EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 14257
947add36
JB
14258void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
14259 enum nl80211_connect_failed_reason reason,
14260 gfp_t gfp)
ed44a951 14261{
947add36 14262 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 14263 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
14264 struct sk_buff *msg;
14265 void *hdr;
14266
14267 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
14268 if (!msg)
14269 return;
14270
14271 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
14272 if (!hdr) {
14273 nlmsg_free(msg);
14274 return;
14275 }
14276
14277 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14278 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
14279 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
14280 goto nla_put_failure;
14281
14282 genlmsg_end(msg, hdr);
14283
68eb5503 14284 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14285 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
14286 return;
14287
14288 nla_put_failure:
14289 genlmsg_cancel(msg, hdr);
14290 nlmsg_free(msg);
14291}
947add36 14292EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 14293
b92ab5d8
JB
14294static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
14295 const u8 *addr, gfp_t gfp)
28946da7
JB
14296{
14297 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14298 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
14299 struct sk_buff *msg;
14300 void *hdr;
6aa7de05 14301 u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
28946da7 14302
15e47304 14303 if (!nlportid)
28946da7
JB
14304 return false;
14305
14306 msg = nlmsg_new(100, gfp);
14307 if (!msg)
14308 return true;
14309
b92ab5d8 14310 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
14311 if (!hdr) {
14312 nlmsg_free(msg);
14313 return true;
14314 }
14315
9360ffd1
DM
14316 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14317 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14318 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
14319 goto nla_put_failure;
28946da7 14320
9c90a9f6 14321 genlmsg_end(msg, hdr);
15e47304 14322 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
14323 return true;
14324
14325 nla_put_failure:
14326 genlmsg_cancel(msg, hdr);
14327 nlmsg_free(msg);
14328 return true;
14329}
14330
947add36
JB
14331bool cfg80211_rx_spurious_frame(struct net_device *dev,
14332 const u8 *addr, gfp_t gfp)
b92ab5d8 14333{
947add36
JB
14334 struct wireless_dev *wdev = dev->ieee80211_ptr;
14335 bool ret;
14336
14337 trace_cfg80211_rx_spurious_frame(dev, addr);
14338
14339 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
14340 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
14341 trace_cfg80211_return_bool(false);
14342 return false;
14343 }
14344 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
14345 addr, gfp);
14346 trace_cfg80211_return_bool(ret);
14347 return ret;
b92ab5d8 14348}
947add36 14349EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 14350
947add36
JB
14351bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
14352 const u8 *addr, gfp_t gfp)
b92ab5d8 14353{
947add36
JB
14354 struct wireless_dev *wdev = dev->ieee80211_ptr;
14355 bool ret;
14356
14357 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
14358
14359 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
14360 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
14361 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
14362 trace_cfg80211_return_bool(false);
14363 return false;
14364 }
14365 ret = __nl80211_unexpected_frame(dev,
14366 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
14367 addr, gfp);
14368 trace_cfg80211_return_bool(ret);
14369 return ret;
b92ab5d8 14370}
947add36 14371EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 14372
2e161f78 14373int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 14374 struct wireless_dev *wdev, u32 nlportid,
804483e9 14375 int freq, int sig_dbm,
19504cf5 14376 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 14377{
71bbc994 14378 struct net_device *netdev = wdev->netdev;
026331c4
JM
14379 struct sk_buff *msg;
14380 void *hdr;
026331c4 14381
4ef8c1c9 14382 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
14383 if (!msg)
14384 return -ENOMEM;
14385
2e161f78 14386 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
14387 if (!hdr) {
14388 nlmsg_free(msg);
14389 return -ENOMEM;
14390 }
14391
9360ffd1 14392 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
14393 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14394 netdev->ifindex)) ||
2dad624e
ND
14395 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14396 NL80211_ATTR_PAD) ||
9360ffd1
DM
14397 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
14398 (sig_dbm &&
14399 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
14400 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
14401 (flags &&
14402 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 14403 goto nla_put_failure;
026331c4 14404
3b7b72ee 14405 genlmsg_end(msg, hdr);
026331c4 14406
15e47304 14407 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
14408
14409 nla_put_failure:
14410 genlmsg_cancel(msg, hdr);
14411 nlmsg_free(msg);
14412 return -ENOBUFS;
14413}
14414
947add36
JB
14415void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
14416 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 14417{
947add36 14418 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14419 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 14420 struct net_device *netdev = wdev->netdev;
026331c4
JM
14421 struct sk_buff *msg;
14422 void *hdr;
14423
947add36
JB
14424 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
14425
4ef8c1c9 14426 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
14427 if (!msg)
14428 return;
14429
2e161f78 14430 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
14431 if (!hdr) {
14432 nlmsg_free(msg);
14433 return;
14434 }
14435
9360ffd1 14436 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
14437 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14438 netdev->ifindex)) ||
2dad624e
ND
14439 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14440 NL80211_ATTR_PAD) ||
9360ffd1 14441 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
14442 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14443 NL80211_ATTR_PAD) ||
9360ffd1
DM
14444 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
14445 goto nla_put_failure;
026331c4 14446
3b7b72ee 14447 genlmsg_end(msg, hdr);
026331c4 14448
68eb5503 14449 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14450 NL80211_MCGRP_MLME, gfp);
026331c4
JM
14451 return;
14452
14453 nla_put_failure:
14454 genlmsg_cancel(msg, hdr);
14455 nlmsg_free(msg);
14456}
947add36 14457EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 14458
5b97f49d
JB
14459static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
14460 const char *mac, gfp_t gfp)
d6dc1a38 14461{
947add36 14462 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
14463 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
14464 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14465 void **cb;
947add36 14466
d6dc1a38 14467 if (!msg)
5b97f49d 14468 return NULL;
d6dc1a38 14469
5b97f49d
JB
14470 cb = (void **)msg->cb;
14471
14472 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
14473 if (!cb[0]) {
d6dc1a38 14474 nlmsg_free(msg);
5b97f49d 14475 return NULL;
d6dc1a38
JO
14476 }
14477
9360ffd1 14478 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 14479 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 14480 goto nla_put_failure;
d6dc1a38 14481
5b97f49d 14482 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
14483 goto nla_put_failure;
14484
5b97f49d
JB
14485 cb[1] = nla_nest_start(msg, NL80211_ATTR_CQM);
14486 if (!cb[1])
9360ffd1 14487 goto nla_put_failure;
d6dc1a38 14488
5b97f49d 14489 cb[2] = rdev;
d6dc1a38 14490
5b97f49d
JB
14491 return msg;
14492 nla_put_failure:
14493 nlmsg_free(msg);
14494 return NULL;
14495}
14496
14497static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
14498{
14499 void **cb = (void **)msg->cb;
14500 struct cfg80211_registered_device *rdev = cb[2];
14501
14502 nla_nest_end(msg, cb[1]);
14503 genlmsg_end(msg, cb[0]);
14504
14505 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 14506
68eb5503 14507 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14508 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
14509}
14510
14511void cfg80211_cqm_rssi_notify(struct net_device *dev,
14512 enum nl80211_cqm_rssi_threshold_event rssi_event,
bee427b8 14513 s32 rssi_level, gfp_t gfp)
5b97f49d
JB
14514{
14515 struct sk_buff *msg;
4a4b8169
AZ
14516 struct wireless_dev *wdev = dev->ieee80211_ptr;
14517 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
5b97f49d 14518
bee427b8 14519 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
5b97f49d 14520
98f03342
JB
14521 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
14522 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
14523 return;
14524
4a4b8169
AZ
14525 if (wdev->cqm_config) {
14526 wdev->cqm_config->last_rssi_event_value = rssi_level;
14527
14528 cfg80211_cqm_rssi_update(rdev, dev);
14529
14530 if (rssi_level == 0)
14531 rssi_level = wdev->cqm_config->last_rssi_event_value;
14532 }
14533
5b97f49d
JB
14534 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
14535 if (!msg)
14536 return;
14537
14538 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
14539 rssi_event))
14540 goto nla_put_failure;
14541
bee427b8
AZ
14542 if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
14543 rssi_level))
14544 goto nla_put_failure;
14545
5b97f49d
JB
14546 cfg80211_send_cqm(msg, gfp);
14547
d6dc1a38
JO
14548 return;
14549
14550 nla_put_failure:
d6dc1a38
JO
14551 nlmsg_free(msg);
14552}
947add36 14553EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 14554
5b97f49d
JB
14555void cfg80211_cqm_txe_notify(struct net_device *dev,
14556 const u8 *peer, u32 num_packets,
14557 u32 rate, u32 intvl, gfp_t gfp)
14558{
14559 struct sk_buff *msg;
14560
14561 msg = cfg80211_prepare_cqm(dev, peer, gfp);
14562 if (!msg)
14563 return;
14564
14565 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
14566 goto nla_put_failure;
14567
14568 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
14569 goto nla_put_failure;
14570
14571 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
14572 goto nla_put_failure;
14573
14574 cfg80211_send_cqm(msg, gfp);
14575 return;
14576
14577 nla_put_failure:
14578 nlmsg_free(msg);
14579}
14580EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
14581
14582void cfg80211_cqm_pktloss_notify(struct net_device *dev,
14583 const u8 *peer, u32 num_packets, gfp_t gfp)
14584{
14585 struct sk_buff *msg;
14586
14587 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
14588
14589 msg = cfg80211_prepare_cqm(dev, peer, gfp);
14590 if (!msg)
14591 return;
14592
14593 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
14594 goto nla_put_failure;
14595
14596 cfg80211_send_cqm(msg, gfp);
14597 return;
14598
14599 nla_put_failure:
14600 nlmsg_free(msg);
14601}
14602EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
14603
98f03342
JB
14604void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
14605{
14606 struct sk_buff *msg;
14607
14608 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
14609 if (!msg)
14610 return;
14611
14612 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
14613 goto nla_put_failure;
14614
14615 cfg80211_send_cqm(msg, gfp);
14616 return;
14617
14618 nla_put_failure:
14619 nlmsg_free(msg);
14620}
14621EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
14622
947add36
JB
14623static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
14624 struct net_device *netdev, const u8 *bssid,
14625 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
14626{
14627 struct sk_buff *msg;
14628 struct nlattr *rekey_attr;
14629 void *hdr;
14630
58050fce 14631 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
14632 if (!msg)
14633 return;
14634
14635 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
14636 if (!hdr) {
14637 nlmsg_free(msg);
14638 return;
14639 }
14640
9360ffd1
DM
14641 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14642 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14643 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
14644 goto nla_put_failure;
e5497d76
JB
14645
14646 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
14647 if (!rekey_attr)
14648 goto nla_put_failure;
14649
9360ffd1
DM
14650 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
14651 NL80211_REPLAY_CTR_LEN, replay_ctr))
14652 goto nla_put_failure;
e5497d76
JB
14653
14654 nla_nest_end(msg, rekey_attr);
14655
3b7b72ee 14656 genlmsg_end(msg, hdr);
e5497d76 14657
68eb5503 14658 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14659 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
14660 return;
14661
14662 nla_put_failure:
14663 genlmsg_cancel(msg, hdr);
14664 nlmsg_free(msg);
14665}
14666
947add36
JB
14667void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
14668 const u8 *replay_ctr, gfp_t gfp)
14669{
14670 struct wireless_dev *wdev = dev->ieee80211_ptr;
14671 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14672 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14673
14674 trace_cfg80211_gtk_rekey_notify(dev, bssid);
14675 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
14676}
14677EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
14678
14679static void
14680nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
14681 struct net_device *netdev, int index,
14682 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
14683{
14684 struct sk_buff *msg;
14685 struct nlattr *attr;
14686 void *hdr;
14687
58050fce 14688 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
14689 if (!msg)
14690 return;
14691
14692 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
14693 if (!hdr) {
14694 nlmsg_free(msg);
14695 return;
14696 }
14697
9360ffd1
DM
14698 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14699 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
14700 goto nla_put_failure;
c9df56b4
JM
14701
14702 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
14703 if (!attr)
14704 goto nla_put_failure;
14705
9360ffd1
DM
14706 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
14707 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
14708 (preauth &&
14709 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
14710 goto nla_put_failure;
c9df56b4
JM
14711
14712 nla_nest_end(msg, attr);
14713
3b7b72ee 14714 genlmsg_end(msg, hdr);
c9df56b4 14715
68eb5503 14716 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14717 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
14718 return;
14719
14720 nla_put_failure:
14721 genlmsg_cancel(msg, hdr);
14722 nlmsg_free(msg);
14723}
14724
947add36
JB
14725void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
14726 const u8 *bssid, bool preauth, gfp_t gfp)
14727{
14728 struct wireless_dev *wdev = dev->ieee80211_ptr;
14729 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14730 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14731
14732 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
14733 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
14734}
14735EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
14736
14737static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
14738 struct net_device *netdev,
14739 struct cfg80211_chan_def *chandef,
f8d7552e
LC
14740 gfp_t gfp,
14741 enum nl80211_commands notif,
14742 u8 count)
5314526b
TP
14743{
14744 struct sk_buff *msg;
14745 void *hdr;
14746
58050fce 14747 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
14748 if (!msg)
14749 return;
14750
f8d7552e 14751 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
14752 if (!hdr) {
14753 nlmsg_free(msg);
14754 return;
14755 }
14756
683b6d3b
JB
14757 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
14758 goto nla_put_failure;
14759
14760 if (nl80211_send_chandef(msg, chandef))
7eab0f64 14761 goto nla_put_failure;
5314526b 14762
f8d7552e
LC
14763 if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
14764 (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
14765 goto nla_put_failure;
14766
5314526b
TP
14767 genlmsg_end(msg, hdr);
14768
68eb5503 14769 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14770 NL80211_MCGRP_MLME, gfp);
5314526b
TP
14771 return;
14772
14773 nla_put_failure:
14774 genlmsg_cancel(msg, hdr);
14775 nlmsg_free(msg);
14776}
14777
947add36
JB
14778void cfg80211_ch_switch_notify(struct net_device *dev,
14779 struct cfg80211_chan_def *chandef)
84f10708 14780{
947add36
JB
14781 struct wireless_dev *wdev = dev->ieee80211_ptr;
14782 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14783 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 14784
e487eaeb 14785 ASSERT_WDEV_LOCK(wdev);
947add36 14786
e487eaeb 14787 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 14788
9e0e2961 14789 wdev->chandef = *chandef;
96f55f12 14790 wdev->preset_chandef = *chandef;
f8d7552e
LC
14791 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
14792 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
947add36
JB
14793}
14794EXPORT_SYMBOL(cfg80211_ch_switch_notify);
14795
f8d7552e
LC
14796void cfg80211_ch_switch_started_notify(struct net_device *dev,
14797 struct cfg80211_chan_def *chandef,
14798 u8 count)
14799{
14800 struct wireless_dev *wdev = dev->ieee80211_ptr;
14801 struct wiphy *wiphy = wdev->wiphy;
14802 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14803
14804 trace_cfg80211_ch_switch_started_notify(dev, chandef);
14805
14806 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
14807 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
14808}
14809EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
14810
04f39047
SW
14811void
14812nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 14813 const struct cfg80211_chan_def *chandef,
04f39047
SW
14814 enum nl80211_radar_event event,
14815 struct net_device *netdev, gfp_t gfp)
14816{
14817 struct sk_buff *msg;
14818 void *hdr;
14819
14820 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14821 if (!msg)
14822 return;
14823
14824 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
14825 if (!hdr) {
14826 nlmsg_free(msg);
14827 return;
14828 }
14829
14830 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
14831 goto nla_put_failure;
14832
14833 /* NOP and radar events don't need a netdev parameter */
14834 if (netdev) {
14835 struct wireless_dev *wdev = netdev->ieee80211_ptr;
14836
14837 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
14838 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14839 NL80211_ATTR_PAD))
04f39047
SW
14840 goto nla_put_failure;
14841 }
14842
14843 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
14844 goto nla_put_failure;
14845
14846 if (nl80211_send_chandef(msg, chandef))
14847 goto nla_put_failure;
14848
9c90a9f6 14849 genlmsg_end(msg, hdr);
04f39047 14850
68eb5503 14851 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14852 NL80211_MCGRP_MLME, gfp);
04f39047
SW
14853 return;
14854
14855 nla_put_failure:
14856 genlmsg_cancel(msg, hdr);
14857 nlmsg_free(msg);
14858}
14859
7f6cf311
JB
14860void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
14861 u64 cookie, bool acked, gfp_t gfp)
14862{
14863 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14864 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
14865 struct sk_buff *msg;
14866 void *hdr;
7f6cf311 14867
4ee3e063
BL
14868 trace_cfg80211_probe_status(dev, addr, cookie, acked);
14869
58050fce 14870 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 14871
7f6cf311
JB
14872 if (!msg)
14873 return;
14874
14875 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
14876 if (!hdr) {
14877 nlmsg_free(msg);
14878 return;
14879 }
14880
9360ffd1
DM
14881 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14882 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14883 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
14884 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14885 NL80211_ATTR_PAD) ||
9360ffd1
DM
14886 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
14887 goto nla_put_failure;
7f6cf311 14888
9c90a9f6 14889 genlmsg_end(msg, hdr);
7f6cf311 14890
68eb5503 14891 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14892 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
14893 return;
14894
14895 nla_put_failure:
14896 genlmsg_cancel(msg, hdr);
14897 nlmsg_free(msg);
14898}
14899EXPORT_SYMBOL(cfg80211_probe_status);
14900
5e760230
JB
14901void cfg80211_report_obss_beacon(struct wiphy *wiphy,
14902 const u8 *frame, size_t len,
37c73b5f 14903 int freq, int sig_dbm)
5e760230 14904{
f26cbf40 14905 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
14906 struct sk_buff *msg;
14907 void *hdr;
37c73b5f 14908 struct cfg80211_beacon_registration *reg;
5e760230 14909
4ee3e063
BL
14910 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
14911
37c73b5f
BG
14912 spin_lock_bh(&rdev->beacon_registrations_lock);
14913 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
14914 msg = nlmsg_new(len + 100, GFP_ATOMIC);
14915 if (!msg) {
14916 spin_unlock_bh(&rdev->beacon_registrations_lock);
14917 return;
14918 }
5e760230 14919
37c73b5f
BG
14920 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
14921 if (!hdr)
14922 goto nla_put_failure;
5e760230 14923
37c73b5f
BG
14924 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14925 (freq &&
14926 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
14927 (sig_dbm &&
14928 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
14929 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
14930 goto nla_put_failure;
5e760230 14931
37c73b5f 14932 genlmsg_end(msg, hdr);
5e760230 14933
37c73b5f
BG
14934 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
14935 }
14936 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
14937 return;
14938
14939 nla_put_failure:
37c73b5f
BG
14940 spin_unlock_bh(&rdev->beacon_registrations_lock);
14941 if (hdr)
14942 genlmsg_cancel(msg, hdr);
5e760230
JB
14943 nlmsg_free(msg);
14944}
14945EXPORT_SYMBOL(cfg80211_report_obss_beacon);
14946
cd8f7cb4 14947#ifdef CONFIG_PM
8cd4d456
LC
14948static int cfg80211_net_detect_results(struct sk_buff *msg,
14949 struct cfg80211_wowlan_wakeup *wakeup)
14950{
14951 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
14952 struct nlattr *nl_results, *nl_match, *nl_freqs;
14953 int i, j;
14954
14955 nl_results = nla_nest_start(
14956 msg, NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
14957 if (!nl_results)
14958 return -EMSGSIZE;
14959
14960 for (i = 0; i < nd->n_matches; i++) {
14961 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
14962
14963 nl_match = nla_nest_start(msg, i);
14964 if (!nl_match)
14965 break;
14966
14967 /* The SSID attribute is optional in nl80211, but for
14968 * simplicity reasons it's always present in the
14969 * cfg80211 structure. If a driver can't pass the
14970 * SSID, that needs to be changed. A zero length SSID
14971 * is still a valid SSID (wildcard), so it cannot be
14972 * used for this purpose.
14973 */
14974 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
14975 match->ssid.ssid)) {
14976 nla_nest_cancel(msg, nl_match);
14977 goto out;
14978 }
14979
14980 if (match->n_channels) {
14981 nl_freqs = nla_nest_start(
14982 msg, NL80211_ATTR_SCAN_FREQUENCIES);
14983 if (!nl_freqs) {
14984 nla_nest_cancel(msg, nl_match);
14985 goto out;
14986 }
14987
14988 for (j = 0; j < match->n_channels; j++) {
5528fae8 14989 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
14990 nla_nest_cancel(msg, nl_freqs);
14991 nla_nest_cancel(msg, nl_match);
14992 goto out;
14993 }
14994 }
14995
14996 nla_nest_end(msg, nl_freqs);
14997 }
14998
14999 nla_nest_end(msg, nl_match);
15000 }
15001
15002out:
15003 nla_nest_end(msg, nl_results);
15004 return 0;
15005}
15006
cd8f7cb4
JB
15007void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
15008 struct cfg80211_wowlan_wakeup *wakeup,
15009 gfp_t gfp)
15010{
f26cbf40 15011 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
15012 struct sk_buff *msg;
15013 void *hdr;
9c90a9f6 15014 int size = 200;
cd8f7cb4
JB
15015
15016 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
15017
15018 if (wakeup)
15019 size += wakeup->packet_present_len;
15020
15021 msg = nlmsg_new(size, gfp);
15022 if (!msg)
15023 return;
15024
15025 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
15026 if (!hdr)
15027 goto free_msg;
15028
15029 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
15030 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15031 NL80211_ATTR_PAD))
cd8f7cb4
JB
15032 goto free_msg;
15033
15034 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15035 wdev->netdev->ifindex))
15036 goto free_msg;
15037
15038 if (wakeup) {
15039 struct nlattr *reasons;
15040
15041 reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
15042 if (!reasons)
15043 goto free_msg;
cd8f7cb4
JB
15044
15045 if (wakeup->disconnect &&
15046 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
15047 goto free_msg;
15048 if (wakeup->magic_pkt &&
15049 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
15050 goto free_msg;
15051 if (wakeup->gtk_rekey_failure &&
15052 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
15053 goto free_msg;
15054 if (wakeup->eap_identity_req &&
15055 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
15056 goto free_msg;
15057 if (wakeup->four_way_handshake &&
15058 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
15059 goto free_msg;
15060 if (wakeup->rfkill_release &&
15061 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
15062 goto free_msg;
15063
15064 if (wakeup->pattern_idx >= 0 &&
15065 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
15066 wakeup->pattern_idx))
15067 goto free_msg;
15068
ae917c9f
JB
15069 if (wakeup->tcp_match &&
15070 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
15071 goto free_msg;
2a0e047e 15072
ae917c9f
JB
15073 if (wakeup->tcp_connlost &&
15074 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
15075 goto free_msg;
2a0e047e 15076
ae917c9f
JB
15077 if (wakeup->tcp_nomoretokens &&
15078 nla_put_flag(msg,
15079 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
15080 goto free_msg;
2a0e047e 15081
cd8f7cb4
JB
15082 if (wakeup->packet) {
15083 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
15084 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
15085
15086 if (!wakeup->packet_80211) {
15087 pkt_attr =
15088 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
15089 len_attr =
15090 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
15091 }
15092
15093 if (wakeup->packet_len &&
15094 nla_put_u32(msg, len_attr, wakeup->packet_len))
15095 goto free_msg;
15096
15097 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
15098 wakeup->packet))
15099 goto free_msg;
15100 }
15101
8cd4d456
LC
15102 if (wakeup->net_detect &&
15103 cfg80211_net_detect_results(msg, wakeup))
15104 goto free_msg;
15105
cd8f7cb4
JB
15106 nla_nest_end(msg, reasons);
15107 }
15108
9c90a9f6 15109 genlmsg_end(msg, hdr);
cd8f7cb4 15110
68eb5503 15111 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15112 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
15113 return;
15114
15115 free_msg:
15116 nlmsg_free(msg);
15117}
15118EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
15119#endif
15120
3475b094
JM
15121void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
15122 enum nl80211_tdls_operation oper,
15123 u16 reason_code, gfp_t gfp)
15124{
15125 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 15126 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
15127 struct sk_buff *msg;
15128 void *hdr;
3475b094
JM
15129
15130 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
15131 reason_code);
15132
15133 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15134 if (!msg)
15135 return;
15136
15137 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
15138 if (!hdr) {
15139 nlmsg_free(msg);
15140 return;
15141 }
15142
15143 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15144 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15145 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
15146 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
15147 (reason_code > 0 &&
15148 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
15149 goto nla_put_failure;
15150
9c90a9f6 15151 genlmsg_end(msg, hdr);
3475b094 15152
68eb5503 15153 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15154 NL80211_MCGRP_MLME, gfp);
3475b094
JM
15155 return;
15156
15157 nla_put_failure:
15158 genlmsg_cancel(msg, hdr);
15159 nlmsg_free(msg);
15160}
15161EXPORT_SYMBOL(cfg80211_tdls_oper_request);
15162
026331c4
JM
15163static int nl80211_netlink_notify(struct notifier_block * nb,
15164 unsigned long state,
15165 void *_notify)
15166{
15167 struct netlink_notify *notify = _notify;
15168 struct cfg80211_registered_device *rdev;
15169 struct wireless_dev *wdev;
37c73b5f 15170 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 15171
8f815cdd 15172 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
15173 return NOTIFY_DONE;
15174
15175 rcu_read_lock();
15176
5e760230 15177 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
ca986ad9 15178 struct cfg80211_sched_scan_request *sched_scan_req;
753aacfd 15179
ca986ad9
AVS
15180 list_for_each_entry_rcu(sched_scan_req,
15181 &rdev->sched_scan_req_list,
15182 list) {
15183 if (sched_scan_req->owner_nlportid == notify->portid) {
15184 sched_scan_req->nl_owner_dead = true;
753aacfd 15185 schedule_work(&rdev->sched_scan_stop_wk);
ca986ad9 15186 }
753aacfd 15187 }
78f22b6a 15188
53873f13 15189 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 15190 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 15191
ab81007a
JB
15192 if (wdev->owner_nlportid == notify->portid) {
15193 wdev->nl_owner_dead = true;
15194 schedule_work(&rdev->destroy_work);
15195 } else if (wdev->conn_owner_nlportid == notify->portid) {
bd2522b1 15196 schedule_work(&wdev->disconnect_wk);
ab81007a 15197 }
78f22b6a
JB
15198 }
15199
37c73b5f
BG
15200 spin_lock_bh(&rdev->beacon_registrations_lock);
15201 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
15202 list) {
15203 if (reg->nlportid == notify->portid) {
15204 list_del(&reg->list);
15205 kfree(reg);
15206 break;
15207 }
15208 }
15209 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230 15210 }
026331c4
JM
15211
15212 rcu_read_unlock();
15213
05050753
I
15214 /*
15215 * It is possible that the user space process that is controlling the
15216 * indoor setting disappeared, so notify the regulatory core.
15217 */
15218 regulatory_netlink_notify(notify->portid);
6784c7db 15219 return NOTIFY_OK;
026331c4
JM
15220}
15221
15222static struct notifier_block nl80211_netlink_notifier = {
15223 .notifier_call = nl80211_netlink_notify,
15224};
15225
355199e0
JM
15226void cfg80211_ft_event(struct net_device *netdev,
15227 struct cfg80211_ft_event_params *ft_event)
15228{
15229 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 15230 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
15231 struct sk_buff *msg;
15232 void *hdr;
355199e0
JM
15233
15234 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
15235
15236 if (!ft_event->target_ap)
15237 return;
15238
4ef8c1c9 15239 msg = nlmsg_new(100 + ft_event->ric_ies_len, GFP_KERNEL);
355199e0
JM
15240 if (!msg)
15241 return;
15242
15243 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
15244 if (!hdr)
15245 goto out;
355199e0 15246
ae917c9f
JB
15247 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15248 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15249 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
15250 goto out;
355199e0 15251
ae917c9f
JB
15252 if (ft_event->ies &&
15253 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
15254 goto out;
15255 if (ft_event->ric_ies &&
15256 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
15257 ft_event->ric_ies))
15258 goto out;
355199e0 15259
9c90a9f6 15260 genlmsg_end(msg, hdr);
355199e0 15261
68eb5503 15262 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15263 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
15264 return;
15265 out:
15266 nlmsg_free(msg);
355199e0
JM
15267}
15268EXPORT_SYMBOL(cfg80211_ft_event);
15269
5de17984
AS
15270void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
15271{
15272 struct cfg80211_registered_device *rdev;
15273 struct sk_buff *msg;
15274 void *hdr;
15275 u32 nlportid;
15276
f26cbf40 15277 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
15278 if (!rdev->crit_proto_nlportid)
15279 return;
15280
15281 nlportid = rdev->crit_proto_nlportid;
15282 rdev->crit_proto_nlportid = 0;
15283
15284 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15285 if (!msg)
15286 return;
15287
15288 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
15289 if (!hdr)
15290 goto nla_put_failure;
15291
15292 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
15293 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15294 NL80211_ATTR_PAD))
5de17984
AS
15295 goto nla_put_failure;
15296
15297 genlmsg_end(msg, hdr);
15298
15299 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
15300 return;
15301
15302 nla_put_failure:
15303 if (hdr)
15304 genlmsg_cancel(msg, hdr);
15305 nlmsg_free(msg);
5de17984
AS
15306}
15307EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
15308
348baf0e
JB
15309void nl80211_send_ap_stopped(struct wireless_dev *wdev)
15310{
15311 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15312 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
15313 struct sk_buff *msg;
15314 void *hdr;
15315
15316 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
15317 if (!msg)
15318 return;
15319
15320 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
15321 if (!hdr)
15322 goto out;
15323
15324 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15325 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
15326 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15327 NL80211_ATTR_PAD))
348baf0e
JB
15328 goto out;
15329
15330 genlmsg_end(msg, hdr);
15331
15332 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
15333 NL80211_MCGRP_MLME, GFP_KERNEL);
15334 return;
15335 out:
15336 nlmsg_free(msg);
15337}
15338
55682965
JB
15339/* initialisation/exit functions */
15340
56989f6d 15341int __init nl80211_init(void)
55682965 15342{
0d63cbb5 15343 int err;
55682965 15344
489111e5 15345 err = genl_register_family(&nl80211_fam);
55682965
JB
15346 if (err)
15347 return err;
15348
026331c4
JM
15349 err = netlink_register_notifier(&nl80211_netlink_notifier);
15350 if (err)
15351 goto err_out;
15352
55682965
JB
15353 return 0;
15354 err_out:
15355 genl_unregister_family(&nl80211_fam);
15356 return err;
15357}
15358
15359void nl80211_exit(void)
15360{
026331c4 15361 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
15362 genl_unregister_family(&nl80211_fam);
15363}