]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - net/wireless/nl80211.c
Merge tag 'drm-misc-fixes-2018-01-17' of git://anongit.freedesktop.org/drm/drm-misc...
[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] ||
3ea15452
HC
11364 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] ||
11365 !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) {
a442b761
AB
11366 err = -EINVAL;
11367 goto out;
11368 }
11369
11370 func->followup_id =
11371 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
11372 func->followup_reqid =
11373 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
11374 memcpy(func->followup_dest.addr,
11375 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
11376 sizeof(func->followup_dest.addr));
11377 if (func->ttl) {
11378 err = -EINVAL;
11379 goto out;
11380 }
11381 break;
11382 default:
11383 err = -EINVAL;
11384 goto out;
11385 }
11386
11387 if (tb[NL80211_NAN_FUNC_SRF]) {
11388 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
11389
bfe2c7b1
JB
11390 err = nla_parse_nested(srf_tb, NL80211_NAN_SRF_ATTR_MAX,
11391 tb[NL80211_NAN_FUNC_SRF],
fe52145f 11392 nl80211_nan_srf_policy, info->extack);
a442b761
AB
11393 if (err)
11394 goto out;
11395
11396 func->srf_include =
11397 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
11398
11399 if (srf_tb[NL80211_NAN_SRF_BF]) {
11400 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
11401 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
11402 err = -EINVAL;
11403 goto out;
11404 }
11405
11406 func->srf_bf_len =
11407 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
11408 func->srf_bf =
11409 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
11410 func->srf_bf_len, GFP_KERNEL);
11411 if (!func->srf_bf) {
11412 err = -ENOMEM;
11413 goto out;
11414 }
11415
11416 func->srf_bf_idx =
11417 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
11418 } else {
11419 struct nlattr *attr, *mac_attr =
11420 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
11421 int n_entries, rem, i = 0;
11422
11423 if (!mac_attr) {
11424 err = -EINVAL;
11425 goto out;
11426 }
11427
11428 n_entries = validate_acl_mac_addrs(mac_attr);
11429 if (n_entries <= 0) {
11430 err = -EINVAL;
11431 goto out;
11432 }
11433
11434 func->srf_num_macs = n_entries;
11435 func->srf_macs =
11436 kzalloc(sizeof(*func->srf_macs) * n_entries,
11437 GFP_KERNEL);
11438 if (!func->srf_macs) {
11439 err = -ENOMEM;
11440 goto out;
11441 }
11442
11443 nla_for_each_nested(attr, mac_attr, rem)
11444 memcpy(func->srf_macs[i++].addr, nla_data(attr),
11445 sizeof(*func->srf_macs));
11446 }
11447 }
11448
11449 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
11450 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
11451 func, true);
11452 if (err)
11453 goto out;
11454 }
11455
11456 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
11457 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
11458 func, false);
11459 if (err)
11460 goto out;
11461 }
11462
11463 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11464 if (!msg) {
11465 err = -ENOMEM;
11466 goto out;
11467 }
11468
11469 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11470 NL80211_CMD_ADD_NAN_FUNCTION);
11471 /* This can't really happen - we just allocated 4KB */
11472 if (WARN_ON(!hdr)) {
11473 err = -ENOMEM;
11474 goto out;
11475 }
11476
11477 err = rdev_add_nan_func(rdev, wdev, func);
11478out:
11479 if (err < 0) {
11480 cfg80211_free_nan_func(func);
11481 nlmsg_free(msg);
11482 return err;
11483 }
11484
11485 /* propagate the instance id and cookie to userspace */
11486 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
11487 NL80211_ATTR_PAD))
11488 goto nla_put_failure;
11489
11490 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
11491 if (!func_attr)
11492 goto nla_put_failure;
11493
11494 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
11495 func->instance_id))
11496 goto nla_put_failure;
11497
11498 nla_nest_end(msg, func_attr);
11499
11500 genlmsg_end(msg, hdr);
11501 return genlmsg_reply(msg, info);
11502
11503nla_put_failure:
11504 nlmsg_free(msg);
11505 return -ENOBUFS;
11506}
11507
11508static int nl80211_nan_del_func(struct sk_buff *skb,
11509 struct genl_info *info)
11510{
11511 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11512 struct wireless_dev *wdev = info->user_ptr[1];
11513 u64 cookie;
11514
11515 if (wdev->iftype != NL80211_IFTYPE_NAN)
11516 return -EOPNOTSUPP;
11517
73c7da3d 11518 if (!wdev_running(wdev))
a442b761
AB
11519 return -ENOTCONN;
11520
11521 if (!info->attrs[NL80211_ATTR_COOKIE])
11522 return -EINVAL;
11523
a442b761
AB
11524 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
11525
11526 rdev_del_nan_func(rdev, wdev, cookie);
11527
11528 return 0;
11529}
11530
a5a9dcf2
AB
11531static int nl80211_nan_change_config(struct sk_buff *skb,
11532 struct genl_info *info)
11533{
11534 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11535 struct wireless_dev *wdev = info->user_ptr[1];
11536 struct cfg80211_nan_conf conf = {};
11537 u32 changed = 0;
11538
11539 if (wdev->iftype != NL80211_IFTYPE_NAN)
11540 return -EOPNOTSUPP;
11541
73c7da3d 11542 if (!wdev_running(wdev))
a5a9dcf2
AB
11543 return -ENOTCONN;
11544
11545 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
11546 conf.master_pref =
11547 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
11548 if (conf.master_pref <= 1 || conf.master_pref == 255)
11549 return -EINVAL;
11550
11551 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
11552 }
11553
8585989d
LC
11554 if (info->attrs[NL80211_ATTR_BANDS]) {
11555 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
11556
11557 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
11558 return -EOPNOTSUPP;
11559
11560 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
11561 return -EINVAL;
11562
11563 conf.bands = bands;
11564 changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
a5a9dcf2
AB
11565 }
11566
11567 if (!changed)
11568 return -EINVAL;
11569
11570 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
11571}
11572
50bcd31d
AB
11573void cfg80211_nan_match(struct wireless_dev *wdev,
11574 struct cfg80211_nan_match_params *match, gfp_t gfp)
11575{
11576 struct wiphy *wiphy = wdev->wiphy;
11577 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11578 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
11579 struct sk_buff *msg;
11580 void *hdr;
11581
11582 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
11583 return;
11584
11585 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11586 if (!msg)
11587 return;
11588
11589 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
11590 if (!hdr) {
11591 nlmsg_free(msg);
11592 return;
11593 }
11594
11595 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11596 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
11597 wdev->netdev->ifindex)) ||
11598 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
11599 NL80211_ATTR_PAD))
11600 goto nla_put_failure;
11601
11602 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
11603 NL80211_ATTR_PAD) ||
11604 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
11605 goto nla_put_failure;
11606
11607 match_attr = nla_nest_start(msg, NL80211_ATTR_NAN_MATCH);
11608 if (!match_attr)
11609 goto nla_put_failure;
11610
11611 local_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_LOCAL);
11612 if (!local_func_attr)
11613 goto nla_put_failure;
11614
11615 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
11616 goto nla_put_failure;
11617
11618 nla_nest_end(msg, local_func_attr);
11619
11620 peer_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_PEER);
11621 if (!peer_func_attr)
11622 goto nla_put_failure;
11623
11624 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
11625 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
11626 goto nla_put_failure;
11627
11628 if (match->info && match->info_len &&
11629 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
11630 match->info))
11631 goto nla_put_failure;
11632
11633 nla_nest_end(msg, peer_func_attr);
11634 nla_nest_end(msg, match_attr);
11635 genlmsg_end(msg, hdr);
11636
11637 if (!wdev->owner_nlportid)
11638 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11639 msg, 0, NL80211_MCGRP_NAN, gfp);
11640 else
11641 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
11642 wdev->owner_nlportid);
11643
11644 return;
11645
11646nla_put_failure:
11647 nlmsg_free(msg);
11648}
11649EXPORT_SYMBOL(cfg80211_nan_match);
11650
368e5a7b
AB
11651void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
11652 u8 inst_id,
11653 enum nl80211_nan_func_term_reason reason,
11654 u64 cookie, gfp_t gfp)
11655{
11656 struct wiphy *wiphy = wdev->wiphy;
11657 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11658 struct sk_buff *msg;
11659 struct nlattr *func_attr;
11660 void *hdr;
11661
11662 if (WARN_ON(!inst_id))
11663 return;
11664
11665 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11666 if (!msg)
11667 return;
11668
11669 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
11670 if (!hdr) {
11671 nlmsg_free(msg);
11672 return;
11673 }
11674
11675 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11676 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
11677 wdev->netdev->ifindex)) ||
11678 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
11679 NL80211_ATTR_PAD))
11680 goto nla_put_failure;
11681
11682 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11683 NL80211_ATTR_PAD))
11684 goto nla_put_failure;
11685
11686 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
11687 if (!func_attr)
11688 goto nla_put_failure;
11689
11690 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
11691 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
11692 goto nla_put_failure;
11693
11694 nla_nest_end(msg, func_attr);
11695 genlmsg_end(msg, hdr);
11696
11697 if (!wdev->owner_nlportid)
11698 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11699 msg, 0, NL80211_MCGRP_NAN, gfp);
11700 else
11701 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
11702 wdev->owner_nlportid);
11703
11704 return;
11705
11706nla_put_failure:
11707 nlmsg_free(msg);
11708}
11709EXPORT_SYMBOL(cfg80211_nan_func_terminated);
11710
3713b4e3
JB
11711static int nl80211_get_protocol_features(struct sk_buff *skb,
11712 struct genl_info *info)
11713{
11714 void *hdr;
11715 struct sk_buff *msg;
11716
11717 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11718 if (!msg)
11719 return -ENOMEM;
11720
11721 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11722 NL80211_CMD_GET_PROTOCOL_FEATURES);
11723 if (!hdr)
11724 goto nla_put_failure;
11725
11726 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
11727 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
11728 goto nla_put_failure;
11729
11730 genlmsg_end(msg, hdr);
11731 return genlmsg_reply(msg, info);
11732
11733 nla_put_failure:
11734 kfree_skb(msg);
11735 return -ENOBUFS;
11736}
11737
355199e0
JM
11738static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
11739{
11740 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11741 struct cfg80211_update_ft_ies_params ft_params;
11742 struct net_device *dev = info->user_ptr[1];
11743
11744 if (!rdev->ops->update_ft_ies)
11745 return -EOPNOTSUPP;
11746
11747 if (!info->attrs[NL80211_ATTR_MDID] ||
11748 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
11749 return -EINVAL;
11750
11751 memset(&ft_params, 0, sizeof(ft_params));
11752 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
11753 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11754 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11755
11756 return rdev_update_ft_ies(rdev, dev, &ft_params);
11757}
11758
5de17984
AS
11759static int nl80211_crit_protocol_start(struct sk_buff *skb,
11760 struct genl_info *info)
11761{
11762 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11763 struct wireless_dev *wdev = info->user_ptr[1];
11764 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
11765 u16 duration;
11766 int ret;
11767
11768 if (!rdev->ops->crit_proto_start)
11769 return -EOPNOTSUPP;
11770
11771 if (WARN_ON(!rdev->ops->crit_proto_stop))
11772 return -EINVAL;
11773
11774 if (rdev->crit_proto_nlportid)
11775 return -EBUSY;
11776
11777 /* determine protocol if provided */
11778 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
11779 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
11780
11781 if (proto >= NUM_NL80211_CRIT_PROTO)
11782 return -EINVAL;
11783
11784 /* timeout must be provided */
11785 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
11786 return -EINVAL;
11787
11788 duration =
11789 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
11790
11791 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
11792 return -ERANGE;
11793
11794 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
11795 if (!ret)
11796 rdev->crit_proto_nlportid = info->snd_portid;
11797
11798 return ret;
11799}
11800
11801static int nl80211_crit_protocol_stop(struct sk_buff *skb,
11802 struct genl_info *info)
11803{
11804 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11805 struct wireless_dev *wdev = info->user_ptr[1];
11806
11807 if (!rdev->ops->crit_proto_stop)
11808 return -EOPNOTSUPP;
11809
11810 if (rdev->crit_proto_nlportid) {
11811 rdev->crit_proto_nlportid = 0;
11812 rdev_crit_proto_stop(rdev, wdev);
11813 }
11814 return 0;
11815}
11816
ad7e718c
JB
11817static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
11818{
11819 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11820 struct wireless_dev *wdev =
11821 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
11822 int i, err;
11823 u32 vid, subcmd;
11824
11825 if (!rdev->wiphy.vendor_commands)
11826 return -EOPNOTSUPP;
11827
11828 if (IS_ERR(wdev)) {
11829 err = PTR_ERR(wdev);
11830 if (err != -EINVAL)
11831 return err;
11832 wdev = NULL;
11833 } else if (wdev->wiphy != &rdev->wiphy) {
11834 return -EINVAL;
11835 }
11836
11837 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
11838 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
11839 return -EINVAL;
11840
11841 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
11842 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
11843 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
11844 const struct wiphy_vendor_command *vcmd;
11845 void *data = NULL;
11846 int len = 0;
11847
11848 vcmd = &rdev->wiphy.vendor_commands[i];
11849
11850 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11851 continue;
11852
11853 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11854 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11855 if (!wdev)
11856 return -EINVAL;
11857 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11858 !wdev->netdev)
11859 return -EINVAL;
11860
11861 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 11862 if (!wdev_running(wdev))
ad7e718c
JB
11863 return -ENETDOWN;
11864 }
7bdbe400
JB
11865
11866 if (!vcmd->doit)
11867 return -EOPNOTSUPP;
ad7e718c
JB
11868 } else {
11869 wdev = NULL;
11870 }
11871
11872 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
11873 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11874 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11875 }
11876
11877 rdev->cur_cmd_info = info;
11878 err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
11879 data, len);
11880 rdev->cur_cmd_info = NULL;
11881 return err;
11882 }
11883
11884 return -EOPNOTSUPP;
11885}
11886
7bdbe400
JB
11887static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
11888 struct netlink_callback *cb,
11889 struct cfg80211_registered_device **rdev,
11890 struct wireless_dev **wdev)
11891{
c90c39da 11892 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
7bdbe400
JB
11893 u32 vid, subcmd;
11894 unsigned int i;
11895 int vcmd_idx = -1;
11896 int err;
11897 void *data = NULL;
11898 unsigned int data_len = 0;
11899
7bdbe400
JB
11900 if (cb->args[0]) {
11901 /* subtract the 1 again here */
11902 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
11903 struct wireless_dev *tmp;
11904
ea90e0dc
JB
11905 if (!wiphy)
11906 return -ENODEV;
7bdbe400
JB
11907 *rdev = wiphy_to_rdev(wiphy);
11908 *wdev = NULL;
11909
11910 if (cb->args[1]) {
53873f13 11911 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
11912 if (tmp->identifier == cb->args[1] - 1) {
11913 *wdev = tmp;
11914 break;
11915 }
11916 }
11917 }
11918
11919 /* keep rtnl locked in successful case */
11920 return 0;
11921 }
11922
fceb6435
JB
11923 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, attrbuf,
11924 nl80211_fam.maxattr, nl80211_policy, NULL);
7bdbe400 11925 if (err)
ea90e0dc 11926 return err;
7bdbe400 11927
c90c39da 11928 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
ea90e0dc
JB
11929 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD])
11930 return -EINVAL;
7bdbe400 11931
c90c39da 11932 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
7bdbe400
JB
11933 if (IS_ERR(*wdev))
11934 *wdev = NULL;
11935
c90c39da 11936 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
ea90e0dc
JB
11937 if (IS_ERR(*rdev))
11938 return PTR_ERR(*rdev);
7bdbe400 11939
c90c39da
JB
11940 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
11941 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
7bdbe400
JB
11942
11943 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
11944 const struct wiphy_vendor_command *vcmd;
11945
11946 vcmd = &(*rdev)->wiphy.vendor_commands[i];
11947
11948 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11949 continue;
11950
ea90e0dc
JB
11951 if (!vcmd->dumpit)
11952 return -EOPNOTSUPP;
7bdbe400
JB
11953
11954 vcmd_idx = i;
11955 break;
11956 }
11957
ea90e0dc
JB
11958 if (vcmd_idx < 0)
11959 return -EOPNOTSUPP;
7bdbe400 11960
c90c39da
JB
11961 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
11962 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
11963 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
7bdbe400
JB
11964 }
11965
11966 /* 0 is the first index - add 1 to parse only once */
11967 cb->args[0] = (*rdev)->wiphy_idx + 1;
11968 /* add 1 to know if it was NULL */
11969 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
11970 cb->args[2] = vcmd_idx;
11971 cb->args[3] = (unsigned long)data;
11972 cb->args[4] = data_len;
11973
11974 /* keep rtnl locked in successful case */
11975 return 0;
7bdbe400
JB
11976}
11977
11978static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
11979 struct netlink_callback *cb)
11980{
11981 struct cfg80211_registered_device *rdev;
11982 struct wireless_dev *wdev;
11983 unsigned int vcmd_idx;
11984 const struct wiphy_vendor_command *vcmd;
11985 void *data;
11986 int data_len;
11987 int err;
11988 struct nlattr *vendor_data;
11989
ea90e0dc 11990 rtnl_lock();
7bdbe400
JB
11991 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
11992 if (err)
ea90e0dc 11993 goto out;
7bdbe400
JB
11994
11995 vcmd_idx = cb->args[2];
11996 data = (void *)cb->args[3];
11997 data_len = cb->args[4];
11998 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
11999
12000 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
12001 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
ea90e0dc
JB
12002 if (!wdev) {
12003 err = -EINVAL;
12004 goto out;
12005 }
7bdbe400 12006 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
ea90e0dc
JB
12007 !wdev->netdev) {
12008 err = -EINVAL;
12009 goto out;
12010 }
7bdbe400
JB
12011
12012 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
ea90e0dc
JB
12013 if (!wdev_running(wdev)) {
12014 err = -ENETDOWN;
12015 goto out;
12016 }
7bdbe400
JB
12017 }
12018 }
12019
12020 while (1) {
12021 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
12022 cb->nlh->nlmsg_seq, NLM_F_MULTI,
12023 NL80211_CMD_VENDOR);
12024 if (!hdr)
12025 break;
12026
12027 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
12028 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
12029 wdev_id(wdev),
12030 NL80211_ATTR_PAD))) {
7bdbe400
JB
12031 genlmsg_cancel(skb, hdr);
12032 break;
12033 }
12034
12035 vendor_data = nla_nest_start(skb, NL80211_ATTR_VENDOR_DATA);
12036 if (!vendor_data) {
12037 genlmsg_cancel(skb, hdr);
12038 break;
12039 }
12040
12041 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
12042 (unsigned long *)&cb->args[5]);
12043 nla_nest_end(skb, vendor_data);
12044
12045 if (err == -ENOBUFS || err == -ENOENT) {
12046 genlmsg_cancel(skb, hdr);
12047 break;
12048 } else if (err) {
12049 genlmsg_cancel(skb, hdr);
12050 goto out;
12051 }
12052
12053 genlmsg_end(skb, hdr);
12054 }
12055
12056 err = skb->len;
12057 out:
12058 rtnl_unlock();
12059 return err;
12060}
12061
ad7e718c
JB
12062struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
12063 enum nl80211_commands cmd,
12064 enum nl80211_attrs attr,
12065 int approxlen)
12066{
f26cbf40 12067 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
12068
12069 if (WARN_ON(!rdev->cur_cmd_info))
12070 return NULL;
12071
6c09e791 12072 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
12073 rdev->cur_cmd_info->snd_portid,
12074 rdev->cur_cmd_info->snd_seq,
567ffc35 12075 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
12076}
12077EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
12078
12079int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
12080{
12081 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
12082 void *hdr = ((void **)skb->cb)[1];
12083 struct nlattr *data = ((void **)skb->cb)[2];
12084
bd8c78e7
JB
12085 /* clear CB data for netlink core to own from now on */
12086 memset(skb->cb, 0, sizeof(skb->cb));
12087
ad7e718c
JB
12088 if (WARN_ON(!rdev->cur_cmd_info)) {
12089 kfree_skb(skb);
12090 return -EINVAL;
12091 }
12092
12093 nla_nest_end(skb, data);
12094 genlmsg_end(skb, hdr);
12095 return genlmsg_reply(skb, rdev->cur_cmd_info);
12096}
12097EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
12098
fa9ffc74
KP
12099static int nl80211_set_qos_map(struct sk_buff *skb,
12100 struct genl_info *info)
12101{
12102 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12103 struct cfg80211_qos_map *qos_map = NULL;
12104 struct net_device *dev = info->user_ptr[1];
12105 u8 *pos, len, num_des, des_len, des;
12106 int ret;
12107
12108 if (!rdev->ops->set_qos_map)
12109 return -EOPNOTSUPP;
12110
12111 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
12112 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
12113 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
12114
12115 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
12116 len > IEEE80211_QOS_MAP_LEN_MAX)
12117 return -EINVAL;
12118
12119 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
12120 if (!qos_map)
12121 return -ENOMEM;
12122
12123 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
12124 if (num_des) {
12125 des_len = num_des *
12126 sizeof(struct cfg80211_dscp_exception);
12127 memcpy(qos_map->dscp_exception, pos, des_len);
12128 qos_map->num_des = num_des;
12129 for (des = 0; des < num_des; des++) {
12130 if (qos_map->dscp_exception[des].up > 7) {
12131 kfree(qos_map);
12132 return -EINVAL;
12133 }
12134 }
12135 pos += des_len;
12136 }
12137 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
12138 }
12139
12140 wdev_lock(dev->ieee80211_ptr);
12141 ret = nl80211_key_allowed(dev->ieee80211_ptr);
12142 if (!ret)
12143 ret = rdev_set_qos_map(rdev, dev, qos_map);
12144 wdev_unlock(dev->ieee80211_ptr);
12145
12146 kfree(qos_map);
12147 return ret;
12148}
12149
960d01ac
JB
12150static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
12151{
12152 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12153 struct net_device *dev = info->user_ptr[1];
12154 struct wireless_dev *wdev = dev->ieee80211_ptr;
12155 const u8 *peer;
12156 u8 tsid, up;
12157 u16 admitted_time = 0;
12158 int err;
12159
723e73ac 12160 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
12161 return -EOPNOTSUPP;
12162
12163 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
12164 !info->attrs[NL80211_ATTR_USER_PRIO])
12165 return -EINVAL;
12166
12167 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
12168 if (tsid >= IEEE80211_NUM_TIDS)
12169 return -EINVAL;
12170
12171 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
12172 if (up >= IEEE80211_NUM_UPS)
12173 return -EINVAL;
12174
12175 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 12176 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 12177 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
12178 * need more attributes for that (e.g. BA session requirement);
12179 * change the WMM adminssion test above to allow both then
960d01ac
JB
12180 */
12181 return -EINVAL;
12182 }
12183
12184 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
12185
12186 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
12187 admitted_time =
12188 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
12189 if (!admitted_time)
12190 return -EINVAL;
12191 }
12192
12193 wdev_lock(wdev);
12194 switch (wdev->iftype) {
12195 case NL80211_IFTYPE_STATION:
12196 case NL80211_IFTYPE_P2P_CLIENT:
12197 if (wdev->current_bss)
12198 break;
12199 err = -ENOTCONN;
12200 goto out;
12201 default:
12202 err = -EOPNOTSUPP;
12203 goto out;
12204 }
12205
12206 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
12207
12208 out:
12209 wdev_unlock(wdev);
12210 return err;
12211}
12212
12213static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
12214{
12215 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12216 struct net_device *dev = info->user_ptr[1];
12217 struct wireless_dev *wdev = dev->ieee80211_ptr;
12218 const u8 *peer;
12219 u8 tsid;
12220 int err;
12221
12222 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
12223 return -EINVAL;
12224
12225 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
12226 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
12227
12228 wdev_lock(wdev);
12229 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
12230 wdev_unlock(wdev);
12231
12232 return err;
12233}
12234
1057d35e
AN
12235static int nl80211_tdls_channel_switch(struct sk_buff *skb,
12236 struct genl_info *info)
12237{
12238 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12239 struct net_device *dev = info->user_ptr[1];
12240 struct wireless_dev *wdev = dev->ieee80211_ptr;
12241 struct cfg80211_chan_def chandef = {};
12242 const u8 *addr;
12243 u8 oper_class;
12244 int err;
12245
12246 if (!rdev->ops->tdls_channel_switch ||
12247 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
12248 return -EOPNOTSUPP;
12249
12250 switch (dev->ieee80211_ptr->iftype) {
12251 case NL80211_IFTYPE_STATION:
12252 case NL80211_IFTYPE_P2P_CLIENT:
12253 break;
12254 default:
12255 return -EOPNOTSUPP;
12256 }
12257
12258 if (!info->attrs[NL80211_ATTR_MAC] ||
12259 !info->attrs[NL80211_ATTR_OPER_CLASS])
12260 return -EINVAL;
12261
12262 err = nl80211_parse_chandef(rdev, info, &chandef);
12263 if (err)
12264 return err;
12265
12266 /*
12267 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
12268 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
12269 * specification is not defined for them.
12270 */
57fbcce3 12271 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
12272 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
12273 chandef.width != NL80211_CHAN_WIDTH_20)
12274 return -EINVAL;
12275
12276 /* we will be active on the TDLS link */
923b352f
AN
12277 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
12278 wdev->iftype))
1057d35e
AN
12279 return -EINVAL;
12280
12281 /* don't allow switching to DFS channels */
12282 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
12283 return -EINVAL;
12284
12285 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
12286 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
12287
12288 wdev_lock(wdev);
12289 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
12290 wdev_unlock(wdev);
12291
12292 return err;
12293}
12294
12295static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
12296 struct genl_info *info)
12297{
12298 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12299 struct net_device *dev = info->user_ptr[1];
12300 struct wireless_dev *wdev = dev->ieee80211_ptr;
12301 const u8 *addr;
12302
12303 if (!rdev->ops->tdls_channel_switch ||
12304 !rdev->ops->tdls_cancel_channel_switch ||
12305 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
12306 return -EOPNOTSUPP;
12307
12308 switch (dev->ieee80211_ptr->iftype) {
12309 case NL80211_IFTYPE_STATION:
12310 case NL80211_IFTYPE_P2P_CLIENT:
12311 break;
12312 default:
12313 return -EOPNOTSUPP;
12314 }
12315
12316 if (!info->attrs[NL80211_ATTR_MAC])
12317 return -EINVAL;
12318
12319 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
12320
12321 wdev_lock(wdev);
12322 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
12323 wdev_unlock(wdev);
12324
12325 return 0;
12326}
12327
ce0ce13a
MB
12328static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
12329 struct genl_info *info)
12330{
12331 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12332 struct net_device *dev = info->user_ptr[1];
12333 struct wireless_dev *wdev = dev->ieee80211_ptr;
12334 const struct nlattr *nla;
12335 bool enabled;
12336
ce0ce13a
MB
12337 if (!rdev->ops->set_multicast_to_unicast)
12338 return -EOPNOTSUPP;
12339
12340 if (wdev->iftype != NL80211_IFTYPE_AP &&
12341 wdev->iftype != NL80211_IFTYPE_P2P_GO)
12342 return -EOPNOTSUPP;
12343
12344 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
12345 enabled = nla_get_flag(nla);
12346
12347 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
12348}
12349
3a00df57
AS
12350static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
12351{
12352 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12353 struct net_device *dev = info->user_ptr[1];
12354 struct wireless_dev *wdev = dev->ieee80211_ptr;
12355 struct cfg80211_pmk_conf pmk_conf = {};
12356 int ret;
12357
12358 if (wdev->iftype != NL80211_IFTYPE_STATION &&
12359 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
12360 return -EOPNOTSUPP;
12361
12362 if (!wiphy_ext_feature_isset(&rdev->wiphy,
12363 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
12364 return -EOPNOTSUPP;
12365
12366 if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
12367 return -EINVAL;
12368
12369 wdev_lock(wdev);
12370 if (!wdev->current_bss) {
12371 ret = -ENOTCONN;
12372 goto out;
12373 }
12374
12375 pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
12376 if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
12377 ret = -EINVAL;
12378 goto out;
12379 }
12380
12381 pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
12382 pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
12383 if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
12384 pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
12385 ret = -EINVAL;
12386 goto out;
12387 }
12388
12389 if (info->attrs[NL80211_ATTR_PMKR0_NAME]) {
12390 int r0_name_len = nla_len(info->attrs[NL80211_ATTR_PMKR0_NAME]);
12391
12392 if (r0_name_len != WLAN_PMK_NAME_LEN) {
12393 ret = -EINVAL;
12394 goto out;
12395 }
12396
12397 pmk_conf.pmk_r0_name =
12398 nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
12399 }
12400
12401 ret = rdev_set_pmk(rdev, dev, &pmk_conf);
12402out:
12403 wdev_unlock(wdev);
12404 return ret;
12405}
12406
12407static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
12408{
12409 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12410 struct net_device *dev = info->user_ptr[1];
12411 struct wireless_dev *wdev = dev->ieee80211_ptr;
12412 const u8 *aa;
12413 int ret;
12414
12415 if (wdev->iftype != NL80211_IFTYPE_STATION &&
12416 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
12417 return -EOPNOTSUPP;
12418
12419 if (!wiphy_ext_feature_isset(&rdev->wiphy,
12420 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
12421 return -EOPNOTSUPP;
12422
12423 if (!info->attrs[NL80211_ATTR_MAC])
12424 return -EINVAL;
12425
12426 wdev_lock(wdev);
12427 aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
12428 ret = rdev_del_pmk(rdev, dev, aa);
12429 wdev_unlock(wdev);
12430
12431 return ret;
12432}
12433
4c476991
JB
12434#define NL80211_FLAG_NEED_WIPHY 0x01
12435#define NL80211_FLAG_NEED_NETDEV 0x02
12436#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
12437#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
12438#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
12439 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 12440#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 12441/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
12442#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
12443 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 12444#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 12445
f84f771d 12446static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
12447 struct genl_info *info)
12448{
12449 struct cfg80211_registered_device *rdev;
89a54e48 12450 struct wireless_dev *wdev;
4c476991 12451 struct net_device *dev;
4c476991
JB
12452 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
12453
12454 if (rtnl)
12455 rtnl_lock();
12456
12457 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 12458 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
12459 if (IS_ERR(rdev)) {
12460 if (rtnl)
12461 rtnl_unlock();
12462 return PTR_ERR(rdev);
12463 }
12464 info->user_ptr[0] = rdev;
1bf614ef
JB
12465 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
12466 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
12467 ASSERT_RTNL();
12468
89a54e48
JB
12469 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
12470 info->attrs);
12471 if (IS_ERR(wdev)) {
4c476991
JB
12472 if (rtnl)
12473 rtnl_unlock();
89a54e48 12474 return PTR_ERR(wdev);
4c476991 12475 }
89a54e48 12476
89a54e48 12477 dev = wdev->netdev;
f26cbf40 12478 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 12479
1bf614ef
JB
12480 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
12481 if (!dev) {
1bf614ef
JB
12482 if (rtnl)
12483 rtnl_unlock();
12484 return -EINVAL;
12485 }
12486
12487 info->user_ptr[1] = dev;
12488 } else {
12489 info->user_ptr[1] = wdev;
41265714 12490 }
1bf614ef 12491
73c7da3d
AVS
12492 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
12493 !wdev_running(wdev)) {
12494 if (rtnl)
12495 rtnl_unlock();
12496 return -ENETDOWN;
12497 }
1bf614ef 12498
73c7da3d 12499 if (dev)
1bf614ef 12500 dev_hold(dev);
89a54e48 12501
4c476991 12502 info->user_ptr[0] = rdev;
4c476991
JB
12503 }
12504
12505 return 0;
12506}
12507
f84f771d 12508static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
12509 struct genl_info *info)
12510{
1bf614ef
JB
12511 if (info->user_ptr[1]) {
12512 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
12513 struct wireless_dev *wdev = info->user_ptr[1];
12514
12515 if (wdev->netdev)
12516 dev_put(wdev->netdev);
12517 } else {
12518 dev_put(info->user_ptr[1]);
12519 }
12520 }
5393b917 12521
4c476991
JB
12522 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
12523 rtnl_unlock();
5393b917
JB
12524
12525 /* If needed, clear the netlink message payload from the SKB
12526 * as it might contain key data that shouldn't stick around on
12527 * the heap after the SKB is freed. The netlink message header
12528 * is still needed for further processing, so leave it intact.
12529 */
12530 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
12531 struct nlmsghdr *nlh = nlmsg_hdr(skb);
12532
12533 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
12534 }
4c476991
JB
12535}
12536
4534de83 12537static const struct genl_ops nl80211_ops[] = {
55682965
JB
12538 {
12539 .cmd = NL80211_CMD_GET_WIPHY,
12540 .doit = nl80211_get_wiphy,
12541 .dumpit = nl80211_dump_wiphy,
86e8cf98 12542 .done = nl80211_dump_wiphy_done,
55682965
JB
12543 .policy = nl80211_policy,
12544 /* can be retrieved by unprivileged users */
5fe231e8
JB
12545 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12546 NL80211_FLAG_NEED_RTNL,
55682965
JB
12547 },
12548 {
12549 .cmd = NL80211_CMD_SET_WIPHY,
12550 .doit = nl80211_set_wiphy,
12551 .policy = nl80211_policy,
5617c6cd 12552 .flags = GENL_UNS_ADMIN_PERM,
4c476991 12553 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
12554 },
12555 {
12556 .cmd = NL80211_CMD_GET_INTERFACE,
12557 .doit = nl80211_get_interface,
12558 .dumpit = nl80211_dump_interface,
12559 .policy = nl80211_policy,
12560 /* can be retrieved by unprivileged users */
5fe231e8
JB
12561 .internal_flags = NL80211_FLAG_NEED_WDEV |
12562 NL80211_FLAG_NEED_RTNL,
55682965
JB
12563 },
12564 {
12565 .cmd = NL80211_CMD_SET_INTERFACE,
12566 .doit = nl80211_set_interface,
12567 .policy = nl80211_policy,
5617c6cd 12568 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12569 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12570 NL80211_FLAG_NEED_RTNL,
55682965
JB
12571 },
12572 {
12573 .cmd = NL80211_CMD_NEW_INTERFACE,
12574 .doit = nl80211_new_interface,
12575 .policy = nl80211_policy,
5617c6cd 12576 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12577 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12578 NL80211_FLAG_NEED_RTNL,
55682965
JB
12579 },
12580 {
12581 .cmd = NL80211_CMD_DEL_INTERFACE,
12582 .doit = nl80211_del_interface,
12583 .policy = nl80211_policy,
5617c6cd 12584 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 12585 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 12586 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
12587 },
12588 {
12589 .cmd = NL80211_CMD_GET_KEY,
12590 .doit = nl80211_get_key,
12591 .policy = nl80211_policy,
5617c6cd 12592 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12593 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12594 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
12595 },
12596 {
12597 .cmd = NL80211_CMD_SET_KEY,
12598 .doit = nl80211_set_key,
12599 .policy = nl80211_policy,
5617c6cd 12600 .flags = GENL_UNS_ADMIN_PERM,
41265714 12601 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12602 NL80211_FLAG_NEED_RTNL |
12603 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
12604 },
12605 {
12606 .cmd = NL80211_CMD_NEW_KEY,
12607 .doit = nl80211_new_key,
12608 .policy = nl80211_policy,
5617c6cd 12609 .flags = GENL_UNS_ADMIN_PERM,
41265714 12610 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12611 NL80211_FLAG_NEED_RTNL |
12612 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
12613 },
12614 {
12615 .cmd = NL80211_CMD_DEL_KEY,
12616 .doit = nl80211_del_key,
12617 .policy = nl80211_policy,
5617c6cd 12618 .flags = GENL_UNS_ADMIN_PERM,
41265714 12619 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12620 NL80211_FLAG_NEED_RTNL,
55682965 12621 },
ed1b6cc7
JB
12622 {
12623 .cmd = NL80211_CMD_SET_BEACON,
12624 .policy = nl80211_policy,
5617c6cd 12625 .flags = GENL_UNS_ADMIN_PERM,
8860020e 12626 .doit = nl80211_set_beacon,
2b5f8b0b 12627 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12628 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
12629 },
12630 {
8860020e 12631 .cmd = NL80211_CMD_START_AP,
ed1b6cc7 12632 .policy = nl80211_policy,
5617c6cd 12633 .flags = GENL_UNS_ADMIN_PERM,
8860020e 12634 .doit = nl80211_start_ap,
2b5f8b0b 12635 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12636 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
12637 },
12638 {
8860020e 12639 .cmd = NL80211_CMD_STOP_AP,
ed1b6cc7 12640 .policy = nl80211_policy,
5617c6cd 12641 .flags = GENL_UNS_ADMIN_PERM,
8860020e 12642 .doit = nl80211_stop_ap,
2b5f8b0b 12643 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12644 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 12645 },
5727ef1b
JB
12646 {
12647 .cmd = NL80211_CMD_GET_STATION,
12648 .doit = nl80211_get_station,
2ec600d6 12649 .dumpit = nl80211_dump_station,
5727ef1b 12650 .policy = nl80211_policy,
4c476991
JB
12651 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12652 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
12653 },
12654 {
12655 .cmd = NL80211_CMD_SET_STATION,
12656 .doit = nl80211_set_station,
12657 .policy = nl80211_policy,
5617c6cd 12658 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12659 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12660 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
12661 },
12662 {
12663 .cmd = NL80211_CMD_NEW_STATION,
12664 .doit = nl80211_new_station,
12665 .policy = nl80211_policy,
5617c6cd 12666 .flags = GENL_UNS_ADMIN_PERM,
41265714 12667 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12668 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
12669 },
12670 {
12671 .cmd = NL80211_CMD_DEL_STATION,
12672 .doit = nl80211_del_station,
12673 .policy = nl80211_policy,
5617c6cd 12674 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12675 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12676 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12677 },
12678 {
12679 .cmd = NL80211_CMD_GET_MPATH,
12680 .doit = nl80211_get_mpath,
12681 .dumpit = nl80211_dump_mpath,
12682 .policy = nl80211_policy,
5617c6cd 12683 .flags = GENL_UNS_ADMIN_PERM,
41265714 12684 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12685 NL80211_FLAG_NEED_RTNL,
2ec600d6 12686 },
66be7d2b
HR
12687 {
12688 .cmd = NL80211_CMD_GET_MPP,
12689 .doit = nl80211_get_mpp,
12690 .dumpit = nl80211_dump_mpp,
12691 .policy = nl80211_policy,
5617c6cd 12692 .flags = GENL_UNS_ADMIN_PERM,
66be7d2b
HR
12693 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12694 NL80211_FLAG_NEED_RTNL,
12695 },
2ec600d6
LCC
12696 {
12697 .cmd = NL80211_CMD_SET_MPATH,
12698 .doit = nl80211_set_mpath,
12699 .policy = nl80211_policy,
5617c6cd 12700 .flags = GENL_UNS_ADMIN_PERM,
41265714 12701 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12702 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12703 },
12704 {
12705 .cmd = NL80211_CMD_NEW_MPATH,
12706 .doit = nl80211_new_mpath,
12707 .policy = nl80211_policy,
5617c6cd 12708 .flags = GENL_UNS_ADMIN_PERM,
41265714 12709 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12710 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12711 },
12712 {
12713 .cmd = NL80211_CMD_DEL_MPATH,
12714 .doit = nl80211_del_mpath,
12715 .policy = nl80211_policy,
5617c6cd 12716 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12717 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12718 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
12719 },
12720 {
12721 .cmd = NL80211_CMD_SET_BSS,
12722 .doit = nl80211_set_bss,
12723 .policy = nl80211_policy,
5617c6cd 12724 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12725 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12726 NL80211_FLAG_NEED_RTNL,
b2e1b302 12727 },
f130347c
LR
12728 {
12729 .cmd = NL80211_CMD_GET_REG,
ad30ca2c
AN
12730 .doit = nl80211_get_reg_do,
12731 .dumpit = nl80211_get_reg_dump,
f130347c 12732 .policy = nl80211_policy,
5fe231e8 12733 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
12734 /* can be retrieved by unprivileged users */
12735 },
b6863036 12736#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
12737 {
12738 .cmd = NL80211_CMD_SET_REG,
12739 .doit = nl80211_set_reg,
12740 .policy = nl80211_policy,
12741 .flags = GENL_ADMIN_PERM,
5fe231e8 12742 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302 12743 },
b6863036 12744#endif
b2e1b302
LR
12745 {
12746 .cmd = NL80211_CMD_REQ_SET_REG,
12747 .doit = nl80211_req_set_reg,
12748 .policy = nl80211_policy,
93da9cc1 12749 .flags = GENL_ADMIN_PERM,
12750 },
1ea4ff3e
JB
12751 {
12752 .cmd = NL80211_CMD_RELOAD_REGDB,
12753 .doit = nl80211_reload_regdb,
12754 .policy = nl80211_policy,
12755 .flags = GENL_ADMIN_PERM,
12756 },
93da9cc1 12757 {
24bdd9f4
JC
12758 .cmd = NL80211_CMD_GET_MESH_CONFIG,
12759 .doit = nl80211_get_mesh_config,
93da9cc1 12760 .policy = nl80211_policy,
12761 /* can be retrieved by unprivileged users */
2b5f8b0b 12762 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12763 NL80211_FLAG_NEED_RTNL,
93da9cc1 12764 },
12765 {
24bdd9f4
JC
12766 .cmd = NL80211_CMD_SET_MESH_CONFIG,
12767 .doit = nl80211_update_mesh_config,
93da9cc1 12768 .policy = nl80211_policy,
5617c6cd 12769 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c 12770 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12771 NL80211_FLAG_NEED_RTNL,
9aed3cc1 12772 },
2a519311
JB
12773 {
12774 .cmd = NL80211_CMD_TRIGGER_SCAN,
12775 .doit = nl80211_trigger_scan,
12776 .policy = nl80211_policy,
5617c6cd 12777 .flags = GENL_UNS_ADMIN_PERM,
fd014284 12778 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12779 NL80211_FLAG_NEED_RTNL,
2a519311 12780 },
91d3ab46
VK
12781 {
12782 .cmd = NL80211_CMD_ABORT_SCAN,
12783 .doit = nl80211_abort_scan,
12784 .policy = nl80211_policy,
5617c6cd 12785 .flags = GENL_UNS_ADMIN_PERM,
91d3ab46
VK
12786 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12787 NL80211_FLAG_NEED_RTNL,
12788 },
2a519311
JB
12789 {
12790 .cmd = NL80211_CMD_GET_SCAN,
12791 .policy = nl80211_policy,
12792 .dumpit = nl80211_dump_scan,
12793 },
807f8a8c
LC
12794 {
12795 .cmd = NL80211_CMD_START_SCHED_SCAN,
12796 .doit = nl80211_start_sched_scan,
12797 .policy = nl80211_policy,
5617c6cd 12798 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
12799 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12800 NL80211_FLAG_NEED_RTNL,
12801 },
12802 {
12803 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
12804 .doit = nl80211_stop_sched_scan,
12805 .policy = nl80211_policy,
5617c6cd 12806 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
12807 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12808 NL80211_FLAG_NEED_RTNL,
12809 },
636a5d36
JM
12810 {
12811 .cmd = NL80211_CMD_AUTHENTICATE,
12812 .doit = nl80211_authenticate,
12813 .policy = nl80211_policy,
5617c6cd 12814 .flags = GENL_UNS_ADMIN_PERM,
41265714 12815 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12816 NL80211_FLAG_NEED_RTNL |
12817 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
12818 },
12819 {
12820 .cmd = NL80211_CMD_ASSOCIATE,
12821 .doit = nl80211_associate,
12822 .policy = nl80211_policy,
5617c6cd 12823 .flags = GENL_UNS_ADMIN_PERM,
41265714 12824 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12825 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
12826 },
12827 {
12828 .cmd = NL80211_CMD_DEAUTHENTICATE,
12829 .doit = nl80211_deauthenticate,
12830 .policy = nl80211_policy,
5617c6cd 12831 .flags = GENL_UNS_ADMIN_PERM,
41265714 12832 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12833 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
12834 },
12835 {
12836 .cmd = NL80211_CMD_DISASSOCIATE,
12837 .doit = nl80211_disassociate,
12838 .policy = nl80211_policy,
5617c6cd 12839 .flags = GENL_UNS_ADMIN_PERM,
41265714 12840 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12841 NL80211_FLAG_NEED_RTNL,
636a5d36 12842 },
04a773ad
JB
12843 {
12844 .cmd = NL80211_CMD_JOIN_IBSS,
12845 .doit = nl80211_join_ibss,
12846 .policy = nl80211_policy,
5617c6cd 12847 .flags = GENL_UNS_ADMIN_PERM,
41265714 12848 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12849 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
12850 },
12851 {
12852 .cmd = NL80211_CMD_LEAVE_IBSS,
12853 .doit = nl80211_leave_ibss,
12854 .policy = nl80211_policy,
5617c6cd 12855 .flags = GENL_UNS_ADMIN_PERM,
41265714 12856 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12857 NL80211_FLAG_NEED_RTNL,
04a773ad 12858 },
aff89a9b
JB
12859#ifdef CONFIG_NL80211_TESTMODE
12860 {
12861 .cmd = NL80211_CMD_TESTMODE,
12862 .doit = nl80211_testmode_do,
71063f0e 12863 .dumpit = nl80211_testmode_dump,
aff89a9b 12864 .policy = nl80211_policy,
5617c6cd 12865 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12866 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12867 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
12868 },
12869#endif
b23aa676
SO
12870 {
12871 .cmd = NL80211_CMD_CONNECT,
12872 .doit = nl80211_connect,
12873 .policy = nl80211_policy,
5617c6cd 12874 .flags = GENL_UNS_ADMIN_PERM,
41265714 12875 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12876 NL80211_FLAG_NEED_RTNL,
b23aa676 12877 },
088e8df8 12878 {
12879 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
12880 .doit = nl80211_update_connect_params,
12881 .policy = nl80211_policy,
12882 .flags = GENL_ADMIN_PERM,
12883 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12884 NL80211_FLAG_NEED_RTNL,
12885 },
b23aa676
SO
12886 {
12887 .cmd = NL80211_CMD_DISCONNECT,
12888 .doit = nl80211_disconnect,
12889 .policy = nl80211_policy,
5617c6cd 12890 .flags = GENL_UNS_ADMIN_PERM,
41265714 12891 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12892 NL80211_FLAG_NEED_RTNL,
b23aa676 12893 },
463d0183
JB
12894 {
12895 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
12896 .doit = nl80211_wiphy_netns,
12897 .policy = nl80211_policy,
5617c6cd 12898 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12899 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12900 NL80211_FLAG_NEED_RTNL,
463d0183 12901 },
61fa713c
HS
12902 {
12903 .cmd = NL80211_CMD_GET_SURVEY,
12904 .policy = nl80211_policy,
12905 .dumpit = nl80211_dump_survey,
12906 },
67fbb16b
SO
12907 {
12908 .cmd = NL80211_CMD_SET_PMKSA,
12909 .doit = nl80211_setdel_pmksa,
12910 .policy = nl80211_policy,
5617c6cd 12911 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12912 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12913 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12914 },
12915 {
12916 .cmd = NL80211_CMD_DEL_PMKSA,
12917 .doit = nl80211_setdel_pmksa,
12918 .policy = nl80211_policy,
5617c6cd 12919 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12920 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12921 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12922 },
12923 {
12924 .cmd = NL80211_CMD_FLUSH_PMKSA,
12925 .doit = nl80211_flush_pmksa,
12926 .policy = nl80211_policy,
5617c6cd 12927 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12928 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12929 NL80211_FLAG_NEED_RTNL,
67fbb16b 12930 },
9588bbd5
JM
12931 {
12932 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
12933 .doit = nl80211_remain_on_channel,
12934 .policy = nl80211_policy,
5617c6cd 12935 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12936 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12937 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
12938 },
12939 {
12940 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
12941 .doit = nl80211_cancel_remain_on_channel,
12942 .policy = nl80211_policy,
5617c6cd 12943 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12944 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12945 NL80211_FLAG_NEED_RTNL,
9588bbd5 12946 },
13ae75b1
JM
12947 {
12948 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
12949 .doit = nl80211_set_tx_bitrate_mask,
12950 .policy = nl80211_policy,
5617c6cd 12951 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12952 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12953 NL80211_FLAG_NEED_RTNL,
13ae75b1 12954 },
026331c4 12955 {
2e161f78
JB
12956 .cmd = NL80211_CMD_REGISTER_FRAME,
12957 .doit = nl80211_register_mgmt,
026331c4 12958 .policy = nl80211_policy,
5617c6cd 12959 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12960 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 12961 NL80211_FLAG_NEED_RTNL,
026331c4
JM
12962 },
12963 {
2e161f78
JB
12964 .cmd = NL80211_CMD_FRAME,
12965 .doit = nl80211_tx_mgmt,
026331c4 12966 .policy = nl80211_policy,
5617c6cd 12967 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12968 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
12969 NL80211_FLAG_NEED_RTNL,
12970 },
12971 {
12972 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
12973 .doit = nl80211_tx_mgmt_cancel_wait,
12974 .policy = nl80211_policy,
5617c6cd 12975 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12976 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12977 NL80211_FLAG_NEED_RTNL,
026331c4 12978 },
ffb9eb3d
KV
12979 {
12980 .cmd = NL80211_CMD_SET_POWER_SAVE,
12981 .doit = nl80211_set_power_save,
12982 .policy = nl80211_policy,
5617c6cd 12983 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12984 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12985 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
12986 },
12987 {
12988 .cmd = NL80211_CMD_GET_POWER_SAVE,
12989 .doit = nl80211_get_power_save,
12990 .policy = nl80211_policy,
12991 /* can be retrieved by unprivileged users */
4c476991
JB
12992 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12993 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 12994 },
d6dc1a38
JO
12995 {
12996 .cmd = NL80211_CMD_SET_CQM,
12997 .doit = nl80211_set_cqm,
12998 .policy = nl80211_policy,
5617c6cd 12999 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13000 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13001 NL80211_FLAG_NEED_RTNL,
d6dc1a38 13002 },
f444de05
JB
13003 {
13004 .cmd = NL80211_CMD_SET_CHANNEL,
13005 .doit = nl80211_set_channel,
13006 .policy = nl80211_policy,
5617c6cd 13007 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13008 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13009 NL80211_FLAG_NEED_RTNL,
f444de05 13010 },
e8347eba
BJ
13011 {
13012 .cmd = NL80211_CMD_SET_WDS_PEER,
13013 .doit = nl80211_set_wds_peer,
13014 .policy = nl80211_policy,
5617c6cd 13015 .flags = GENL_UNS_ADMIN_PERM,
43b19952
JB
13016 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13017 NL80211_FLAG_NEED_RTNL,
e8347eba 13018 },
29cbe68c
JB
13019 {
13020 .cmd = NL80211_CMD_JOIN_MESH,
13021 .doit = nl80211_join_mesh,
13022 .policy = nl80211_policy,
5617c6cd 13023 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
13024 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13025 NL80211_FLAG_NEED_RTNL,
13026 },
13027 {
13028 .cmd = NL80211_CMD_LEAVE_MESH,
13029 .doit = nl80211_leave_mesh,
13030 .policy = nl80211_policy,
5617c6cd 13031 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
13032 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13033 NL80211_FLAG_NEED_RTNL,
13034 },
6e0bd6c3
RL
13035 {
13036 .cmd = NL80211_CMD_JOIN_OCB,
13037 .doit = nl80211_join_ocb,
13038 .policy = nl80211_policy,
5617c6cd 13039 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
13040 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13041 NL80211_FLAG_NEED_RTNL,
13042 },
13043 {
13044 .cmd = NL80211_CMD_LEAVE_OCB,
13045 .doit = nl80211_leave_ocb,
13046 .policy = nl80211_policy,
5617c6cd 13047 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
13048 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13049 NL80211_FLAG_NEED_RTNL,
13050 },
dfb89c56 13051#ifdef CONFIG_PM
ff1b6e69
JB
13052 {
13053 .cmd = NL80211_CMD_GET_WOWLAN,
13054 .doit = nl80211_get_wowlan,
13055 .policy = nl80211_policy,
13056 /* can be retrieved by unprivileged users */
13057 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13058 NL80211_FLAG_NEED_RTNL,
13059 },
13060 {
13061 .cmd = NL80211_CMD_SET_WOWLAN,
13062 .doit = nl80211_set_wowlan,
13063 .policy = nl80211_policy,
5617c6cd 13064 .flags = GENL_UNS_ADMIN_PERM,
ff1b6e69
JB
13065 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13066 NL80211_FLAG_NEED_RTNL,
13067 },
dfb89c56 13068#endif
e5497d76
JB
13069 {
13070 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
13071 .doit = nl80211_set_rekey_data,
13072 .policy = nl80211_policy,
5617c6cd 13073 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 13074 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
13075 NL80211_FLAG_NEED_RTNL |
13076 NL80211_FLAG_CLEAR_SKB,
e5497d76 13077 },
109086ce
AN
13078 {
13079 .cmd = NL80211_CMD_TDLS_MGMT,
13080 .doit = nl80211_tdls_mgmt,
13081 .policy = nl80211_policy,
5617c6cd 13082 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
13083 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13084 NL80211_FLAG_NEED_RTNL,
13085 },
13086 {
13087 .cmd = NL80211_CMD_TDLS_OPER,
13088 .doit = nl80211_tdls_oper,
13089 .policy = nl80211_policy,
5617c6cd 13090 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
13091 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13092 NL80211_FLAG_NEED_RTNL,
13093 },
28946da7
JB
13094 {
13095 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
13096 .doit = nl80211_register_unexpected_frame,
13097 .policy = nl80211_policy,
5617c6cd 13098 .flags = GENL_UNS_ADMIN_PERM,
28946da7
JB
13099 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13100 NL80211_FLAG_NEED_RTNL,
13101 },
7f6cf311
JB
13102 {
13103 .cmd = NL80211_CMD_PROBE_CLIENT,
13104 .doit = nl80211_probe_client,
13105 .policy = nl80211_policy,
5617c6cd 13106 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13107 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
13108 NL80211_FLAG_NEED_RTNL,
13109 },
5e760230
JB
13110 {
13111 .cmd = NL80211_CMD_REGISTER_BEACONS,
13112 .doit = nl80211_register_beacons,
13113 .policy = nl80211_policy,
5617c6cd 13114 .flags = GENL_UNS_ADMIN_PERM,
5e760230
JB
13115 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13116 NL80211_FLAG_NEED_RTNL,
13117 },
1d9d9213
SW
13118 {
13119 .cmd = NL80211_CMD_SET_NOACK_MAP,
13120 .doit = nl80211_set_noack_map,
13121 .policy = nl80211_policy,
5617c6cd 13122 .flags = GENL_UNS_ADMIN_PERM,
1d9d9213
SW
13123 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13124 NL80211_FLAG_NEED_RTNL,
13125 },
98104fde
JB
13126 {
13127 .cmd = NL80211_CMD_START_P2P_DEVICE,
13128 .doit = nl80211_start_p2p_device,
13129 .policy = nl80211_policy,
5617c6cd 13130 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
13131 .internal_flags = NL80211_FLAG_NEED_WDEV |
13132 NL80211_FLAG_NEED_RTNL,
13133 },
13134 {
13135 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
13136 .doit = nl80211_stop_p2p_device,
13137 .policy = nl80211_policy,
5617c6cd 13138 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
13139 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13140 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
13141 },
13142 {
13143 .cmd = NL80211_CMD_START_NAN,
13144 .doit = nl80211_start_nan,
13145 .policy = nl80211_policy,
13146 .flags = GENL_ADMIN_PERM,
13147 .internal_flags = NL80211_FLAG_NEED_WDEV |
13148 NL80211_FLAG_NEED_RTNL,
13149 },
13150 {
13151 .cmd = NL80211_CMD_STOP_NAN,
13152 .doit = nl80211_stop_nan,
13153 .policy = nl80211_policy,
13154 .flags = GENL_ADMIN_PERM,
13155 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13156 NL80211_FLAG_NEED_RTNL,
a442b761
AB
13157 },
13158 {
13159 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
13160 .doit = nl80211_nan_add_func,
13161 .policy = nl80211_policy,
13162 .flags = GENL_ADMIN_PERM,
13163 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13164 NL80211_FLAG_NEED_RTNL,
13165 },
13166 {
13167 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
13168 .doit = nl80211_nan_del_func,
13169 .policy = nl80211_policy,
13170 .flags = GENL_ADMIN_PERM,
13171 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13172 NL80211_FLAG_NEED_RTNL,
a5a9dcf2
AB
13173 },
13174 {
13175 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
13176 .doit = nl80211_nan_change_config,
13177 .policy = nl80211_policy,
13178 .flags = GENL_ADMIN_PERM,
13179 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13180 NL80211_FLAG_NEED_RTNL,
98104fde 13181 },
f4e583c8
AQ
13182 {
13183 .cmd = NL80211_CMD_SET_MCAST_RATE,
13184 .doit = nl80211_set_mcast_rate,
77765eaf 13185 .policy = nl80211_policy,
5617c6cd 13186 .flags = GENL_UNS_ADMIN_PERM,
77765eaf
VT
13187 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13188 NL80211_FLAG_NEED_RTNL,
13189 },
13190 {
13191 .cmd = NL80211_CMD_SET_MAC_ACL,
13192 .doit = nl80211_set_mac_acl,
f4e583c8 13193 .policy = nl80211_policy,
5617c6cd 13194 .flags = GENL_UNS_ADMIN_PERM,
f4e583c8
AQ
13195 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13196 NL80211_FLAG_NEED_RTNL,
13197 },
04f39047
SW
13198 {
13199 .cmd = NL80211_CMD_RADAR_DETECT,
13200 .doit = nl80211_start_radar_detection,
13201 .policy = nl80211_policy,
5617c6cd 13202 .flags = GENL_UNS_ADMIN_PERM,
04f39047
SW
13203 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13204 NL80211_FLAG_NEED_RTNL,
13205 },
3713b4e3
JB
13206 {
13207 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
13208 .doit = nl80211_get_protocol_features,
13209 .policy = nl80211_policy,
13210 },
355199e0
JM
13211 {
13212 .cmd = NL80211_CMD_UPDATE_FT_IES,
13213 .doit = nl80211_update_ft_ies,
13214 .policy = nl80211_policy,
5617c6cd 13215 .flags = GENL_UNS_ADMIN_PERM,
355199e0
JM
13216 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13217 NL80211_FLAG_NEED_RTNL,
13218 },
5de17984
AS
13219 {
13220 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
13221 .doit = nl80211_crit_protocol_start,
13222 .policy = nl80211_policy,
5617c6cd 13223 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
13224 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13225 NL80211_FLAG_NEED_RTNL,
13226 },
13227 {
13228 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
13229 .doit = nl80211_crit_protocol_stop,
13230 .policy = nl80211_policy,
5617c6cd 13231 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
13232 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13233 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
13234 },
13235 {
13236 .cmd = NL80211_CMD_GET_COALESCE,
13237 .doit = nl80211_get_coalesce,
13238 .policy = nl80211_policy,
13239 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13240 NL80211_FLAG_NEED_RTNL,
13241 },
13242 {
13243 .cmd = NL80211_CMD_SET_COALESCE,
13244 .doit = nl80211_set_coalesce,
13245 .policy = nl80211_policy,
5617c6cd 13246 .flags = GENL_UNS_ADMIN_PERM,
be29b99a
AK
13247 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13248 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
13249 },
13250 {
13251 .cmd = NL80211_CMD_CHANNEL_SWITCH,
13252 .doit = nl80211_channel_switch,
13253 .policy = nl80211_policy,
5617c6cd 13254 .flags = GENL_UNS_ADMIN_PERM,
16ef1fe2
SW
13255 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13256 NL80211_FLAG_NEED_RTNL,
13257 },
ad7e718c
JB
13258 {
13259 .cmd = NL80211_CMD_VENDOR,
13260 .doit = nl80211_vendor_cmd,
7bdbe400 13261 .dumpit = nl80211_vendor_cmd_dump,
ad7e718c 13262 .policy = nl80211_policy,
5617c6cd 13263 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c
JB
13264 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13265 NL80211_FLAG_NEED_RTNL,
13266 },
fa9ffc74
KP
13267 {
13268 .cmd = NL80211_CMD_SET_QOS_MAP,
13269 .doit = nl80211_set_qos_map,
13270 .policy = nl80211_policy,
5617c6cd 13271 .flags = GENL_UNS_ADMIN_PERM,
fa9ffc74
KP
13272 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13273 NL80211_FLAG_NEED_RTNL,
13274 },
960d01ac
JB
13275 {
13276 .cmd = NL80211_CMD_ADD_TX_TS,
13277 .doit = nl80211_add_tx_ts,
13278 .policy = nl80211_policy,
5617c6cd 13279 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
13280 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13281 NL80211_FLAG_NEED_RTNL,
13282 },
13283 {
13284 .cmd = NL80211_CMD_DEL_TX_TS,
13285 .doit = nl80211_del_tx_ts,
13286 .policy = nl80211_policy,
5617c6cd 13287 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
13288 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13289 NL80211_FLAG_NEED_RTNL,
13290 },
1057d35e
AN
13291 {
13292 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
13293 .doit = nl80211_tdls_channel_switch,
13294 .policy = nl80211_policy,
5617c6cd 13295 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
13296 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13297 NL80211_FLAG_NEED_RTNL,
13298 },
13299 {
13300 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
13301 .doit = nl80211_tdls_cancel_channel_switch,
13302 .policy = nl80211_policy,
5617c6cd 13303 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
13304 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13305 NL80211_FLAG_NEED_RTNL,
13306 },
ce0ce13a
MB
13307 {
13308 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
13309 .doit = nl80211_set_multicast_to_unicast,
13310 .policy = nl80211_policy,
13311 .flags = GENL_UNS_ADMIN_PERM,
13312 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13313 NL80211_FLAG_NEED_RTNL,
13314 },
3a00df57
AS
13315 {
13316 .cmd = NL80211_CMD_SET_PMK,
13317 .doit = nl80211_set_pmk,
13318 .policy = nl80211_policy,
13319 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13320 NL80211_FLAG_NEED_RTNL,
13321 },
13322 {
13323 .cmd = NL80211_CMD_DEL_PMK,
13324 .doit = nl80211_del_pmk,
13325 .policy = nl80211_policy,
13326 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13327 NL80211_FLAG_NEED_RTNL,
13328 },
13329
55682965 13330};
9588bbd5 13331
56989f6d 13332static struct genl_family nl80211_fam __ro_after_init = {
489111e5
JB
13333 .name = NL80211_GENL_NAME, /* have users key off the name instead */
13334 .hdrsize = 0, /* no private header */
13335 .version = 1, /* no particular meaning now */
13336 .maxattr = NL80211_ATTR_MAX,
13337 .netnsok = true,
13338 .pre_doit = nl80211_pre_doit,
13339 .post_doit = nl80211_post_doit,
13340 .module = THIS_MODULE,
13341 .ops = nl80211_ops,
13342 .n_ops = ARRAY_SIZE(nl80211_ops),
13343 .mcgrps = nl80211_mcgrps,
13344 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
13345};
13346
55682965
JB
13347/* notification functions */
13348
3bb20556
JB
13349void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
13350 enum nl80211_commands cmd)
55682965
JB
13351{
13352 struct sk_buff *msg;
86e8cf98 13353 struct nl80211_dump_wiphy_state state = {};
55682965 13354
3bb20556
JB
13355 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
13356 cmd != NL80211_CMD_DEL_WIPHY);
13357
fd2120ca 13358 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
13359 if (!msg)
13360 return;
13361
3bb20556 13362 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
13363 nlmsg_free(msg);
13364 return;
13365 }
13366
68eb5503 13367 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13368 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
13369}
13370
896ff063
DK
13371void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
13372 struct wireless_dev *wdev,
13373 enum nl80211_commands cmd)
13374{
13375 struct sk_buff *msg;
13376
13377 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
13378 cmd != NL80211_CMD_DEL_INTERFACE);
13379
13380 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13381 if (!msg)
13382 return;
13383
13384 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev,
13385 cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
13386 nlmsg_free(msg);
13387 return;
13388 }
13389
13390 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
13391 NL80211_MCGRP_CONFIG, GFP_KERNEL);
13392}
13393
362a415d
JB
13394static int nl80211_add_scan_req(struct sk_buff *msg,
13395 struct cfg80211_registered_device *rdev)
13396{
13397 struct cfg80211_scan_request *req = rdev->scan_req;
13398 struct nlattr *nest;
13399 int i;
13400
13401 if (WARN_ON(!req))
13402 return 0;
13403
13404 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
13405 if (!nest)
13406 goto nla_put_failure;
9360ffd1
DM
13407 for (i = 0; i < req->n_ssids; i++) {
13408 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
13409 goto nla_put_failure;
13410 }
362a415d
JB
13411 nla_nest_end(msg, nest);
13412
13413 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
13414 if (!nest)
13415 goto nla_put_failure;
9360ffd1
DM
13416 for (i = 0; i < req->n_channels; i++) {
13417 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
13418 goto nla_put_failure;
13419 }
362a415d
JB
13420 nla_nest_end(msg, nest);
13421
9360ffd1
DM
13422 if (req->ie &&
13423 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
13424 goto nla_put_failure;
362a415d 13425
ae917c9f
JB
13426 if (req->flags &&
13427 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
13428 goto nla_put_failure;
ed473771 13429
1d76250b
AS
13430 if (req->info.scan_start_tsf &&
13431 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
13432 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
13433 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
13434 req->info.tsf_bssid)))
13435 goto nla_put_failure;
13436
362a415d
JB
13437 return 0;
13438 nla_put_failure:
13439 return -ENOBUFS;
13440}
13441
505a2e88 13442static int nl80211_prep_scan_msg(struct sk_buff *msg,
a538e2d5 13443 struct cfg80211_registered_device *rdev,
fd014284 13444 struct wireless_dev *wdev,
15e47304 13445 u32 portid, u32 seq, int flags,
a538e2d5 13446 u32 cmd)
2a519311
JB
13447{
13448 void *hdr;
13449
15e47304 13450 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
13451 if (!hdr)
13452 return -1;
13453
9360ffd1 13454 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
13455 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13456 wdev->netdev->ifindex)) ||
2dad624e
ND
13457 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13458 NL80211_ATTR_PAD))
9360ffd1 13459 goto nla_put_failure;
2a519311 13460
362a415d
JB
13461 /* ignore errors and send incomplete event anyway */
13462 nl80211_add_scan_req(msg, rdev);
2a519311 13463
053c095a
JB
13464 genlmsg_end(msg, hdr);
13465 return 0;
2a519311
JB
13466
13467 nla_put_failure:
13468 genlmsg_cancel(msg, hdr);
13469 return -EMSGSIZE;
13470}
13471
807f8a8c 13472static int
505a2e88 13473nl80211_prep_sched_scan_msg(struct sk_buff *msg,
96b08fd6 13474 struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
13475{
13476 void *hdr;
13477
96b08fd6 13478 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
807f8a8c
LC
13479 if (!hdr)
13480 return -1;
13481
96b08fd6
AVS
13482 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
13483 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
13484 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
13485 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
13486 NL80211_ATTR_PAD))
9360ffd1 13487 goto nla_put_failure;
807f8a8c 13488
053c095a
JB
13489 genlmsg_end(msg, hdr);
13490 return 0;
807f8a8c
LC
13491
13492 nla_put_failure:
13493 genlmsg_cancel(msg, hdr);
13494 return -EMSGSIZE;
13495}
13496
a538e2d5 13497void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 13498 struct wireless_dev *wdev)
a538e2d5
JB
13499{
13500 struct sk_buff *msg;
13501
58050fce 13502 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
13503 if (!msg)
13504 return;
13505
505a2e88 13506 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
13507 NL80211_CMD_TRIGGER_SCAN) < 0) {
13508 nlmsg_free(msg);
13509 return;
13510 }
13511
68eb5503 13512 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13513 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
13514}
13515
f9d15d16
JB
13516struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
13517 struct wireless_dev *wdev, bool aborted)
2a519311
JB
13518{
13519 struct sk_buff *msg;
13520
fd2120ca 13521 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 13522 if (!msg)
f9d15d16 13523 return NULL;
2a519311 13524
505a2e88 13525 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
13526 aborted ? NL80211_CMD_SCAN_ABORTED :
13527 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 13528 nlmsg_free(msg);
f9d15d16 13529 return NULL;
2a519311
JB
13530 }
13531
f9d15d16 13532 return msg;
2a519311
JB
13533}
13534
505a2e88
AVS
13535/* send message created by nl80211_build_scan_msg() */
13536void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
13537 struct sk_buff *msg)
807f8a8c 13538{
807f8a8c
LC
13539 if (!msg)
13540 return;
13541
68eb5503 13542 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13543 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
13544}
13545
96b08fd6 13546void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
13547{
13548 struct sk_buff *msg;
13549
58050fce 13550 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
13551 if (!msg)
13552 return;
13553
96b08fd6 13554 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
807f8a8c
LC
13555 nlmsg_free(msg);
13556 return;
13557 }
13558
96b08fd6 13559 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
2a94fe48 13560 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
13561}
13562
b0d7aa59
JD
13563static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
13564 struct regulatory_request *request)
73d54c9e 13565{
73d54c9e 13566 /* Userspace can always count this one always being set */
9360ffd1
DM
13567 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
13568 goto nla_put_failure;
13569
13570 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
13571 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13572 NL80211_REGDOM_TYPE_WORLD))
13573 goto nla_put_failure;
13574 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
13575 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13576 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
13577 goto nla_put_failure;
13578 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
13579 request->intersect) {
13580 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13581 NL80211_REGDOM_TYPE_INTERSECTION))
13582 goto nla_put_failure;
13583 } else {
13584 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13585 NL80211_REGDOM_TYPE_COUNTRY) ||
13586 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
13587 request->alpha2))
13588 goto nla_put_failure;
13589 }
13590
ad30ca2c
AN
13591 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
13592 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
13593
13594 if (wiphy &&
13595 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
13596 goto nla_put_failure;
1bdd716c
AN
13597
13598 if (wiphy &&
13599 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
13600 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
13601 goto nla_put_failure;
ad30ca2c 13602 }
73d54c9e 13603
b0d7aa59
JD
13604 return true;
13605
13606nla_put_failure:
13607 return false;
13608}
13609
13610/*
13611 * This can happen on global regulatory changes or device specific settings
13612 * based on custom regulatory domains.
13613 */
13614void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
13615 struct regulatory_request *request)
13616{
13617 struct sk_buff *msg;
13618 void *hdr;
13619
13620 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13621 if (!msg)
13622 return;
13623
13624 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
13625 if (!hdr) {
13626 nlmsg_free(msg);
13627 return;
13628 }
13629
13630 if (nl80211_reg_change_event_fill(msg, request) == false)
13631 goto nla_put_failure;
13632
3b7b72ee 13633 genlmsg_end(msg, hdr);
73d54c9e 13634
bc43b28c 13635 rcu_read_lock();
68eb5503 13636 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 13637 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 13638 rcu_read_unlock();
73d54c9e
LR
13639
13640 return;
13641
13642nla_put_failure:
13643 genlmsg_cancel(msg, hdr);
13644 nlmsg_free(msg);
13645}
13646
6039f6d2
JM
13647static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
13648 struct net_device *netdev,
13649 const u8 *buf, size_t len,
b0b6aa2c
EP
13650 enum nl80211_commands cmd, gfp_t gfp,
13651 int uapsd_queues)
6039f6d2
JM
13652{
13653 struct sk_buff *msg;
13654 void *hdr;
13655
4ef8c1c9 13656 msg = nlmsg_new(100 + len, gfp);
6039f6d2
JM
13657 if (!msg)
13658 return;
13659
13660 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13661 if (!hdr) {
13662 nlmsg_free(msg);
13663 return;
13664 }
13665
9360ffd1
DM
13666 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13667 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13668 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
13669 goto nla_put_failure;
6039f6d2 13670
b0b6aa2c
EP
13671 if (uapsd_queues >= 0) {
13672 struct nlattr *nla_wmm =
13673 nla_nest_start(msg, NL80211_ATTR_STA_WME);
13674 if (!nla_wmm)
13675 goto nla_put_failure;
13676
13677 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
13678 uapsd_queues))
13679 goto nla_put_failure;
13680
13681 nla_nest_end(msg, nla_wmm);
13682 }
13683
3b7b72ee 13684 genlmsg_end(msg, hdr);
6039f6d2 13685
68eb5503 13686 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13687 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
13688 return;
13689
13690 nla_put_failure:
13691 genlmsg_cancel(msg, hdr);
13692 nlmsg_free(msg);
13693}
13694
13695void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13696 struct net_device *netdev, const u8 *buf,
13697 size_t len, gfp_t gfp)
6039f6d2
JM
13698{
13699 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13700 NL80211_CMD_AUTHENTICATE, gfp, -1);
6039f6d2
JM
13701}
13702
13703void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
13704 struct net_device *netdev, const u8 *buf,
b0b6aa2c 13705 size_t len, gfp_t gfp, int uapsd_queues)
6039f6d2 13706{
e6d6e342 13707 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13708 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues);
6039f6d2
JM
13709}
13710
53b46b84 13711void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13712 struct net_device *netdev, const u8 *buf,
13713 size_t len, gfp_t gfp)
6039f6d2
JM
13714{
13715 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13716 NL80211_CMD_DEAUTHENTICATE, gfp, -1);
6039f6d2
JM
13717}
13718
53b46b84
JM
13719void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
13720 struct net_device *netdev, const u8 *buf,
e6d6e342 13721 size_t len, gfp_t gfp)
6039f6d2
JM
13722{
13723 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13724 NL80211_CMD_DISASSOCIATE, gfp, -1);
6039f6d2
JM
13725}
13726
6ff57cf8
JB
13727void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
13728 size_t len)
cf4e594e 13729{
947add36
JB
13730 struct wireless_dev *wdev = dev->ieee80211_ptr;
13731 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13732 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
13733 const struct ieee80211_mgmt *mgmt = (void *)buf;
13734 u32 cmd;
947add36 13735
6ff57cf8
JB
13736 if (WARN_ON(len < 2))
13737 return;
cf4e594e 13738
6ff57cf8
JB
13739 if (ieee80211_is_deauth(mgmt->frame_control))
13740 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
13741 else
13742 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 13743
6ff57cf8 13744 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
b0b6aa2c 13745 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1);
cf4e594e 13746}
6ff57cf8 13747EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 13748
1b06bb40
LR
13749static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
13750 struct net_device *netdev, int cmd,
e6d6e342 13751 const u8 *addr, gfp_t gfp)
1965c853
JM
13752{
13753 struct sk_buff *msg;
13754 void *hdr;
13755
e6d6e342 13756 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
13757 if (!msg)
13758 return;
13759
13760 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13761 if (!hdr) {
13762 nlmsg_free(msg);
13763 return;
13764 }
13765
9360ffd1
DM
13766 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13767 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13768 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
13769 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
13770 goto nla_put_failure;
1965c853 13771
3b7b72ee 13772 genlmsg_end(msg, hdr);
1965c853 13773
68eb5503 13774 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13775 NL80211_MCGRP_MLME, gfp);
1965c853
JM
13776 return;
13777
13778 nla_put_failure:
13779 genlmsg_cancel(msg, hdr);
13780 nlmsg_free(msg);
13781}
13782
13783void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13784 struct net_device *netdev, const u8 *addr,
13785 gfp_t gfp)
1965c853
JM
13786{
13787 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 13788 addr, gfp);
1965c853
JM
13789}
13790
13791void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13792 struct net_device *netdev, const u8 *addr,
13793 gfp_t gfp)
1965c853 13794{
e6d6e342
JB
13795 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
13796 addr, gfp);
1965c853
JM
13797}
13798
b23aa676 13799void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
5349a0f7
VK
13800 struct net_device *netdev,
13801 struct cfg80211_connect_resp_params *cr,
3093ebbe 13802 gfp_t gfp)
b23aa676
SO
13803{
13804 struct sk_buff *msg;
13805 void *hdr;
13806
a3caf744
VK
13807 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
13808 cr->fils_kek_len + cr->pmk_len +
13809 (cr->pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
13810 if (!msg)
13811 return;
13812
13813 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
13814 if (!hdr) {
13815 nlmsg_free(msg);
13816 return;
13817 }
13818
9360ffd1
DM
13819 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13820 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
5349a0f7
VK
13821 (cr->bssid &&
13822 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
bf1ecd21 13823 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
5349a0f7
VK
13824 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
13825 cr->status) ||
13826 (cr->status < 0 &&
3093ebbe 13827 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
5349a0f7
VK
13828 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
13829 cr->timeout_reason))) ||
13830 (cr->req_ie &&
13831 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
13832 (cr->resp_ie &&
13833 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
a3caf744
VK
13834 cr->resp_ie)) ||
13835 (cr->update_erp_next_seq_num &&
13836 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
13837 cr->fils_erp_next_seq_num)) ||
13838 (cr->status == WLAN_STATUS_SUCCESS &&
13839 ((cr->fils_kek &&
13840 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils_kek_len,
13841 cr->fils_kek)) ||
13842 (cr->pmk &&
13843 nla_put(msg, NL80211_ATTR_PMK, cr->pmk_len, cr->pmk)) ||
13844 (cr->pmkid &&
13845 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->pmkid)))))
9360ffd1 13846 goto nla_put_failure;
b23aa676 13847
3b7b72ee 13848 genlmsg_end(msg, hdr);
b23aa676 13849
68eb5503 13850 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13851 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
13852 return;
13853
13854 nla_put_failure:
13855 genlmsg_cancel(msg, hdr);
13856 nlmsg_free(msg);
b23aa676
SO
13857}
13858
13859void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
29ce6ecb
AS
13860 struct net_device *netdev,
13861 struct cfg80211_roam_info *info, gfp_t gfp)
b23aa676
SO
13862{
13863 struct sk_buff *msg;
13864 void *hdr;
29ce6ecb 13865 const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
b23aa676 13866
29ce6ecb 13867 msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len, gfp);
b23aa676
SO
13868 if (!msg)
13869 return;
13870
13871 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
13872 if (!hdr) {
13873 nlmsg_free(msg);
13874 return;
13875 }
13876
9360ffd1
DM
13877 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13878 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13879 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
29ce6ecb
AS
13880 (info->req_ie &&
13881 nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
13882 info->req_ie)) ||
13883 (info->resp_ie &&
13884 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
503c1fb9 13885 info->resp_ie)))
9360ffd1 13886 goto nla_put_failure;
b23aa676 13887
3b7b72ee 13888 genlmsg_end(msg, hdr);
b23aa676 13889
68eb5503 13890 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13891 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
13892 return;
13893
503c1fb9
AS
13894 nla_put_failure:
13895 genlmsg_cancel(msg, hdr);
13896 nlmsg_free(msg);
13897}
13898
13899void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
13900 struct net_device *netdev, const u8 *bssid)
13901{
13902 struct sk_buff *msg;
13903 void *hdr;
13904
13905 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13906 if (!msg)
13907 return;
13908
13909 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
13910 if (!hdr) {
13911 nlmsg_free(msg);
13912 return;
13913 }
13914
13915 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13916 goto nla_put_failure;
13917
13918 genlmsg_end(msg, hdr);
13919
13920 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
13921 NL80211_MCGRP_MLME, GFP_KERNEL);
13922 return;
13923
b23aa676
SO
13924 nla_put_failure:
13925 genlmsg_cancel(msg, hdr);
13926 nlmsg_free(msg);
b23aa676
SO
13927}
13928
13929void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
13930 struct net_device *netdev, u16 reason,
667503dd 13931 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
13932{
13933 struct sk_buff *msg;
13934 void *hdr;
13935
4ef8c1c9 13936 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
b23aa676
SO
13937 if (!msg)
13938 return;
13939
13940 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
13941 if (!hdr) {
13942 nlmsg_free(msg);
13943 return;
13944 }
13945
9360ffd1
DM
13946 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13947 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13948 (from_ap && reason &&
13949 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
13950 (from_ap &&
13951 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
13952 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
13953 goto nla_put_failure;
b23aa676 13954
3b7b72ee 13955 genlmsg_end(msg, hdr);
b23aa676 13956
68eb5503 13957 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13958 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
13959 return;
13960
13961 nla_put_failure:
13962 genlmsg_cancel(msg, hdr);
13963 nlmsg_free(msg);
b23aa676
SO
13964}
13965
04a773ad
JB
13966void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
13967 struct net_device *netdev, const u8 *bssid,
13968 gfp_t gfp)
13969{
13970 struct sk_buff *msg;
13971 void *hdr;
13972
fd2120ca 13973 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
13974 if (!msg)
13975 return;
13976
13977 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
13978 if (!hdr) {
13979 nlmsg_free(msg);
13980 return;
13981 }
13982
9360ffd1
DM
13983 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13984 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13985 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13986 goto nla_put_failure;
04a773ad 13987
3b7b72ee 13988 genlmsg_end(msg, hdr);
04a773ad 13989
68eb5503 13990 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13991 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
13992 return;
13993
13994 nla_put_failure:
13995 genlmsg_cancel(msg, hdr);
13996 nlmsg_free(msg);
13997}
13998
947add36
JB
13999void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
14000 const u8* ie, u8 ie_len, gfp_t gfp)
c93b5e71 14001{
947add36 14002 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14003 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
14004 struct sk_buff *msg;
14005 void *hdr;
14006
947add36
JB
14007 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
14008 return;
14009
14010 trace_cfg80211_notify_new_peer_candidate(dev, addr);
14011
4ef8c1c9 14012 msg = nlmsg_new(100 + ie_len, gfp);
c93b5e71
JC
14013 if (!msg)
14014 return;
14015
14016 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
14017 if (!hdr) {
14018 nlmsg_free(msg);
14019 return;
14020 }
14021
9360ffd1 14022 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
14023 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14024 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1
DM
14025 (ie_len && ie &&
14026 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
14027 goto nla_put_failure;
c93b5e71 14028
3b7b72ee 14029 genlmsg_end(msg, hdr);
c93b5e71 14030
68eb5503 14031 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14032 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
14033 return;
14034
14035 nla_put_failure:
14036 genlmsg_cancel(msg, hdr);
14037 nlmsg_free(msg);
14038}
947add36 14039EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 14040
a3b8b056
JM
14041void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
14042 struct net_device *netdev, const u8 *addr,
14043 enum nl80211_key_type key_type, int key_id,
e6d6e342 14044 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
14045{
14046 struct sk_buff *msg;
14047 void *hdr;
14048
e6d6e342 14049 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
14050 if (!msg)
14051 return;
14052
14053 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
14054 if (!hdr) {
14055 nlmsg_free(msg);
14056 return;
14057 }
14058
9360ffd1
DM
14059 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14060 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14061 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
14062 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
14063 (key_id != -1 &&
14064 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
14065 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
14066 goto nla_put_failure;
a3b8b056 14067
3b7b72ee 14068 genlmsg_end(msg, hdr);
a3b8b056 14069
68eb5503 14070 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14071 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
14072 return;
14073
14074 nla_put_failure:
14075 genlmsg_cancel(msg, hdr);
14076 nlmsg_free(msg);
14077}
14078
6bad8766
LR
14079void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
14080 struct ieee80211_channel *channel_before,
14081 struct ieee80211_channel *channel_after)
14082{
14083 struct sk_buff *msg;
14084 void *hdr;
14085 struct nlattr *nl_freq;
14086
fd2120ca 14087 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
14088 if (!msg)
14089 return;
14090
14091 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
14092 if (!hdr) {
14093 nlmsg_free(msg);
14094 return;
14095 }
14096
14097 /*
14098 * Since we are applying the beacon hint to a wiphy we know its
14099 * wiphy_idx is valid
14100 */
9360ffd1
DM
14101 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
14102 goto nla_put_failure;
6bad8766
LR
14103
14104 /* Before */
14105 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
14106 if (!nl_freq)
14107 goto nla_put_failure;
cdc89b97 14108 if (nl80211_msg_put_channel(msg, channel_before, false))
6bad8766
LR
14109 goto nla_put_failure;
14110 nla_nest_end(msg, nl_freq);
14111
14112 /* After */
14113 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
14114 if (!nl_freq)
14115 goto nla_put_failure;
cdc89b97 14116 if (nl80211_msg_put_channel(msg, channel_after, false))
6bad8766
LR
14117 goto nla_put_failure;
14118 nla_nest_end(msg, nl_freq);
14119
3b7b72ee 14120 genlmsg_end(msg, hdr);
6bad8766 14121
463d0183 14122 rcu_read_lock();
68eb5503 14123 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 14124 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 14125 rcu_read_unlock();
6bad8766
LR
14126
14127 return;
14128
14129nla_put_failure:
14130 genlmsg_cancel(msg, hdr);
14131 nlmsg_free(msg);
14132}
14133
9588bbd5
JM
14134static void nl80211_send_remain_on_chan_event(
14135 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 14136 struct wireless_dev *wdev, u64 cookie,
9588bbd5 14137 struct ieee80211_channel *chan,
9588bbd5
JM
14138 unsigned int duration, gfp_t gfp)
14139{
14140 struct sk_buff *msg;
14141 void *hdr;
14142
14143 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14144 if (!msg)
14145 return;
14146
14147 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
14148 if (!hdr) {
14149 nlmsg_free(msg);
14150 return;
14151 }
14152
9360ffd1 14153 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
14154 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14155 wdev->netdev->ifindex)) ||
2dad624e
ND
14156 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14157 NL80211_ATTR_PAD) ||
9360ffd1 14158 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
14159 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
14160 NL80211_CHAN_NO_HT) ||
2dad624e
ND
14161 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14162 NL80211_ATTR_PAD))
9360ffd1 14163 goto nla_put_failure;
9588bbd5 14164
9360ffd1
DM
14165 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
14166 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
14167 goto nla_put_failure;
9588bbd5 14168
3b7b72ee 14169 genlmsg_end(msg, hdr);
9588bbd5 14170
68eb5503 14171 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14172 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
14173 return;
14174
14175 nla_put_failure:
14176 genlmsg_cancel(msg, hdr);
14177 nlmsg_free(msg);
14178}
14179
947add36
JB
14180void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
14181 struct ieee80211_channel *chan,
14182 unsigned int duration, gfp_t gfp)
9588bbd5 14183{
947add36 14184 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14185 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14186
14187 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 14188 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 14189 rdev, wdev, cookie, chan,
42d97a59 14190 duration, gfp);
9588bbd5 14191}
947add36 14192EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 14193
947add36
JB
14194void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
14195 struct ieee80211_channel *chan,
14196 gfp_t gfp)
9588bbd5 14197{
947add36 14198 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14199 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14200
14201 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 14202 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 14203 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 14204}
947add36 14205EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 14206
947add36
JB
14207void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
14208 struct station_info *sinfo, gfp_t gfp)
98b62183 14209{
947add36 14210 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 14211 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
14212 struct sk_buff *msg;
14213
947add36
JB
14214 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
14215
58050fce 14216 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
14217 if (!msg)
14218 return;
14219
cf5ead82 14220 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 14221 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
14222 nlmsg_free(msg);
14223 return;
14224 }
14225
68eb5503 14226 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14227 NL80211_MCGRP_MLME, gfp);
98b62183 14228}
947add36 14229EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 14230
cf5ead82
JB
14231void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
14232 struct station_info *sinfo, gfp_t gfp)
ec15e68b 14233{
947add36 14234 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 14235 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 14236 struct sk_buff *msg;
cf5ead82
JB
14237 struct station_info empty_sinfo = {};
14238
14239 if (!sinfo)
14240 sinfo = &empty_sinfo;
ec15e68b 14241
947add36
JB
14242 trace_cfg80211_del_sta(dev, mac_addr);
14243
58050fce 14244 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
ec15e68b
JM
14245 if (!msg)
14246 return;
14247
cf5ead82 14248 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 14249 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b
JM
14250 nlmsg_free(msg);
14251 return;
14252 }
14253
68eb5503 14254 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14255 NL80211_MCGRP_MLME, gfp);
ec15e68b 14256}
cf5ead82 14257EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 14258
947add36
JB
14259void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
14260 enum nl80211_connect_failed_reason reason,
14261 gfp_t gfp)
ed44a951 14262{
947add36 14263 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 14264 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
14265 struct sk_buff *msg;
14266 void *hdr;
14267
14268 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
14269 if (!msg)
14270 return;
14271
14272 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
14273 if (!hdr) {
14274 nlmsg_free(msg);
14275 return;
14276 }
14277
14278 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14279 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
14280 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
14281 goto nla_put_failure;
14282
14283 genlmsg_end(msg, hdr);
14284
68eb5503 14285 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14286 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
14287 return;
14288
14289 nla_put_failure:
14290 genlmsg_cancel(msg, hdr);
14291 nlmsg_free(msg);
14292}
947add36 14293EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 14294
b92ab5d8
JB
14295static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
14296 const u8 *addr, gfp_t gfp)
28946da7
JB
14297{
14298 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14299 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
14300 struct sk_buff *msg;
14301 void *hdr;
6aa7de05 14302 u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
28946da7 14303
15e47304 14304 if (!nlportid)
28946da7
JB
14305 return false;
14306
14307 msg = nlmsg_new(100, gfp);
14308 if (!msg)
14309 return true;
14310
b92ab5d8 14311 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
14312 if (!hdr) {
14313 nlmsg_free(msg);
14314 return true;
14315 }
14316
9360ffd1
DM
14317 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14318 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14319 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
14320 goto nla_put_failure;
28946da7 14321
9c90a9f6 14322 genlmsg_end(msg, hdr);
15e47304 14323 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
14324 return true;
14325
14326 nla_put_failure:
14327 genlmsg_cancel(msg, hdr);
14328 nlmsg_free(msg);
14329 return true;
14330}
14331
947add36
JB
14332bool cfg80211_rx_spurious_frame(struct net_device *dev,
14333 const u8 *addr, gfp_t gfp)
b92ab5d8 14334{
947add36
JB
14335 struct wireless_dev *wdev = dev->ieee80211_ptr;
14336 bool ret;
14337
14338 trace_cfg80211_rx_spurious_frame(dev, addr);
14339
14340 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
14341 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
14342 trace_cfg80211_return_bool(false);
14343 return false;
14344 }
14345 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
14346 addr, gfp);
14347 trace_cfg80211_return_bool(ret);
14348 return ret;
b92ab5d8 14349}
947add36 14350EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 14351
947add36
JB
14352bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
14353 const u8 *addr, gfp_t gfp)
b92ab5d8 14354{
947add36
JB
14355 struct wireless_dev *wdev = dev->ieee80211_ptr;
14356 bool ret;
14357
14358 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
14359
14360 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
14361 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
14362 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
14363 trace_cfg80211_return_bool(false);
14364 return false;
14365 }
14366 ret = __nl80211_unexpected_frame(dev,
14367 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
14368 addr, gfp);
14369 trace_cfg80211_return_bool(ret);
14370 return ret;
b92ab5d8 14371}
947add36 14372EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 14373
2e161f78 14374int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 14375 struct wireless_dev *wdev, u32 nlportid,
804483e9 14376 int freq, int sig_dbm,
19504cf5 14377 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 14378{
71bbc994 14379 struct net_device *netdev = wdev->netdev;
026331c4
JM
14380 struct sk_buff *msg;
14381 void *hdr;
026331c4 14382
4ef8c1c9 14383 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
14384 if (!msg)
14385 return -ENOMEM;
14386
2e161f78 14387 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
14388 if (!hdr) {
14389 nlmsg_free(msg);
14390 return -ENOMEM;
14391 }
14392
9360ffd1 14393 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
14394 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14395 netdev->ifindex)) ||
2dad624e
ND
14396 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14397 NL80211_ATTR_PAD) ||
9360ffd1
DM
14398 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
14399 (sig_dbm &&
14400 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
14401 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
14402 (flags &&
14403 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 14404 goto nla_put_failure;
026331c4 14405
3b7b72ee 14406 genlmsg_end(msg, hdr);
026331c4 14407
15e47304 14408 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
14409
14410 nla_put_failure:
14411 genlmsg_cancel(msg, hdr);
14412 nlmsg_free(msg);
14413 return -ENOBUFS;
14414}
14415
947add36
JB
14416void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
14417 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 14418{
947add36 14419 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14420 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 14421 struct net_device *netdev = wdev->netdev;
026331c4
JM
14422 struct sk_buff *msg;
14423 void *hdr;
14424
947add36
JB
14425 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
14426
4ef8c1c9 14427 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
14428 if (!msg)
14429 return;
14430
2e161f78 14431 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
14432 if (!hdr) {
14433 nlmsg_free(msg);
14434 return;
14435 }
14436
9360ffd1 14437 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
14438 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14439 netdev->ifindex)) ||
2dad624e
ND
14440 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14441 NL80211_ATTR_PAD) ||
9360ffd1 14442 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
14443 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14444 NL80211_ATTR_PAD) ||
9360ffd1
DM
14445 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
14446 goto nla_put_failure;
026331c4 14447
3b7b72ee 14448 genlmsg_end(msg, hdr);
026331c4 14449
68eb5503 14450 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14451 NL80211_MCGRP_MLME, gfp);
026331c4
JM
14452 return;
14453
14454 nla_put_failure:
14455 genlmsg_cancel(msg, hdr);
14456 nlmsg_free(msg);
14457}
947add36 14458EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 14459
5b97f49d
JB
14460static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
14461 const char *mac, gfp_t gfp)
d6dc1a38 14462{
947add36 14463 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
14464 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
14465 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14466 void **cb;
947add36 14467
d6dc1a38 14468 if (!msg)
5b97f49d 14469 return NULL;
d6dc1a38 14470
5b97f49d
JB
14471 cb = (void **)msg->cb;
14472
14473 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
14474 if (!cb[0]) {
d6dc1a38 14475 nlmsg_free(msg);
5b97f49d 14476 return NULL;
d6dc1a38
JO
14477 }
14478
9360ffd1 14479 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 14480 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 14481 goto nla_put_failure;
d6dc1a38 14482
5b97f49d 14483 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
14484 goto nla_put_failure;
14485
5b97f49d
JB
14486 cb[1] = nla_nest_start(msg, NL80211_ATTR_CQM);
14487 if (!cb[1])
9360ffd1 14488 goto nla_put_failure;
d6dc1a38 14489
5b97f49d 14490 cb[2] = rdev;
d6dc1a38 14491
5b97f49d
JB
14492 return msg;
14493 nla_put_failure:
14494 nlmsg_free(msg);
14495 return NULL;
14496}
14497
14498static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
14499{
14500 void **cb = (void **)msg->cb;
14501 struct cfg80211_registered_device *rdev = cb[2];
14502
14503 nla_nest_end(msg, cb[1]);
14504 genlmsg_end(msg, cb[0]);
14505
14506 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 14507
68eb5503 14508 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14509 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
14510}
14511
14512void cfg80211_cqm_rssi_notify(struct net_device *dev,
14513 enum nl80211_cqm_rssi_threshold_event rssi_event,
bee427b8 14514 s32 rssi_level, gfp_t gfp)
5b97f49d
JB
14515{
14516 struct sk_buff *msg;
4a4b8169
AZ
14517 struct wireless_dev *wdev = dev->ieee80211_ptr;
14518 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
5b97f49d 14519
bee427b8 14520 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
5b97f49d 14521
98f03342
JB
14522 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
14523 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
14524 return;
14525
4a4b8169
AZ
14526 if (wdev->cqm_config) {
14527 wdev->cqm_config->last_rssi_event_value = rssi_level;
14528
14529 cfg80211_cqm_rssi_update(rdev, dev);
14530
14531 if (rssi_level == 0)
14532 rssi_level = wdev->cqm_config->last_rssi_event_value;
14533 }
14534
5b97f49d
JB
14535 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
14536 if (!msg)
14537 return;
14538
14539 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
14540 rssi_event))
14541 goto nla_put_failure;
14542
bee427b8
AZ
14543 if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
14544 rssi_level))
14545 goto nla_put_failure;
14546
5b97f49d
JB
14547 cfg80211_send_cqm(msg, gfp);
14548
d6dc1a38
JO
14549 return;
14550
14551 nla_put_failure:
d6dc1a38
JO
14552 nlmsg_free(msg);
14553}
947add36 14554EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 14555
5b97f49d
JB
14556void cfg80211_cqm_txe_notify(struct net_device *dev,
14557 const u8 *peer, u32 num_packets,
14558 u32 rate, u32 intvl, gfp_t gfp)
14559{
14560 struct sk_buff *msg;
14561
14562 msg = cfg80211_prepare_cqm(dev, peer, gfp);
14563 if (!msg)
14564 return;
14565
14566 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
14567 goto nla_put_failure;
14568
14569 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
14570 goto nla_put_failure;
14571
14572 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
14573 goto nla_put_failure;
14574
14575 cfg80211_send_cqm(msg, gfp);
14576 return;
14577
14578 nla_put_failure:
14579 nlmsg_free(msg);
14580}
14581EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
14582
14583void cfg80211_cqm_pktloss_notify(struct net_device *dev,
14584 const u8 *peer, u32 num_packets, gfp_t gfp)
14585{
14586 struct sk_buff *msg;
14587
14588 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
14589
14590 msg = cfg80211_prepare_cqm(dev, peer, gfp);
14591 if (!msg)
14592 return;
14593
14594 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
14595 goto nla_put_failure;
14596
14597 cfg80211_send_cqm(msg, gfp);
14598 return;
14599
14600 nla_put_failure:
14601 nlmsg_free(msg);
14602}
14603EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
14604
98f03342
JB
14605void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
14606{
14607 struct sk_buff *msg;
14608
14609 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
14610 if (!msg)
14611 return;
14612
14613 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
14614 goto nla_put_failure;
14615
14616 cfg80211_send_cqm(msg, gfp);
14617 return;
14618
14619 nla_put_failure:
14620 nlmsg_free(msg);
14621}
14622EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
14623
947add36
JB
14624static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
14625 struct net_device *netdev, const u8 *bssid,
14626 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
14627{
14628 struct sk_buff *msg;
14629 struct nlattr *rekey_attr;
14630 void *hdr;
14631
58050fce 14632 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
14633 if (!msg)
14634 return;
14635
14636 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
14637 if (!hdr) {
14638 nlmsg_free(msg);
14639 return;
14640 }
14641
9360ffd1
DM
14642 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14643 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14644 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
14645 goto nla_put_failure;
e5497d76
JB
14646
14647 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
14648 if (!rekey_attr)
14649 goto nla_put_failure;
14650
9360ffd1
DM
14651 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
14652 NL80211_REPLAY_CTR_LEN, replay_ctr))
14653 goto nla_put_failure;
e5497d76
JB
14654
14655 nla_nest_end(msg, rekey_attr);
14656
3b7b72ee 14657 genlmsg_end(msg, hdr);
e5497d76 14658
68eb5503 14659 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14660 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
14661 return;
14662
14663 nla_put_failure:
14664 genlmsg_cancel(msg, hdr);
14665 nlmsg_free(msg);
14666}
14667
947add36
JB
14668void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
14669 const u8 *replay_ctr, gfp_t gfp)
14670{
14671 struct wireless_dev *wdev = dev->ieee80211_ptr;
14672 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14673 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14674
14675 trace_cfg80211_gtk_rekey_notify(dev, bssid);
14676 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
14677}
14678EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
14679
14680static void
14681nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
14682 struct net_device *netdev, int index,
14683 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
14684{
14685 struct sk_buff *msg;
14686 struct nlattr *attr;
14687 void *hdr;
14688
58050fce 14689 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
14690 if (!msg)
14691 return;
14692
14693 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
14694 if (!hdr) {
14695 nlmsg_free(msg);
14696 return;
14697 }
14698
9360ffd1
DM
14699 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14700 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
14701 goto nla_put_failure;
c9df56b4
JM
14702
14703 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
14704 if (!attr)
14705 goto nla_put_failure;
14706
9360ffd1
DM
14707 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
14708 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
14709 (preauth &&
14710 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
14711 goto nla_put_failure;
c9df56b4
JM
14712
14713 nla_nest_end(msg, attr);
14714
3b7b72ee 14715 genlmsg_end(msg, hdr);
c9df56b4 14716
68eb5503 14717 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14718 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
14719 return;
14720
14721 nla_put_failure:
14722 genlmsg_cancel(msg, hdr);
14723 nlmsg_free(msg);
14724}
14725
947add36
JB
14726void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
14727 const u8 *bssid, bool preauth, gfp_t gfp)
14728{
14729 struct wireless_dev *wdev = dev->ieee80211_ptr;
14730 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14731 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14732
14733 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
14734 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
14735}
14736EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
14737
14738static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
14739 struct net_device *netdev,
14740 struct cfg80211_chan_def *chandef,
f8d7552e
LC
14741 gfp_t gfp,
14742 enum nl80211_commands notif,
14743 u8 count)
5314526b
TP
14744{
14745 struct sk_buff *msg;
14746 void *hdr;
14747
58050fce 14748 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
14749 if (!msg)
14750 return;
14751
f8d7552e 14752 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
14753 if (!hdr) {
14754 nlmsg_free(msg);
14755 return;
14756 }
14757
683b6d3b
JB
14758 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
14759 goto nla_put_failure;
14760
14761 if (nl80211_send_chandef(msg, chandef))
7eab0f64 14762 goto nla_put_failure;
5314526b 14763
f8d7552e
LC
14764 if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
14765 (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
14766 goto nla_put_failure;
14767
5314526b
TP
14768 genlmsg_end(msg, hdr);
14769
68eb5503 14770 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14771 NL80211_MCGRP_MLME, gfp);
5314526b
TP
14772 return;
14773
14774 nla_put_failure:
14775 genlmsg_cancel(msg, hdr);
14776 nlmsg_free(msg);
14777}
14778
947add36
JB
14779void cfg80211_ch_switch_notify(struct net_device *dev,
14780 struct cfg80211_chan_def *chandef)
84f10708 14781{
947add36
JB
14782 struct wireless_dev *wdev = dev->ieee80211_ptr;
14783 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14784 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 14785
e487eaeb 14786 ASSERT_WDEV_LOCK(wdev);
947add36 14787
e487eaeb 14788 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 14789
9e0e2961 14790 wdev->chandef = *chandef;
96f55f12 14791 wdev->preset_chandef = *chandef;
f8d7552e
LC
14792 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
14793 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
947add36
JB
14794}
14795EXPORT_SYMBOL(cfg80211_ch_switch_notify);
14796
f8d7552e
LC
14797void cfg80211_ch_switch_started_notify(struct net_device *dev,
14798 struct cfg80211_chan_def *chandef,
14799 u8 count)
14800{
14801 struct wireless_dev *wdev = dev->ieee80211_ptr;
14802 struct wiphy *wiphy = wdev->wiphy;
14803 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14804
14805 trace_cfg80211_ch_switch_started_notify(dev, chandef);
14806
14807 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
14808 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
14809}
14810EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
14811
04f39047
SW
14812void
14813nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 14814 const struct cfg80211_chan_def *chandef,
04f39047
SW
14815 enum nl80211_radar_event event,
14816 struct net_device *netdev, gfp_t gfp)
14817{
14818 struct sk_buff *msg;
14819 void *hdr;
14820
14821 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14822 if (!msg)
14823 return;
14824
14825 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
14826 if (!hdr) {
14827 nlmsg_free(msg);
14828 return;
14829 }
14830
14831 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
14832 goto nla_put_failure;
14833
14834 /* NOP and radar events don't need a netdev parameter */
14835 if (netdev) {
14836 struct wireless_dev *wdev = netdev->ieee80211_ptr;
14837
14838 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
14839 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14840 NL80211_ATTR_PAD))
04f39047
SW
14841 goto nla_put_failure;
14842 }
14843
14844 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
14845 goto nla_put_failure;
14846
14847 if (nl80211_send_chandef(msg, chandef))
14848 goto nla_put_failure;
14849
9c90a9f6 14850 genlmsg_end(msg, hdr);
04f39047 14851
68eb5503 14852 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14853 NL80211_MCGRP_MLME, gfp);
04f39047
SW
14854 return;
14855
14856 nla_put_failure:
14857 genlmsg_cancel(msg, hdr);
14858 nlmsg_free(msg);
14859}
14860
7f6cf311
JB
14861void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
14862 u64 cookie, bool acked, gfp_t gfp)
14863{
14864 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14865 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
14866 struct sk_buff *msg;
14867 void *hdr;
7f6cf311 14868
4ee3e063
BL
14869 trace_cfg80211_probe_status(dev, addr, cookie, acked);
14870
58050fce 14871 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 14872
7f6cf311
JB
14873 if (!msg)
14874 return;
14875
14876 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
14877 if (!hdr) {
14878 nlmsg_free(msg);
14879 return;
14880 }
14881
9360ffd1
DM
14882 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14883 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14884 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
14885 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14886 NL80211_ATTR_PAD) ||
9360ffd1
DM
14887 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
14888 goto nla_put_failure;
7f6cf311 14889
9c90a9f6 14890 genlmsg_end(msg, hdr);
7f6cf311 14891
68eb5503 14892 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14893 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
14894 return;
14895
14896 nla_put_failure:
14897 genlmsg_cancel(msg, hdr);
14898 nlmsg_free(msg);
14899}
14900EXPORT_SYMBOL(cfg80211_probe_status);
14901
5e760230
JB
14902void cfg80211_report_obss_beacon(struct wiphy *wiphy,
14903 const u8 *frame, size_t len,
37c73b5f 14904 int freq, int sig_dbm)
5e760230 14905{
f26cbf40 14906 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
14907 struct sk_buff *msg;
14908 void *hdr;
37c73b5f 14909 struct cfg80211_beacon_registration *reg;
5e760230 14910
4ee3e063
BL
14911 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
14912
37c73b5f
BG
14913 spin_lock_bh(&rdev->beacon_registrations_lock);
14914 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
14915 msg = nlmsg_new(len + 100, GFP_ATOMIC);
14916 if (!msg) {
14917 spin_unlock_bh(&rdev->beacon_registrations_lock);
14918 return;
14919 }
5e760230 14920
37c73b5f
BG
14921 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
14922 if (!hdr)
14923 goto nla_put_failure;
5e760230 14924
37c73b5f
BG
14925 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14926 (freq &&
14927 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
14928 (sig_dbm &&
14929 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
14930 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
14931 goto nla_put_failure;
5e760230 14932
37c73b5f 14933 genlmsg_end(msg, hdr);
5e760230 14934
37c73b5f
BG
14935 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
14936 }
14937 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
14938 return;
14939
14940 nla_put_failure:
37c73b5f
BG
14941 spin_unlock_bh(&rdev->beacon_registrations_lock);
14942 if (hdr)
14943 genlmsg_cancel(msg, hdr);
5e760230
JB
14944 nlmsg_free(msg);
14945}
14946EXPORT_SYMBOL(cfg80211_report_obss_beacon);
14947
cd8f7cb4 14948#ifdef CONFIG_PM
8cd4d456
LC
14949static int cfg80211_net_detect_results(struct sk_buff *msg,
14950 struct cfg80211_wowlan_wakeup *wakeup)
14951{
14952 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
14953 struct nlattr *nl_results, *nl_match, *nl_freqs;
14954 int i, j;
14955
14956 nl_results = nla_nest_start(
14957 msg, NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
14958 if (!nl_results)
14959 return -EMSGSIZE;
14960
14961 for (i = 0; i < nd->n_matches; i++) {
14962 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
14963
14964 nl_match = nla_nest_start(msg, i);
14965 if (!nl_match)
14966 break;
14967
14968 /* The SSID attribute is optional in nl80211, but for
14969 * simplicity reasons it's always present in the
14970 * cfg80211 structure. If a driver can't pass the
14971 * SSID, that needs to be changed. A zero length SSID
14972 * is still a valid SSID (wildcard), so it cannot be
14973 * used for this purpose.
14974 */
14975 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
14976 match->ssid.ssid)) {
14977 nla_nest_cancel(msg, nl_match);
14978 goto out;
14979 }
14980
14981 if (match->n_channels) {
14982 nl_freqs = nla_nest_start(
14983 msg, NL80211_ATTR_SCAN_FREQUENCIES);
14984 if (!nl_freqs) {
14985 nla_nest_cancel(msg, nl_match);
14986 goto out;
14987 }
14988
14989 for (j = 0; j < match->n_channels; j++) {
5528fae8 14990 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
14991 nla_nest_cancel(msg, nl_freqs);
14992 nla_nest_cancel(msg, nl_match);
14993 goto out;
14994 }
14995 }
14996
14997 nla_nest_end(msg, nl_freqs);
14998 }
14999
15000 nla_nest_end(msg, nl_match);
15001 }
15002
15003out:
15004 nla_nest_end(msg, nl_results);
15005 return 0;
15006}
15007
cd8f7cb4
JB
15008void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
15009 struct cfg80211_wowlan_wakeup *wakeup,
15010 gfp_t gfp)
15011{
f26cbf40 15012 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
15013 struct sk_buff *msg;
15014 void *hdr;
9c90a9f6 15015 int size = 200;
cd8f7cb4
JB
15016
15017 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
15018
15019 if (wakeup)
15020 size += wakeup->packet_present_len;
15021
15022 msg = nlmsg_new(size, gfp);
15023 if (!msg)
15024 return;
15025
15026 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
15027 if (!hdr)
15028 goto free_msg;
15029
15030 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
15031 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15032 NL80211_ATTR_PAD))
cd8f7cb4
JB
15033 goto free_msg;
15034
15035 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15036 wdev->netdev->ifindex))
15037 goto free_msg;
15038
15039 if (wakeup) {
15040 struct nlattr *reasons;
15041
15042 reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
15043 if (!reasons)
15044 goto free_msg;
cd8f7cb4
JB
15045
15046 if (wakeup->disconnect &&
15047 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
15048 goto free_msg;
15049 if (wakeup->magic_pkt &&
15050 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
15051 goto free_msg;
15052 if (wakeup->gtk_rekey_failure &&
15053 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
15054 goto free_msg;
15055 if (wakeup->eap_identity_req &&
15056 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
15057 goto free_msg;
15058 if (wakeup->four_way_handshake &&
15059 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
15060 goto free_msg;
15061 if (wakeup->rfkill_release &&
15062 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
15063 goto free_msg;
15064
15065 if (wakeup->pattern_idx >= 0 &&
15066 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
15067 wakeup->pattern_idx))
15068 goto free_msg;
15069
ae917c9f
JB
15070 if (wakeup->tcp_match &&
15071 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
15072 goto free_msg;
2a0e047e 15073
ae917c9f
JB
15074 if (wakeup->tcp_connlost &&
15075 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
15076 goto free_msg;
2a0e047e 15077
ae917c9f
JB
15078 if (wakeup->tcp_nomoretokens &&
15079 nla_put_flag(msg,
15080 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
15081 goto free_msg;
2a0e047e 15082
cd8f7cb4
JB
15083 if (wakeup->packet) {
15084 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
15085 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
15086
15087 if (!wakeup->packet_80211) {
15088 pkt_attr =
15089 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
15090 len_attr =
15091 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
15092 }
15093
15094 if (wakeup->packet_len &&
15095 nla_put_u32(msg, len_attr, wakeup->packet_len))
15096 goto free_msg;
15097
15098 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
15099 wakeup->packet))
15100 goto free_msg;
15101 }
15102
8cd4d456
LC
15103 if (wakeup->net_detect &&
15104 cfg80211_net_detect_results(msg, wakeup))
15105 goto free_msg;
15106
cd8f7cb4
JB
15107 nla_nest_end(msg, reasons);
15108 }
15109
9c90a9f6 15110 genlmsg_end(msg, hdr);
cd8f7cb4 15111
68eb5503 15112 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15113 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
15114 return;
15115
15116 free_msg:
15117 nlmsg_free(msg);
15118}
15119EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
15120#endif
15121
3475b094
JM
15122void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
15123 enum nl80211_tdls_operation oper,
15124 u16 reason_code, gfp_t gfp)
15125{
15126 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 15127 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
15128 struct sk_buff *msg;
15129 void *hdr;
3475b094
JM
15130
15131 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
15132 reason_code);
15133
15134 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15135 if (!msg)
15136 return;
15137
15138 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
15139 if (!hdr) {
15140 nlmsg_free(msg);
15141 return;
15142 }
15143
15144 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15145 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15146 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
15147 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
15148 (reason_code > 0 &&
15149 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
15150 goto nla_put_failure;
15151
9c90a9f6 15152 genlmsg_end(msg, hdr);
3475b094 15153
68eb5503 15154 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15155 NL80211_MCGRP_MLME, gfp);
3475b094
JM
15156 return;
15157
15158 nla_put_failure:
15159 genlmsg_cancel(msg, hdr);
15160 nlmsg_free(msg);
15161}
15162EXPORT_SYMBOL(cfg80211_tdls_oper_request);
15163
026331c4
JM
15164static int nl80211_netlink_notify(struct notifier_block * nb,
15165 unsigned long state,
15166 void *_notify)
15167{
15168 struct netlink_notify *notify = _notify;
15169 struct cfg80211_registered_device *rdev;
15170 struct wireless_dev *wdev;
37c73b5f 15171 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 15172
8f815cdd 15173 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
15174 return NOTIFY_DONE;
15175
15176 rcu_read_lock();
15177
5e760230 15178 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
ca986ad9 15179 struct cfg80211_sched_scan_request *sched_scan_req;
753aacfd 15180
ca986ad9
AVS
15181 list_for_each_entry_rcu(sched_scan_req,
15182 &rdev->sched_scan_req_list,
15183 list) {
15184 if (sched_scan_req->owner_nlportid == notify->portid) {
15185 sched_scan_req->nl_owner_dead = true;
753aacfd 15186 schedule_work(&rdev->sched_scan_stop_wk);
ca986ad9 15187 }
753aacfd 15188 }
78f22b6a 15189
53873f13 15190 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 15191 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 15192
ab81007a
JB
15193 if (wdev->owner_nlportid == notify->portid) {
15194 wdev->nl_owner_dead = true;
15195 schedule_work(&rdev->destroy_work);
15196 } else if (wdev->conn_owner_nlportid == notify->portid) {
bd2522b1 15197 schedule_work(&wdev->disconnect_wk);
ab81007a 15198 }
78f22b6a
JB
15199 }
15200
37c73b5f
BG
15201 spin_lock_bh(&rdev->beacon_registrations_lock);
15202 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
15203 list) {
15204 if (reg->nlportid == notify->portid) {
15205 list_del(&reg->list);
15206 kfree(reg);
15207 break;
15208 }
15209 }
15210 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230 15211 }
026331c4
JM
15212
15213 rcu_read_unlock();
15214
05050753
I
15215 /*
15216 * It is possible that the user space process that is controlling the
15217 * indoor setting disappeared, so notify the regulatory core.
15218 */
15219 regulatory_netlink_notify(notify->portid);
6784c7db 15220 return NOTIFY_OK;
026331c4
JM
15221}
15222
15223static struct notifier_block nl80211_netlink_notifier = {
15224 .notifier_call = nl80211_netlink_notify,
15225};
15226
355199e0
JM
15227void cfg80211_ft_event(struct net_device *netdev,
15228 struct cfg80211_ft_event_params *ft_event)
15229{
15230 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 15231 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
15232 struct sk_buff *msg;
15233 void *hdr;
355199e0
JM
15234
15235 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
15236
15237 if (!ft_event->target_ap)
15238 return;
15239
4ef8c1c9 15240 msg = nlmsg_new(100 + ft_event->ric_ies_len, GFP_KERNEL);
355199e0
JM
15241 if (!msg)
15242 return;
15243
15244 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
15245 if (!hdr)
15246 goto out;
355199e0 15247
ae917c9f
JB
15248 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15249 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15250 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
15251 goto out;
355199e0 15252
ae917c9f
JB
15253 if (ft_event->ies &&
15254 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
15255 goto out;
15256 if (ft_event->ric_ies &&
15257 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
15258 ft_event->ric_ies))
15259 goto out;
355199e0 15260
9c90a9f6 15261 genlmsg_end(msg, hdr);
355199e0 15262
68eb5503 15263 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15264 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
15265 return;
15266 out:
15267 nlmsg_free(msg);
355199e0
JM
15268}
15269EXPORT_SYMBOL(cfg80211_ft_event);
15270
5de17984
AS
15271void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
15272{
15273 struct cfg80211_registered_device *rdev;
15274 struct sk_buff *msg;
15275 void *hdr;
15276 u32 nlportid;
15277
f26cbf40 15278 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
15279 if (!rdev->crit_proto_nlportid)
15280 return;
15281
15282 nlportid = rdev->crit_proto_nlportid;
15283 rdev->crit_proto_nlportid = 0;
15284
15285 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15286 if (!msg)
15287 return;
15288
15289 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
15290 if (!hdr)
15291 goto nla_put_failure;
15292
15293 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
15294 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15295 NL80211_ATTR_PAD))
5de17984
AS
15296 goto nla_put_failure;
15297
15298 genlmsg_end(msg, hdr);
15299
15300 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
15301 return;
15302
15303 nla_put_failure:
15304 if (hdr)
15305 genlmsg_cancel(msg, hdr);
15306 nlmsg_free(msg);
5de17984
AS
15307}
15308EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
15309
348baf0e
JB
15310void nl80211_send_ap_stopped(struct wireless_dev *wdev)
15311{
15312 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15313 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
15314 struct sk_buff *msg;
15315 void *hdr;
15316
15317 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
15318 if (!msg)
15319 return;
15320
15321 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
15322 if (!hdr)
15323 goto out;
15324
15325 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15326 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
15327 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15328 NL80211_ATTR_PAD))
348baf0e
JB
15329 goto out;
15330
15331 genlmsg_end(msg, hdr);
15332
15333 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
15334 NL80211_MCGRP_MLME, GFP_KERNEL);
15335 return;
15336 out:
15337 nlmsg_free(msg);
15338}
15339
55682965
JB
15340/* initialisation/exit functions */
15341
56989f6d 15342int __init nl80211_init(void)
55682965 15343{
0d63cbb5 15344 int err;
55682965 15345
489111e5 15346 err = genl_register_family(&nl80211_fam);
55682965
JB
15347 if (err)
15348 return err;
15349
026331c4
JM
15350 err = netlink_register_notifier(&nl80211_netlink_notifier);
15351 if (err)
15352 goto err_out;
15353
55682965
JB
15354 return 0;
15355 err_out:
15356 genl_unregister_family(&nl80211_fam);
15357 return err;
15358}
15359
15360void nl80211_exit(void)
15361{
026331c4 15362 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
15363 genl_unregister_family(&nl80211_fam);
15364}