]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - net/wireless/nl80211.c
mac80211: check for allocation failure in debugfs code
[mirror_ubuntu-focal-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
0c9ca11b 6 * Copyright 2015-2016 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 },
67fbb16b
SO
294 [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
295 .len = WLAN_PMKID_LEN },
9588bbd5
JM
296 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
297 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 298 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
299 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
300 .len = IEEE80211_MAX_DATA_LEN },
301 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ffb9eb3d 302 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
d6dc1a38 303 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 304 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 305 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
306 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
307 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 308 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
309 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
310 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 311 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 312 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 313 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 314 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
9c3990aa 315 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
bbe6ad6d 316 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 317 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 318 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
32e9de84 319 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
9946ecfb
JM
320 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
321 .len = IEEE80211_MAX_DATA_LEN },
322 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
323 .len = IEEE80211_MAX_DATA_LEN },
f4b34b55 324 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 325 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 326 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
327 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
328 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
329 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
330 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
331 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 332 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 333 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
334 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
335 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 336 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
337 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
338 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
339 .len = NL80211_HT_CAPABILITY_LEN
340 },
1d9d9213 341 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 342 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 343 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 344 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 345 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
11b6b5a4 346 [NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, },
f461be3e 347 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
ed473771 348 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
53cabad7
JB
349 [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
350 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
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
AB
400 [NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 },
401 [NL80211_ATTR_NAN_DUAL] = { .type = NLA_U8 },
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 },
55682965
JB
413};
414
e31b8213 415/* policy for the key attributes */
b54452b0 416static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 417 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
418 [NL80211_KEY_IDX] = { .type = NLA_U8 },
419 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 420 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
421 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
422 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
e31b8213 423 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
dbd2fd65
JB
424 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
425};
426
427/* policy for the key default flags */
428static const struct nla_policy
429nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
430 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
431 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
432};
433
f83ace3b 434#ifdef CONFIG_PM
ff1b6e69
JB
435/* policy for WoWLAN attributes */
436static const struct nla_policy
437nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
438 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
439 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
440 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
441 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
442 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
443 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
444 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
445 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 446 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 447 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
448};
449
450static const struct nla_policy
451nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
452 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
453 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
454 [NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
455 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
456 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
457 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
458 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
459 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
460 },
461 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
462 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
463 },
464 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
465 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
466 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
ff1b6e69 467};
f83ace3b 468#endif /* CONFIG_PM */
ff1b6e69 469
be29b99a
AK
470/* policy for coalesce rule attributes */
471static const struct nla_policy
472nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
473 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
474 [NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U32 },
475 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
476};
477
e5497d76
JB
478/* policy for GTK rekey offload attributes */
479static const struct nla_policy
480nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
481 [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
482 [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
483 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
484};
485
a1f1c21c
LC
486static const struct nla_policy
487nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 488 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 489 .len = IEEE80211_MAX_SSID_LEN },
88e920b4 490 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
a1f1c21c
LC
491};
492
3b06d277
AS
493static const struct nla_policy
494nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
495 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
496 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
497};
498
38de03d2
AS
499static const struct nla_policy
500nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
501 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
502 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
503 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
504 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
505 },
506};
507
a442b761
AB
508/* policy for NAN function attributes */
509static const struct nla_policy
510nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
511 [NL80211_NAN_FUNC_TYPE] = { .type = NLA_U8 },
512 [NL80211_NAN_FUNC_SERVICE_ID] = { .type = NLA_BINARY,
513 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
514 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
515 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
516 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
517 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
518 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
519 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = { .len = ETH_ALEN },
520 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
521 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
522 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
523 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
524 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
525 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
526 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
527 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
528 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
529};
530
531/* policy for Service Response Filter attributes */
532static const struct nla_policy
533nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
534 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
535 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
536 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
537 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
538 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
539};
540
97990a06
JB
541static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
542 struct netlink_callback *cb,
543 struct cfg80211_registered_device **rdev,
544 struct wireless_dev **wdev)
a043897a 545{
97990a06 546 int err;
a043897a 547
97990a06 548 rtnl_lock();
a043897a 549
97990a06
JB
550 if (!cb->args[0]) {
551 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
c90c39da
JB
552 genl_family_attrbuf(&nl80211_fam),
553 nl80211_fam.maxattr, nl80211_policy);
97990a06
JB
554 if (err)
555 goto out_unlock;
67748893 556
c90c39da
JB
557 *wdev = __cfg80211_wdev_from_attrs(
558 sock_net(skb->sk),
559 genl_family_attrbuf(&nl80211_fam));
97990a06
JB
560 if (IS_ERR(*wdev)) {
561 err = PTR_ERR(*wdev);
562 goto out_unlock;
563 }
f26cbf40 564 *rdev = wiphy_to_rdev((*wdev)->wiphy);
c319d50b
JB
565 /* 0 is the first index - add 1 to parse only once */
566 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
567 cb->args[1] = (*wdev)->identifier;
568 } else {
c319d50b
JB
569 /* subtract the 1 again here */
570 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
97990a06 571 struct wireless_dev *tmp;
67748893 572
97990a06
JB
573 if (!wiphy) {
574 err = -ENODEV;
575 goto out_unlock;
576 }
f26cbf40 577 *rdev = wiphy_to_rdev(wiphy);
97990a06 578 *wdev = NULL;
67748893 579
53873f13 580 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
581 if (tmp->identifier == cb->args[1]) {
582 *wdev = tmp;
583 break;
584 }
585 }
67748893 586
97990a06
JB
587 if (!*wdev) {
588 err = -ENODEV;
589 goto out_unlock;
590 }
67748893
JB
591 }
592
67748893 593 return 0;
97990a06 594 out_unlock:
67748893
JB
595 rtnl_unlock();
596 return err;
597}
598
97990a06 599static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
67748893 600{
67748893
JB
601 rtnl_unlock();
602}
603
f4a11bb0
JB
604/* IE validation */
605static bool is_valid_ie_attr(const struct nlattr *attr)
606{
607 const u8 *pos;
608 int len;
609
610 if (!attr)
611 return true;
612
613 pos = nla_data(attr);
614 len = nla_len(attr);
615
616 while (len) {
617 u8 elemlen;
618
619 if (len < 2)
620 return false;
621 len -= 2;
622
623 elemlen = pos[1];
624 if (elemlen > len)
625 return false;
626
627 len -= elemlen;
628 pos += 2 + elemlen;
629 }
630
631 return true;
632}
633
55682965 634/* message building helper */
15e47304 635static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
55682965
JB
636 int flags, u8 cmd)
637{
638 /* since there is no private header just add the generic one */
15e47304 639 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
640}
641
5dab3b8a 642static int nl80211_msg_put_channel(struct sk_buff *msg,
cdc89b97
JB
643 struct ieee80211_channel *chan,
644 bool large)
5dab3b8a 645{
ea077c1c
RL
646 /* Some channels must be completely excluded from the
647 * list to protect old user-space tools from breaking
648 */
649 if (!large && chan->flags &
650 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
651 return 0;
652
9360ffd1
DM
653 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
654 chan->center_freq))
655 goto nla_put_failure;
5dab3b8a 656
9360ffd1
DM
657 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
658 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
659 goto nla_put_failure;
8fe02e16
LR
660 if (chan->flags & IEEE80211_CHAN_NO_IR) {
661 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
662 goto nla_put_failure;
663 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
664 goto nla_put_failure;
665 }
cdc89b97
JB
666 if (chan->flags & IEEE80211_CHAN_RADAR) {
667 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
668 goto nla_put_failure;
669 if (large) {
670 u32 time;
671
672 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
673
674 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
675 chan->dfs_state))
676 goto nla_put_failure;
677 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
678 time))
679 goto nla_put_failure;
089027e5
JD
680 if (nla_put_u32(msg,
681 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
682 chan->dfs_cac_ms))
683 goto nla_put_failure;
cdc89b97
JB
684 }
685 }
5dab3b8a 686
fe1abafd
JB
687 if (large) {
688 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
689 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
690 goto nla_put_failure;
691 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
692 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
693 goto nla_put_failure;
694 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
695 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
696 goto nla_put_failure;
697 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
698 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
699 goto nla_put_failure;
570dbde1
DS
700 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
701 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
702 goto nla_put_failure;
06f207fc
AN
703 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
704 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 705 goto nla_put_failure;
ea077c1c
RL
706 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
707 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
708 goto nla_put_failure;
709 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
710 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
711 goto nla_put_failure;
fe1abafd
JB
712 }
713
9360ffd1
DM
714 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
715 DBM_TO_MBM(chan->max_power)))
716 goto nla_put_failure;
5dab3b8a
LR
717
718 return 0;
719
720 nla_put_failure:
721 return -ENOBUFS;
722}
723
55682965
JB
724/* netlink command implementations */
725
b9454e83
JB
726struct key_parse {
727 struct key_params p;
728 int idx;
e31b8213 729 int type;
b9454e83 730 bool def, defmgmt;
dbd2fd65 731 bool def_uni, def_multi;
b9454e83
JB
732};
733
734static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
735{
736 struct nlattr *tb[NL80211_KEY_MAX + 1];
737 int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
738 nl80211_key_policy);
739 if (err)
740 return err;
741
742 k->def = !!tb[NL80211_KEY_DEFAULT];
743 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
744
dbd2fd65
JB
745 if (k->def) {
746 k->def_uni = true;
747 k->def_multi = true;
748 }
749 if (k->defmgmt)
750 k->def_multi = true;
751
b9454e83
JB
752 if (tb[NL80211_KEY_IDX])
753 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
754
755 if (tb[NL80211_KEY_DATA]) {
756 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
757 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
758 }
759
760 if (tb[NL80211_KEY_SEQ]) {
761 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
762 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
763 }
764
765 if (tb[NL80211_KEY_CIPHER])
766 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
767
e31b8213
JB
768 if (tb[NL80211_KEY_TYPE]) {
769 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
770 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
771 return -EINVAL;
772 }
773
dbd2fd65
JB
774 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
775 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 776
2da8f419
JB
777 err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
778 tb[NL80211_KEY_DEFAULT_TYPES],
779 nl80211_key_default_policy);
dbd2fd65
JB
780 if (err)
781 return err;
782
783 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
784 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
785 }
786
b9454e83
JB
787 return 0;
788}
789
790static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
791{
792 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
793 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
794 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
795 }
796
797 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
798 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
799 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
800 }
801
802 if (info->attrs[NL80211_ATTR_KEY_IDX])
803 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
804
805 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
806 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
807
808 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
809 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
810
dbd2fd65
JB
811 if (k->def) {
812 k->def_uni = true;
813 k->def_multi = true;
814 }
815 if (k->defmgmt)
816 k->def_multi = true;
817
e31b8213
JB
818 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
819 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
820 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
821 return -EINVAL;
822 }
823
dbd2fd65
JB
824 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
825 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
826 int err = nla_parse_nested(
827 kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
828 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
829 nl80211_key_default_policy);
830 if (err)
831 return err;
832
833 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
834 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
835 }
836
b9454e83
JB
837 return 0;
838}
839
840static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
841{
842 int err;
843
844 memset(k, 0, sizeof(*k));
845 k->idx = -1;
e31b8213 846 k->type = -1;
b9454e83
JB
847
848 if (info->attrs[NL80211_ATTR_KEY])
849 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
850 else
851 err = nl80211_parse_key_old(info, k);
852
853 if (err)
854 return err;
855
856 if (k->def && k->defmgmt)
857 return -EINVAL;
858
dbd2fd65
JB
859 if (k->defmgmt) {
860 if (k->def_uni || !k->def_multi)
861 return -EINVAL;
862 }
863
b9454e83
JB
864 if (k->idx != -1) {
865 if (k->defmgmt) {
866 if (k->idx < 4 || k->idx > 5)
867 return -EINVAL;
868 } else if (k->def) {
869 if (k->idx < 0 || k->idx > 3)
870 return -EINVAL;
871 } else {
872 if (k->idx < 0 || k->idx > 5)
873 return -EINVAL;
874 }
875 }
876
877 return 0;
878}
879
fffd0934
JB
880static struct cfg80211_cached_keys *
881nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
de7044ee 882 struct nlattr *keys, bool *no_ht)
fffd0934
JB
883{
884 struct key_parse parse;
885 struct nlattr *key;
886 struct cfg80211_cached_keys *result;
887 int rem, err, def = 0;
f1c1f17a
JB
888 bool have_key = false;
889
890 nla_for_each_nested(key, keys, rem) {
891 have_key = true;
892 break;
893 }
894
895 if (!have_key)
896 return NULL;
fffd0934
JB
897
898 result = kzalloc(sizeof(*result), GFP_KERNEL);
899 if (!result)
900 return ERR_PTR(-ENOMEM);
901
902 result->def = -1;
fffd0934
JB
903
904 nla_for_each_nested(key, keys, rem) {
905 memset(&parse, 0, sizeof(parse));
906 parse.idx = -1;
907
908 err = nl80211_parse_key_new(key, &parse);
909 if (err)
910 goto error;
911 err = -EINVAL;
912 if (!parse.p.key)
913 goto error;
42ee231c 914 if (parse.idx < 0 || parse.idx > 3)
fffd0934
JB
915 goto error;
916 if (parse.def) {
917 if (def)
918 goto error;
919 def = 1;
920 result->def = parse.idx;
dbd2fd65
JB
921 if (!parse.def_uni || !parse.def_multi)
922 goto error;
fffd0934
JB
923 } else if (parse.defmgmt)
924 goto error;
925 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 926 parse.idx, false, NULL);
fffd0934
JB
927 if (err)
928 goto error;
386b1f27
JB
929 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
930 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
931 err = -EINVAL;
932 goto error;
933 }
fffd0934
JB
934 result->params[parse.idx].cipher = parse.p.cipher;
935 result->params[parse.idx].key_len = parse.p.key_len;
936 result->params[parse.idx].key = result->data[parse.idx];
937 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 938
386b1f27
JB
939 /* must be WEP key if we got here */
940 if (no_ht)
941 *no_ht = true;
fffd0934
JB
942 }
943
f1c1f17a
JB
944 if (result->def < 0) {
945 err = -EINVAL;
946 goto error;
947 }
948
fffd0934
JB
949 return result;
950 error:
951 kfree(result);
952 return ERR_PTR(err);
953}
954
955static int nl80211_key_allowed(struct wireless_dev *wdev)
956{
957 ASSERT_WDEV_LOCK(wdev);
958
fffd0934
JB
959 switch (wdev->iftype) {
960 case NL80211_IFTYPE_AP:
961 case NL80211_IFTYPE_AP_VLAN:
074ac8df 962 case NL80211_IFTYPE_P2P_GO:
ff973af7 963 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
964 break;
965 case NL80211_IFTYPE_ADHOC:
fffd0934 966 case NL80211_IFTYPE_STATION:
074ac8df 967 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 968 if (!wdev->current_bss)
fffd0934
JB
969 return -ENOLINK;
970 break;
de4fcbad 971 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 972 case NL80211_IFTYPE_OCB:
de4fcbad 973 case NL80211_IFTYPE_MONITOR:
cb3b7d87 974 case NL80211_IFTYPE_NAN:
de4fcbad
JB
975 case NL80211_IFTYPE_P2P_DEVICE:
976 case NL80211_IFTYPE_WDS:
977 case NUM_NL80211_IFTYPES:
fffd0934
JB
978 return -EINVAL;
979 }
980
981 return 0;
982}
983
664834de
JM
984static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
985 struct nlattr *tb)
986{
987 struct ieee80211_channel *chan;
988
989 if (tb == NULL)
990 return NULL;
991 chan = ieee80211_get_channel(wiphy, nla_get_u32(tb));
992 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
993 return NULL;
994 return chan;
995}
996
7527a782
JB
997static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
998{
999 struct nlattr *nl_modes = nla_nest_start(msg, attr);
1000 int i;
1001
1002 if (!nl_modes)
1003 goto nla_put_failure;
1004
1005 i = 0;
1006 while (ifmodes) {
9360ffd1
DM
1007 if ((ifmodes & 1) && nla_put_flag(msg, i))
1008 goto nla_put_failure;
7527a782
JB
1009 ifmodes >>= 1;
1010 i++;
1011 }
1012
1013 nla_nest_end(msg, nl_modes);
1014 return 0;
1015
1016nla_put_failure:
1017 return -ENOBUFS;
1018}
1019
1020static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1021 struct sk_buff *msg,
1022 bool large)
7527a782
JB
1023{
1024 struct nlattr *nl_combis;
1025 int i, j;
1026
1027 nl_combis = nla_nest_start(msg,
1028 NL80211_ATTR_INTERFACE_COMBINATIONS);
1029 if (!nl_combis)
1030 goto nla_put_failure;
1031
1032 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1033 const struct ieee80211_iface_combination *c;
1034 struct nlattr *nl_combi, *nl_limits;
1035
1036 c = &wiphy->iface_combinations[i];
1037
1038 nl_combi = nla_nest_start(msg, i + 1);
1039 if (!nl_combi)
1040 goto nla_put_failure;
1041
1042 nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
1043 if (!nl_limits)
1044 goto nla_put_failure;
1045
1046 for (j = 0; j < c->n_limits; j++) {
1047 struct nlattr *nl_limit;
1048
1049 nl_limit = nla_nest_start(msg, j + 1);
1050 if (!nl_limit)
1051 goto nla_put_failure;
9360ffd1
DM
1052 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1053 c->limits[j].max))
1054 goto nla_put_failure;
7527a782
JB
1055 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1056 c->limits[j].types))
1057 goto nla_put_failure;
1058 nla_nest_end(msg, nl_limit);
1059 }
1060
1061 nla_nest_end(msg, nl_limits);
1062
9360ffd1
DM
1063 if (c->beacon_int_infra_match &&
1064 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1065 goto nla_put_failure;
1066 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1067 c->num_different_channels) ||
1068 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1069 c->max_interfaces))
1070 goto nla_put_failure;
cdc89b97 1071 if (large &&
8c48b50a
FF
1072 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1073 c->radar_detect_widths) ||
1074 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1075 c->radar_detect_regions)))
cdc89b97 1076 goto nla_put_failure;
0c317a02
PK
1077 if (c->beacon_int_min_gcd &&
1078 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1079 c->beacon_int_min_gcd))
1080 goto nla_put_failure;
7527a782
JB
1081
1082 nla_nest_end(msg, nl_combi);
1083 }
1084
1085 nla_nest_end(msg, nl_combis);
1086
1087 return 0;
1088nla_put_failure:
1089 return -ENOBUFS;
1090}
1091
3713b4e3 1092#ifdef CONFIG_PM
b56cf720
JB
1093static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1094 struct sk_buff *msg)
1095{
964dc9e2 1096 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1097 struct nlattr *nl_tcp;
1098
1099 if (!tcp)
1100 return 0;
1101
1102 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
1103 if (!nl_tcp)
1104 return -ENOBUFS;
1105
1106 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1107 tcp->data_payload_max))
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 (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1115 return -ENOBUFS;
1116
1117 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1118 sizeof(*tcp->tok), tcp->tok))
1119 return -ENOBUFS;
1120
1121 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1122 tcp->data_interval_max))
1123 return -ENOBUFS;
1124
1125 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1126 tcp->wake_payload_max))
1127 return -ENOBUFS;
1128
1129 nla_nest_end(msg, nl_tcp);
1130 return 0;
1131}
1132
3713b4e3 1133static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1134 struct cfg80211_registered_device *rdev,
b56cf720 1135 bool large)
55682965 1136{
3713b4e3 1137 struct nlattr *nl_wowlan;
55682965 1138
1b8ec87a 1139 if (!rdev->wiphy.wowlan)
3713b4e3 1140 return 0;
55682965 1141
3713b4e3
JB
1142 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
1143 if (!nl_wowlan)
1144 return -ENOBUFS;
9360ffd1 1145
1b8ec87a 1146 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1147 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1148 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1149 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1150 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1151 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1152 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1153 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1154 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1155 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1156 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1157 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1158 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1159 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1160 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1161 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1162 return -ENOBUFS;
9360ffd1 1163
1b8ec87a 1164 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1165 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1166 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1167 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1168 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1169 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1170 };
9360ffd1 1171
3713b4e3
JB
1172 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1173 sizeof(pat), &pat))
1174 return -ENOBUFS;
1175 }
9360ffd1 1176
75453ccb
LC
1177 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1178 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1179 rdev->wiphy.wowlan->max_nd_match_sets))
1180 return -ENOBUFS;
1181
1b8ec87a 1182 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1183 return -ENOBUFS;
1184
3713b4e3 1185 nla_nest_end(msg, nl_wowlan);
9360ffd1 1186
3713b4e3
JB
1187 return 0;
1188}
1189#endif
9360ffd1 1190
be29b99a 1191static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1192 struct cfg80211_registered_device *rdev)
be29b99a
AK
1193{
1194 struct nl80211_coalesce_rule_support rule;
1195
1b8ec87a 1196 if (!rdev->wiphy.coalesce)
be29b99a
AK
1197 return 0;
1198
1b8ec87a
ZG
1199 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1200 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1201 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1202 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1203 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1204 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1205
1206 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1207 return -ENOBUFS;
1208
1209 return 0;
1210}
1211
3713b4e3
JB
1212static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1213 struct ieee80211_supported_band *sband)
1214{
1215 struct nlattr *nl_rates, *nl_rate;
1216 struct ieee80211_rate *rate;
1217 int i;
87bbbe22 1218
3713b4e3
JB
1219 /* add HT info */
1220 if (sband->ht_cap.ht_supported &&
1221 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1222 sizeof(sband->ht_cap.mcs),
1223 &sband->ht_cap.mcs) ||
1224 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1225 sband->ht_cap.cap) ||
1226 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1227 sband->ht_cap.ampdu_factor) ||
1228 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1229 sband->ht_cap.ampdu_density)))
1230 return -ENOBUFS;
afe0cbf8 1231
3713b4e3
JB
1232 /* add VHT info */
1233 if (sband->vht_cap.vht_supported &&
1234 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1235 sizeof(sband->vht_cap.vht_mcs),
1236 &sband->vht_cap.vht_mcs) ||
1237 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1238 sband->vht_cap.cap)))
1239 return -ENOBUFS;
f59ac048 1240
3713b4e3
JB
1241 /* add bitrates */
1242 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
1243 if (!nl_rates)
1244 return -ENOBUFS;
ee688b00 1245
3713b4e3
JB
1246 for (i = 0; i < sband->n_bitrates; i++) {
1247 nl_rate = nla_nest_start(msg, i);
1248 if (!nl_rate)
1249 return -ENOBUFS;
ee688b00 1250
3713b4e3
JB
1251 rate = &sband->bitrates[i];
1252 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1253 rate->bitrate))
1254 return -ENOBUFS;
1255 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1256 nla_put_flag(msg,
1257 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1258 return -ENOBUFS;
ee688b00 1259
3713b4e3
JB
1260 nla_nest_end(msg, nl_rate);
1261 }
d51626df 1262
3713b4e3 1263 nla_nest_end(msg, nl_rates);
bf0c111e 1264
3713b4e3
JB
1265 return 0;
1266}
ee688b00 1267
3713b4e3
JB
1268static int
1269nl80211_send_mgmt_stypes(struct sk_buff *msg,
1270 const struct ieee80211_txrx_stypes *mgmt_stypes)
1271{
1272 u16 stypes;
1273 struct nlattr *nl_ftypes, *nl_ifs;
1274 enum nl80211_iftype ift;
1275 int i;
ee688b00 1276
3713b4e3
JB
1277 if (!mgmt_stypes)
1278 return 0;
5dab3b8a 1279
3713b4e3
JB
1280 nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES);
1281 if (!nl_ifs)
1282 return -ENOBUFS;
e2f367f2 1283
3713b4e3
JB
1284 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1285 nl_ftypes = nla_nest_start(msg, ift);
1286 if (!nl_ftypes)
1287 return -ENOBUFS;
1288 i = 0;
1289 stypes = mgmt_stypes[ift].tx;
1290 while (stypes) {
1291 if ((stypes & 1) &&
1292 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1293 (i << 4) | IEEE80211_FTYPE_MGMT))
1294 return -ENOBUFS;
1295 stypes >>= 1;
1296 i++;
ee688b00 1297 }
3713b4e3
JB
1298 nla_nest_end(msg, nl_ftypes);
1299 }
ee688b00 1300
3713b4e3 1301 nla_nest_end(msg, nl_ifs);
ee688b00 1302
3713b4e3
JB
1303 nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES);
1304 if (!nl_ifs)
1305 return -ENOBUFS;
ee688b00 1306
3713b4e3
JB
1307 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1308 nl_ftypes = nla_nest_start(msg, ift);
1309 if (!nl_ftypes)
1310 return -ENOBUFS;
1311 i = 0;
1312 stypes = mgmt_stypes[ift].rx;
1313 while (stypes) {
1314 if ((stypes & 1) &&
1315 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1316 (i << 4) | IEEE80211_FTYPE_MGMT))
1317 return -ENOBUFS;
1318 stypes >>= 1;
1319 i++;
1320 }
1321 nla_nest_end(msg, nl_ftypes);
1322 }
1323 nla_nest_end(msg, nl_ifs);
ee688b00 1324
3713b4e3
JB
1325 return 0;
1326}
ee688b00 1327
1794899e
JB
1328#define CMD(op, n) \
1329 do { \
1330 if (rdev->ops->op) { \
1331 i++; \
1332 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1333 goto nla_put_failure; \
1334 } \
1335 } while (0)
1336
1337static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
1338 struct sk_buff *msg)
1339{
1340 int i = 0;
1341
1342 /*
1343 * do *NOT* add anything into this function, new things need to be
1344 * advertised only to new versions of userspace that can deal with
1345 * the split (and they can't possibly care about new features...
1346 */
1347 CMD(add_virtual_intf, NEW_INTERFACE);
1348 CMD(change_virtual_intf, SET_INTERFACE);
1349 CMD(add_key, NEW_KEY);
1350 CMD(start_ap, START_AP);
1351 CMD(add_station, NEW_STATION);
1352 CMD(add_mpath, NEW_MPATH);
1353 CMD(update_mesh_config, SET_MESH_CONFIG);
1354 CMD(change_bss, SET_BSS);
1355 CMD(auth, AUTHENTICATE);
1356 CMD(assoc, ASSOCIATE);
1357 CMD(deauth, DEAUTHENTICATE);
1358 CMD(disassoc, DISASSOCIATE);
1359 CMD(join_ibss, JOIN_IBSS);
1360 CMD(join_mesh, JOIN_MESH);
1361 CMD(set_pmksa, SET_PMKSA);
1362 CMD(del_pmksa, DEL_PMKSA);
1363 CMD(flush_pmksa, FLUSH_PMKSA);
1364 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1365 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1366 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1367 CMD(mgmt_tx, FRAME);
1368 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1369 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1370 i++;
1371 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1372 goto nla_put_failure;
1373 }
1374 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
1375 rdev->ops->join_mesh) {
1376 i++;
1377 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1378 goto nla_put_failure;
1379 }
1380 CMD(set_wds_peer, SET_WDS_PEER);
1381 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1382 CMD(tdls_mgmt, TDLS_MGMT);
1383 CMD(tdls_oper, TDLS_OPER);
1384 }
1385 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
1386 CMD(sched_scan_start, START_SCHED_SCAN);
1387 CMD(probe_client, PROBE_CLIENT);
1388 CMD(set_noack_map, SET_NOACK_MAP);
1389 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1390 i++;
1391 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1392 goto nla_put_failure;
1393 }
1394 CMD(start_p2p_device, START_P2P_DEVICE);
1395 CMD(set_mcast_rate, SET_MCAST_RATE);
1396#ifdef CONFIG_NL80211_TESTMODE
1397 CMD(testmode_cmd, TESTMODE);
1398#endif
1399
1400 if (rdev->ops->connect || rdev->ops->auth) {
1401 i++;
1402 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1403 goto nla_put_failure;
1404 }
1405
1406 if (rdev->ops->disconnect || rdev->ops->deauth) {
1407 i++;
1408 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1409 goto nla_put_failure;
1410 }
1411
1412 return i;
1413 nla_put_failure:
1414 return -ENOBUFS;
1415}
1416
86e8cf98
JB
1417struct nl80211_dump_wiphy_state {
1418 s64 filter_wiphy;
1419 long start;
019ae3a9 1420 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
1421 bool split;
1422};
1423
1b8ec87a 1424static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 1425 enum nl80211_commands cmd,
3713b4e3 1426 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 1427 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
1428{
1429 void *hdr;
1430 struct nlattr *nl_bands, *nl_band;
1431 struct nlattr *nl_freqs, *nl_freq;
1432 struct nlattr *nl_cmds;
57fbcce3 1433 enum nl80211_band band;
3713b4e3
JB
1434 struct ieee80211_channel *chan;
1435 int i;
1436 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 1437 rdev->wiphy.mgmt_stypes;
fe1abafd 1438 u32 features;
ee688b00 1439
3bb20556 1440 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
1441 if (!hdr)
1442 return -ENOBUFS;
ee688b00 1443
86e8cf98
JB
1444 if (WARN_ON(!state))
1445 return -EINVAL;
ee688b00 1446
1b8ec87a 1447 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 1448 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 1449 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
1450 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1451 cfg80211_rdev_list_generation))
8fdc621d
JB
1452 goto nla_put_failure;
1453
3bb20556
JB
1454 if (cmd != NL80211_CMD_NEW_WIPHY)
1455 goto finish;
1456
86e8cf98 1457 switch (state->split_start) {
3713b4e3
JB
1458 case 0:
1459 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 1460 rdev->wiphy.retry_short) ||
3713b4e3 1461 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 1462 rdev->wiphy.retry_long) ||
3713b4e3 1463 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 1464 rdev->wiphy.frag_threshold) ||
3713b4e3 1465 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 1466 rdev->wiphy.rts_threshold) ||
3713b4e3 1467 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 1468 rdev->wiphy.coverage_class) ||
3713b4e3 1469 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 1470 rdev->wiphy.max_scan_ssids) ||
3713b4e3 1471 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 1472 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 1473 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 1474 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 1475 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 1476 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 1477 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
3b06d277
AS
1478 rdev->wiphy.max_match_sets) ||
1479 nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
1480 rdev->wiphy.max_sched_scan_plans) ||
1481 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
1482 rdev->wiphy.max_sched_scan_plan_interval) ||
1483 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
1484 rdev->wiphy.max_sched_scan_plan_iterations))
9360ffd1 1485 goto nla_put_failure;
3713b4e3 1486
1b8ec87a 1487 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 1488 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 1489 goto nla_put_failure;
1b8ec87a 1490 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
1491 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
1492 goto nla_put_failure;
1b8ec87a 1493 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
1494 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
1495 goto nla_put_failure;
1b8ec87a 1496 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
1497 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
1498 goto nla_put_failure;
1b8ec87a 1499 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
1500 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
1501 goto nla_put_failure;
1b8ec87a 1502 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 1503 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 1504 goto nla_put_failure;
86e8cf98
JB
1505 state->split_start++;
1506 if (state->split)
3713b4e3
JB
1507 break;
1508 case 1:
1509 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
1510 sizeof(u32) * rdev->wiphy.n_cipher_suites,
1511 rdev->wiphy.cipher_suites))
3713b4e3 1512 goto nla_put_failure;
4745fc09 1513
3713b4e3 1514 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 1515 rdev->wiphy.max_num_pmkids))
3713b4e3 1516 goto nla_put_failure;
b23aa676 1517
1b8ec87a 1518 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 1519 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 1520 goto nla_put_failure;
b23aa676 1521
3713b4e3 1522 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 1523 rdev->wiphy.available_antennas_tx) ||
3713b4e3 1524 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 1525 rdev->wiphy.available_antennas_rx))
9360ffd1 1526 goto nla_put_failure;
b23aa676 1527
1b8ec87a 1528 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 1529 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 1530 rdev->wiphy.probe_resp_offload))
3713b4e3 1531 goto nla_put_failure;
8fdc621d 1532
1b8ec87a
ZG
1533 if ((rdev->wiphy.available_antennas_tx ||
1534 rdev->wiphy.available_antennas_rx) &&
1535 rdev->ops->get_antenna) {
3713b4e3
JB
1536 u32 tx_ant = 0, rx_ant = 0;
1537 int res;
7a087e74 1538
1b8ec87a 1539 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
1540 if (!res) {
1541 if (nla_put_u32(msg,
1542 NL80211_ATTR_WIPHY_ANTENNA_TX,
1543 tx_ant) ||
1544 nla_put_u32(msg,
1545 NL80211_ATTR_WIPHY_ANTENNA_RX,
1546 rx_ant))
1547 goto nla_put_failure;
1548 }
1549 }
a293911d 1550
86e8cf98
JB
1551 state->split_start++;
1552 if (state->split)
3713b4e3
JB
1553 break;
1554 case 2:
1555 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 1556 rdev->wiphy.interface_modes))
3713b4e3 1557 goto nla_put_failure;
86e8cf98
JB
1558 state->split_start++;
1559 if (state->split)
3713b4e3
JB
1560 break;
1561 case 3:
1562 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1563 if (!nl_bands)
1564 goto nla_put_failure;
f7ca38df 1565
86e8cf98 1566 for (band = state->band_start;
57fbcce3 1567 band < NUM_NL80211_BANDS; band++) {
3713b4e3 1568 struct ieee80211_supported_band *sband;
2e161f78 1569
1b8ec87a 1570 sband = rdev->wiphy.bands[band];
2e161f78 1571
3713b4e3
JB
1572 if (!sband)
1573 continue;
1574
1575 nl_band = nla_nest_start(msg, band);
1576 if (!nl_band)
2e161f78 1577 goto nla_put_failure;
3713b4e3 1578
86e8cf98 1579 switch (state->chan_start) {
3713b4e3
JB
1580 case 0:
1581 if (nl80211_send_band_rateinfo(msg, sband))
9360ffd1 1582 goto nla_put_failure;
86e8cf98
JB
1583 state->chan_start++;
1584 if (state->split)
3713b4e3
JB
1585 break;
1586 default:
1587 /* add frequencies */
1588 nl_freqs = nla_nest_start(
1589 msg, NL80211_BAND_ATTR_FREQS);
1590 if (!nl_freqs)
1591 goto nla_put_failure;
1592
86e8cf98 1593 for (i = state->chan_start - 1;
3713b4e3
JB
1594 i < sband->n_channels;
1595 i++) {
1596 nl_freq = nla_nest_start(msg, i);
1597 if (!nl_freq)
1598 goto nla_put_failure;
1599
1600 chan = &sband->channels[i];
1601
86e8cf98
JB
1602 if (nl80211_msg_put_channel(
1603 msg, chan,
1604 state->split))
3713b4e3
JB
1605 goto nla_put_failure;
1606
1607 nla_nest_end(msg, nl_freq);
86e8cf98 1608 if (state->split)
3713b4e3
JB
1609 break;
1610 }
1611 if (i < sband->n_channels)
86e8cf98 1612 state->chan_start = i + 2;
3713b4e3 1613 else
86e8cf98 1614 state->chan_start = 0;
3713b4e3
JB
1615 nla_nest_end(msg, nl_freqs);
1616 }
1617
1618 nla_nest_end(msg, nl_band);
1619
86e8cf98 1620 if (state->split) {
3713b4e3 1621 /* start again here */
86e8cf98 1622 if (state->chan_start)
3713b4e3
JB
1623 band--;
1624 break;
2e161f78 1625 }
2e161f78 1626 }
3713b4e3 1627 nla_nest_end(msg, nl_bands);
2e161f78 1628
57fbcce3 1629 if (band < NUM_NL80211_BANDS)
86e8cf98 1630 state->band_start = band + 1;
3713b4e3 1631 else
86e8cf98 1632 state->band_start = 0;
74b70a4e 1633
3713b4e3 1634 /* if bands & channels are done, continue outside */
86e8cf98
JB
1635 if (state->band_start == 0 && state->chan_start == 0)
1636 state->split_start++;
1637 if (state->split)
3713b4e3
JB
1638 break;
1639 case 4:
1640 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
1641 if (!nl_cmds)
2e161f78
JB
1642 goto nla_put_failure;
1643
1794899e
JB
1644 i = nl80211_add_commands_unsplit(rdev, msg);
1645 if (i < 0)
1646 goto nla_put_failure;
86e8cf98 1647 if (state->split) {
5de17984
AS
1648 CMD(crit_proto_start, CRIT_PROTOCOL_START);
1649 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 1650 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 1651 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 1652 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
1653 if (rdev->wiphy.features &
1654 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 1655 CMD(add_tx_ts, ADD_TX_TS);
ce0ce13a 1656 CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
088e8df8 1657 CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
5de17984 1658 }
3713b4e3 1659#undef CMD
ff1b6e69 1660
3713b4e3 1661 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
1662 state->split_start++;
1663 if (state->split)
3713b4e3
JB
1664 break;
1665 case 5:
1b8ec87a
ZG
1666 if (rdev->ops->remain_on_channel &&
1667 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
1668 nla_put_u32(msg,
1669 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 1670 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
1671 goto nla_put_failure;
1672
1b8ec87a 1673 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
1674 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
1675 goto nla_put_failure;
1676
1677 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
1678 goto nla_put_failure;
86e8cf98
JB
1679 state->split_start++;
1680 if (state->split)
3713b4e3
JB
1681 break;
1682 case 6:
1683#ifdef CONFIG_PM
1b8ec87a 1684 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 1685 goto nla_put_failure;
86e8cf98
JB
1686 state->split_start++;
1687 if (state->split)
3713b4e3
JB
1688 break;
1689#else
86e8cf98 1690 state->split_start++;
dfb89c56 1691#endif
3713b4e3
JB
1692 case 7:
1693 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 1694 rdev->wiphy.software_iftypes))
3713b4e3 1695 goto nla_put_failure;
ff1b6e69 1696
1b8ec87a 1697 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 1698 state->split))
3713b4e3 1699 goto nla_put_failure;
7527a782 1700
86e8cf98
JB
1701 state->split_start++;
1702 if (state->split)
3713b4e3
JB
1703 break;
1704 case 8:
1b8ec87a 1705 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 1706 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 1707 rdev->wiphy.ap_sme_capa))
3713b4e3 1708 goto nla_put_failure;
7527a782 1709
1b8ec87a 1710 features = rdev->wiphy.features;
fe1abafd
JB
1711 /*
1712 * We can only add the per-channel limit information if the
1713 * dump is split, otherwise it makes it too big. Therefore
1714 * only advertise it in that case.
1715 */
86e8cf98 1716 if (state->split)
fe1abafd
JB
1717 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
1718 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 1719 goto nla_put_failure;
562a7480 1720
1b8ec87a 1721 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 1722 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
1723 sizeof(*rdev->wiphy.ht_capa_mod_mask),
1724 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 1725 goto nla_put_failure;
1f074bd8 1726
1b8ec87a
ZG
1727 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
1728 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 1729 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 1730 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 1731 goto nla_put_failure;
7e7c8926 1732
3713b4e3
JB
1733 /*
1734 * Any information below this point is only available to
1735 * applications that can deal with it being split. This
1736 * helps ensure that newly added capabilities don't break
1737 * older tools by overrunning their buffers.
1738 *
1739 * We still increment split_start so that in the split
1740 * case we'll continue with more data in the next round,
1741 * but break unconditionally so unsplit data stops here.
1742 */
86e8cf98 1743 state->split_start++;
3713b4e3
JB
1744 break;
1745 case 9:
1b8ec87a 1746 if (rdev->wiphy.extended_capabilities &&
fe1abafd 1747 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
1748 rdev->wiphy.extended_capabilities_len,
1749 rdev->wiphy.extended_capabilities) ||
fe1abafd 1750 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
1751 rdev->wiphy.extended_capabilities_len,
1752 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 1753 goto nla_put_failure;
a50df0c4 1754
1b8ec87a 1755 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 1756 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
1757 sizeof(*rdev->wiphy.vht_capa_mod_mask),
1758 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
1759 goto nla_put_failure;
1760
be29b99a
AK
1761 state->split_start++;
1762 break;
1763 case 10:
1b8ec87a 1764 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
1765 goto nla_put_failure;
1766
1b8ec87a 1767 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
1768 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
1769 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
1770 goto nla_put_failure;
b43504cf 1771
1b8ec87a 1772 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 1773 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 1774 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
1775 goto nla_put_failure;
1776
ad7e718c
JB
1777 state->split_start++;
1778 break;
1779 case 11:
1b8ec87a 1780 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
1781 const struct nl80211_vendor_cmd_info *info;
1782 struct nlattr *nested;
1783
1784 nested = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1785 if (!nested)
1786 goto nla_put_failure;
1787
1b8ec87a
ZG
1788 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
1789 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
1790 if (nla_put(msg, i + 1, sizeof(*info), info))
1791 goto nla_put_failure;
1792 }
1793 nla_nest_end(msg, nested);
1794 }
1795
1b8ec87a 1796 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
1797 const struct nl80211_vendor_cmd_info *info;
1798 struct nlattr *nested;
ad7e718c 1799
567ffc35
JB
1800 nested = nla_nest_start(msg,
1801 NL80211_ATTR_VENDOR_EVENTS);
1802 if (!nested)
ad7e718c 1803 goto nla_put_failure;
567ffc35 1804
1b8ec87a
ZG
1805 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
1806 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
1807 if (nla_put(msg, i + 1, sizeof(*info), info))
1808 goto nla_put_failure;
1809 }
1810 nla_nest_end(msg, nested);
1811 }
9a774c78
AO
1812 state->split_start++;
1813 break;
1814 case 12:
1815 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
1816 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
1817 rdev->wiphy.max_num_csa_counters))
1818 goto nla_put_failure;
01e0daa4 1819
1bdd716c
AN
1820 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
1821 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
1822 goto nla_put_failure;
1823
d75bb06b
GKS
1824 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
1825 sizeof(rdev->wiphy.ext_features),
1826 rdev->wiphy.ext_features))
1827 goto nla_put_failure;
1828
38de03d2
AS
1829 if (rdev->wiphy.bss_select_support) {
1830 struct nlattr *nested;
1831 u32 bss_select_support = rdev->wiphy.bss_select_support;
1832
1833 nested = nla_nest_start(msg, NL80211_ATTR_BSS_SELECT);
1834 if (!nested)
1835 goto nla_put_failure;
1836
1837 i = 0;
1838 while (bss_select_support) {
1839 if ((bss_select_support & 1) &&
1840 nla_put_flag(msg, i))
1841 goto nla_put_failure;
1842 i++;
1843 bss_select_support >>= 1;
1844 }
1845 nla_nest_end(msg, nested);
1846 }
1847
019ae3a9
KV
1848 state->split_start++;
1849 break;
1850 case 13:
1851 if (rdev->wiphy.num_iftype_ext_capab &&
1852 rdev->wiphy.iftype_ext_capab) {
1853 struct nlattr *nested_ext_capab, *nested;
1854
1855 nested = nla_nest_start(msg,
1856 NL80211_ATTR_IFTYPE_EXT_CAPA);
1857 if (!nested)
1858 goto nla_put_failure;
1859
1860 for (i = state->capa_start;
1861 i < rdev->wiphy.num_iftype_ext_capab; i++) {
1862 const struct wiphy_iftype_ext_capab *capab;
1863
1864 capab = &rdev->wiphy.iftype_ext_capab[i];
1865
1866 nested_ext_capab = nla_nest_start(msg, i);
1867 if (!nested_ext_capab ||
1868 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
1869 capab->iftype) ||
1870 nla_put(msg, NL80211_ATTR_EXT_CAPA,
1871 capab->extended_capabilities_len,
1872 capab->extended_capabilities) ||
1873 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1874 capab->extended_capabilities_len,
1875 capab->extended_capabilities_mask))
1876 goto nla_put_failure;
1877
1878 nla_nest_end(msg, nested_ext_capab);
1879 if (state->split)
1880 break;
1881 }
1882 nla_nest_end(msg, nested);
1883 if (i < rdev->wiphy.num_iftype_ext_capab) {
1884 state->capa_start = i + 1;
1885 break;
1886 }
1887 }
1888
3713b4e3 1889 /* done */
86e8cf98 1890 state->split_start = 0;
3713b4e3
JB
1891 break;
1892 }
3bb20556 1893 finish:
053c095a
JB
1894 genlmsg_end(msg, hdr);
1895 return 0;
55682965
JB
1896
1897 nla_put_failure:
bc3ed28c
TG
1898 genlmsg_cancel(msg, hdr);
1899 return -EMSGSIZE;
55682965
JB
1900}
1901
86e8cf98
JB
1902static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
1903 struct netlink_callback *cb,
1904 struct nl80211_dump_wiphy_state *state)
1905{
c90c39da 1906 struct nlattr **tb = genl_family_attrbuf(&nl80211_fam);
86e8cf98
JB
1907 int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1908 tb, nl80211_fam.maxattr, nl80211_policy);
1909 /* ignore parse errors for backward compatibility */
1910 if (ret)
1911 return 0;
1912
1913 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
1914 if (tb[NL80211_ATTR_WIPHY])
1915 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1916 if (tb[NL80211_ATTR_WDEV])
1917 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
1918 if (tb[NL80211_ATTR_IFINDEX]) {
1919 struct net_device *netdev;
1920 struct cfg80211_registered_device *rdev;
1921 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1922
7f2b8562 1923 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
86e8cf98
JB
1924 if (!netdev)
1925 return -ENODEV;
1926 if (netdev->ieee80211_ptr) {
f26cbf40 1927 rdev = wiphy_to_rdev(
86e8cf98
JB
1928 netdev->ieee80211_ptr->wiphy);
1929 state->filter_wiphy = rdev->wiphy_idx;
1930 }
86e8cf98
JB
1931 }
1932
1933 return 0;
1934}
1935
55682965
JB
1936static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1937{
645e77de 1938 int idx = 0, ret;
86e8cf98 1939 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 1940 struct cfg80211_registered_device *rdev;
3a5a423b 1941
5fe231e8 1942 rtnl_lock();
86e8cf98
JB
1943 if (!state) {
1944 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
1945 if (!state) {
1946 rtnl_unlock();
86e8cf98 1947 return -ENOMEM;
3713b4e3 1948 }
86e8cf98
JB
1949 state->filter_wiphy = -1;
1950 ret = nl80211_dump_wiphy_parse(skb, cb, state);
1951 if (ret) {
1952 kfree(state);
1953 rtnl_unlock();
1954 return ret;
3713b4e3 1955 }
86e8cf98 1956 cb->args[0] = (long)state;
3713b4e3
JB
1957 }
1958
1b8ec87a
ZG
1959 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1960 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 1961 continue;
86e8cf98 1962 if (++idx <= state->start)
55682965 1963 continue;
86e8cf98 1964 if (state->filter_wiphy != -1 &&
1b8ec87a 1965 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
1966 continue;
1967 /* attempt to fit multiple wiphy data chunks into the skb */
1968 do {
3bb20556
JB
1969 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
1970 skb,
3713b4e3
JB
1971 NETLINK_CB(cb->skb).portid,
1972 cb->nlh->nlmsg_seq,
86e8cf98 1973 NLM_F_MULTI, state);
3713b4e3
JB
1974 if (ret < 0) {
1975 /*
1976 * If sending the wiphy data didn't fit (ENOBUFS
1977 * or EMSGSIZE returned), this SKB is still
1978 * empty (so it's not too big because another
1979 * wiphy dataset is already in the skb) and
1980 * we've not tried to adjust the dump allocation
1981 * yet ... then adjust the alloc size to be
1982 * bigger, and return 1 but with the empty skb.
1983 * This results in an empty message being RX'ed
1984 * in userspace, but that is ignored.
1985 *
1986 * We can then retry with the larger buffer.
1987 */
1988 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 1989 !skb->len && !state->split &&
3713b4e3
JB
1990 cb->min_dump_alloc < 4096) {
1991 cb->min_dump_alloc = 4096;
f12cb289 1992 state->split_start = 0;
d98cae64 1993 rtnl_unlock();
3713b4e3
JB
1994 return 1;
1995 }
1996 idx--;
1997 break;
645e77de 1998 }
86e8cf98 1999 } while (state->split_start > 0);
3713b4e3 2000 break;
55682965 2001 }
5fe231e8 2002 rtnl_unlock();
55682965 2003
86e8cf98 2004 state->start = idx;
55682965
JB
2005
2006 return skb->len;
2007}
2008
86e8cf98
JB
2009static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
2010{
2011 kfree((void *)cb->args[0]);
2012 return 0;
2013}
2014
55682965
JB
2015static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
2016{
2017 struct sk_buff *msg;
1b8ec87a 2018 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 2019 struct nl80211_dump_wiphy_state state = {};
55682965 2020
645e77de 2021 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 2022 if (!msg)
4c476991 2023 return -ENOMEM;
55682965 2024
3bb20556
JB
2025 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
2026 info->snd_portid, info->snd_seq, 0,
86e8cf98 2027 &state) < 0) {
4c476991
JB
2028 nlmsg_free(msg);
2029 return -ENOBUFS;
2030 }
55682965 2031
134e6375 2032 return genlmsg_reply(msg, info);
55682965
JB
2033}
2034
31888487
JM
2035static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
2036 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
2037 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
2038 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
2039 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
2040 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
2041};
2042
2043static int parse_txq_params(struct nlattr *tb[],
2044 struct ieee80211_txq_params *txq_params)
2045{
a3304b0a 2046 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
2047 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
2048 !tb[NL80211_TXQ_ATTR_AIFS])
2049 return -EINVAL;
2050
a3304b0a 2051 txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
2052 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
2053 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
2054 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
2055 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
2056
a3304b0a
JB
2057 if (txq_params->ac >= NL80211_NUM_ACS)
2058 return -EINVAL;
2059
31888487
JM
2060 return 0;
2061}
2062
f444de05
JB
2063static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2064{
2065 /*
cc1d2806
JB
2066 * You can only set the channel explicitly for WDS interfaces,
2067 * all others have their channel managed via their respective
2068 * "establish a connection" command (connect, join, ...)
2069 *
2070 * For AP/GO and mesh mode, the channel can be set with the
2071 * channel userspace API, but is only stored and passed to the
2072 * low-level driver when the AP starts or the mesh is joined.
2073 * This is for backward compatibility, userspace can also give
2074 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
2075 *
2076 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
2077 * whatever else is going on, so they have their own special
2078 * operation to set the monitor channel if possible.
f444de05
JB
2079 */
2080 return !wdev ||
2081 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 2082 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
2083 wdev->iftype == NL80211_IFTYPE_MONITOR ||
2084 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
2085}
2086
683b6d3b
JB
2087static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2088 struct genl_info *info,
2089 struct cfg80211_chan_def *chandef)
2090{
dbeca2ea 2091 u32 control_freq;
683b6d3b
JB
2092
2093 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
2094 return -EINVAL;
2095
2096 control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
2097
2098 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
3d9d1d66
JB
2099 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
2100 chandef->center_freq1 = control_freq;
2101 chandef->center_freq2 = 0;
683b6d3b
JB
2102
2103 /* Primary channel not allowed */
2104 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
2105 return -EINVAL;
2106
3d9d1d66
JB
2107 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2108 enum nl80211_channel_type chantype;
2109
2110 chantype = nla_get_u32(
2111 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
2112
2113 switch (chantype) {
2114 case NL80211_CHAN_NO_HT:
2115 case NL80211_CHAN_HT20:
2116 case NL80211_CHAN_HT40PLUS:
2117 case NL80211_CHAN_HT40MINUS:
2118 cfg80211_chandef_create(chandef, chandef->chan,
2119 chantype);
2120 break;
2121 default:
2122 return -EINVAL;
2123 }
2124 } else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
2125 chandef->width =
2126 nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
2127 if (info->attrs[NL80211_ATTR_CENTER_FREQ1])
2128 chandef->center_freq1 =
2129 nla_get_u32(
2130 info->attrs[NL80211_ATTR_CENTER_FREQ1]);
2131 if (info->attrs[NL80211_ATTR_CENTER_FREQ2])
2132 chandef->center_freq2 =
2133 nla_get_u32(
2134 info->attrs[NL80211_ATTR_CENTER_FREQ2]);
2135 }
2136
9f5e8f6e 2137 if (!cfg80211_chandef_valid(chandef))
3d9d1d66
JB
2138 return -EINVAL;
2139
9f5e8f6e
JB
2140 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
2141 IEEE80211_CHAN_DISABLED))
3d9d1d66
JB
2142 return -EINVAL;
2143
2f301ab2
SW
2144 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
2145 chandef->width == NL80211_CHAN_WIDTH_10) &&
2146 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ))
2147 return -EINVAL;
2148
683b6d3b
JB
2149 return 0;
2150}
2151
f444de05 2152static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 2153 struct net_device *dev,
f444de05
JB
2154 struct genl_info *info)
2155{
683b6d3b 2156 struct cfg80211_chan_def chandef;
f444de05 2157 int result;
e8c9bd5b 2158 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 2159 struct wireless_dev *wdev = NULL;
e8c9bd5b 2160
e16821bc
JM
2161 if (dev)
2162 wdev = dev->ieee80211_ptr;
f444de05
JB
2163 if (!nl80211_can_set_dev_channel(wdev))
2164 return -EOPNOTSUPP;
e16821bc
JM
2165 if (wdev)
2166 iftype = wdev->iftype;
f444de05 2167
683b6d3b
JB
2168 result = nl80211_parse_chandef(rdev, info, &chandef);
2169 if (result)
2170 return result;
f444de05 2171
e8c9bd5b 2172 switch (iftype) {
aa430da4
JB
2173 case NL80211_IFTYPE_AP:
2174 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
2175 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
2176 iftype)) {
aa430da4
JB
2177 result = -EINVAL;
2178 break;
2179 }
e16821bc
JM
2180 if (wdev->beacon_interval) {
2181 if (!dev || !rdev->ops->set_ap_chanwidth ||
2182 !(rdev->wiphy.features &
2183 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
2184 result = -EBUSY;
2185 break;
2186 }
2187
2188 /* Only allow dynamic channel width changes */
2189 if (chandef.chan != wdev->preset_chandef.chan) {
2190 result = -EBUSY;
2191 break;
2192 }
2193 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
2194 if (result)
2195 break;
2196 }
683b6d3b 2197 wdev->preset_chandef = chandef;
aa430da4
JB
2198 result = 0;
2199 break;
cc1d2806 2200 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 2201 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 2202 break;
e8c9bd5b 2203 case NL80211_IFTYPE_MONITOR:
683b6d3b 2204 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 2205 break;
aa430da4 2206 default:
e8c9bd5b 2207 result = -EINVAL;
f444de05 2208 }
f444de05
JB
2209
2210 return result;
2211}
2212
2213static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
2214{
4c476991
JB
2215 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2216 struct net_device *netdev = info->user_ptr[1];
f444de05 2217
e16821bc 2218 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
2219}
2220
e8347eba
BJ
2221static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
2222{
43b19952
JB
2223 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2224 struct net_device *dev = info->user_ptr[1];
2225 struct wireless_dev *wdev = dev->ieee80211_ptr;
388ac775 2226 const u8 *bssid;
e8347eba
BJ
2227
2228 if (!info->attrs[NL80211_ATTR_MAC])
2229 return -EINVAL;
2230
43b19952
JB
2231 if (netif_running(dev))
2232 return -EBUSY;
e8347eba 2233
43b19952
JB
2234 if (!rdev->ops->set_wds_peer)
2235 return -EOPNOTSUPP;
e8347eba 2236
43b19952
JB
2237 if (wdev->iftype != NL80211_IFTYPE_WDS)
2238 return -EOPNOTSUPP;
e8347eba
BJ
2239
2240 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
e35e4d28 2241 return rdev_set_wds_peer(rdev, dev, bssid);
e8347eba
BJ
2242}
2243
55682965
JB
2244static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2245{
2246 struct cfg80211_registered_device *rdev;
f444de05
JB
2247 struct net_device *netdev = NULL;
2248 struct wireless_dev *wdev;
a1e567c8 2249 int result = 0, rem_txq_params = 0;
31888487 2250 struct nlattr *nl_txq_params;
b9a5f8ca
JM
2251 u32 changed;
2252 u8 retry_short = 0, retry_long = 0;
2253 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 2254 u8 coverage_class = 0;
55682965 2255
5fe231e8
JB
2256 ASSERT_RTNL();
2257
f444de05
JB
2258 /*
2259 * Try to find the wiphy and netdev. Normally this
2260 * function shouldn't need the netdev, but this is
2261 * done for backward compatibility -- previously
2262 * setting the channel was done per wiphy, but now
2263 * it is per netdev. Previous userland like hostapd
2264 * also passed a netdev to set_wiphy, so that it is
2265 * possible to let that go to the right netdev!
2266 */
4bbf4d56 2267
f444de05
JB
2268 if (info->attrs[NL80211_ATTR_IFINDEX]) {
2269 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
2270
7f2b8562 2271 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 2272 if (netdev && netdev->ieee80211_ptr)
f26cbf40 2273 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 2274 else
f444de05 2275 netdev = NULL;
4bbf4d56
JB
2276 }
2277
f444de05 2278 if (!netdev) {
878d9ec7
JB
2279 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
2280 info->attrs);
5fe231e8 2281 if (IS_ERR(rdev))
4c476991 2282 return PTR_ERR(rdev);
f444de05
JB
2283 wdev = NULL;
2284 netdev = NULL;
2285 result = 0;
71fe96bf 2286 } else
f444de05 2287 wdev = netdev->ieee80211_ptr;
f444de05
JB
2288
2289 /*
2290 * end workaround code, by now the rdev is available
2291 * and locked, and wdev may or may not be NULL.
2292 */
4bbf4d56
JB
2293
2294 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
2295 result = cfg80211_dev_rename(
2296 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56 2297
4bbf4d56 2298 if (result)
7f2b8562 2299 return result;
31888487
JM
2300
2301 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
2302 struct ieee80211_txq_params txq_params;
2303 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
2304
7f2b8562
YX
2305 if (!rdev->ops->set_txq_params)
2306 return -EOPNOTSUPP;
31888487 2307
7f2b8562
YX
2308 if (!netdev)
2309 return -EINVAL;
f70f01c2 2310
133a3ff2 2311 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
7f2b8562
YX
2312 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2313 return -EINVAL;
133a3ff2 2314
7f2b8562
YX
2315 if (!netif_running(netdev))
2316 return -ENETDOWN;
2b5f8b0b 2317
31888487
JM
2318 nla_for_each_nested(nl_txq_params,
2319 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
2320 rem_txq_params) {
bfe2c7b1
JB
2321 result = nla_parse_nested(tb, NL80211_TXQ_ATTR_MAX,
2322 nl_txq_params,
2323 txq_params_policy);
ae811e21
JB
2324 if (result)
2325 return result;
31888487
JM
2326 result = parse_txq_params(tb, &txq_params);
2327 if (result)
7f2b8562 2328 return result;
31888487 2329
e35e4d28
HG
2330 result = rdev_set_txq_params(rdev, netdev,
2331 &txq_params);
31888487 2332 if (result)
7f2b8562 2333 return result;
31888487
JM
2334 }
2335 }
55682965 2336
72bdcf34 2337 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
2338 result = __nl80211_set_channel(
2339 rdev,
2340 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
2341 info);
72bdcf34 2342 if (result)
7f2b8562 2343 return result;
72bdcf34
JM
2344 }
2345
98d2ff8b 2346 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 2347 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
2348 enum nl80211_tx_power_setting type;
2349 int idx, mbm = 0;
2350
c8442118
JB
2351 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
2352 txp_wdev = NULL;
2353
7f2b8562
YX
2354 if (!rdev->ops->set_tx_power)
2355 return -EOPNOTSUPP;
98d2ff8b
JO
2356
2357 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
2358 type = nla_get_u32(info->attrs[idx]);
2359
2360 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
7f2b8562
YX
2361 (type != NL80211_TX_POWER_AUTOMATIC))
2362 return -EINVAL;
98d2ff8b
JO
2363
2364 if (type != NL80211_TX_POWER_AUTOMATIC) {
2365 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
2366 mbm = nla_get_u32(info->attrs[idx]);
2367 }
2368
c8442118 2369 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 2370 if (result)
7f2b8562 2371 return result;
98d2ff8b
JO
2372 }
2373
afe0cbf8
BR
2374 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
2375 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
2376 u32 tx_ant, rx_ant;
7a087e74 2377
7f531e03
BR
2378 if ((!rdev->wiphy.available_antennas_tx &&
2379 !rdev->wiphy.available_antennas_rx) ||
7f2b8562
YX
2380 !rdev->ops->set_antenna)
2381 return -EOPNOTSUPP;
afe0cbf8
BR
2382
2383 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
2384 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
2385
a7ffac95 2386 /* reject antenna configurations which don't match the
7f531e03
BR
2387 * available antenna masks, except for the "all" mask */
2388 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
7f2b8562
YX
2389 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
2390 return -EINVAL;
a7ffac95 2391
7f531e03
BR
2392 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
2393 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 2394
e35e4d28 2395 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 2396 if (result)
7f2b8562 2397 return result;
afe0cbf8
BR
2398 }
2399
b9a5f8ca
JM
2400 changed = 0;
2401
2402 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
2403 retry_short = nla_get_u8(
2404 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562
YX
2405 if (retry_short == 0)
2406 return -EINVAL;
2407
b9a5f8ca
JM
2408 changed |= WIPHY_PARAM_RETRY_SHORT;
2409 }
2410
2411 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
2412 retry_long = nla_get_u8(
2413 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562
YX
2414 if (retry_long == 0)
2415 return -EINVAL;
2416
b9a5f8ca
JM
2417 changed |= WIPHY_PARAM_RETRY_LONG;
2418 }
2419
2420 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
2421 frag_threshold = nla_get_u32(
2422 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
7f2b8562
YX
2423 if (frag_threshold < 256)
2424 return -EINVAL;
2425
b9a5f8ca
JM
2426 if (frag_threshold != (u32) -1) {
2427 /*
2428 * Fragments (apart from the last one) are required to
2429 * have even length. Make the fragmentation code
2430 * simpler by stripping LSB should someone try to use
2431 * odd threshold value.
2432 */
2433 frag_threshold &= ~0x1;
2434 }
2435 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
2436 }
2437
2438 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
2439 rts_threshold = nla_get_u32(
2440 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
2441 changed |= WIPHY_PARAM_RTS_THRESHOLD;
2442 }
2443
81077e82 2444 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
3057dbfd
LB
2445 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK])
2446 return -EINVAL;
2447
81077e82
LT
2448 coverage_class = nla_get_u8(
2449 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
2450 changed |= WIPHY_PARAM_COVERAGE_CLASS;
2451 }
2452
3057dbfd
LB
2453 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
2454 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION))
2455 return -EOPNOTSUPP;
2456
2457 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
2458 }
2459
b9a5f8ca
JM
2460 if (changed) {
2461 u8 old_retry_short, old_retry_long;
2462 u32 old_frag_threshold, old_rts_threshold;
81077e82 2463 u8 old_coverage_class;
b9a5f8ca 2464
7f2b8562
YX
2465 if (!rdev->ops->set_wiphy_params)
2466 return -EOPNOTSUPP;
b9a5f8ca
JM
2467
2468 old_retry_short = rdev->wiphy.retry_short;
2469 old_retry_long = rdev->wiphy.retry_long;
2470 old_frag_threshold = rdev->wiphy.frag_threshold;
2471 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 2472 old_coverage_class = rdev->wiphy.coverage_class;
b9a5f8ca
JM
2473
2474 if (changed & WIPHY_PARAM_RETRY_SHORT)
2475 rdev->wiphy.retry_short = retry_short;
2476 if (changed & WIPHY_PARAM_RETRY_LONG)
2477 rdev->wiphy.retry_long = retry_long;
2478 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
2479 rdev->wiphy.frag_threshold = frag_threshold;
2480 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
2481 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
2482 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
2483 rdev->wiphy.coverage_class = coverage_class;
b9a5f8ca 2484
e35e4d28 2485 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
2486 if (result) {
2487 rdev->wiphy.retry_short = old_retry_short;
2488 rdev->wiphy.retry_long = old_retry_long;
2489 rdev->wiphy.frag_threshold = old_frag_threshold;
2490 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 2491 rdev->wiphy.coverage_class = old_coverage_class;
9189ee31 2492 return result;
b9a5f8ca
JM
2493 }
2494 }
7f2b8562 2495 return 0;
55682965
JB
2496}
2497
71bbc994
JB
2498static inline u64 wdev_id(struct wireless_dev *wdev)
2499{
2500 return (u64)wdev->identifier |
f26cbf40 2501 ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32);
71bbc994 2502}
55682965 2503
683b6d3b 2504static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 2505 const struct cfg80211_chan_def *chandef)
683b6d3b 2506{
601555cd
JB
2507 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
2508 return -EINVAL;
3d9d1d66 2509
683b6d3b
JB
2510 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
2511 chandef->chan->center_freq))
2512 return -ENOBUFS;
3d9d1d66
JB
2513 switch (chandef->width) {
2514 case NL80211_CHAN_WIDTH_20_NOHT:
2515 case NL80211_CHAN_WIDTH_20:
2516 case NL80211_CHAN_WIDTH_40:
2517 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2518 cfg80211_get_chandef_type(chandef)))
2519 return -ENOBUFS;
2520 break;
2521 default:
2522 break;
2523 }
2524 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
2525 return -ENOBUFS;
2526 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
2527 return -ENOBUFS;
2528 if (chandef->center_freq2 &&
2529 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
2530 return -ENOBUFS;
2531 return 0;
2532}
2533
15e47304 2534static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 2535 struct cfg80211_registered_device *rdev,
8f894be2 2536 struct wireless_dev *wdev, bool removal)
55682965 2537{
72fb2abc 2538 struct net_device *dev = wdev->netdev;
8f894be2 2539 u8 cmd = NL80211_CMD_NEW_INTERFACE;
55682965
JB
2540 void *hdr;
2541
8f894be2
TB
2542 if (removal)
2543 cmd = NL80211_CMD_DEL_INTERFACE;
2544
2545 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
2546 if (!hdr)
2547 return -1;
2548
72fb2abc
JB
2549 if (dev &&
2550 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 2551 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
2552 goto nla_put_failure;
2553
2554 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2555 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
2556 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
2557 NL80211_ATTR_PAD) ||
98104fde 2558 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
2559 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2560 rdev->devlist_generation ^
2561 (cfg80211_rdev_list_generation << 2)))
2562 goto nla_put_failure;
f5ea9120 2563
5b7ccaf3 2564 if (rdev->ops->get_channel) {
683b6d3b
JB
2565 int ret;
2566 struct cfg80211_chan_def chandef;
2567
2568 ret = rdev_get_channel(rdev, wdev, &chandef);
2569 if (ret == 0) {
2570 if (nl80211_send_chandef(msg, &chandef))
2571 goto nla_put_failure;
2572 }
d91df0e3
PF
2573 }
2574
d55d0d59
RM
2575 if (rdev->ops->get_tx_power) {
2576 int dbm, ret;
2577
2578 ret = rdev_get_tx_power(rdev, wdev, &dbm);
2579 if (ret == 0 &&
2580 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
2581 DBM_TO_MBM(dbm)))
2582 goto nla_put_failure;
2583 }
2584
b84e7a05
AQ
2585 if (wdev->ssid_len) {
2586 if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
2587 goto nla_put_failure;
2588 }
2589
053c095a
JB
2590 genlmsg_end(msg, hdr);
2591 return 0;
55682965
JB
2592
2593 nla_put_failure:
bc3ed28c
TG
2594 genlmsg_cancel(msg, hdr);
2595 return -EMSGSIZE;
55682965
JB
2596}
2597
2598static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
2599{
2600 int wp_idx = 0;
2601 int if_idx = 0;
2602 int wp_start = cb->args[0];
2603 int if_start = cb->args[1];
b7fb44da 2604 int filter_wiphy = -1;
f5ea9120 2605 struct cfg80211_registered_device *rdev;
55682965
JB
2606 struct wireless_dev *wdev;
2607
5fe231e8 2608 rtnl_lock();
b7fb44da
DK
2609 if (!cb->args[2]) {
2610 struct nl80211_dump_wiphy_state state = {
2611 .filter_wiphy = -1,
2612 };
2613 int ret;
2614
2615 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
2616 if (ret)
2617 return ret;
2618
2619 filter_wiphy = state.filter_wiphy;
2620
2621 /*
2622 * if filtering, set cb->args[2] to +1 since 0 is the default
2623 * value needed to determine that parsing is necessary.
2624 */
2625 if (filter_wiphy >= 0)
2626 cb->args[2] = filter_wiphy + 1;
2627 else
2628 cb->args[2] = -1;
2629 } else if (cb->args[2] > 0) {
2630 filter_wiphy = cb->args[2] - 1;
2631 }
2632
f5ea9120
JB
2633 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2634 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2635 continue;
bba95fef
JB
2636 if (wp_idx < wp_start) {
2637 wp_idx++;
55682965 2638 continue;
bba95fef 2639 }
b7fb44da
DK
2640
2641 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
2642 continue;
2643
55682965
JB
2644 if_idx = 0;
2645
53873f13 2646 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
2647 if (if_idx < if_start) {
2648 if_idx++;
55682965 2649 continue;
bba95fef 2650 }
15e47304 2651 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 2652 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8f894be2 2653 rdev, wdev, false) < 0) {
bba95fef
JB
2654 goto out;
2655 }
2656 if_idx++;
55682965 2657 }
bba95fef
JB
2658
2659 wp_idx++;
55682965 2660 }
bba95fef 2661 out:
5fe231e8 2662 rtnl_unlock();
55682965
JB
2663
2664 cb->args[0] = wp_idx;
2665 cb->args[1] = if_idx;
2666
2667 return skb->len;
2668}
2669
2670static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
2671{
2672 struct sk_buff *msg;
1b8ec87a 2673 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 2674 struct wireless_dev *wdev = info->user_ptr[1];
55682965 2675
fd2120ca 2676 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 2677 if (!msg)
4c476991 2678 return -ENOMEM;
55682965 2679
15e47304 2680 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 2681 rdev, wdev, false) < 0) {
4c476991
JB
2682 nlmsg_free(msg);
2683 return -ENOBUFS;
2684 }
55682965 2685
134e6375 2686 return genlmsg_reply(msg, info);
55682965
JB
2687}
2688
66f7ac50
MW
2689static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
2690 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
2691 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
2692 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
2693 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
2694 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 2695 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
2696};
2697
2698static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
2699{
2700 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
2701 int flag;
2702
2703 *mntrflags = 0;
2704
2705 if (!nla)
2706 return -EINVAL;
2707
2708 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
2709 nla, mntr_flags_policy))
2710 return -EINVAL;
2711
2712 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
2713 if (flags[flag])
2714 *mntrflags |= (1<<flag);
2715
2716 return 0;
2717}
2718
9bc383de 2719static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
2720 struct net_device *netdev, u8 use_4addr,
2721 enum nl80211_iftype iftype)
9bc383de 2722{
ad4bb6f8 2723 if (!use_4addr) {
f350a0a8 2724 if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT))
ad4bb6f8 2725 return -EBUSY;
9bc383de 2726 return 0;
ad4bb6f8 2727 }
9bc383de
JB
2728
2729 switch (iftype) {
2730 case NL80211_IFTYPE_AP_VLAN:
2731 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
2732 return 0;
2733 break;
2734 case NL80211_IFTYPE_STATION:
2735 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
2736 return 0;
2737 break;
2738 default:
2739 break;
2740 }
2741
2742 return -EOPNOTSUPP;
2743}
2744
55682965
JB
2745static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
2746{
4c476991 2747 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2748 struct vif_params params;
e36d56b6 2749 int err;
04a773ad 2750 enum nl80211_iftype otype, ntype;
4c476991 2751 struct net_device *dev = info->user_ptr[1];
92ffe055 2752 u32 _flags, *flags = NULL;
ac7f9cfa 2753 bool change = false;
55682965 2754
2ec600d6
LCC
2755 memset(&params, 0, sizeof(params));
2756
04a773ad 2757 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 2758
723b038d 2759 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 2760 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 2761 if (otype != ntype)
ac7f9cfa 2762 change = true;
4c476991
JB
2763 if (ntype > NL80211_IFTYPE_MAX)
2764 return -EINVAL;
723b038d
JB
2765 }
2766
92ffe055 2767 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
2768 struct wireless_dev *wdev = dev->ieee80211_ptr;
2769
4c476991
JB
2770 if (ntype != NL80211_IFTYPE_MESH_POINT)
2771 return -EINVAL;
29cbe68c
JB
2772 if (netif_running(dev))
2773 return -EBUSY;
2774
2775 wdev_lock(wdev);
2776 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2777 IEEE80211_MAX_MESH_ID_LEN);
2778 wdev->mesh_id_up_len =
2779 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2780 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
2781 wdev->mesh_id_up_len);
2782 wdev_unlock(wdev);
2ec600d6
LCC
2783 }
2784
8b787643
FF
2785 if (info->attrs[NL80211_ATTR_4ADDR]) {
2786 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
2787 change = true;
ad4bb6f8 2788 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 2789 if (err)
4c476991 2790 return err;
8b787643
FF
2791 } else {
2792 params.use_4addr = -1;
2793 }
2794
92ffe055 2795 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
4c476991
JB
2796 if (ntype != NL80211_IFTYPE_MONITOR)
2797 return -EINVAL;
92ffe055
JB
2798 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
2799 &_flags);
ac7f9cfa 2800 if (err)
4c476991 2801 return err;
ac7f9cfa
JB
2802
2803 flags = &_flags;
2804 change = true;
92ffe055 2805 }
3b85875a 2806
c6e6a0c8
AE
2807 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
2808 const u8 *mumimo_groups;
2809 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2810
2811 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2812 return -EOPNOTSUPP;
2813
2814 mumimo_groups =
2815 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
2816
2817 /* bits 0 and 63 are reserved and must be zero */
2818 if ((mumimo_groups[0] & BIT(7)) ||
2819 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(0)))
2820 return -EINVAL;
2821
2822 memcpy(params.vht_mumimo_groups, mumimo_groups,
2823 VHT_MUMIMO_GROUPS_DATA_LEN);
2824 change = true;
2825 }
2826
2827 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
2828 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2829
2830 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2831 return -EOPNOTSUPP;
2832
2833 nla_memcpy(params.macaddr,
2834 info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR],
2835 ETH_ALEN);
2836 change = true;
2837 }
2838
18003297 2839 if (flags && (*flags & MONITOR_FLAG_ACTIVE) &&
e057d3c3
FF
2840 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2841 return -EOPNOTSUPP;
2842
ac7f9cfa 2843 if (change)
3d54d255 2844 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
ac7f9cfa
JB
2845 else
2846 err = 0;
60719ffd 2847
9bc383de
JB
2848 if (!err && params.use_4addr != -1)
2849 dev->ieee80211_ptr->use_4addr = params.use_4addr;
2850
55682965
JB
2851 return err;
2852}
2853
2854static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2855{
4c476991 2856 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2857 struct vif_params params;
84efbb84 2858 struct wireless_dev *wdev;
896ff063 2859 struct sk_buff *msg;
55682965
JB
2860 int err;
2861 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
66f7ac50 2862 u32 flags;
55682965 2863
78f22b6a
JB
2864 /* to avoid failing a new interface creation due to pending removal */
2865 cfg80211_destroy_ifaces(rdev);
2866
2ec600d6
LCC
2867 memset(&params, 0, sizeof(params));
2868
55682965
JB
2869 if (!info->attrs[NL80211_ATTR_IFNAME])
2870 return -EINVAL;
2871
2872 if (info->attrs[NL80211_ATTR_IFTYPE]) {
2873 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
2874 if (type > NL80211_IFTYPE_MAX)
2875 return -EINVAL;
2876 }
2877
79c97e97 2878 if (!rdev->ops->add_virtual_intf ||
4c476991
JB
2879 !(rdev->wiphy.interface_modes & (1 << type)))
2880 return -EOPNOTSUPP;
55682965 2881
cb3b7d87 2882 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
2883 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
2884 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
2885 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
2886 ETH_ALEN);
2887 if (!is_valid_ether_addr(params.macaddr))
2888 return -EADDRNOTAVAIL;
2889 }
2890
9bc383de 2891 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 2892 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 2893 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 2894 if (err)
4c476991 2895 return err;
9bc383de 2896 }
8b787643 2897
66f7ac50
MW
2898 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
2899 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
2900 &flags);
e057d3c3 2901
18003297 2902 if (!err && (flags & MONITOR_FLAG_ACTIVE) &&
e057d3c3
FF
2903 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2904 return -EOPNOTSUPP;
2905
a18c7192
JB
2906 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2907 if (!msg)
2908 return -ENOMEM;
2909
e35e4d28
HG
2910 wdev = rdev_add_virtual_intf(rdev,
2911 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
6bab2e19
TG
2912 NET_NAME_USER, type, err ? NULL : &flags,
2913 &params);
d687cbb7
RM
2914 if (WARN_ON(!wdev)) {
2915 nlmsg_free(msg);
2916 return -EPROTO;
2917 } else if (IS_ERR(wdev)) {
1c90f9d4 2918 nlmsg_free(msg);
84efbb84 2919 return PTR_ERR(wdev);
1c90f9d4 2920 }
2ec600d6 2921
18e5ca65 2922 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
2923 wdev->owner_nlportid = info->snd_portid;
2924
98104fde
JB
2925 switch (type) {
2926 case NL80211_IFTYPE_MESH_POINT:
2927 if (!info->attrs[NL80211_ATTR_MESH_ID])
2928 break;
29cbe68c
JB
2929 wdev_lock(wdev);
2930 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2931 IEEE80211_MAX_MESH_ID_LEN);
2932 wdev->mesh_id_up_len =
2933 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2934 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
2935 wdev->mesh_id_up_len);
2936 wdev_unlock(wdev);
98104fde 2937 break;
cb3b7d87 2938 case NL80211_IFTYPE_NAN:
98104fde
JB
2939 case NL80211_IFTYPE_P2P_DEVICE:
2940 /*
cb3b7d87 2941 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
2942 * through the netdev notifier and must be added here
2943 */
2944 mutex_init(&wdev->mtx);
2945 INIT_LIST_HEAD(&wdev->event_list);
2946 spin_lock_init(&wdev->event_lock);
2947 INIT_LIST_HEAD(&wdev->mgmt_registrations);
2948 spin_lock_init(&wdev->mgmt_registrations_lock);
2949
98104fde 2950 wdev->identifier = ++rdev->wdev_id;
53873f13 2951 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
98104fde 2952 rdev->devlist_generation++;
98104fde
JB
2953 break;
2954 default:
2955 break;
29cbe68c
JB
2956 }
2957
15e47304 2958 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 2959 rdev, wdev, false) < 0) {
1c90f9d4
JB
2960 nlmsg_free(msg);
2961 return -ENOBUFS;
2962 }
2963
896ff063
DK
2964 /*
2965 * For wdevs which have no associated netdev object (e.g. of type
2966 * NL80211_IFTYPE_P2P_DEVICE), emit the NEW_INTERFACE event here.
2967 * For all other types, the event will be generated from the
2968 * netdev notifier
2969 */
2970 if (!wdev->netdev)
2971 nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
8f894be2 2972
1c90f9d4 2973 return genlmsg_reply(msg, info);
55682965
JB
2974}
2975
2976static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
2977{
4c476991 2978 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 2979 struct wireless_dev *wdev = info->user_ptr[1];
55682965 2980
4c476991
JB
2981 if (!rdev->ops->del_virtual_intf)
2982 return -EOPNOTSUPP;
55682965 2983
84efbb84
JB
2984 /*
2985 * If we remove a wireless device without a netdev then clear
2986 * user_ptr[1] so that nl80211_post_doit won't dereference it
2987 * to check if it needs to do dev_put(). Otherwise it crashes
2988 * since the wdev has been freed, unlike with a netdev where
2989 * we need the dev_put() for the netdev to really be freed.
2990 */
2991 if (!wdev->netdev)
2992 info->user_ptr[1] = NULL;
2993
7f8ed01e 2994 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
2995}
2996
1d9d9213
SW
2997static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
2998{
2999 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3000 struct net_device *dev = info->user_ptr[1];
3001 u16 noack_map;
3002
3003 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
3004 return -EINVAL;
3005
3006 if (!rdev->ops->set_noack_map)
3007 return -EOPNOTSUPP;
3008
3009 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
3010
e35e4d28 3011 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
3012}
3013
41ade00f
JB
3014struct get_key_cookie {
3015 struct sk_buff *msg;
3016 int error;
b9454e83 3017 int idx;
41ade00f
JB
3018};
3019
3020static void get_key_callback(void *c, struct key_params *params)
3021{
b9454e83 3022 struct nlattr *key;
41ade00f
JB
3023 struct get_key_cookie *cookie = c;
3024
9360ffd1
DM
3025 if ((params->key &&
3026 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
3027 params->key_len, params->key)) ||
3028 (params->seq &&
3029 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
3030 params->seq_len, params->seq)) ||
3031 (params->cipher &&
3032 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
3033 params->cipher)))
3034 goto nla_put_failure;
41ade00f 3035
b9454e83
JB
3036 key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
3037 if (!key)
3038 goto nla_put_failure;
3039
9360ffd1
DM
3040 if ((params->key &&
3041 nla_put(cookie->msg, NL80211_KEY_DATA,
3042 params->key_len, params->key)) ||
3043 (params->seq &&
3044 nla_put(cookie->msg, NL80211_KEY_SEQ,
3045 params->seq_len, params->seq)) ||
3046 (params->cipher &&
3047 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
3048 params->cipher)))
3049 goto nla_put_failure;
b9454e83 3050
9360ffd1
DM
3051 if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx))
3052 goto nla_put_failure;
b9454e83
JB
3053
3054 nla_nest_end(cookie->msg, key);
3055
41ade00f
JB
3056 return;
3057 nla_put_failure:
3058 cookie->error = 1;
3059}
3060
3061static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
3062{
4c476991 3063 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3064 int err;
4c476991 3065 struct net_device *dev = info->user_ptr[1];
41ade00f 3066 u8 key_idx = 0;
e31b8213
JB
3067 const u8 *mac_addr = NULL;
3068 bool pairwise;
41ade00f
JB
3069 struct get_key_cookie cookie = {
3070 .error = 0,
3071 };
3072 void *hdr;
3073 struct sk_buff *msg;
3074
3075 if (info->attrs[NL80211_ATTR_KEY_IDX])
3076 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
3077
3cfcf6ac 3078 if (key_idx > 5)
41ade00f
JB
3079 return -EINVAL;
3080
3081 if (info->attrs[NL80211_ATTR_MAC])
3082 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3083
e31b8213
JB
3084 pairwise = !!mac_addr;
3085 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
3086 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 3087
e31b8213
JB
3088 if (kt >= NUM_NL80211_KEYTYPES)
3089 return -EINVAL;
3090 if (kt != NL80211_KEYTYPE_GROUP &&
3091 kt != NL80211_KEYTYPE_PAIRWISE)
3092 return -EINVAL;
3093 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
3094 }
3095
4c476991
JB
3096 if (!rdev->ops->get_key)
3097 return -EOPNOTSUPP;
41ade00f 3098
0fa7b391
JB
3099 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3100 return -ENOENT;
3101
fd2120ca 3102 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
3103 if (!msg)
3104 return -ENOMEM;
41ade00f 3105
15e47304 3106 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 3107 NL80211_CMD_NEW_KEY);
cb35fba3 3108 if (!hdr)
9fe271af 3109 goto nla_put_failure;
41ade00f
JB
3110
3111 cookie.msg = msg;
b9454e83 3112 cookie.idx = key_idx;
41ade00f 3113
9360ffd1
DM
3114 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3115 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
3116 goto nla_put_failure;
3117 if (mac_addr &&
3118 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
3119 goto nla_put_failure;
41ade00f 3120
e35e4d28
HG
3121 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
3122 get_key_callback);
41ade00f
JB
3123
3124 if (err)
6c95e2a2 3125 goto free_msg;
41ade00f
JB
3126
3127 if (cookie.error)
3128 goto nla_put_failure;
3129
3130 genlmsg_end(msg, hdr);
4c476991 3131 return genlmsg_reply(msg, info);
41ade00f
JB
3132
3133 nla_put_failure:
3134 err = -ENOBUFS;
6c95e2a2 3135 free_msg:
41ade00f 3136 nlmsg_free(msg);
41ade00f
JB
3137 return err;
3138}
3139
3140static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
3141{
4c476991 3142 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 3143 struct key_parse key;
41ade00f 3144 int err;
4c476991 3145 struct net_device *dev = info->user_ptr[1];
41ade00f 3146
b9454e83
JB
3147 err = nl80211_parse_key(info, &key);
3148 if (err)
3149 return err;
41ade00f 3150
b9454e83 3151 if (key.idx < 0)
41ade00f
JB
3152 return -EINVAL;
3153
b9454e83
JB
3154 /* only support setting default key */
3155 if (!key.def && !key.defmgmt)
41ade00f
JB
3156 return -EINVAL;
3157
dbd2fd65 3158 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 3159
dbd2fd65
JB
3160 if (key.def) {
3161 if (!rdev->ops->set_default_key) {
3162 err = -EOPNOTSUPP;
3163 goto out;
3164 }
41ade00f 3165
dbd2fd65
JB
3166 err = nl80211_key_allowed(dev->ieee80211_ptr);
3167 if (err)
3168 goto out;
3169
e35e4d28 3170 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
3171 key.def_uni, key.def_multi);
3172
3173 if (err)
3174 goto out;
fffd0934 3175
3d23e349 3176#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
3177 dev->ieee80211_ptr->wext.default_key = key.idx;
3178#endif
3179 } else {
3180 if (key.def_uni || !key.def_multi) {
3181 err = -EINVAL;
3182 goto out;
3183 }
3184
3185 if (!rdev->ops->set_default_mgmt_key) {
3186 err = -EOPNOTSUPP;
3187 goto out;
3188 }
3189
3190 err = nl80211_key_allowed(dev->ieee80211_ptr);
3191 if (err)
3192 goto out;
3193
e35e4d28 3194 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
3195 if (err)
3196 goto out;
3197
3198#ifdef CONFIG_CFG80211_WEXT
3199 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 3200#endif
dbd2fd65
JB
3201 }
3202
3203 out:
fffd0934 3204 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3205
41ade00f
JB
3206 return err;
3207}
3208
3209static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
3210{
4c476991 3211 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 3212 int err;
4c476991 3213 struct net_device *dev = info->user_ptr[1];
b9454e83 3214 struct key_parse key;
e31b8213 3215 const u8 *mac_addr = NULL;
41ade00f 3216
b9454e83
JB
3217 err = nl80211_parse_key(info, &key);
3218 if (err)
3219 return err;
41ade00f 3220
b9454e83 3221 if (!key.p.key)
41ade00f
JB
3222 return -EINVAL;
3223
41ade00f
JB
3224 if (info->attrs[NL80211_ATTR_MAC])
3225 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3226
e31b8213
JB
3227 if (key.type == -1) {
3228 if (mac_addr)
3229 key.type = NL80211_KEYTYPE_PAIRWISE;
3230 else
3231 key.type = NL80211_KEYTYPE_GROUP;
3232 }
3233
3234 /* for now */
3235 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3236 key.type != NL80211_KEYTYPE_GROUP)
3237 return -EINVAL;
3238
4c476991
JB
3239 if (!rdev->ops->add_key)
3240 return -EOPNOTSUPP;
25e47c18 3241
e31b8213
JB
3242 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
3243 key.type == NL80211_KEYTYPE_PAIRWISE,
3244 mac_addr))
4c476991 3245 return -EINVAL;
41ade00f 3246
fffd0934
JB
3247 wdev_lock(dev->ieee80211_ptr);
3248 err = nl80211_key_allowed(dev->ieee80211_ptr);
3249 if (!err)
e35e4d28
HG
3250 err = rdev_add_key(rdev, dev, key.idx,
3251 key.type == NL80211_KEYTYPE_PAIRWISE,
3252 mac_addr, &key.p);
fffd0934 3253 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3254
41ade00f
JB
3255 return err;
3256}
3257
3258static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
3259{
4c476991 3260 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3261 int err;
4c476991 3262 struct net_device *dev = info->user_ptr[1];
41ade00f 3263 u8 *mac_addr = NULL;
b9454e83 3264 struct key_parse key;
41ade00f 3265
b9454e83
JB
3266 err = nl80211_parse_key(info, &key);
3267 if (err)
3268 return err;
41ade00f
JB
3269
3270 if (info->attrs[NL80211_ATTR_MAC])
3271 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3272
e31b8213
JB
3273 if (key.type == -1) {
3274 if (mac_addr)
3275 key.type = NL80211_KEYTYPE_PAIRWISE;
3276 else
3277 key.type = NL80211_KEYTYPE_GROUP;
3278 }
3279
3280 /* for now */
3281 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3282 key.type != NL80211_KEYTYPE_GROUP)
3283 return -EINVAL;
3284
4c476991
JB
3285 if (!rdev->ops->del_key)
3286 return -EOPNOTSUPP;
41ade00f 3287
fffd0934
JB
3288 wdev_lock(dev->ieee80211_ptr);
3289 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 3290
0fa7b391 3291 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
3292 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3293 err = -ENOENT;
3294
fffd0934 3295 if (!err)
e35e4d28
HG
3296 err = rdev_del_key(rdev, dev, key.idx,
3297 key.type == NL80211_KEYTYPE_PAIRWISE,
3298 mac_addr);
41ade00f 3299
3d23e349 3300#ifdef CONFIG_CFG80211_WEXT
08645126 3301 if (!err) {
b9454e83 3302 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 3303 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 3304 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
3305 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
3306 }
3307#endif
fffd0934 3308 wdev_unlock(dev->ieee80211_ptr);
08645126 3309
41ade00f
JB
3310 return err;
3311}
3312
77765eaf
VT
3313/* This function returns an error or the number of nested attributes */
3314static int validate_acl_mac_addrs(struct nlattr *nl_attr)
3315{
3316 struct nlattr *attr;
3317 int n_entries = 0, tmp;
3318
3319 nla_for_each_nested(attr, nl_attr, tmp) {
3320 if (nla_len(attr) != ETH_ALEN)
3321 return -EINVAL;
3322
3323 n_entries++;
3324 }
3325
3326 return n_entries;
3327}
3328
3329/*
3330 * This function parses ACL information and allocates memory for ACL data.
3331 * On successful return, the calling function is responsible to free the
3332 * ACL buffer returned by this function.
3333 */
3334static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
3335 struct genl_info *info)
3336{
3337 enum nl80211_acl_policy acl_policy;
3338 struct nlattr *attr;
3339 struct cfg80211_acl_data *acl;
3340 int i = 0, n_entries, tmp;
3341
3342 if (!wiphy->max_acl_mac_addrs)
3343 return ERR_PTR(-EOPNOTSUPP);
3344
3345 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
3346 return ERR_PTR(-EINVAL);
3347
3348 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
3349 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
3350 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
3351 return ERR_PTR(-EINVAL);
3352
3353 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
3354 return ERR_PTR(-EINVAL);
3355
3356 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
3357 if (n_entries < 0)
3358 return ERR_PTR(n_entries);
3359
3360 if (n_entries > wiphy->max_acl_mac_addrs)
3361 return ERR_PTR(-ENOTSUPP);
3362
3363 acl = kzalloc(sizeof(*acl) + (sizeof(struct mac_address) * n_entries),
3364 GFP_KERNEL);
3365 if (!acl)
3366 return ERR_PTR(-ENOMEM);
3367
3368 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
3369 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
3370 i++;
3371 }
3372
3373 acl->n_acl_entries = n_entries;
3374 acl->acl_policy = acl_policy;
3375
3376 return acl;
3377}
3378
3379static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
3380{
3381 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3382 struct net_device *dev = info->user_ptr[1];
3383 struct cfg80211_acl_data *acl;
3384 int err;
3385
3386 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3387 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3388 return -EOPNOTSUPP;
3389
3390 if (!dev->ieee80211_ptr->beacon_interval)
3391 return -EINVAL;
3392
3393 acl = parse_acl_data(&rdev->wiphy, info);
3394 if (IS_ERR(acl))
3395 return PTR_ERR(acl);
3396
3397 err = rdev_set_mac_acl(rdev, dev, acl);
3398
3399 kfree(acl);
3400
3401 return err;
3402}
3403
a7c7fbff
PK
3404static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
3405 u8 *rates, u8 rates_len)
3406{
3407 u8 i;
3408 u32 mask = 0;
3409
3410 for (i = 0; i < rates_len; i++) {
3411 int rate = (rates[i] & 0x7f) * 5;
3412 int ridx;
3413
3414 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
3415 struct ieee80211_rate *srate =
3416 &sband->bitrates[ridx];
3417 if (rate == srate->bitrate) {
3418 mask |= 1 << ridx;
3419 break;
3420 }
3421 }
3422 if (ridx == sband->n_bitrates)
3423 return 0; /* rate not found */
3424 }
3425
3426 return mask;
3427}
3428
3429static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
3430 u8 *rates, u8 rates_len,
3431 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
3432{
3433 u8 i;
3434
3435 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
3436
3437 for (i = 0; i < rates_len; i++) {
3438 int ridx, rbit;
3439
3440 ridx = rates[i] / 8;
3441 rbit = BIT(rates[i] % 8);
3442
3443 /* check validity */
3444 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
3445 return false;
3446
3447 /* check availability */
3448 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
3449 mcs[ridx] |= rbit;
3450 else
3451 return false;
3452 }
3453
3454 return true;
3455}
3456
3457static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
3458{
3459 u16 mcs_mask = 0;
3460
3461 switch (vht_mcs_map) {
3462 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
3463 break;
3464 case IEEE80211_VHT_MCS_SUPPORT_0_7:
3465 mcs_mask = 0x00FF;
3466 break;
3467 case IEEE80211_VHT_MCS_SUPPORT_0_8:
3468 mcs_mask = 0x01FF;
3469 break;
3470 case IEEE80211_VHT_MCS_SUPPORT_0_9:
3471 mcs_mask = 0x03FF;
3472 break;
3473 default:
3474 break;
3475 }
3476
3477 return mcs_mask;
3478}
3479
3480static void vht_build_mcs_mask(u16 vht_mcs_map,
3481 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
3482{
3483 u8 nss;
3484
3485 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
3486 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
3487 vht_mcs_map >>= 2;
3488 }
3489}
3490
3491static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
3492 struct nl80211_txrate_vht *txrate,
3493 u16 mcs[NL80211_VHT_NSS_MAX])
3494{
3495 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3496 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
3497 u8 i;
3498
3499 if (!sband->vht_cap.vht_supported)
3500 return false;
3501
3502 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
3503
3504 /* Build vht_mcs_mask from VHT capabilities */
3505 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
3506
3507 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
3508 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
3509 mcs[i] = txrate->mcs[i];
3510 else
3511 return false;
3512 }
3513
3514 return true;
3515}
3516
3517static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
3518 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
3519 .len = NL80211_MAX_SUPP_RATES },
3520 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
3521 .len = NL80211_MAX_SUPP_HT_RATES },
3522 [NL80211_TXRATE_VHT] = { .len = sizeof(struct nl80211_txrate_vht)},
3523 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
3524};
3525
3526static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
3527 struct cfg80211_bitrate_mask *mask)
3528{
3529 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
3530 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3531 int rem, i;
3532 struct nlattr *tx_rates;
3533 struct ieee80211_supported_band *sband;
3534 u16 vht_tx_mcs_map;
3535
3536 memset(mask, 0, sizeof(*mask));
3537 /* Default to all rates enabled */
3538 for (i = 0; i < NUM_NL80211_BANDS; i++) {
3539 sband = rdev->wiphy.bands[i];
3540
3541 if (!sband)
3542 continue;
3543
3544 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
3545 memcpy(mask->control[i].ht_mcs,
3546 sband->ht_cap.mcs.rx_mask,
3547 sizeof(mask->control[i].ht_mcs));
3548
3549 if (!sband->vht_cap.vht_supported)
3550 continue;
3551
3552 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3553 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
3554 }
3555
3556 /* if no rates are given set it back to the defaults */
3557 if (!info->attrs[NL80211_ATTR_TX_RATES])
3558 goto out;
3559
3560 /* The nested attribute uses enum nl80211_band as the index. This maps
3561 * directly to the enum nl80211_band values used in cfg80211.
3562 */
3563 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
3564 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
3565 enum nl80211_band band = nla_type(tx_rates);
3566 int err;
3567
3568 if (band < 0 || band >= NUM_NL80211_BANDS)
3569 return -EINVAL;
3570 sband = rdev->wiphy.bands[band];
3571 if (sband == NULL)
3572 return -EINVAL;
bfe2c7b1
JB
3573 err = nla_parse_nested(tb, NL80211_TXRATE_MAX, tx_rates,
3574 nl80211_txattr_policy);
a7c7fbff
PK
3575 if (err)
3576 return err;
3577 if (tb[NL80211_TXRATE_LEGACY]) {
3578 mask->control[band].legacy = rateset_to_mask(
3579 sband,
3580 nla_data(tb[NL80211_TXRATE_LEGACY]),
3581 nla_len(tb[NL80211_TXRATE_LEGACY]));
3582 if ((mask->control[band].legacy == 0) &&
3583 nla_len(tb[NL80211_TXRATE_LEGACY]))
3584 return -EINVAL;
3585 }
3586 if (tb[NL80211_TXRATE_HT]) {
3587 if (!ht_rateset_to_mask(
3588 sband,
3589 nla_data(tb[NL80211_TXRATE_HT]),
3590 nla_len(tb[NL80211_TXRATE_HT]),
3591 mask->control[band].ht_mcs))
3592 return -EINVAL;
3593 }
3594 if (tb[NL80211_TXRATE_VHT]) {
3595 if (!vht_set_mcs_mask(
3596 sband,
3597 nla_data(tb[NL80211_TXRATE_VHT]),
3598 mask->control[band].vht_mcs))
3599 return -EINVAL;
3600 }
3601 if (tb[NL80211_TXRATE_GI]) {
3602 mask->control[band].gi =
3603 nla_get_u8(tb[NL80211_TXRATE_GI]);
3604 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
3605 return -EINVAL;
3606 }
3607
3608 if (mask->control[band].legacy == 0) {
3609 /* don't allow empty legacy rates if HT or VHT
3610 * are not even supported.
3611 */
3612 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
3613 rdev->wiphy.bands[band]->vht_cap.vht_supported))
3614 return -EINVAL;
3615
3616 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
3617 if (mask->control[band].ht_mcs[i])
3618 goto out;
3619
3620 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
3621 if (mask->control[band].vht_mcs[i])
3622 goto out;
3623
3624 /* legacy and mcs rates may not be both empty */
3625 return -EINVAL;
3626 }
3627 }
3628
3629out:
3630 return 0;
3631}
3632
8564e382
JB
3633static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
3634 enum nl80211_band band,
3635 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 3636{
8564e382
JB
3637 u32 count_ht, count_vht, i;
3638 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
3639
3640 /* Allow only one rate */
3641 if (hweight32(rate) > 1)
3642 return -EINVAL;
3643
3644 count_ht = 0;
3645 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 3646 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 3647 return -EINVAL;
8564e382 3648 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
3649 count_ht++;
3650 if (count_ht > 1)
3651 return -EINVAL;
3652 }
3653 if (count_ht && rate)
3654 return -EINVAL;
3655 }
3656
3657 count_vht = 0;
3658 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 3659 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 3660 return -EINVAL;
8564e382 3661 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
3662 count_vht++;
3663 if (count_vht > 1)
3664 return -EINVAL;
3665 }
3666 if (count_vht && rate)
3667 return -EINVAL;
3668 }
3669
3670 if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht))
3671 return -EINVAL;
3672
8564e382
JB
3673 if (rate &&
3674 !wiphy_ext_feature_isset(&rdev->wiphy,
3675 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
3676 return -EINVAL;
3677 if (count_ht &&
3678 !wiphy_ext_feature_isset(&rdev->wiphy,
3679 NL80211_EXT_FEATURE_BEACON_RATE_HT))
3680 return -EINVAL;
3681 if (count_vht &&
3682 !wiphy_ext_feature_isset(&rdev->wiphy,
3683 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
3684 return -EINVAL;
3685
a7c7fbff
PK
3686 return 0;
3687}
3688
a1193be8 3689static int nl80211_parse_beacon(struct nlattr *attrs[],
8860020e 3690 struct cfg80211_beacon_data *bcn)
ed1b6cc7 3691{
8860020e 3692 bool haveinfo = false;
ed1b6cc7 3693
a1193be8
SW
3694 if (!is_valid_ie_attr(attrs[NL80211_ATTR_BEACON_TAIL]) ||
3695 !is_valid_ie_attr(attrs[NL80211_ATTR_IE]) ||
3696 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
3697 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_ASSOC_RESP]))
f4a11bb0
JB
3698 return -EINVAL;
3699
8860020e 3700 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 3701
a1193be8
SW
3702 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
3703 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
3704 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
3705 if (!bcn->head_len)
3706 return -EINVAL;
3707 haveinfo = true;
ed1b6cc7
JB
3708 }
3709
a1193be8
SW
3710 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
3711 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
3712 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 3713 haveinfo = true;
ed1b6cc7
JB
3714 }
3715
4c476991
JB
3716 if (!haveinfo)
3717 return -EINVAL;
3b85875a 3718
a1193be8
SW
3719 if (attrs[NL80211_ATTR_IE]) {
3720 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
3721 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
3722 }
3723
a1193be8 3724 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 3725 bcn->proberesp_ies =
a1193be8 3726 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 3727 bcn->proberesp_ies_len =
a1193be8 3728 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
3729 }
3730
a1193be8 3731 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 3732 bcn->assocresp_ies =
a1193be8 3733 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 3734 bcn->assocresp_ies_len =
a1193be8 3735 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
3736 }
3737
a1193be8
SW
3738 if (attrs[NL80211_ATTR_PROBE_RESP]) {
3739 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
3740 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
3741 }
3742
8860020e
JB
3743 return 0;
3744}
3745
46c1dd0c
FF
3746static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3747 struct cfg80211_ap_settings *params)
3748{
3749 struct wireless_dev *wdev;
3750 bool ret = false;
3751
53873f13 3752 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
3753 if (wdev->iftype != NL80211_IFTYPE_AP &&
3754 wdev->iftype != NL80211_IFTYPE_P2P_GO)
3755 continue;
3756
683b6d3b 3757 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
3758 continue;
3759
683b6d3b 3760 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
3761 ret = true;
3762 break;
3763 }
3764
46c1dd0c
FF
3765 return ret;
3766}
3767
e39e5b5e
JM
3768static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
3769 enum nl80211_auth_type auth_type,
3770 enum nl80211_commands cmd)
3771{
3772 if (auth_type > NL80211_AUTHTYPE_MAX)
3773 return false;
3774
3775 switch (cmd) {
3776 case NL80211_CMD_AUTHENTICATE:
3777 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
3778 auth_type == NL80211_AUTHTYPE_SAE)
3779 return false;
63181060
JM
3780 if (!wiphy_ext_feature_isset(&rdev->wiphy,
3781 NL80211_EXT_FEATURE_FILS_STA) &&
3782 (auth_type == NL80211_AUTHTYPE_FILS_SK ||
3783 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
3784 auth_type == NL80211_AUTHTYPE_FILS_PK))
3785 return false;
e39e5b5e
JM
3786 return true;
3787 case NL80211_CMD_CONNECT:
3788 case NL80211_CMD_START_AP:
3789 /* SAE not supported yet */
3790 if (auth_type == NL80211_AUTHTYPE_SAE)
3791 return false;
63181060
JM
3792 /* FILS not supported yet */
3793 if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
3794 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
3795 auth_type == NL80211_AUTHTYPE_FILS_PK)
3796 return false;
e39e5b5e
JM
3797 return true;
3798 default:
3799 return false;
3800 }
3801}
3802
8860020e
JB
3803static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3804{
3805 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3806 struct net_device *dev = info->user_ptr[1];
3807 struct wireless_dev *wdev = dev->ieee80211_ptr;
3808 struct cfg80211_ap_settings params;
3809 int err;
3810
3811 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3812 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3813 return -EOPNOTSUPP;
3814
3815 if (!rdev->ops->start_ap)
3816 return -EOPNOTSUPP;
3817
3818 if (wdev->beacon_interval)
3819 return -EALREADY;
3820
3821 memset(&params, 0, sizeof(params));
3822
3823 /* these are required for START_AP */
3824 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
3825 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
3826 !info->attrs[NL80211_ATTR_BEACON_HEAD])
3827 return -EINVAL;
3828
a1193be8 3829 err = nl80211_parse_beacon(info->attrs, &params.beacon);
8860020e
JB
3830 if (err)
3831 return err;
3832
3833 params.beacon_interval =
3834 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3835 params.dtim_period =
3836 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
3837
0c317a02
PK
3838 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
3839 params.beacon_interval);
8860020e
JB
3840 if (err)
3841 return err;
3842
3843 /*
3844 * In theory, some of these attributes should be required here
3845 * but since they were not used when the command was originally
3846 * added, keep them optional for old user space programs to let
3847 * them continue to work with drivers that do not need the
3848 * additional information -- drivers must check!
3849 */
3850 if (info->attrs[NL80211_ATTR_SSID]) {
3851 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3852 params.ssid_len =
3853 nla_len(info->attrs[NL80211_ATTR_SSID]);
3854 if (params.ssid_len == 0 ||
3855 params.ssid_len > IEEE80211_MAX_SSID_LEN)
3856 return -EINVAL;
3857 }
3858
3859 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
3860 params.hidden_ssid = nla_get_u32(
3861 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
3862 if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
3863 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
3864 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
3865 return -EINVAL;
3866 }
3867
3868 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
3869
3870 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
3871 params.auth_type = nla_get_u32(
3872 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
3873 if (!nl80211_valid_auth_type(rdev, params.auth_type,
3874 NL80211_CMD_START_AP))
8860020e
JB
3875 return -EINVAL;
3876 } else
3877 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
3878
3879 err = nl80211_crypto_settings(rdev, info, &params.crypto,
3880 NL80211_MAX_NR_CIPHER_SUITES);
3881 if (err)
3882 return err;
3883
1b658f11
VT
3884 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
3885 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
3886 return -EOPNOTSUPP;
3887 params.inactivity_timeout = nla_get_u16(
3888 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
3889 }
3890
53cabad7
JB
3891 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
3892 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3893 return -EINVAL;
3894 params.p2p_ctwindow =
3895 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
3896 if (params.p2p_ctwindow > 127)
3897 return -EINVAL;
3898 if (params.p2p_ctwindow != 0 &&
3899 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
3900 return -EINVAL;
3901 }
3902
3903 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
3904 u8 tmp;
3905
3906 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3907 return -EINVAL;
3908 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
3909 if (tmp > 1)
3910 return -EINVAL;
3911 params.p2p_opp_ps = tmp;
3912 if (params.p2p_opp_ps != 0 &&
3913 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
3914 return -EINVAL;
3915 }
3916
aa430da4 3917 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
3918 err = nl80211_parse_chandef(rdev, info, &params.chandef);
3919 if (err)
3920 return err;
3921 } else if (wdev->preset_chandef.chan) {
3922 params.chandef = wdev->preset_chandef;
46c1dd0c 3923 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
3924 return -EINVAL;
3925
923b352f
AN
3926 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
3927 wdev->iftype))
aa430da4
JB
3928 return -EINVAL;
3929
a7c7fbff
PK
3930 if (info->attrs[NL80211_ATTR_TX_RATES]) {
3931 err = nl80211_parse_tx_bitrate_mask(info, &params.beacon_rate);
3932 if (err)
3933 return err;
3934
8564e382
JB
3935 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
3936 &params.beacon_rate);
a7c7fbff
PK
3937 if (err)
3938 return err;
3939 }
3940
18998c38
EP
3941 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
3942 params.smps_mode =
3943 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
3944 switch (params.smps_mode) {
3945 case NL80211_SMPS_OFF:
3946 break;
3947 case NL80211_SMPS_STATIC:
3948 if (!(rdev->wiphy.features &
3949 NL80211_FEATURE_STATIC_SMPS))
3950 return -EINVAL;
3951 break;
3952 case NL80211_SMPS_DYNAMIC:
3953 if (!(rdev->wiphy.features &
3954 NL80211_FEATURE_DYNAMIC_SMPS))
3955 return -EINVAL;
3956 break;
3957 default:
3958 return -EINVAL;
3959 }
3960 } else {
3961 params.smps_mode = NL80211_SMPS_OFF;
3962 }
3963
6e8ef842
PK
3964 params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
3965 if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
3966 return -EOPNOTSUPP;
3967
4baf6bea
OO
3968 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
3969 params.acl = parse_acl_data(&rdev->wiphy, info);
3970 if (IS_ERR(params.acl))
3971 return PTR_ERR(params.acl);
3972 }
3973
c56589ed 3974 wdev_lock(wdev);
e35e4d28 3975 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 3976 if (!err) {
683b6d3b 3977 wdev->preset_chandef = params.chandef;
8860020e 3978 wdev->beacon_interval = params.beacon_interval;
9e0e2961 3979 wdev->chandef = params.chandef;
06e191e2
AQ
3980 wdev->ssid_len = params.ssid_len;
3981 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
46c1dd0c 3982 }
c56589ed 3983 wdev_unlock(wdev);
77765eaf
VT
3984
3985 kfree(params.acl);
3986
56d1893d 3987 return err;
ed1b6cc7
JB
3988}
3989
8860020e
JB
3990static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
3991{
3992 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3993 struct net_device *dev = info->user_ptr[1];
3994 struct wireless_dev *wdev = dev->ieee80211_ptr;
3995 struct cfg80211_beacon_data params;
3996 int err;
3997
3998 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3999 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4000 return -EOPNOTSUPP;
4001
4002 if (!rdev->ops->change_beacon)
4003 return -EOPNOTSUPP;
4004
4005 if (!wdev->beacon_interval)
4006 return -EINVAL;
4007
a1193be8 4008 err = nl80211_parse_beacon(info->attrs, &params);
8860020e
JB
4009 if (err)
4010 return err;
4011
c56589ed
SW
4012 wdev_lock(wdev);
4013 err = rdev_change_beacon(rdev, dev, &params);
4014 wdev_unlock(wdev);
4015
4016 return err;
8860020e
JB
4017}
4018
4019static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 4020{
4c476991
JB
4021 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4022 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 4023
7c8d5e03 4024 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
4025}
4026
5727ef1b
JB
4027static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
4028 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
4029 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
4030 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 4031 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 4032 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 4033 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
4034};
4035
eccb8e8f 4036static int parse_station_flags(struct genl_info *info,
bdd3ae3d 4037 enum nl80211_iftype iftype,
eccb8e8f 4038 struct station_parameters *params)
5727ef1b
JB
4039{
4040 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 4041 struct nlattr *nla;
5727ef1b
JB
4042 int flag;
4043
eccb8e8f
JB
4044 /*
4045 * Try parsing the new attribute first so userspace
4046 * can specify both for older kernels.
4047 */
4048 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
4049 if (nla) {
4050 struct nl80211_sta_flag_update *sta_flags;
4051
4052 sta_flags = nla_data(nla);
4053 params->sta_flags_mask = sta_flags->mask;
4054 params->sta_flags_set = sta_flags->set;
77ee7c89 4055 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
4056 if ((params->sta_flags_mask |
4057 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
4058 return -EINVAL;
4059 return 0;
4060 }
4061
4062 /* if present, parse the old attribute */
5727ef1b 4063
eccb8e8f 4064 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
4065 if (!nla)
4066 return 0;
4067
4068 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
4069 nla, sta_flags_policy))
4070 return -EINVAL;
4071
bdd3ae3d
JB
4072 /*
4073 * Only allow certain flags for interface types so that
4074 * other attributes are silently ignored. Remember that
4075 * this is backward compatibility code with old userspace
4076 * and shouldn't be hit in other cases anyway.
4077 */
4078 switch (iftype) {
4079 case NL80211_IFTYPE_AP:
4080 case NL80211_IFTYPE_AP_VLAN:
4081 case NL80211_IFTYPE_P2P_GO:
4082 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4083 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4084 BIT(NL80211_STA_FLAG_WME) |
4085 BIT(NL80211_STA_FLAG_MFP);
4086 break;
4087 case NL80211_IFTYPE_P2P_CLIENT:
4088 case NL80211_IFTYPE_STATION:
4089 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4090 BIT(NL80211_STA_FLAG_TDLS_PEER);
4091 break;
4092 case NL80211_IFTYPE_MESH_POINT:
4093 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4094 BIT(NL80211_STA_FLAG_MFP) |
4095 BIT(NL80211_STA_FLAG_AUTHORIZED);
4096 default:
4097 return -EINVAL;
4098 }
5727ef1b 4099
3383b5a6
JB
4100 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
4101 if (flags[flag]) {
eccb8e8f 4102 params->sta_flags_set |= (1<<flag);
5727ef1b 4103
3383b5a6
JB
4104 /* no longer support new API additions in old API */
4105 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
4106 return -EINVAL;
4107 }
4108 }
4109
5727ef1b
JB
4110 return 0;
4111}
4112
c8dcfd8a
FF
4113static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
4114 int attr)
4115{
4116 struct nlattr *rate;
8eb41c8d
VK
4117 u32 bitrate;
4118 u16 bitrate_compat;
b51f3bee 4119 enum nl80211_attrs rate_flg;
c8dcfd8a
FF
4120
4121 rate = nla_nest_start(msg, attr);
4122 if (!rate)
db9c64cf 4123 return false;
c8dcfd8a
FF
4124
4125 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
4126 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
4127 /* report 16-bit bitrate only if we can */
4128 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
4129 if (bitrate > 0 &&
4130 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
4131 return false;
4132 if (bitrate_compat > 0 &&
4133 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
4134 return false;
4135
b51f3bee
JB
4136 switch (info->bw) {
4137 case RATE_INFO_BW_5:
4138 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
4139 break;
4140 case RATE_INFO_BW_10:
4141 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
4142 break;
4143 default:
4144 WARN_ON(1);
4145 /* fall through */
4146 case RATE_INFO_BW_20:
4147 rate_flg = 0;
4148 break;
4149 case RATE_INFO_BW_40:
4150 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
4151 break;
4152 case RATE_INFO_BW_80:
4153 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
4154 break;
4155 case RATE_INFO_BW_160:
4156 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
4157 break;
4158 }
4159
4160 if (rate_flg && nla_put_flag(msg, rate_flg))
4161 return false;
4162
db9c64cf
JB
4163 if (info->flags & RATE_INFO_FLAGS_MCS) {
4164 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
4165 return false;
db9c64cf
JB
4166 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4167 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4168 return false;
4169 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
4170 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
4171 return false;
4172 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
4173 return false;
db9c64cf
JB
4174 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4175 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4176 return false;
4177 }
c8dcfd8a
FF
4178
4179 nla_nest_end(msg, rate);
4180 return true;
c8dcfd8a
FF
4181}
4182
119363c7
FF
4183static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
4184 int id)
4185{
4186 void *attr;
4187 int i = 0;
4188
4189 if (!mask)
4190 return true;
4191
4192 attr = nla_nest_start(msg, id);
4193 if (!attr)
4194 return false;
4195
4196 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
4197 if (!(mask & BIT(i)))
4198 continue;
4199
4200 if (nla_put_u8(msg, i, signal[i]))
4201 return false;
4202 }
4203
4204 nla_nest_end(msg, attr);
4205
4206 return true;
4207}
4208
cf5ead82
JB
4209static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
4210 u32 seq, int flags,
66266b3a
JL
4211 struct cfg80211_registered_device *rdev,
4212 struct net_device *dev,
98b62183 4213 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
4214{
4215 void *hdr;
f4263c98 4216 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 4217
cf5ead82 4218 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
fd5b74dc
JB
4219 if (!hdr)
4220 return -1;
4221
9360ffd1
DM
4222 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4223 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
4224 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
4225 goto nla_put_failure;
f5ea9120 4226
2ec600d6
LCC
4227 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
4228 if (!sinfoattr)
fd5b74dc 4229 goto nla_put_failure;
319090bf
JB
4230
4231#define PUT_SINFO(attr, memb, type) do { \
d686b920 4232 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
739960f1 4233 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
319090bf
JB
4234 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
4235 sinfo->memb)) \
4236 goto nla_put_failure; \
4237 } while (0)
d686b920
JB
4238#define PUT_SINFO_U64(attr, memb) do { \
4239 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
4240 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
4241 sinfo->memb, NL80211_STA_INFO_PAD)) \
4242 goto nla_put_failure; \
4243 } while (0)
319090bf
JB
4244
4245 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
4246 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
4247
4248 if (sinfo->filled & (BIT(NL80211_STA_INFO_RX_BYTES) |
4249 BIT(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 4250 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 4251 (u32)sinfo->rx_bytes))
9360ffd1 4252 goto nla_put_failure;
319090bf
JB
4253
4254 if (sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES) |
4255 BIT(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 4256 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
4257 (u32)sinfo->tx_bytes))
4258 goto nla_put_failure;
319090bf 4259
d686b920
JB
4260 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
4261 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
4262 PUT_SINFO(LLID, llid, u16);
4263 PUT_SINFO(PLID, plid, u16);
4264 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 4265 PUT_SINFO_U64(RX_DURATION, rx_duration);
319090bf 4266
66266b3a
JL
4267 switch (rdev->wiphy.signal_type) {
4268 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
4269 PUT_SINFO(SIGNAL, signal, u8);
4270 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
4271 break;
4272 default:
4273 break;
4274 }
319090bf 4275 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
4276 if (!nl80211_put_signal(msg, sinfo->chains,
4277 sinfo->chain_signal,
4278 NL80211_STA_INFO_CHAIN_SIGNAL))
4279 goto nla_put_failure;
4280 }
319090bf 4281 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
4282 if (!nl80211_put_signal(msg, sinfo->chains,
4283 sinfo->chain_signal_avg,
4284 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
4285 goto nla_put_failure;
4286 }
319090bf 4287 if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
4288 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
4289 NL80211_STA_INFO_TX_BITRATE))
4290 goto nla_put_failure;
4291 }
319090bf 4292 if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
4293 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
4294 NL80211_STA_INFO_RX_BITRATE))
420e7fab 4295 goto nla_put_failure;
420e7fab 4296 }
319090bf
JB
4297
4298 PUT_SINFO(RX_PACKETS, rx_packets, u32);
4299 PUT_SINFO(TX_PACKETS, tx_packets, u32);
4300 PUT_SINFO(TX_RETRIES, tx_retries, u32);
4301 PUT_SINFO(TX_FAILED, tx_failed, u32);
4302 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
4303 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
4304 PUT_SINFO(LOCAL_PM, local_pm, u32);
4305 PUT_SINFO(PEER_PM, peer_pm, u32);
4306 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
4307
4308 if (sinfo->filled & BIT(NL80211_STA_INFO_BSS_PARAM)) {
f4263c98
PS
4309 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
4310 if (!bss_param)
4311 goto nla_put_failure;
4312
9360ffd1
DM
4313 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
4314 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
4315 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
4316 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
4317 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
4318 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
4319 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
4320 sinfo->bss_param.dtim_period) ||
4321 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
4322 sinfo->bss_param.beacon_interval))
4323 goto nla_put_failure;
f4263c98
PS
4324
4325 nla_nest_end(msg, bss_param);
4326 }
319090bf 4327 if ((sinfo->filled & BIT(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
4328 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
4329 sizeof(struct nl80211_sta_flag_update),
4330 &sinfo->sta_flags))
4331 goto nla_put_failure;
319090bf 4332
d686b920
JB
4333 PUT_SINFO_U64(T_OFFSET, t_offset);
4334 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
4335 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 4336 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
319090bf
JB
4337
4338#undef PUT_SINFO
d686b920 4339#undef PUT_SINFO_U64
6de39808
JB
4340
4341 if (sinfo->filled & BIT(NL80211_STA_INFO_TID_STATS)) {
4342 struct nlattr *tidsattr;
4343 int tid;
4344
4345 tidsattr = nla_nest_start(msg, NL80211_STA_INFO_TID_STATS);
4346 if (!tidsattr)
4347 goto nla_put_failure;
4348
4349 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
4350 struct cfg80211_tid_stats *tidstats;
4351 struct nlattr *tidattr;
4352
4353 tidstats = &sinfo->pertid[tid];
4354
4355 if (!tidstats->filled)
4356 continue;
4357
4358 tidattr = nla_nest_start(msg, tid + 1);
4359 if (!tidattr)
4360 goto nla_put_failure;
4361
d686b920 4362#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 4363 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
4364 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
4365 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
4366 goto nla_put_failure; \
4367 } while (0)
4368
d686b920
JB
4369 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
4370 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
4371 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
4372 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 4373
d686b920 4374#undef PUT_TIDVAL_U64
6de39808
JB
4375 nla_nest_end(msg, tidattr);
4376 }
4377
4378 nla_nest_end(msg, tidsattr);
4379 }
4380
2ec600d6 4381 nla_nest_end(msg, sinfoattr);
fd5b74dc 4382
319090bf 4383 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
4384 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
4385 sinfo->assoc_req_ies))
4386 goto nla_put_failure;
50d3dfb7 4387
053c095a
JB
4388 genlmsg_end(msg, hdr);
4389 return 0;
fd5b74dc
JB
4390
4391 nla_put_failure:
bc3ed28c
TG
4392 genlmsg_cancel(msg, hdr);
4393 return -EMSGSIZE;
fd5b74dc
JB
4394}
4395
2ec600d6 4396static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 4397 struct netlink_callback *cb)
2ec600d6 4398{
2ec600d6 4399 struct station_info sinfo;
1b8ec87a 4400 struct cfg80211_registered_device *rdev;
97990a06 4401 struct wireless_dev *wdev;
2ec600d6 4402 u8 mac_addr[ETH_ALEN];
97990a06 4403 int sta_idx = cb->args[2];
2ec600d6 4404 int err;
2ec600d6 4405
1b8ec87a 4406 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
4407 if (err)
4408 return err;
bba95fef 4409
97990a06
JB
4410 if (!wdev->netdev) {
4411 err = -EINVAL;
4412 goto out_err;
4413 }
4414
1b8ec87a 4415 if (!rdev->ops->dump_station) {
eec60b03 4416 err = -EOPNOTSUPP;
bba95fef
JB
4417 goto out_err;
4418 }
4419
bba95fef 4420 while (1) {
f612cedf 4421 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 4422 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
e35e4d28 4423 mac_addr, &sinfo);
bba95fef
JB
4424 if (err == -ENOENT)
4425 break;
4426 if (err)
3b85875a 4427 goto out_err;
bba95fef 4428
cf5ead82 4429 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 4430 NETLINK_CB(cb->skb).portid,
bba95fef 4431 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 4432 rdev, wdev->netdev, mac_addr,
bba95fef
JB
4433 &sinfo) < 0)
4434 goto out;
4435
4436 sta_idx++;
4437 }
4438
bba95fef 4439 out:
97990a06 4440 cb->args[2] = sta_idx;
bba95fef 4441 err = skb->len;
bba95fef 4442 out_err:
1b8ec87a 4443 nl80211_finish_wdev_dump(rdev);
bba95fef
JB
4444
4445 return err;
2ec600d6 4446}
fd5b74dc 4447
5727ef1b
JB
4448static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
4449{
4c476991
JB
4450 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4451 struct net_device *dev = info->user_ptr[1];
2ec600d6 4452 struct station_info sinfo;
fd5b74dc
JB
4453 struct sk_buff *msg;
4454 u8 *mac_addr = NULL;
4c476991 4455 int err;
fd5b74dc 4456
2ec600d6 4457 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc
JB
4458
4459 if (!info->attrs[NL80211_ATTR_MAC])
4460 return -EINVAL;
4461
4462 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4463
4c476991
JB
4464 if (!rdev->ops->get_station)
4465 return -EOPNOTSUPP;
3b85875a 4466
e35e4d28 4467 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 4468 if (err)
4c476991 4469 return err;
2ec600d6 4470
fd2120ca 4471 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
fd5b74dc 4472 if (!msg)
4c476991 4473 return -ENOMEM;
fd5b74dc 4474
cf5ead82
JB
4475 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
4476 info->snd_portid, info->snd_seq, 0,
66266b3a 4477 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991
JB
4478 nlmsg_free(msg);
4479 return -ENOBUFS;
4480 }
3b85875a 4481
4c476991 4482 return genlmsg_reply(msg, info);
5727ef1b
JB
4483}
4484
77ee7c89
JB
4485int cfg80211_check_station_change(struct wiphy *wiphy,
4486 struct station_parameters *params,
4487 enum cfg80211_station_type statype)
4488{
e4208427
AB
4489 if (params->listen_interval != -1 &&
4490 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 4491 return -EINVAL;
e4208427 4492
17b94247
AB
4493 if (params->support_p2p_ps != -1 &&
4494 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
4495 return -EINVAL;
4496
c72e1140 4497 if (params->aid &&
e4208427
AB
4498 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
4499 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
4500 return -EINVAL;
4501
4502 /* When you run into this, adjust the code below for the new flag */
4503 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
4504
4505 switch (statype) {
eef941e6
TP
4506 case CFG80211_STA_MESH_PEER_KERNEL:
4507 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
4508 /*
4509 * No ignoring the TDLS flag here -- the userspace mesh
4510 * code doesn't have the bug of including TDLS in the
4511 * mask everywhere.
4512 */
4513 if (params->sta_flags_mask &
4514 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4515 BIT(NL80211_STA_FLAG_MFP) |
4516 BIT(NL80211_STA_FLAG_AUTHORIZED)))
4517 return -EINVAL;
4518 break;
4519 case CFG80211_STA_TDLS_PEER_SETUP:
4520 case CFG80211_STA_TDLS_PEER_ACTIVE:
4521 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
4522 return -EINVAL;
4523 /* ignore since it can't change */
4524 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
4525 break;
4526 default:
4527 /* disallow mesh-specific things */
4528 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
4529 return -EINVAL;
4530 if (params->local_pm)
4531 return -EINVAL;
4532 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
4533 return -EINVAL;
4534 }
4535
4536 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
4537 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
4538 /* TDLS can't be set, ... */
4539 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
4540 return -EINVAL;
4541 /*
4542 * ... but don't bother the driver with it. This works around
4543 * a hostapd/wpa_supplicant issue -- it always includes the
4544 * TLDS_PEER flag in the mask even for AP mode.
4545 */
4546 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
4547 }
4548
47edb11b
AB
4549 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
4550 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
4551 /* reject other things that can't change */
4552 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
4553 return -EINVAL;
4554 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
4555 return -EINVAL;
4556 if (params->supported_rates)
4557 return -EINVAL;
4558 if (params->ext_capab || params->ht_capa || params->vht_capa)
4559 return -EINVAL;
4560 }
4561
47edb11b
AB
4562 if (statype != CFG80211_STA_AP_CLIENT &&
4563 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
4564 if (params->vlan)
4565 return -EINVAL;
4566 }
4567
4568 switch (statype) {
4569 case CFG80211_STA_AP_MLME_CLIENT:
4570 /* Use this only for authorizing/unauthorizing a station */
4571 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4572 return -EOPNOTSUPP;
4573 break;
4574 case CFG80211_STA_AP_CLIENT:
47edb11b 4575 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
4576 /* accept only the listed bits */
4577 if (params->sta_flags_mask &
4578 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
4579 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4580 BIT(NL80211_STA_FLAG_ASSOCIATED) |
4581 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4582 BIT(NL80211_STA_FLAG_WME) |
4583 BIT(NL80211_STA_FLAG_MFP)))
4584 return -EINVAL;
4585
4586 /* but authenticated/associated only if driver handles it */
4587 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
4588 params->sta_flags_mask &
4589 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4590 BIT(NL80211_STA_FLAG_ASSOCIATED)))
4591 return -EINVAL;
4592 break;
4593 case CFG80211_STA_IBSS:
4594 case CFG80211_STA_AP_STA:
4595 /* reject any changes other than AUTHORIZED */
4596 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
4597 return -EINVAL;
4598 break;
4599 case CFG80211_STA_TDLS_PEER_SETUP:
4600 /* reject any changes other than AUTHORIZED or WME */
4601 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
4602 BIT(NL80211_STA_FLAG_WME)))
4603 return -EINVAL;
4604 /* force (at least) rates when authorizing */
4605 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
4606 !params->supported_rates)
4607 return -EINVAL;
4608 break;
4609 case CFG80211_STA_TDLS_PEER_ACTIVE:
4610 /* reject any changes */
4611 return -EINVAL;
eef941e6 4612 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
4613 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
4614 return -EINVAL;
4615 break;
eef941e6 4616 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
4617 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
4618 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
4619 return -EINVAL;
4620 break;
4621 }
4622
06f7c88c
BL
4623 /*
4624 * Older kernel versions ignored this attribute entirely, so don't
4625 * reject attempts to update it but mark it as unused instead so the
4626 * driver won't look at the data.
4627 */
4628 if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
4629 statype != CFG80211_STA_TDLS_PEER_SETUP)
4630 params->opmode_notif_used = false;
4631
77ee7c89
JB
4632 return 0;
4633}
4634EXPORT_SYMBOL(cfg80211_check_station_change);
4635
5727ef1b 4636/*
c258d2de 4637 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 4638 */
80b99899
JB
4639static struct net_device *get_vlan(struct genl_info *info,
4640 struct cfg80211_registered_device *rdev)
5727ef1b 4641{
463d0183 4642 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
4643 struct net_device *v;
4644 int ret;
4645
4646 if (!vlanattr)
4647 return NULL;
4648
4649 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
4650 if (!v)
4651 return ERR_PTR(-ENODEV);
4652
4653 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
4654 ret = -EINVAL;
4655 goto error;
5727ef1b 4656 }
80b99899 4657
77ee7c89
JB
4658 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4659 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4660 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
4661 ret = -EINVAL;
4662 goto error;
4663 }
4664
80b99899
JB
4665 if (!netif_running(v)) {
4666 ret = -ENETDOWN;
4667 goto error;
4668 }
4669
4670 return v;
4671 error:
4672 dev_put(v);
4673 return ERR_PTR(ret);
5727ef1b
JB
4674}
4675
94e860f1
JB
4676static const struct nla_policy
4677nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
4678 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
4679 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
4680};
4681
ff276691
JB
4682static int nl80211_parse_sta_wme(struct genl_info *info,
4683 struct station_parameters *params)
df881293 4684{
df881293
JM
4685 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
4686 struct nlattr *nla;
4687 int err;
4688
df881293
JM
4689 /* parse WME attributes if present */
4690 if (!info->attrs[NL80211_ATTR_STA_WME])
4691 return 0;
4692
4693 nla = info->attrs[NL80211_ATTR_STA_WME];
4694 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
4695 nl80211_sta_wme_policy);
4696 if (err)
4697 return err;
4698
4699 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
4700 params->uapsd_queues = nla_get_u8(
4701 tb[NL80211_STA_WME_UAPSD_QUEUES]);
4702 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
4703 return -EINVAL;
4704
4705 if (tb[NL80211_STA_WME_MAX_SP])
4706 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
4707
4708 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
4709 return -EINVAL;
4710
4711 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
4712
4713 return 0;
4714}
4715
c01fc9ad
SD
4716static int nl80211_parse_sta_channel_info(struct genl_info *info,
4717 struct station_parameters *params)
4718{
4719 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
4720 params->supported_channels =
4721 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
4722 params->supported_channels_len =
4723 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
4724 /*
4725 * Need to include at least one (first channel, number of
4726 * channels) tuple for each subband, and must have proper
4727 * tuples for the rest of the data as well.
4728 */
4729 if (params->supported_channels_len < 2)
4730 return -EINVAL;
4731 if (params->supported_channels_len % 2)
4732 return -EINVAL;
4733 }
4734
4735 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
4736 params->supported_oper_classes =
4737 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
4738 params->supported_oper_classes_len =
4739 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
4740 /*
4741 * The value of the Length field of the Supported Operating
4742 * Classes element is between 2 and 253.
4743 */
4744 if (params->supported_oper_classes_len < 2 ||
4745 params->supported_oper_classes_len > 253)
4746 return -EINVAL;
4747 }
4748 return 0;
4749}
4750
ff276691
JB
4751static int nl80211_set_station_tdls(struct genl_info *info,
4752 struct station_parameters *params)
4753{
c01fc9ad 4754 int err;
ff276691 4755 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
4756 if (info->attrs[NL80211_ATTR_PEER_AID])
4757 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
4758 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
4759 params->ht_capa =
4760 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
4761 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
4762 params->vht_capa =
4763 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
4764
c01fc9ad
SD
4765 err = nl80211_parse_sta_channel_info(info, params);
4766 if (err)
4767 return err;
4768
ff276691
JB
4769 return nl80211_parse_sta_wme(info, params);
4770}
4771
5727ef1b
JB
4772static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
4773{
4c476991 4774 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 4775 struct net_device *dev = info->user_ptr[1];
5727ef1b 4776 struct station_parameters params;
77ee7c89
JB
4777 u8 *mac_addr;
4778 int err;
5727ef1b
JB
4779
4780 memset(&params, 0, sizeof(params));
4781
77ee7c89
JB
4782 if (!rdev->ops->change_station)
4783 return -EOPNOTSUPP;
4784
e4208427
AB
4785 /*
4786 * AID and listen_interval properties can be set only for unassociated
4787 * station. Include these parameters here and will check them in
4788 * cfg80211_check_station_change().
4789 */
a9bc31e4
AB
4790 if (info->attrs[NL80211_ATTR_STA_AID])
4791 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427
AB
4792
4793 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
4794 params.listen_interval =
4795 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
4796 else
4797 params.listen_interval = -1;
5727ef1b 4798
17b94247
AB
4799 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
4800 u8 tmp;
4801
4802 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
4803 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
4804 return -EINVAL;
4805
4806 params.support_p2p_ps = tmp;
4807 } else {
4808 params.support_p2p_ps = -1;
4809 }
4810
5727ef1b
JB
4811 if (!info->attrs[NL80211_ATTR_MAC])
4812 return -EINVAL;
4813
4814 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4815
4816 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
4817 params.supported_rates =
4818 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4819 params.supported_rates_len =
4820 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4821 }
4822
9d62a986
JM
4823 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
4824 params.capability =
4825 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
4826 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
4827 }
4828
4829 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
4830 params.ext_capab =
4831 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4832 params.ext_capab_len =
4833 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4834 }
4835
bdd3ae3d 4836 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
4837 return -EINVAL;
4838
f8bacc21 4839 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
2ec600d6 4840 params.plink_action =
f8bacc21
JB
4841 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
4842 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
4843 return -EINVAL;
4844 }
2ec600d6 4845
f8bacc21 4846 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 4847 params.plink_state =
f8bacc21
JB
4848 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
4849 if (params.plink_state >= NUM_NL80211_PLINK_STATES)
4850 return -EINVAL;
7d27a0ba
MH
4851 if (info->attrs[NL80211_ATTR_MESH_PEER_AID]) {
4852 params.peer_aid = nla_get_u16(
4853 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
4854 if (params.peer_aid > IEEE80211_MAX_AID)
4855 return -EINVAL;
4856 }
f8bacc21
JB
4857 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
4858 }
9c3990aa 4859
3b1c5a53
MP
4860 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) {
4861 enum nl80211_mesh_power_mode pm = nla_get_u32(
4862 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
4863
4864 if (pm <= NL80211_MESH_POWER_UNKNOWN ||
4865 pm > NL80211_MESH_POWER_MAX)
4866 return -EINVAL;
4867
4868 params.local_pm = pm;
4869 }
4870
06f7c88c
BL
4871 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
4872 params.opmode_notif_used = true;
4873 params.opmode_notif =
4874 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
4875 }
4876
77ee7c89
JB
4877 /* Include parameters for TDLS peer (will check later) */
4878 err = nl80211_set_station_tdls(info, &params);
4879 if (err)
4880 return err;
4881
4882 params.vlan = get_vlan(info, rdev);
4883 if (IS_ERR(params.vlan))
4884 return PTR_ERR(params.vlan);
4885
a97f4424
JB
4886 switch (dev->ieee80211_ptr->iftype) {
4887 case NL80211_IFTYPE_AP:
4888 case NL80211_IFTYPE_AP_VLAN:
074ac8df 4889 case NL80211_IFTYPE_P2P_GO:
074ac8df 4890 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 4891 case NL80211_IFTYPE_STATION:
267335d6 4892 case NL80211_IFTYPE_ADHOC:
a97f4424 4893 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
4894 break;
4895 default:
77ee7c89
JB
4896 err = -EOPNOTSUPP;
4897 goto out_put_vlan;
034d655e
JB
4898 }
4899
77ee7c89 4900 /* driver will call cfg80211_check_station_change() */
e35e4d28 4901 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 4902
77ee7c89 4903 out_put_vlan:
5727ef1b
JB
4904 if (params.vlan)
4905 dev_put(params.vlan);
3b85875a 4906
5727ef1b
JB
4907 return err;
4908}
4909
4910static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
4911{
4c476991 4912 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 4913 int err;
4c476991 4914 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
4915 struct station_parameters params;
4916 u8 *mac_addr = NULL;
bda95eb1
JB
4917 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4918 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
4919
4920 memset(&params, 0, sizeof(params));
4921
984c311b
JB
4922 if (!rdev->ops->add_station)
4923 return -EOPNOTSUPP;
4924
5727ef1b
JB
4925 if (!info->attrs[NL80211_ATTR_MAC])
4926 return -EINVAL;
4927
5727ef1b
JB
4928 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
4929 return -EINVAL;
4930
4931 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
4932 return -EINVAL;
4933
5e4b6f56
JM
4934 if (!info->attrs[NL80211_ATTR_STA_AID] &&
4935 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
4936 return -EINVAL;
4937
5727ef1b
JB
4938 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4939 params.supported_rates =
4940 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4941 params.supported_rates_len =
4942 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4943 params.listen_interval =
4944 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 4945
17b94247
AB
4946 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
4947 u8 tmp;
4948
4949 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
4950 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
4951 return -EINVAL;
4952
4953 params.support_p2p_ps = tmp;
4954 } else {
4955 /*
4956 * if not specified, assume it's supported for P2P GO interface,
4957 * and is NOT supported for AP interface
4958 */
4959 params.support_p2p_ps =
4960 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
4961 }
4962
3d124ea2 4963 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 4964 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
4965 else
4966 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
0e956c13
TLSC
4967 if (!params.aid || params.aid > IEEE80211_MAX_AID)
4968 return -EINVAL;
51b50fbe 4969
9d62a986
JM
4970 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
4971 params.capability =
4972 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
4973 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
4974 }
4975
4976 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
4977 params.ext_capab =
4978 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4979 params.ext_capab_len =
4980 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4981 }
4982
36aedc90
JM
4983 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
4984 params.ht_capa =
4985 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 4986
f461be3e
MP
4987 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
4988 params.vht_capa =
4989 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
4990
60f4a7b1
MK
4991 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
4992 params.opmode_notif_used = true;
4993 params.opmode_notif =
4994 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
4995 }
4996
f8bacc21 4997 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
96b78dff 4998 params.plink_action =
f8bacc21
JB
4999 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
5000 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
5001 return -EINVAL;
5002 }
96b78dff 5003
c01fc9ad
SD
5004 err = nl80211_parse_sta_channel_info(info, &params);
5005 if (err)
5006 return err;
5007
ff276691
JB
5008 err = nl80211_parse_sta_wme(info, &params);
5009 if (err)
5010 return err;
bdd90d5e 5011
bdd3ae3d 5012 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
5013 return -EINVAL;
5014
496fcc29
JB
5015 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
5016 * as userspace might just pass through the capabilities from the IEs
5017 * directly, rather than enforcing this restriction and returning an
5018 * error in this case.
5019 */
5020 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
5021 params.ht_capa = NULL;
5022 params.vht_capa = NULL;
5023 }
5024
77ee7c89
JB
5025 /* When you run into this, adjust the code below for the new flag */
5026 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
5027
bdd90d5e
JB
5028 switch (dev->ieee80211_ptr->iftype) {
5029 case NL80211_IFTYPE_AP:
5030 case NL80211_IFTYPE_AP_VLAN:
5031 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
5032 /* ignore WME attributes if iface/sta is not capable */
5033 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
5034 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
5035 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 5036
bdd90d5e 5037 /* TDLS peers cannot be added */
3d124ea2
JM
5038 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5039 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 5040 return -EINVAL;
bdd90d5e
JB
5041 /* but don't bother the driver with it */
5042 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 5043
d582cffb
JB
5044 /* allow authenticated/associated only if driver handles it */
5045 if (!(rdev->wiphy.features &
5046 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 5047 params.sta_flags_mask & auth_assoc)
d582cffb
JB
5048 return -EINVAL;
5049
bda95eb1
JB
5050 /* Older userspace, or userspace wanting to be compatible with
5051 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
5052 * and assoc flags in the mask, but assumes the station will be
5053 * added as associated anyway since this was the required driver
5054 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
5055 * introduced.
5056 * In order to not bother drivers with this quirk in the API
5057 * set the flags in both the mask and set for new stations in
5058 * this case.
5059 */
5060 if (!(params.sta_flags_mask & auth_assoc)) {
5061 params.sta_flags_mask |= auth_assoc;
5062 params.sta_flags_set |= auth_assoc;
5063 }
5064
bdd90d5e
JB
5065 /* must be last in here for error handling */
5066 params.vlan = get_vlan(info, rdev);
5067 if (IS_ERR(params.vlan))
5068 return PTR_ERR(params.vlan);
5069 break;
5070 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
5071 /* ignore uAPSD data */
5072 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5073
d582cffb
JB
5074 /* associated is disallowed */
5075 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
5076 return -EINVAL;
bdd90d5e 5077 /* TDLS peers cannot be added */
3d124ea2
JM
5078 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5079 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
5080 return -EINVAL;
5081 break;
5082 case NL80211_IFTYPE_STATION:
93d08f0b 5083 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
5084 /* ignore uAPSD data */
5085 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5086
77ee7c89
JB
5087 /* these are disallowed */
5088 if (params.sta_flags_mask &
5089 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
5090 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 5091 return -EINVAL;
bdd90d5e
JB
5092 /* Only TDLS peers can be added */
5093 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
5094 return -EINVAL;
5095 /* Can only add if TDLS ... */
5096 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
5097 return -EOPNOTSUPP;
5098 /* ... with external setup is supported */
5099 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
5100 return -EOPNOTSUPP;
77ee7c89
JB
5101 /*
5102 * Older wpa_supplicant versions always mark the TDLS peer
5103 * as authorized, but it shouldn't yet be.
5104 */
5105 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
5106 break;
5107 default:
5108 return -EOPNOTSUPP;
c75786c9
EP
5109 }
5110
bdd90d5e 5111 /* be aware of params.vlan when changing code here */
5727ef1b 5112
e35e4d28 5113 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 5114
5727ef1b
JB
5115 if (params.vlan)
5116 dev_put(params.vlan);
5727ef1b
JB
5117 return err;
5118}
5119
5120static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
5121{
4c476991
JB
5122 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5123 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
5124 struct station_del_parameters params;
5125
5126 memset(&params, 0, sizeof(params));
5727ef1b
JB
5127
5128 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 5129 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 5130
e80cf853 5131 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
d5d9de02 5132 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
074ac8df 5133 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
5134 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5135 return -EINVAL;
5727ef1b 5136
4c476991
JB
5137 if (!rdev->ops->del_station)
5138 return -EOPNOTSUPP;
3b85875a 5139
98856866
JM
5140 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
5141 params.subtype =
5142 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
5143 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
5144 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
5145 return -EINVAL;
5146 } else {
5147 /* Default to Deauthentication frame */
5148 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
5149 }
5150
5151 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
5152 params.reason_code =
5153 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
5154 if (params.reason_code == 0)
5155 return -EINVAL; /* 0 is reserved */
5156 } else {
5157 /* Default to reason code 2 */
5158 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
5159 }
5160
89c771e5 5161 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
5162}
5163
15e47304 5164static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
5165 int flags, struct net_device *dev,
5166 u8 *dst, u8 *next_hop,
5167 struct mpath_info *pinfo)
5168{
5169 void *hdr;
5170 struct nlattr *pinfoattr;
5171
1ef4c850 5172 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
5173 if (!hdr)
5174 return -1;
5175
9360ffd1
DM
5176 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5177 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
5178 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
5179 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
5180 goto nla_put_failure;
f5ea9120 5181
2ec600d6
LCC
5182 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
5183 if (!pinfoattr)
5184 goto nla_put_failure;
9360ffd1
DM
5185 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
5186 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
5187 pinfo->frame_qlen))
5188 goto nla_put_failure;
5189 if (((pinfo->filled & MPATH_INFO_SN) &&
5190 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
5191 ((pinfo->filled & MPATH_INFO_METRIC) &&
5192 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
5193 pinfo->metric)) ||
5194 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
5195 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
5196 pinfo->exptime)) ||
5197 ((pinfo->filled & MPATH_INFO_FLAGS) &&
5198 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
5199 pinfo->flags)) ||
5200 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
5201 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
5202 pinfo->discovery_timeout)) ||
5203 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
5204 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
5205 pinfo->discovery_retries)))
5206 goto nla_put_failure;
2ec600d6
LCC
5207
5208 nla_nest_end(msg, pinfoattr);
5209
053c095a
JB
5210 genlmsg_end(msg, hdr);
5211 return 0;
2ec600d6
LCC
5212
5213 nla_put_failure:
bc3ed28c
TG
5214 genlmsg_cancel(msg, hdr);
5215 return -EMSGSIZE;
2ec600d6
LCC
5216}
5217
5218static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 5219 struct netlink_callback *cb)
2ec600d6 5220{
2ec600d6 5221 struct mpath_info pinfo;
1b8ec87a 5222 struct cfg80211_registered_device *rdev;
97990a06 5223 struct wireless_dev *wdev;
2ec600d6
LCC
5224 u8 dst[ETH_ALEN];
5225 u8 next_hop[ETH_ALEN];
97990a06 5226 int path_idx = cb->args[2];
2ec600d6 5227 int err;
2ec600d6 5228
1b8ec87a 5229 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
5230 if (err)
5231 return err;
bba95fef 5232
1b8ec87a 5233 if (!rdev->ops->dump_mpath) {
eec60b03 5234 err = -EOPNOTSUPP;
bba95fef
JB
5235 goto out_err;
5236 }
5237
97990a06 5238 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 5239 err = -EOPNOTSUPP;
0448b5fc 5240 goto out_err;
eec60b03
JM
5241 }
5242
bba95fef 5243 while (1) {
1b8ec87a 5244 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 5245 next_hop, &pinfo);
bba95fef 5246 if (err == -ENOENT)
2ec600d6 5247 break;
bba95fef 5248 if (err)
3b85875a 5249 goto out_err;
2ec600d6 5250
15e47304 5251 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 5252 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 5253 wdev->netdev, dst, next_hop,
bba95fef
JB
5254 &pinfo) < 0)
5255 goto out;
2ec600d6 5256
bba95fef 5257 path_idx++;
2ec600d6 5258 }
2ec600d6 5259
bba95fef 5260 out:
97990a06 5261 cb->args[2] = path_idx;
bba95fef 5262 err = skb->len;
bba95fef 5263 out_err:
1b8ec87a 5264 nl80211_finish_wdev_dump(rdev);
bba95fef 5265 return err;
2ec600d6
LCC
5266}
5267
5268static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
5269{
4c476991 5270 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 5271 int err;
4c476991 5272 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5273 struct mpath_info pinfo;
5274 struct sk_buff *msg;
5275 u8 *dst = NULL;
5276 u8 next_hop[ETH_ALEN];
5277
5278 memset(&pinfo, 0, sizeof(pinfo));
5279
5280 if (!info->attrs[NL80211_ATTR_MAC])
5281 return -EINVAL;
5282
5283 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5284
4c476991
JB
5285 if (!rdev->ops->get_mpath)
5286 return -EOPNOTSUPP;
2ec600d6 5287
4c476991
JB
5288 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5289 return -EOPNOTSUPP;
eec60b03 5290
e35e4d28 5291 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 5292 if (err)
4c476991 5293 return err;
2ec600d6 5294
fd2120ca 5295 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 5296 if (!msg)
4c476991 5297 return -ENOMEM;
2ec600d6 5298
15e47304 5299 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
5300 dev, dst, next_hop, &pinfo) < 0) {
5301 nlmsg_free(msg);
5302 return -ENOBUFS;
5303 }
3b85875a 5304
4c476991 5305 return genlmsg_reply(msg, info);
2ec600d6
LCC
5306}
5307
5308static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
5309{
4c476991
JB
5310 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5311 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5312 u8 *dst = NULL;
5313 u8 *next_hop = NULL;
5314
5315 if (!info->attrs[NL80211_ATTR_MAC])
5316 return -EINVAL;
5317
5318 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5319 return -EINVAL;
5320
5321 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5322 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5323
4c476991
JB
5324 if (!rdev->ops->change_mpath)
5325 return -EOPNOTSUPP;
35a8efe1 5326
4c476991
JB
5327 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5328 return -EOPNOTSUPP;
2ec600d6 5329
e35e4d28 5330 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 5331}
4c476991 5332
2ec600d6
LCC
5333static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
5334{
4c476991
JB
5335 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5336 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5337 u8 *dst = NULL;
5338 u8 *next_hop = NULL;
5339
5340 if (!info->attrs[NL80211_ATTR_MAC])
5341 return -EINVAL;
5342
5343 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5344 return -EINVAL;
5345
5346 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5347 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5348
4c476991
JB
5349 if (!rdev->ops->add_mpath)
5350 return -EOPNOTSUPP;
35a8efe1 5351
4c476991
JB
5352 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5353 return -EOPNOTSUPP;
2ec600d6 5354
e35e4d28 5355 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
5356}
5357
5358static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
5359{
4c476991
JB
5360 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5361 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5362 u8 *dst = NULL;
5363
5364 if (info->attrs[NL80211_ATTR_MAC])
5365 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5366
4c476991
JB
5367 if (!rdev->ops->del_mpath)
5368 return -EOPNOTSUPP;
3b85875a 5369
e35e4d28 5370 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
5371}
5372
66be7d2b
HR
5373static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
5374{
5375 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5376 int err;
5377 struct net_device *dev = info->user_ptr[1];
5378 struct mpath_info pinfo;
5379 struct sk_buff *msg;
5380 u8 *dst = NULL;
5381 u8 mpp[ETH_ALEN];
5382
5383 memset(&pinfo, 0, sizeof(pinfo));
5384
5385 if (!info->attrs[NL80211_ATTR_MAC])
5386 return -EINVAL;
5387
5388 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5389
5390 if (!rdev->ops->get_mpp)
5391 return -EOPNOTSUPP;
5392
5393 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5394 return -EOPNOTSUPP;
5395
5396 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
5397 if (err)
5398 return err;
5399
5400 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5401 if (!msg)
5402 return -ENOMEM;
5403
5404 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
5405 dev, dst, mpp, &pinfo) < 0) {
5406 nlmsg_free(msg);
5407 return -ENOBUFS;
5408 }
5409
5410 return genlmsg_reply(msg, info);
5411}
5412
5413static int nl80211_dump_mpp(struct sk_buff *skb,
5414 struct netlink_callback *cb)
5415{
5416 struct mpath_info pinfo;
5417 struct cfg80211_registered_device *rdev;
5418 struct wireless_dev *wdev;
5419 u8 dst[ETH_ALEN];
5420 u8 mpp[ETH_ALEN];
5421 int path_idx = cb->args[2];
5422 int err;
5423
5424 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
5425 if (err)
5426 return err;
5427
5428 if (!rdev->ops->dump_mpp) {
5429 err = -EOPNOTSUPP;
5430 goto out_err;
5431 }
5432
5433 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
5434 err = -EOPNOTSUPP;
5435 goto out_err;
5436 }
5437
5438 while (1) {
5439 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
5440 mpp, &pinfo);
5441 if (err == -ENOENT)
5442 break;
5443 if (err)
5444 goto out_err;
5445
5446 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
5447 cb->nlh->nlmsg_seq, NLM_F_MULTI,
5448 wdev->netdev, dst, mpp,
5449 &pinfo) < 0)
5450 goto out;
5451
5452 path_idx++;
5453 }
5454
5455 out:
5456 cb->args[2] = path_idx;
5457 err = skb->len;
5458 out_err:
5459 nl80211_finish_wdev_dump(rdev);
5460 return err;
5461}
5462
9f1ba906
JM
5463static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
5464{
4c476991
JB
5465 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5466 struct net_device *dev = info->user_ptr[1];
c56589ed 5467 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 5468 struct bss_parameters params;
c56589ed 5469 int err;
9f1ba906
JM
5470
5471 memset(&params, 0, sizeof(params));
5472 /* default to not changing parameters */
5473 params.use_cts_prot = -1;
5474 params.use_short_preamble = -1;
5475 params.use_short_slot_time = -1;
fd8aaaf3 5476 params.ap_isolate = -1;
50b12f59 5477 params.ht_opmode = -1;
53cabad7
JB
5478 params.p2p_ctwindow = -1;
5479 params.p2p_opp_ps = -1;
9f1ba906
JM
5480
5481 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
5482 params.use_cts_prot =
5483 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
5484 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
5485 params.use_short_preamble =
5486 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
5487 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
5488 params.use_short_slot_time =
5489 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
5490 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
5491 params.basic_rates =
5492 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5493 params.basic_rates_len =
5494 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5495 }
fd8aaaf3
FF
5496 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
5497 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
5498 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
5499 params.ht_opmode =
5500 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 5501
53cabad7
JB
5502 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
5503 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5504 return -EINVAL;
5505 params.p2p_ctwindow =
5506 nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
5507 if (params.p2p_ctwindow < 0)
5508 return -EINVAL;
5509 if (params.p2p_ctwindow != 0 &&
5510 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
5511 return -EINVAL;
5512 }
5513
5514 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
5515 u8 tmp;
5516
5517 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5518 return -EINVAL;
5519 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
5520 if (tmp > 1)
5521 return -EINVAL;
5522 params.p2p_opp_ps = tmp;
5523 if (params.p2p_opp_ps &&
5524 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
5525 return -EINVAL;
5526 }
5527
4c476991
JB
5528 if (!rdev->ops->change_bss)
5529 return -EOPNOTSUPP;
9f1ba906 5530
074ac8df 5531 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
5532 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5533 return -EOPNOTSUPP;
3b85875a 5534
c56589ed
SW
5535 wdev_lock(wdev);
5536 err = rdev_change_bss(rdev, dev, &params);
5537 wdev_unlock(wdev);
5538
5539 return err;
9f1ba906
JM
5540}
5541
b2e1b302
LR
5542static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
5543{
b2e1b302 5544 char *data = NULL;
05050753 5545 bool is_indoor;
57b5ce07 5546 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
5547 u32 owner_nlportid;
5548
80778f18
LR
5549 /*
5550 * You should only get this when cfg80211 hasn't yet initialized
5551 * completely when built-in to the kernel right between the time
5552 * window between nl80211_init() and regulatory_init(), if that is
5553 * even possible.
5554 */
458f4f9e 5555 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 5556 return -EINPROGRESS;
80778f18 5557
57b5ce07
LR
5558 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
5559 user_reg_hint_type =
5560 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
5561 else
5562 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
5563
5564 switch (user_reg_hint_type) {
5565 case NL80211_USER_REG_HINT_USER:
5566 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
5567 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
5568 return -EINVAL;
5569
5570 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
5571 return regulatory_hint_user(data, user_reg_hint_type);
5572 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
5573 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
5574 owner_nlportid = info->snd_portid;
5575 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
5576 } else {
5577 owner_nlportid = 0;
5578 is_indoor = true;
5579 }
5580
5581 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
5582 default:
5583 return -EINVAL;
5584 }
b2e1b302
LR
5585}
5586
24bdd9f4 5587static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 5588 struct genl_info *info)
93da9cc1 5589{
4c476991 5590 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 5591 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
5592 struct wireless_dev *wdev = dev->ieee80211_ptr;
5593 struct mesh_config cur_params;
5594 int err = 0;
93da9cc1 5595 void *hdr;
5596 struct nlattr *pinfoattr;
5597 struct sk_buff *msg;
5598
29cbe68c
JB
5599 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
5600 return -EOPNOTSUPP;
5601
24bdd9f4 5602 if (!rdev->ops->get_mesh_config)
4c476991 5603 return -EOPNOTSUPP;
f3f92586 5604
29cbe68c
JB
5605 wdev_lock(wdev);
5606 /* If not connected, get default parameters */
5607 if (!wdev->mesh_id_len)
5608 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
5609 else
e35e4d28 5610 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
5611 wdev_unlock(wdev);
5612
93da9cc1 5613 if (err)
4c476991 5614 return err;
93da9cc1 5615
5616 /* Draw up a netlink message to send back */
fd2120ca 5617 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
5618 if (!msg)
5619 return -ENOMEM;
15e47304 5620 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 5621 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 5622 if (!hdr)
efe1cf0c 5623 goto out;
24bdd9f4 5624 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 5625 if (!pinfoattr)
5626 goto nla_put_failure;
9360ffd1
DM
5627 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5628 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
5629 cur_params.dot11MeshRetryTimeout) ||
5630 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
5631 cur_params.dot11MeshConfirmTimeout) ||
5632 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
5633 cur_params.dot11MeshHoldingTimeout) ||
5634 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
5635 cur_params.dot11MeshMaxPeerLinks) ||
5636 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
5637 cur_params.dot11MeshMaxRetries) ||
5638 nla_put_u8(msg, NL80211_MESHCONF_TTL,
5639 cur_params.dot11MeshTTL) ||
5640 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
5641 cur_params.element_ttl) ||
5642 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
5643 cur_params.auto_open_plinks) ||
7eab0f64
JL
5644 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
5645 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
5646 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
5647 cur_params.dot11MeshHWMPmaxPREQretries) ||
5648 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
5649 cur_params.path_refresh_time) ||
5650 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
5651 cur_params.min_discovery_timeout) ||
5652 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
5653 cur_params.dot11MeshHWMPactivePathTimeout) ||
5654 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
5655 cur_params.dot11MeshHWMPpreqMinInterval) ||
5656 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
5657 cur_params.dot11MeshHWMPperrMinInterval) ||
5658 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
5659 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
5660 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
5661 cur_params.dot11MeshHWMPRootMode) ||
5662 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
5663 cur_params.dot11MeshHWMPRannInterval) ||
5664 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
5665 cur_params.dot11MeshGateAnnouncementProtocol) ||
5666 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
5667 cur_params.dot11MeshForwarding) ||
5668 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
5669 cur_params.rssi_threshold) ||
5670 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
5671 cur_params.ht_opmode) ||
5672 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
5673 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
5674 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
5675 cur_params.dot11MeshHWMProotInterval) ||
5676 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
5677 cur_params.dot11MeshHWMPconfirmationInterval) ||
5678 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
5679 cur_params.power_mode) ||
5680 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
5681 cur_params.dot11MeshAwakeWindowDuration) ||
5682 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
5683 cur_params.plink_timeout))
9360ffd1 5684 goto nla_put_failure;
93da9cc1 5685 nla_nest_end(msg, pinfoattr);
5686 genlmsg_end(msg, hdr);
4c476991 5687 return genlmsg_reply(msg, info);
93da9cc1 5688
3b85875a 5689 nla_put_failure:
93da9cc1 5690 genlmsg_cancel(msg, hdr);
efe1cf0c 5691 out:
d080e275 5692 nlmsg_free(msg);
4c476991 5693 return -ENOBUFS;
93da9cc1 5694}
5695
b54452b0 5696static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
93da9cc1 5697 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
5698 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
5699 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
5700 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
5701 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
5702 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
45904f21 5703 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
93da9cc1 5704 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
d299a1f2 5705 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
93da9cc1 5706 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
5707 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
5708 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
5709 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
5710 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
dca7e943 5711 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 },
93da9cc1 5712 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
699403db 5713 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
0507e159 5714 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
16dd7267 5715 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
94f90656 5716 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
a4f606ea
CYY
5717 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
5718 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6
CYY
5719 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
5720 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
728b19e5 5721 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
3b1c5a53
MP
5722 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 },
5723 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 5724 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
93da9cc1 5725};
5726
c80d545d
JC
5727static const struct nla_policy
5728 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 5729 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
5730 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
5731 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 5732 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 5733 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 5734 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
581a8b0f 5735 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
a4f606ea 5736 .len = IEEE80211_MAX_DATA_LEN },
b130e5ce 5737 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
5738};
5739
f151d9db
AB
5740static int nl80211_check_bool(const struct nlattr *nla, u8 min, u8 max, bool *out)
5741{
5742 u8 val = nla_get_u8(nla);
5743 if (val < min || val > max)
5744 return -EINVAL;
5745 *out = val;
5746 return 0;
5747}
5748
5749static int nl80211_check_u8(const struct nlattr *nla, u8 min, u8 max, u8 *out)
5750{
5751 u8 val = nla_get_u8(nla);
5752 if (val < min || val > max)
5753 return -EINVAL;
5754 *out = val;
5755 return 0;
5756}
5757
5758static int nl80211_check_u16(const struct nlattr *nla, u16 min, u16 max, u16 *out)
5759{
5760 u16 val = nla_get_u16(nla);
5761 if (val < min || val > max)
5762 return -EINVAL;
5763 *out = val;
5764 return 0;
5765}
5766
5767static int nl80211_check_u32(const struct nlattr *nla, u32 min, u32 max, u32 *out)
5768{
5769 u32 val = nla_get_u32(nla);
5770 if (val < min || val > max)
5771 return -EINVAL;
5772 *out = val;
5773 return 0;
5774}
5775
5776static int nl80211_check_s32(const struct nlattr *nla, s32 min, s32 max, s32 *out)
5777{
5778 s32 val = nla_get_s32(nla);
5779 if (val < min || val > max)
5780 return -EINVAL;
5781 *out = val;
5782 return 0;
5783}
5784
ff9a71af
JB
5785static int nl80211_check_power_mode(const struct nlattr *nla,
5786 enum nl80211_mesh_power_mode min,
5787 enum nl80211_mesh_power_mode max,
5788 enum nl80211_mesh_power_mode *out)
5789{
5790 u32 val = nla_get_u32(nla);
5791 if (val < min || val > max)
5792 return -EINVAL;
5793 *out = val;
5794 return 0;
5795}
5796
24bdd9f4 5797static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
5798 struct mesh_config *cfg,
5799 u32 *mask_out)
93da9cc1 5800{
93da9cc1 5801 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 5802 u32 mask = 0;
9757235f 5803 u16 ht_opmode;
93da9cc1 5804
ea54fba2
MP
5805#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \
5806do { \
5807 if (tb[attr]) { \
f151d9db 5808 if (fn(tb[attr], min, max, &cfg->param)) \
ea54fba2 5809 return -EINVAL; \
ea54fba2
MP
5810 mask |= (1 << (attr - 1)); \
5811 } \
5812} while (0)
bd90fdcc 5813
24bdd9f4 5814 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 5815 return -EINVAL;
5816 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
24bdd9f4 5817 info->attrs[NL80211_ATTR_MESH_CONFIG],
bd90fdcc 5818 nl80211_meshconf_params_policy))
93da9cc1 5819 return -EINVAL;
5820
93da9cc1 5821 /* This makes sure that there aren't more than 32 mesh config
5822 * parameters (otherwise our bitfield scheme would not work.) */
5823 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
5824
5825 /* Fill in the params struct */
ea54fba2 5826 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255,
a4f606ea 5827 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
f151d9db 5828 nl80211_check_u16);
ea54fba2 5829 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255,
a4f606ea 5830 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
f151d9db 5831 nl80211_check_u16);
ea54fba2 5832 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255,
a4f606ea 5833 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
f151d9db 5834 nl80211_check_u16);
ea54fba2 5835 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255,
a4f606ea 5836 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
f151d9db 5837 nl80211_check_u16);
ea54fba2 5838 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16,
a4f606ea 5839 mask, NL80211_MESHCONF_MAX_RETRIES,
f151d9db 5840 nl80211_check_u8);
ea54fba2 5841 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255,
f151d9db 5842 mask, NL80211_MESHCONF_TTL, nl80211_check_u8);
ea54fba2 5843 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255,
a4f606ea 5844 mask, NL80211_MESHCONF_ELEMENT_TTL,
f151d9db 5845 nl80211_check_u8);
ea54fba2 5846 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1,
a4f606ea 5847 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
f151d9db 5848 nl80211_check_bool);
ea54fba2
MP
5849 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
5850 1, 255, mask,
a4f606ea 5851 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
f151d9db 5852 nl80211_check_u32);
ea54fba2 5853 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255,
a4f606ea 5854 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
f151d9db 5855 nl80211_check_u8);
ea54fba2 5856 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535,
a4f606ea 5857 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
f151d9db 5858 nl80211_check_u32);
ea54fba2 5859 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535,
a4f606ea 5860 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
f151d9db 5861 nl80211_check_u16);
ea54fba2
MP
5862 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
5863 1, 65535, mask,
a4f606ea 5864 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
f151d9db 5865 nl80211_check_u32);
93da9cc1 5866 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
ea54fba2
MP
5867 1, 65535, mask,
5868 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
f151d9db 5869 nl80211_check_u16);
dca7e943 5870 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
ea54fba2
MP
5871 1, 65535, mask,
5872 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
f151d9db 5873 nl80211_check_u16);
93da9cc1 5874 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
5875 dot11MeshHWMPnetDiameterTraversalTime,
5876 1, 65535, mask,
a4f606ea 5877 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
f151d9db 5878 nl80211_check_u16);
ea54fba2
MP
5879 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4,
5880 mask, NL80211_MESHCONF_HWMP_ROOTMODE,
f151d9db 5881 nl80211_check_u8);
ea54fba2
MP
5882 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535,
5883 mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
f151d9db 5884 nl80211_check_u16);
63c5723b 5885 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
5886 dot11MeshGateAnnouncementProtocol, 0, 1,
5887 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
f151d9db 5888 nl80211_check_bool);
ea54fba2 5889 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1,
a4f606ea 5890 mask, NL80211_MESHCONF_FORWARDING,
f151d9db 5891 nl80211_check_bool);
83374fe9 5892 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
a4f606ea 5893 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
f151d9db 5894 nl80211_check_s32);
9757235f
MH
5895 /*
5896 * Check HT operation mode based on
5897 * IEEE 802.11 2012 8.4.2.59 HT Operation element.
5898 */
5899 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
5900 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
5901
5902 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
5903 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
5904 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
5905 return -EINVAL;
5906
5907 if ((ht_opmode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) &&
5908 (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
5909 return -EINVAL;
5910
5911 switch (ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION) {
5912 case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
5913 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
5914 if (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)
5915 return -EINVAL;
5916 break;
5917 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
5918 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
5919 if (!(ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
5920 return -EINVAL;
5921 break;
5922 }
5923 cfg->ht_opmode = ht_opmode;
5924 }
ac1073a6 5925 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
ea54fba2 5926 1, 65535, mask,
ac1073a6 5927 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
f151d9db 5928 nl80211_check_u32);
ea54fba2 5929 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535,
ac1073a6 5930 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
f151d9db 5931 nl80211_check_u16);
728b19e5 5932 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
5933 dot11MeshHWMPconfirmationInterval,
5934 1, 65535, mask,
728b19e5 5935 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
f151d9db 5936 nl80211_check_u16);
3b1c5a53
MP
5937 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode,
5938 NL80211_MESH_POWER_ACTIVE,
5939 NL80211_MESH_POWER_MAX,
5940 mask, NL80211_MESHCONF_POWER_MODE,
ff9a71af 5941 nl80211_check_power_mode);
3b1c5a53
MP
5942 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration,
5943 0, 65535, mask,
f151d9db 5944 NL80211_MESHCONF_AWAKE_WINDOW, nl80211_check_u16);
31f909a2 5945 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 0, 0xffffffff,
8e7c0538 5946 mask, NL80211_MESHCONF_PLINK_TIMEOUT,
f151d9db 5947 nl80211_check_u32);
bd90fdcc
JB
5948 if (mask_out)
5949 *mask_out = mask;
c80d545d 5950
bd90fdcc
JB
5951 return 0;
5952
5953#undef FILL_IN_MESH_PARAM_IF_SET
5954}
5955
c80d545d
JC
5956static int nl80211_parse_mesh_setup(struct genl_info *info,
5957 struct mesh_setup *setup)
5958{
bb2798d4 5959 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
5960 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
5961
5962 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
5963 return -EINVAL;
5964 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
5965 info->attrs[NL80211_ATTR_MESH_SETUP],
5966 nl80211_mesh_setup_params_policy))
5967 return -EINVAL;
5968
d299a1f2
JC
5969 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
5970 setup->sync_method =
5971 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
5972 IEEE80211_SYNC_METHOD_VENDOR :
5973 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
5974
c80d545d
JC
5975 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
5976 setup->path_sel_proto =
5977 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
5978 IEEE80211_PATH_PROTOCOL_VENDOR :
5979 IEEE80211_PATH_PROTOCOL_HWMP;
5980
5981 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
5982 setup->path_metric =
5983 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
5984 IEEE80211_PATH_METRIC_VENDOR :
5985 IEEE80211_PATH_METRIC_AIRTIME;
5986
581a8b0f 5987 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 5988 struct nlattr *ieattr =
581a8b0f 5989 tb[NL80211_MESH_SETUP_IE];
c80d545d
JC
5990 if (!is_valid_ie_attr(ieattr))
5991 return -EINVAL;
581a8b0f
JC
5992 setup->ie = nla_data(ieattr);
5993 setup->ie_len = nla_len(ieattr);
c80d545d 5994 }
bb2798d4
TP
5995 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
5996 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
5997 return -EINVAL;
5998 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
5999 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
6000 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
6001 if (setup->is_secure)
6002 setup->user_mpm = true;
c80d545d 6003
6e16d90b
CT
6004 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
6005 if (!setup->user_mpm)
6006 return -EINVAL;
6007 setup->auth_id =
6008 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
6009 }
6010
c80d545d
JC
6011 return 0;
6012}
6013
24bdd9f4 6014static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 6015 struct genl_info *info)
bd90fdcc
JB
6016{
6017 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6018 struct net_device *dev = info->user_ptr[1];
29cbe68c 6019 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
6020 struct mesh_config cfg;
6021 u32 mask;
6022 int err;
6023
29cbe68c
JB
6024 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
6025 return -EOPNOTSUPP;
6026
24bdd9f4 6027 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
6028 return -EOPNOTSUPP;
6029
24bdd9f4 6030 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
6031 if (err)
6032 return err;
6033
29cbe68c
JB
6034 wdev_lock(wdev);
6035 if (!wdev->mesh_id_len)
6036 err = -ENOLINK;
6037
6038 if (!err)
e35e4d28 6039 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
6040
6041 wdev_unlock(wdev);
6042
6043 return err;
93da9cc1 6044}
6045
ad30ca2c
AN
6046static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
6047 struct sk_buff *msg)
f130347c 6048{
f130347c
LR
6049 struct nlattr *nl_reg_rules;
6050 unsigned int i;
f130347c 6051
458f4f9e
JB
6052 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
6053 (regdom->dfs_region &&
6054 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 6055 goto nla_put_failure;
458f4f9e 6056
f130347c
LR
6057 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
6058 if (!nl_reg_rules)
ad30ca2c 6059 goto nla_put_failure;
f130347c 6060
458f4f9e 6061 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
6062 struct nlattr *nl_reg_rule;
6063 const struct ieee80211_reg_rule *reg_rule;
6064 const struct ieee80211_freq_range *freq_range;
6065 const struct ieee80211_power_rule *power_rule;
97524820 6066 unsigned int max_bandwidth_khz;
f130347c 6067
458f4f9e 6068 reg_rule = &regdom->reg_rules[i];
f130347c
LR
6069 freq_range = &reg_rule->freq_range;
6070 power_rule = &reg_rule->power_rule;
6071
6072 nl_reg_rule = nla_nest_start(msg, i);
6073 if (!nl_reg_rule)
ad30ca2c 6074 goto nla_put_failure;
f130347c 6075
97524820
JD
6076 max_bandwidth_khz = freq_range->max_bandwidth_khz;
6077 if (!max_bandwidth_khz)
6078 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
6079 reg_rule);
6080
9360ffd1
DM
6081 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
6082 reg_rule->flags) ||
6083 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
6084 freq_range->start_freq_khz) ||
6085 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
6086 freq_range->end_freq_khz) ||
6087 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 6088 max_bandwidth_khz) ||
9360ffd1
DM
6089 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
6090 power_rule->max_antenna_gain) ||
6091 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
6092 power_rule->max_eirp) ||
6093 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
6094 reg_rule->dfs_cac_ms))
ad30ca2c 6095 goto nla_put_failure;
f130347c
LR
6096
6097 nla_nest_end(msg, nl_reg_rule);
6098 }
6099
6100 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
6101 return 0;
6102
6103nla_put_failure:
6104 return -EMSGSIZE;
6105}
6106
6107static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
6108{
6109 const struct ieee80211_regdomain *regdom = NULL;
6110 struct cfg80211_registered_device *rdev;
6111 struct wiphy *wiphy = NULL;
6112 struct sk_buff *msg;
6113 void *hdr;
6114
6115 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6116 if (!msg)
6117 return -ENOBUFS;
6118
6119 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
6120 NL80211_CMD_GET_REG);
6121 if (!hdr)
6122 goto put_failure;
6123
6124 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
6125 bool self_managed;
6126
ad30ca2c
AN
6127 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
6128 if (IS_ERR(rdev)) {
6129 nlmsg_free(msg);
6130 return PTR_ERR(rdev);
6131 }
6132
6133 wiphy = &rdev->wiphy;
1bdd716c
AN
6134 self_managed = wiphy->regulatory_flags &
6135 REGULATORY_WIPHY_SELF_MANAGED;
ad30ca2c
AN
6136 regdom = get_wiphy_regdom(wiphy);
6137
1bdd716c
AN
6138 /* a self-managed-reg device must have a private regdom */
6139 if (WARN_ON(!regdom && self_managed)) {
6140 nlmsg_free(msg);
6141 return -EINVAL;
6142 }
6143
ad30ca2c
AN
6144 if (regdom &&
6145 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6146 goto nla_put_failure;
6147 }
6148
6149 if (!wiphy && reg_last_request_cell_base() &&
6150 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6151 NL80211_USER_REG_HINT_CELL_BASE))
6152 goto nla_put_failure;
6153
6154 rcu_read_lock();
6155
6156 if (!regdom)
6157 regdom = rcu_dereference(cfg80211_regdomain);
6158
6159 if (nl80211_put_regdom(regdom, msg))
6160 goto nla_put_failure_rcu;
6161
6162 rcu_read_unlock();
f130347c
LR
6163
6164 genlmsg_end(msg, hdr);
5fe231e8 6165 return genlmsg_reply(msg, info);
f130347c 6166
458f4f9e
JB
6167nla_put_failure_rcu:
6168 rcu_read_unlock();
f130347c
LR
6169nla_put_failure:
6170 genlmsg_cancel(msg, hdr);
efe1cf0c 6171put_failure:
d080e275 6172 nlmsg_free(msg);
5fe231e8 6173 return -EMSGSIZE;
f130347c
LR
6174}
6175
ad30ca2c
AN
6176static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
6177 u32 seq, int flags, struct wiphy *wiphy,
6178 const struct ieee80211_regdomain *regdom)
6179{
6180 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
6181 NL80211_CMD_GET_REG);
6182
6183 if (!hdr)
6184 return -1;
6185
6186 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
6187
6188 if (nl80211_put_regdom(regdom, msg))
6189 goto nla_put_failure;
6190
6191 if (!wiphy && reg_last_request_cell_base() &&
6192 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6193 NL80211_USER_REG_HINT_CELL_BASE))
6194 goto nla_put_failure;
6195
6196 if (wiphy &&
6197 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6198 goto nla_put_failure;
6199
1bdd716c
AN
6200 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
6201 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
6202 goto nla_put_failure;
6203
053c095a
JB
6204 genlmsg_end(msg, hdr);
6205 return 0;
ad30ca2c
AN
6206
6207nla_put_failure:
6208 genlmsg_cancel(msg, hdr);
6209 return -EMSGSIZE;
6210}
6211
6212static int nl80211_get_reg_dump(struct sk_buff *skb,
6213 struct netlink_callback *cb)
6214{
6215 const struct ieee80211_regdomain *regdom = NULL;
6216 struct cfg80211_registered_device *rdev;
6217 int err, reg_idx, start = cb->args[2];
6218
6219 rtnl_lock();
6220
6221 if (cfg80211_regdomain && start == 0) {
6222 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6223 NLM_F_MULTI, NULL,
6224 rtnl_dereference(cfg80211_regdomain));
6225 if (err < 0)
6226 goto out_err;
6227 }
6228
6229 /* the global regdom is idx 0 */
6230 reg_idx = 1;
6231 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
6232 regdom = get_wiphy_regdom(&rdev->wiphy);
6233 if (!regdom)
6234 continue;
6235
6236 if (++reg_idx <= start)
6237 continue;
6238
6239 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6240 NLM_F_MULTI, &rdev->wiphy, regdom);
6241 if (err < 0) {
6242 reg_idx--;
6243 break;
6244 }
6245 }
6246
6247 cb->args[2] = reg_idx;
6248 err = skb->len;
6249out_err:
6250 rtnl_unlock();
6251 return err;
6252}
6253
b6863036
JB
6254#ifdef CONFIG_CFG80211_CRDA_SUPPORT
6255static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
6256 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
6257 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
6258 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
6259 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
6260 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
6261 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
6262 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
6263};
6264
6265static int parse_reg_rule(struct nlattr *tb[],
6266 struct ieee80211_reg_rule *reg_rule)
6267{
6268 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
6269 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
6270
6271 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
6272 return -EINVAL;
6273 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
6274 return -EINVAL;
6275 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
6276 return -EINVAL;
6277 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
6278 return -EINVAL;
6279 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6280 return -EINVAL;
6281
6282 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
6283
6284 freq_range->start_freq_khz =
6285 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
6286 freq_range->end_freq_khz =
6287 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
6288 freq_range->max_bandwidth_khz =
6289 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
6290
6291 power_rule->max_eirp =
6292 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
6293
6294 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
6295 power_rule->max_antenna_gain =
6296 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
6297
6298 if (tb[NL80211_ATTR_DFS_CAC_TIME])
6299 reg_rule->dfs_cac_ms =
6300 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
6301
6302 return 0;
6303}
6304
b2e1b302
LR
6305static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
6306{
6307 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
6308 struct nlattr *nl_reg_rule;
ea372c54
JB
6309 char *alpha2;
6310 int rem_reg_rules, r;
b2e1b302 6311 u32 num_rules = 0, rule_idx = 0, size_of_regd;
4c7d3982 6312 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 6313 struct ieee80211_regdomain *rd;
b2e1b302
LR
6314
6315 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
6316 return -EINVAL;
6317
6318 if (!info->attrs[NL80211_ATTR_REG_RULES])
6319 return -EINVAL;
6320
6321 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
6322
8b60b078
LR
6323 if (info->attrs[NL80211_ATTR_DFS_REGION])
6324 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
6325
b2e1b302 6326 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6327 rem_reg_rules) {
b2e1b302
LR
6328 num_rules++;
6329 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 6330 return -EINVAL;
b2e1b302
LR
6331 }
6332
e438768f
LR
6333 if (!reg_is_valid_request(alpha2))
6334 return -EINVAL;
6335
b2e1b302 6336 size_of_regd = sizeof(struct ieee80211_regdomain) +
1a919318 6337 num_rules * sizeof(struct ieee80211_reg_rule);
b2e1b302
LR
6338
6339 rd = kzalloc(size_of_regd, GFP_KERNEL);
6913b49a
JB
6340 if (!rd)
6341 return -ENOMEM;
b2e1b302
LR
6342
6343 rd->n_reg_rules = num_rules;
6344 rd->alpha2[0] = alpha2[0];
6345 rd->alpha2[1] = alpha2[1];
6346
8b60b078
LR
6347 /*
6348 * Disable DFS master mode if the DFS region was
6349 * not supported or known on this kernel.
6350 */
6351 if (reg_supported_dfs_region(dfs_region))
6352 rd->dfs_region = dfs_region;
6353
b2e1b302 6354 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6355 rem_reg_rules) {
bfe2c7b1
JB
6356 r = nla_parse_nested(tb, NL80211_REG_RULE_ATTR_MAX,
6357 nl_reg_rule, reg_rule_policy);
ae811e21
JB
6358 if (r)
6359 goto bad_reg;
b2e1b302
LR
6360 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
6361 if (r)
6362 goto bad_reg;
6363
6364 rule_idx++;
6365
d0e18f83
LR
6366 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
6367 r = -EINVAL;
b2e1b302 6368 goto bad_reg;
d0e18f83 6369 }
b2e1b302
LR
6370 }
6371
06627990
JB
6372 /* set_regdom takes ownership of rd */
6373 return set_regdom(rd, REGD_SOURCE_CRDA);
d2372b31 6374 bad_reg:
b2e1b302 6375 kfree(rd);
d0e18f83 6376 return r;
b2e1b302 6377}
b6863036 6378#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 6379
83f5e2cf
JB
6380static int validate_scan_freqs(struct nlattr *freqs)
6381{
6382 struct nlattr *attr1, *attr2;
6383 int n_channels = 0, tmp1, tmp2;
6384
6385 nla_for_each_nested(attr1, freqs, tmp1) {
6386 n_channels++;
6387 /*
6388 * Some hardware has a limited channel list for
6389 * scanning, and it is pretty much nonsensical
6390 * to scan for a channel twice, so disallow that
6391 * and don't require drivers to check that the
6392 * channel list they get isn't longer than what
6393 * they can scan, as long as they can scan all
6394 * the channels they registered at once.
6395 */
6396 nla_for_each_nested(attr2, freqs, tmp2)
6397 if (attr1 != attr2 &&
6398 nla_get_u32(attr1) == nla_get_u32(attr2))
6399 return 0;
6400 }
6401
6402 return n_channels;
6403}
6404
57fbcce3 6405static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 6406{
57fbcce3 6407 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
6408}
6409
6410static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
6411 struct cfg80211_bss_selection *bss_select)
6412{
6413 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
6414 struct nlattr *nest;
6415 int err;
6416 bool found = false;
6417 int i;
6418
6419 /* only process one nested attribute */
6420 nest = nla_data(nla);
6421 if (!nla_ok(nest, nla_len(nest)))
6422 return -EINVAL;
6423
bfe2c7b1
JB
6424 err = nla_parse_nested(attr, NL80211_BSS_SELECT_ATTR_MAX, nest,
6425 nl80211_bss_select_policy);
38de03d2
AS
6426 if (err)
6427 return err;
6428
6429 /* only one attribute may be given */
6430 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
6431 if (attr[i]) {
6432 if (found)
6433 return -EINVAL;
6434 found = true;
6435 }
6436 }
6437
6438 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
6439
6440 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
6441 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
6442
6443 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
6444 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
6445 bss_select->param.band_pref =
6446 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
6447 if (!is_band_valid(wiphy, bss_select->param.band_pref))
6448 return -EINVAL;
6449 }
6450
6451 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
6452 struct nl80211_bss_select_rssi_adjust *adj_param;
6453
6454 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
6455 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
6456 bss_select->param.adjust.band = adj_param->band;
6457 bss_select->param.adjust.delta = adj_param->delta;
6458 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
6459 return -EINVAL;
6460 }
6461
6462 /* user-space did not provide behaviour attribute */
6463 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
6464 return -EINVAL;
6465
6466 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
6467 return -EINVAL;
6468
6469 return 0;
6470}
6471
ad2b26ab
JB
6472static int nl80211_parse_random_mac(struct nlattr **attrs,
6473 u8 *mac_addr, u8 *mac_addr_mask)
6474{
6475 int i;
6476
6477 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
6478 eth_zero_addr(mac_addr);
6479 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
6480 mac_addr[0] = 0x2;
6481 mac_addr_mask[0] = 0x3;
6482
6483 return 0;
6484 }
6485
6486 /* need both or none */
6487 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
6488 return -EINVAL;
6489
6490 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
6491 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
6492
6493 /* don't allow or configure an mcast address */
6494 if (!is_multicast_ether_addr(mac_addr_mask) ||
6495 is_multicast_ether_addr(mac_addr))
6496 return -EINVAL;
6497
6498 /*
6499 * allow users to pass a MAC address that has bits set outside
6500 * of the mask, but don't bother drivers with having to deal
6501 * with such bits
6502 */
6503 for (i = 0; i < ETH_ALEN; i++)
6504 mac_addr[i] &= mac_addr_mask[i];
6505
6506 return 0;
6507}
6508
2a519311
JB
6509static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
6510{
4c476991 6511 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 6512 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 6513 struct cfg80211_scan_request *request;
2a519311
JB
6514 struct nlattr *attr;
6515 struct wiphy *wiphy;
83f5e2cf 6516 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 6517 size_t ie_len;
2a519311 6518
f4a11bb0
JB
6519 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
6520 return -EINVAL;
6521
79c97e97 6522 wiphy = &rdev->wiphy;
2a519311 6523
cb3b7d87
AB
6524 if (wdev->iftype == NL80211_IFTYPE_NAN)
6525 return -EOPNOTSUPP;
6526
4c476991
JB
6527 if (!rdev->ops->scan)
6528 return -EOPNOTSUPP;
2a519311 6529
f9d15d16 6530 if (rdev->scan_req || rdev->scan_msg) {
f9f47529
JB
6531 err = -EBUSY;
6532 goto unlock;
6533 }
2a519311
JB
6534
6535 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
6536 n_channels = validate_scan_freqs(
6537 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
f9f47529
JB
6538 if (!n_channels) {
6539 err = -EINVAL;
6540 goto unlock;
6541 }
2a519311 6542 } else {
bdfbec2d 6543 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
6544 }
6545
6546 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
6547 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
6548 n_ssids++;
6549
f9f47529
JB
6550 if (n_ssids > wiphy->max_scan_ssids) {
6551 err = -EINVAL;
6552 goto unlock;
6553 }
2a519311 6554
70692ad2
JM
6555 if (info->attrs[NL80211_ATTR_IE])
6556 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
6557 else
6558 ie_len = 0;
6559
f9f47529
JB
6560 if (ie_len > wiphy->max_scan_ie_len) {
6561 err = -EINVAL;
6562 goto unlock;
6563 }
18a83659 6564
2a519311 6565 request = kzalloc(sizeof(*request)
a2cd43c5
LC
6566 + sizeof(*request->ssids) * n_ssids
6567 + sizeof(*request->channels) * n_channels
70692ad2 6568 + ie_len, GFP_KERNEL);
f9f47529
JB
6569 if (!request) {
6570 err = -ENOMEM;
6571 goto unlock;
6572 }
2a519311 6573
2a519311 6574 if (n_ssids)
5ba63533 6575 request->ssids = (void *)&request->channels[n_channels];
2a519311 6576 request->n_ssids = n_ssids;
70692ad2 6577 if (ie_len) {
13874e4b 6578 if (n_ssids)
70692ad2
JM
6579 request->ie = (void *)(request->ssids + n_ssids);
6580 else
6581 request->ie = (void *)(request->channels + n_channels);
6582 }
2a519311 6583
584991dc 6584 i = 0;
2a519311
JB
6585 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
6586 /* user specified, bail out if channel not found */
2a519311 6587 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
6588 struct ieee80211_channel *chan;
6589
6590 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
6591
6592 if (!chan) {
2a519311
JB
6593 err = -EINVAL;
6594 goto out_free;
6595 }
584991dc
JB
6596
6597 /* ignore disabled channels */
6598 if (chan->flags & IEEE80211_CHAN_DISABLED)
6599 continue;
6600
6601 request->channels[i] = chan;
2a519311
JB
6602 i++;
6603 }
6604 } else {
57fbcce3 6605 enum nl80211_band band;
34850ab2 6606
2a519311 6607 /* all channels */
57fbcce3 6608 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 6609 int j;
7a087e74 6610
2a519311
JB
6611 if (!wiphy->bands[band])
6612 continue;
6613 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
6614 struct ieee80211_channel *chan;
6615
6616 chan = &wiphy->bands[band]->channels[j];
6617
6618 if (chan->flags & IEEE80211_CHAN_DISABLED)
6619 continue;
6620
6621 request->channels[i] = chan;
2a519311
JB
6622 i++;
6623 }
6624 }
6625 }
6626
584991dc
JB
6627 if (!i) {
6628 err = -EINVAL;
6629 goto out_free;
6630 }
6631
6632 request->n_channels = i;
6633
2a519311 6634 i = 0;
13874e4b 6635 if (n_ssids) {
2a519311 6636 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 6637 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
6638 err = -EINVAL;
6639 goto out_free;
6640 }
57a27e1d 6641 request->ssids[i].ssid_len = nla_len(attr);
2a519311 6642 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
6643 i++;
6644 }
6645 }
6646
70692ad2
JM
6647 if (info->attrs[NL80211_ATTR_IE]) {
6648 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
6649 memcpy((void *)request->ie,
6650 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
6651 request->ie_len);
6652 }
6653
57fbcce3 6654 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
6655 if (wiphy->bands[i])
6656 request->rates[i] =
6657 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
6658
6659 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
6660 nla_for_each_nested(attr,
6661 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
6662 tmp) {
57fbcce3 6663 enum nl80211_band band = nla_type(attr);
34850ab2 6664
57fbcce3 6665 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
6666 err = -EINVAL;
6667 goto out_free;
6668 }
1b09cd82
FF
6669
6670 if (!wiphy->bands[band])
6671 continue;
6672
34850ab2
JB
6673 err = ieee80211_get_ratemask(wiphy->bands[band],
6674 nla_data(attr),
6675 nla_len(attr),
6676 &request->rates[band]);
6677 if (err)
6678 goto out_free;
6679 }
6680 }
6681
1d76250b
AS
6682 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
6683 if (!wiphy_ext_feature_isset(wiphy,
6684 NL80211_EXT_FEATURE_SET_SCAN_DWELL)) {
6685 err = -EOPNOTSUPP;
6686 goto out_free;
6687 }
6688
6689 request->duration =
6690 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
6691 request->duration_mandatory =
6692 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
6693 }
6694
46856bbf 6695 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
ed473771
SL
6696 request->flags = nla_get_u32(
6697 info->attrs[NL80211_ATTR_SCAN_FLAGS]);
00c3a6ed
JB
6698 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
6699 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
46856bbf
SL
6700 err = -EOPNOTSUPP;
6701 goto out_free;
6702 }
ad2b26ab
JB
6703
6704 if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
6705 if (!(wiphy->features &
6706 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)) {
6707 err = -EOPNOTSUPP;
6708 goto out_free;
6709 }
6710
6711 if (wdev->current_bss) {
6712 err = -EOPNOTSUPP;
6713 goto out_free;
6714 }
6715
6716 err = nl80211_parse_random_mac(info->attrs,
6717 request->mac_addr,
6718 request->mac_addr_mask);
6719 if (err)
6720 goto out_free;
6721 }
46856bbf 6722 }
ed473771 6723
e9f935e3
RM
6724 request->no_cck =
6725 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
6726
2fa436b3
VK
6727 /* Initial implementation used NL80211_ATTR_MAC to set the specific
6728 * BSSID to scan for. This was problematic because that same attribute
6729 * was already used for another purpose (local random MAC address). The
6730 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
6731 * compatibility with older userspace components, also use the
6732 * NL80211_ATTR_MAC value here if it can be determined to be used for
6733 * the specific BSSID use case instead of the random MAC address
6734 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
6735 */
6736 if (info->attrs[NL80211_ATTR_BSSID])
6737 memcpy(request->bssid,
6738 nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
6739 else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
6740 info->attrs[NL80211_ATTR_MAC])
818965d3
JM
6741 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
6742 ETH_ALEN);
6743 else
6744 eth_broadcast_addr(request->bssid);
6745
fd014284 6746 request->wdev = wdev;
79c97e97 6747 request->wiphy = &rdev->wiphy;
15d6030b 6748 request->scan_start = jiffies;
2a519311 6749
79c97e97 6750 rdev->scan_req = request;
e35e4d28 6751 err = rdev_scan(rdev, request);
2a519311 6752
463d0183 6753 if (!err) {
fd014284
JB
6754 nl80211_send_scan_start(rdev, wdev);
6755 if (wdev->netdev)
6756 dev_hold(wdev->netdev);
4c476991 6757 } else {
2a519311 6758 out_free:
79c97e97 6759 rdev->scan_req = NULL;
2a519311
JB
6760 kfree(request);
6761 }
3b85875a 6762
f9f47529 6763 unlock:
2a519311
JB
6764 return err;
6765}
6766
91d3ab46
VK
6767static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
6768{
6769 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6770 struct wireless_dev *wdev = info->user_ptr[1];
6771
6772 if (!rdev->ops->abort_scan)
6773 return -EOPNOTSUPP;
6774
6775 if (rdev->scan_msg)
6776 return 0;
6777
6778 if (!rdev->scan_req)
6779 return -ENOENT;
6780
6781 rdev_abort_scan(rdev, wdev);
6782 return 0;
6783}
6784
3b06d277
AS
6785static int
6786nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
6787 struct cfg80211_sched_scan_request *request,
6788 struct nlattr **attrs)
6789{
6790 int tmp, err, i = 0;
6791 struct nlattr *attr;
6792
6793 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
6794 u32 interval;
6795
6796 /*
6797 * If scan plans are not specified,
5a88de53 6798 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
3b06d277
AS
6799 * case one scan plan will be set with the specified scan
6800 * interval and infinite number of iterations.
6801 */
3b06d277
AS
6802 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
6803 if (!interval)
6804 return -EINVAL;
6805
6806 request->scan_plans[0].interval =
6807 DIV_ROUND_UP(interval, MSEC_PER_SEC);
6808 if (!request->scan_plans[0].interval)
6809 return -EINVAL;
6810
6811 if (request->scan_plans[0].interval >
6812 wiphy->max_sched_scan_plan_interval)
6813 request->scan_plans[0].interval =
6814 wiphy->max_sched_scan_plan_interval;
6815
6816 return 0;
6817 }
6818
6819 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
6820 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
6821
6822 if (WARN_ON(i >= n_plans))
6823 return -EINVAL;
6824
bfe2c7b1
JB
6825 err = nla_parse_nested(plan, NL80211_SCHED_SCAN_PLAN_MAX,
6826 attr, nl80211_plan_policy);
3b06d277
AS
6827 if (err)
6828 return err;
6829
6830 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
6831 return -EINVAL;
6832
6833 request->scan_plans[i].interval =
6834 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
6835 if (!request->scan_plans[i].interval ||
6836 request->scan_plans[i].interval >
6837 wiphy->max_sched_scan_plan_interval)
6838 return -EINVAL;
6839
6840 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
6841 request->scan_plans[i].iterations =
6842 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
6843 if (!request->scan_plans[i].iterations ||
6844 (request->scan_plans[i].iterations >
6845 wiphy->max_sched_scan_plan_iterations))
6846 return -EINVAL;
6847 } else if (i < n_plans - 1) {
6848 /*
6849 * All scan plans but the last one must specify
6850 * a finite number of iterations
6851 */
6852 return -EINVAL;
6853 }
6854
6855 i++;
6856 }
6857
6858 /*
6859 * The last scan plan must not specify the number of
6860 * iterations, it is supposed to run infinitely
6861 */
6862 if (request->scan_plans[n_plans - 1].iterations)
6863 return -EINVAL;
6864
6865 return 0;
6866}
6867
256da02d 6868static struct cfg80211_sched_scan_request *
ad2b26ab 6869nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
256da02d 6870 struct nlattr **attrs)
807f8a8c
LC
6871{
6872 struct cfg80211_sched_scan_request *request;
807f8a8c 6873 struct nlattr *attr;
3b06d277 6874 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 6875 enum nl80211_band band;
807f8a8c 6876 size_t ie_len;
a1f1c21c 6877 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 6878 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 6879
256da02d
LC
6880 if (!is_valid_ie_attr(attrs[NL80211_ATTR_IE]))
6881 return ERR_PTR(-EINVAL);
807f8a8c 6882
256da02d 6883 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 6884 n_channels = validate_scan_freqs(
256da02d 6885 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 6886 if (!n_channels)
256da02d 6887 return ERR_PTR(-EINVAL);
807f8a8c 6888 } else {
bdfbec2d 6889 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
6890 }
6891
256da02d
LC
6892 if (attrs[NL80211_ATTR_SCAN_SSIDS])
6893 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
6894 tmp)
6895 n_ssids++;
6896
93b6aa69 6897 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 6898 return ERR_PTR(-EINVAL);
807f8a8c 6899
ea73cbce
JB
6900 /*
6901 * First, count the number of 'real' matchsets. Due to an issue with
6902 * the old implementation, matchsets containing only the RSSI attribute
6903 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
6904 * RSSI for all matchsets, rather than their own matchset for reporting
6905 * all APs with a strong RSSI. This is needed to be compatible with
6906 * older userspace that treated a matchset with only the RSSI as the
6907 * global RSSI for all other matchsets - if there are other matchsets.
6908 */
256da02d 6909 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 6910 nla_for_each_nested(attr,
256da02d 6911 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
6912 tmp) {
6913 struct nlattr *rssi;
6914
bfe2c7b1
JB
6915 err = nla_parse_nested(tb,
6916 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
6917 attr, nl80211_match_policy);
ea73cbce 6918 if (err)
256da02d 6919 return ERR_PTR(err);
ea73cbce
JB
6920 /* add other standalone attributes here */
6921 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
6922 n_match_sets++;
6923 continue;
6924 }
6925 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
6926 if (rssi)
6927 default_match_rssi = nla_get_s32(rssi);
6928 }
6929 }
6930
6931 /* However, if there's no other matchset, add the RSSI one */
6932 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
6933 n_match_sets = 1;
a1f1c21c
LC
6934
6935 if (n_match_sets > wiphy->max_match_sets)
256da02d 6936 return ERR_PTR(-EINVAL);
a1f1c21c 6937
256da02d
LC
6938 if (attrs[NL80211_ATTR_IE])
6939 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
6940 else
6941 ie_len = 0;
6942
5a865bad 6943 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 6944 return ERR_PTR(-EINVAL);
c10841ca 6945
3b06d277
AS
6946 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
6947 /*
6948 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
6949 * each scan plan already specifies its own interval
6950 */
6951 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
6952 return ERR_PTR(-EINVAL);
6953
6954 nla_for_each_nested(attr,
6955 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
6956 n_plans++;
6957 } else {
6958 /*
6959 * The scan interval attribute is kept for backward
6960 * compatibility. If no scan plans are specified and sched scan
6961 * interval is specified, one scan plan will be set with this
6962 * scan interval and infinite number of iterations.
6963 */
6964 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
6965 return ERR_PTR(-EINVAL);
6966
6967 n_plans = 1;
6968 }
6969
6970 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
6971 return ERR_PTR(-EINVAL);
6972
bf95ecdb 6973 if (!wiphy_ext_feature_isset(
6974 wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
6975 (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
6976 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
6977 return ERR_PTR(-EINVAL);
6978
807f8a8c 6979 request = kzalloc(sizeof(*request)
a2cd43c5 6980 + sizeof(*request->ssids) * n_ssids
a1f1c21c 6981 + sizeof(*request->match_sets) * n_match_sets
3b06d277 6982 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 6983 + sizeof(*request->channels) * n_channels
807f8a8c 6984 + ie_len, GFP_KERNEL);
256da02d
LC
6985 if (!request)
6986 return ERR_PTR(-ENOMEM);
807f8a8c
LC
6987
6988 if (n_ssids)
6989 request->ssids = (void *)&request->channels[n_channels];
6990 request->n_ssids = n_ssids;
6991 if (ie_len) {
13874e4b 6992 if (n_ssids)
807f8a8c
LC
6993 request->ie = (void *)(request->ssids + n_ssids);
6994 else
6995 request->ie = (void *)(request->channels + n_channels);
6996 }
6997
a1f1c21c
LC
6998 if (n_match_sets) {
6999 if (request->ie)
7000 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 7001 else if (n_ssids)
a1f1c21c
LC
7002 request->match_sets =
7003 (void *)(request->ssids + n_ssids);
7004 else
7005 request->match_sets =
7006 (void *)(request->channels + n_channels);
7007 }
7008 request->n_match_sets = n_match_sets;
7009
3b06d277
AS
7010 if (n_match_sets)
7011 request->scan_plans = (void *)(request->match_sets +
7012 n_match_sets);
7013 else if (request->ie)
7014 request->scan_plans = (void *)(request->ie + ie_len);
7015 else if (n_ssids)
7016 request->scan_plans = (void *)(request->ssids + n_ssids);
7017 else
7018 request->scan_plans = (void *)(request->channels + n_channels);
7019
7020 request->n_scan_plans = n_plans;
7021
807f8a8c 7022 i = 0;
256da02d 7023 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
7024 /* user specified, bail out if channel not found */
7025 nla_for_each_nested(attr,
256da02d 7026 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
7027 tmp) {
7028 struct ieee80211_channel *chan;
7029
7030 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
7031
7032 if (!chan) {
7033 err = -EINVAL;
7034 goto out_free;
7035 }
7036
7037 /* ignore disabled channels */
7038 if (chan->flags & IEEE80211_CHAN_DISABLED)
7039 continue;
7040
7041 request->channels[i] = chan;
7042 i++;
7043 }
7044 } else {
7045 /* all channels */
57fbcce3 7046 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 7047 int j;
7a087e74 7048
807f8a8c
LC
7049 if (!wiphy->bands[band])
7050 continue;
7051 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
7052 struct ieee80211_channel *chan;
7053
7054 chan = &wiphy->bands[band]->channels[j];
7055
7056 if (chan->flags & IEEE80211_CHAN_DISABLED)
7057 continue;
7058
7059 request->channels[i] = chan;
7060 i++;
7061 }
7062 }
7063 }
7064
7065 if (!i) {
7066 err = -EINVAL;
7067 goto out_free;
7068 }
7069
7070 request->n_channels = i;
7071
7072 i = 0;
13874e4b 7073 if (n_ssids) {
256da02d 7074 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 7075 tmp) {
57a27e1d 7076 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
7077 err = -EINVAL;
7078 goto out_free;
7079 }
57a27e1d 7080 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
7081 memcpy(request->ssids[i].ssid, nla_data(attr),
7082 nla_len(attr));
807f8a8c
LC
7083 i++;
7084 }
7085 }
7086
a1f1c21c 7087 i = 0;
256da02d 7088 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 7089 nla_for_each_nested(attr,
256da02d 7090 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 7091 tmp) {
88e920b4 7092 struct nlattr *ssid, *rssi;
a1f1c21c 7093
bfe2c7b1
JB
7094 err = nla_parse_nested(tb,
7095 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
7096 attr, nl80211_match_policy);
ae811e21
JB
7097 if (err)
7098 goto out_free;
4a4ab0d7 7099 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
a1f1c21c 7100 if (ssid) {
ea73cbce
JB
7101 if (WARN_ON(i >= n_match_sets)) {
7102 /* this indicates a programming error,
7103 * the loop above should have verified
7104 * things properly
7105 */
7106 err = -EINVAL;
7107 goto out_free;
7108 }
7109
a1f1c21c
LC
7110 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
7111 err = -EINVAL;
7112 goto out_free;
7113 }
7114 memcpy(request->match_sets[i].ssid.ssid,
7115 nla_data(ssid), nla_len(ssid));
7116 request->match_sets[i].ssid.ssid_len =
7117 nla_len(ssid);
56ab364f 7118 /* special attribute - old implementation w/a */
ea73cbce
JB
7119 request->match_sets[i].rssi_thold =
7120 default_match_rssi;
7121 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
7122 if (rssi)
7123 request->match_sets[i].rssi_thold =
7124 nla_get_s32(rssi);
a1f1c21c
LC
7125 }
7126 i++;
7127 }
ea73cbce
JB
7128
7129 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 7130 if (i == 0 && n_match_sets)
ea73cbce
JB
7131 request->match_sets[0].rssi_thold = default_match_rssi;
7132
7133 request->min_rssi_thold = INT_MAX;
7134 for (i = 0; i < n_match_sets; i++)
7135 request->min_rssi_thold =
7136 min(request->match_sets[i].rssi_thold,
7137 request->min_rssi_thold);
7138 } else {
7139 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
7140 }
7141
9900e484
JB
7142 if (ie_len) {
7143 request->ie_len = ie_len;
807f8a8c 7144 memcpy((void *)request->ie,
256da02d 7145 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
7146 request->ie_len);
7147 }
7148
256da02d 7149 if (attrs[NL80211_ATTR_SCAN_FLAGS]) {
ed473771 7150 request->flags = nla_get_u32(
256da02d 7151 attrs[NL80211_ATTR_SCAN_FLAGS]);
00c3a6ed
JB
7152 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
7153 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
46856bbf
SL
7154 err = -EOPNOTSUPP;
7155 goto out_free;
7156 }
ad2b26ab
JB
7157
7158 if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
7159 u32 flg = NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
7160
7161 if (!wdev) /* must be net-detect */
7162 flg = NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7163
7164 if (!(wiphy->features & flg)) {
7165 err = -EOPNOTSUPP;
7166 goto out_free;
7167 }
7168
7169 if (wdev && wdev->current_bss) {
7170 err = -EOPNOTSUPP;
7171 goto out_free;
7172 }
7173
7174 err = nl80211_parse_random_mac(attrs, request->mac_addr,
7175 request->mac_addr_mask);
7176 if (err)
7177 goto out_free;
7178 }
46856bbf 7179 }
ed473771 7180
9c748934
LC
7181 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
7182 request->delay =
7183 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
7184
bf95ecdb 7185 if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
7186 request->relative_rssi = nla_get_s8(
7187 attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
7188 request->relative_rssi_set = true;
7189 }
7190
7191 if (request->relative_rssi_set &&
7192 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
7193 struct nl80211_bss_select_rssi_adjust *rssi_adjust;
7194
7195 rssi_adjust = nla_data(
7196 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
7197 request->rssi_adjust.band = rssi_adjust->band;
7198 request->rssi_adjust.delta = rssi_adjust->delta;
7199 if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
7200 err = -EINVAL;
7201 goto out_free;
7202 }
7203 }
7204
3b06d277
AS
7205 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
7206 if (err)
7207 goto out_free;
7208
15d6030b 7209 request->scan_start = jiffies;
807f8a8c 7210
256da02d 7211 return request;
807f8a8c
LC
7212
7213out_free:
7214 kfree(request);
256da02d
LC
7215 return ERR_PTR(err);
7216}
7217
7218static int nl80211_start_sched_scan(struct sk_buff *skb,
7219 struct genl_info *info)
7220{
7221 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7222 struct net_device *dev = info->user_ptr[1];
ad2b26ab 7223 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 7224 struct cfg80211_sched_scan_request *sched_scan_req;
256da02d
LC
7225 int err;
7226
7227 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
7228 !rdev->ops->sched_scan_start)
7229 return -EOPNOTSUPP;
7230
7231 if (rdev->sched_scan_req)
7232 return -EINPROGRESS;
7233
31a60ed1
JR
7234 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
7235 info->attrs);
7236
7237 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
7238 if (err)
7239 goto out_err;
7240
31a60ed1 7241 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
7242 if (err)
7243 goto out_free;
7244
31a60ed1
JR
7245 sched_scan_req->dev = dev;
7246 sched_scan_req->wiphy = &rdev->wiphy;
7247
93a1e86c
JR
7248 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
7249 sched_scan_req->owner_nlportid = info->snd_portid;
7250
31a60ed1 7251 rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req);
256da02d
LC
7252
7253 nl80211_send_sched_scan(rdev, dev,
7254 NL80211_CMD_START_SCHED_SCAN);
7255 return 0;
7256
7257out_free:
31a60ed1 7258 kfree(sched_scan_req);
256da02d 7259out_err:
807f8a8c
LC
7260 return err;
7261}
7262
7263static int nl80211_stop_sched_scan(struct sk_buff *skb,
7264 struct genl_info *info)
7265{
7266 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7267
7268 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
7269 !rdev->ops->sched_scan_stop)
7270 return -EOPNOTSUPP;
7271
5fe231e8 7272 return __cfg80211_stop_sched_scan(rdev, false);
807f8a8c
LC
7273}
7274
04f39047
SW
7275static int nl80211_start_radar_detection(struct sk_buff *skb,
7276 struct genl_info *info)
7277{
7278 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7279 struct net_device *dev = info->user_ptr[1];
7280 struct wireless_dev *wdev = dev->ieee80211_ptr;
7281 struct cfg80211_chan_def chandef;
55f7435c 7282 enum nl80211_dfs_regions dfs_region;
31559f35 7283 unsigned int cac_time_ms;
04f39047
SW
7284 int err;
7285
55f7435c
LR
7286 dfs_region = reg_get_dfs_region(wdev->wiphy);
7287 if (dfs_region == NL80211_DFS_UNSET)
7288 return -EINVAL;
7289
04f39047
SW
7290 err = nl80211_parse_chandef(rdev, info, &chandef);
7291 if (err)
7292 return err;
7293
ff311bc1
SW
7294 if (netif_carrier_ok(dev))
7295 return -EBUSY;
7296
04f39047
SW
7297 if (wdev->cac_started)
7298 return -EBUSY;
7299
2beb6dab 7300 err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef,
00ec75fc 7301 wdev->iftype);
04f39047
SW
7302 if (err < 0)
7303 return err;
7304
7305 if (err == 0)
7306 return -EINVAL;
7307
fe7c3a1f 7308 if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef))
04f39047
SW
7309 return -EINVAL;
7310
7311 if (!rdev->ops->start_radar_detection)
7312 return -EOPNOTSUPP;
7313
31559f35
JD
7314 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
7315 if (WARN_ON(!cac_time_ms))
7316 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
7317
a1056b1b 7318 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 7319 if (!err) {
9e0e2961 7320 wdev->chandef = chandef;
04f39047
SW
7321 wdev->cac_started = true;
7322 wdev->cac_start_time = jiffies;
31559f35 7323 wdev->cac_time_ms = cac_time_ms;
04f39047 7324 }
04f39047
SW
7325 return err;
7326}
7327
16ef1fe2
SW
7328static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
7329{
7330 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7331 struct net_device *dev = info->user_ptr[1];
7332 struct wireless_dev *wdev = dev->ieee80211_ptr;
7333 struct cfg80211_csa_settings params;
7334 /* csa_attrs is defined static to avoid waste of stack size - this
7335 * function is called under RTNL lock, so this should not be a problem.
7336 */
7337 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
16ef1fe2 7338 int err;
ee4bc9e7 7339 bool need_new_beacon = false;
9a774c78 7340 int len, i;
252e07ca 7341 u32 cs_count;
16ef1fe2
SW
7342
7343 if (!rdev->ops->channel_switch ||
7344 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
7345 return -EOPNOTSUPP;
7346
ee4bc9e7
SW
7347 switch (dev->ieee80211_ptr->iftype) {
7348 case NL80211_IFTYPE_AP:
7349 case NL80211_IFTYPE_P2P_GO:
7350 need_new_beacon = true;
7351
7352 /* useless if AP is not running */
7353 if (!wdev->beacon_interval)
1ff79dfa 7354 return -ENOTCONN;
ee4bc9e7
SW
7355 break;
7356 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
7357 if (!wdev->ssid_len)
7358 return -ENOTCONN;
7359 break;
c6da674a 7360 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
7361 if (!wdev->mesh_id_len)
7362 return -ENOTCONN;
ee4bc9e7
SW
7363 break;
7364 default:
16ef1fe2 7365 return -EOPNOTSUPP;
ee4bc9e7 7366 }
16ef1fe2
SW
7367
7368 memset(&params, 0, sizeof(params));
7369
7370 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
7371 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
7372 return -EINVAL;
7373
7374 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 7375 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
7376 return -EINVAL;
7377
252e07ca
LC
7378 /* Even though the attribute is u32, the specification says
7379 * u8, so let's make sure we don't overflow.
7380 */
7381 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
7382 if (cs_count > 255)
7383 return -EINVAL;
7384
7385 params.count = cs_count;
16ef1fe2 7386
ee4bc9e7
SW
7387 if (!need_new_beacon)
7388 goto skip_beacons;
7389
16ef1fe2
SW
7390 err = nl80211_parse_beacon(info->attrs, &params.beacon_after);
7391 if (err)
7392 return err;
7393
7394 err = nla_parse_nested(csa_attrs, NL80211_ATTR_MAX,
7395 info->attrs[NL80211_ATTR_CSA_IES],
7396 nl80211_policy);
7397 if (err)
7398 return err;
7399
7400 err = nl80211_parse_beacon(csa_attrs, &params.beacon_csa);
7401 if (err)
7402 return err;
7403
7404 if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON])
7405 return -EINVAL;
7406
9a774c78
AO
7407 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
7408 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
7409 return -EINVAL;
7410
9a774c78
AO
7411 params.n_counter_offsets_beacon = len / sizeof(u16);
7412 if (rdev->wiphy.max_num_csa_counters &&
7413 (params.n_counter_offsets_beacon >
7414 rdev->wiphy.max_num_csa_counters))
16ef1fe2
SW
7415 return -EINVAL;
7416
9a774c78
AO
7417 params.counter_offsets_beacon =
7418 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
7419
7420 /* sanity checks - counters should fit and be the same */
7421 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
7422 u16 offset = params.counter_offsets_beacon[i];
7423
7424 if (offset >= params.beacon_csa.tail_len)
7425 return -EINVAL;
7426
7427 if (params.beacon_csa.tail[offset] != params.count)
7428 return -EINVAL;
7429 }
7430
16ef1fe2 7431 if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) {
9a774c78
AO
7432 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
7433 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
7434 return -EINVAL;
7435
9a774c78
AO
7436 params.n_counter_offsets_presp = len / sizeof(u16);
7437 if (rdev->wiphy.max_num_csa_counters &&
ad5987b4 7438 (params.n_counter_offsets_presp >
9a774c78 7439 rdev->wiphy.max_num_csa_counters))
16ef1fe2 7440 return -EINVAL;
9a774c78
AO
7441
7442 params.counter_offsets_presp =
7443 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
7444
7445 /* sanity checks - counters should fit and be the same */
7446 for (i = 0; i < params.n_counter_offsets_presp; i++) {
7447 u16 offset = params.counter_offsets_presp[i];
7448
7449 if (offset >= params.beacon_csa.probe_resp_len)
7450 return -EINVAL;
7451
7452 if (params.beacon_csa.probe_resp[offset] !=
7453 params.count)
7454 return -EINVAL;
7455 }
16ef1fe2
SW
7456 }
7457
ee4bc9e7 7458skip_beacons:
16ef1fe2
SW
7459 err = nl80211_parse_chandef(rdev, info, &params.chandef);
7460 if (err)
7461 return err;
7462
923b352f
AN
7463 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
7464 wdev->iftype))
16ef1fe2
SW
7465 return -EINVAL;
7466
2beb6dab
LC
7467 err = cfg80211_chandef_dfs_required(wdev->wiphy,
7468 &params.chandef,
7469 wdev->iftype);
7470 if (err < 0)
7471 return err;
7472
dcc6c2f5 7473 if (err > 0)
2beb6dab 7474 params.radar_required = true;
16ef1fe2 7475
16ef1fe2
SW
7476 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
7477 params.block_tx = true;
7478
c56589ed
SW
7479 wdev_lock(wdev);
7480 err = rdev_channel_switch(rdev, dev, &params);
7481 wdev_unlock(wdev);
7482
7483 return err;
16ef1fe2
SW
7484}
7485
9720bb3a
JB
7486static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
7487 u32 seq, int flags,
2a519311 7488 struct cfg80211_registered_device *rdev,
48ab905d
JB
7489 struct wireless_dev *wdev,
7490 struct cfg80211_internal_bss *intbss)
2a519311 7491{
48ab905d 7492 struct cfg80211_bss *res = &intbss->pub;
9caf0364 7493 const struct cfg80211_bss_ies *ies;
2a519311
JB
7494 void *hdr;
7495 struct nlattr *bss;
48ab905d
JB
7496
7497 ASSERT_WDEV_LOCK(wdev);
2a519311 7498
15e47304 7499 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
7500 NL80211_CMD_NEW_SCAN_RESULTS);
7501 if (!hdr)
7502 return -1;
7503
9720bb3a
JB
7504 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
7505
97990a06
JB
7506 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
7507 goto nla_put_failure;
7508 if (wdev->netdev &&
9360ffd1
DM
7509 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
7510 goto nla_put_failure;
2dad624e
ND
7511 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
7512 NL80211_ATTR_PAD))
97990a06 7513 goto nla_put_failure;
2a519311
JB
7514
7515 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
7516 if (!bss)
7517 goto nla_put_failure;
9360ffd1 7518 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 7519 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 7520 goto nla_put_failure;
9caf0364
JB
7521
7522 rcu_read_lock();
0e227084
JB
7523 /* indicate whether we have probe response data or not */
7524 if (rcu_access_pointer(res->proberesp_ies) &&
7525 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
7526 goto fail_unlock_rcu;
7527
7528 /* this pointer prefers to be pointed to probe response data
7529 * but is always valid
7530 */
9caf0364 7531 ies = rcu_dereference(res->ies);
8cef2c9d 7532 if (ies) {
2dad624e
ND
7533 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
7534 NL80211_BSS_PAD))
8cef2c9d 7535 goto fail_unlock_rcu;
8cef2c9d
JB
7536 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
7537 ies->len, ies->data))
7538 goto fail_unlock_rcu;
9caf0364 7539 }
0e227084
JB
7540
7541 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 7542 ies = rcu_dereference(res->beacon_ies);
0e227084 7543 if (ies && ies->from_beacon) {
2dad624e
ND
7544 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
7545 NL80211_BSS_PAD))
8cef2c9d
JB
7546 goto fail_unlock_rcu;
7547 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
7548 ies->len, ies->data))
7549 goto fail_unlock_rcu;
9caf0364
JB
7550 }
7551 rcu_read_unlock();
7552
9360ffd1
DM
7553 if (res->beacon_interval &&
7554 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
7555 goto nla_put_failure;
7556 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
7557 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
dcd6eac1 7558 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
7559 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
7560 jiffies_to_msecs(jiffies - intbss->ts)))
7561 goto nla_put_failure;
2a519311 7562
1d76250b
AS
7563 if (intbss->parent_tsf &&
7564 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
7565 intbss->parent_tsf, NL80211_BSS_PAD) ||
7566 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
7567 intbss->parent_bssid)))
7568 goto nla_put_failure;
7569
6e19bc4b 7570 if (intbss->ts_boottime &&
2dad624e
ND
7571 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
7572 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
7573 goto nla_put_failure;
7574
77965c97 7575 switch (rdev->wiphy.signal_type) {
2a519311 7576 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
7577 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
7578 goto nla_put_failure;
2a519311
JB
7579 break;
7580 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
7581 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
7582 goto nla_put_failure;
2a519311
JB
7583 break;
7584 default:
7585 break;
7586 }
7587
48ab905d 7588 switch (wdev->iftype) {
074ac8df 7589 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 7590 case NL80211_IFTYPE_STATION:
9360ffd1
DM
7591 if (intbss == wdev->current_bss &&
7592 nla_put_u32(msg, NL80211_BSS_STATUS,
7593 NL80211_BSS_STATUS_ASSOCIATED))
7594 goto nla_put_failure;
48ab905d
JB
7595 break;
7596 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
7597 if (intbss == wdev->current_bss &&
7598 nla_put_u32(msg, NL80211_BSS_STATUS,
7599 NL80211_BSS_STATUS_IBSS_JOINED))
7600 goto nla_put_failure;
48ab905d
JB
7601 break;
7602 default:
7603 break;
7604 }
7605
2a519311
JB
7606 nla_nest_end(msg, bss);
7607
053c095a
JB
7608 genlmsg_end(msg, hdr);
7609 return 0;
2a519311 7610
8cef2c9d
JB
7611 fail_unlock_rcu:
7612 rcu_read_unlock();
2a519311
JB
7613 nla_put_failure:
7614 genlmsg_cancel(msg, hdr);
7615 return -EMSGSIZE;
7616}
7617
97990a06 7618static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 7619{
48ab905d 7620 struct cfg80211_registered_device *rdev;
2a519311 7621 struct cfg80211_internal_bss *scan;
48ab905d 7622 struct wireless_dev *wdev;
97990a06 7623 int start = cb->args[2], idx = 0;
2a519311
JB
7624 int err;
7625
97990a06 7626 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
7627 if (err)
7628 return err;
2a519311 7629
48ab905d
JB
7630 wdev_lock(wdev);
7631 spin_lock_bh(&rdev->bss_lock);
7632 cfg80211_bss_expire(rdev);
7633
9720bb3a
JB
7634 cb->seq = rdev->bss_generation;
7635
48ab905d 7636 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
7637 if (++idx <= start)
7638 continue;
9720bb3a 7639 if (nl80211_send_bss(skb, cb,
2a519311 7640 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 7641 rdev, wdev, scan) < 0) {
2a519311 7642 idx--;
67748893 7643 break;
2a519311
JB
7644 }
7645 }
7646
48ab905d
JB
7647 spin_unlock_bh(&rdev->bss_lock);
7648 wdev_unlock(wdev);
2a519311 7649
97990a06
JB
7650 cb->args[2] = idx;
7651 nl80211_finish_wdev_dump(rdev);
2a519311 7652
67748893 7653 return skb->len;
2a519311
JB
7654}
7655
15e47304 7656static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
7657 int flags, struct net_device *dev,
7658 bool allow_radio_stats,
7659 struct survey_info *survey)
61fa713c
HS
7660{
7661 void *hdr;
7662 struct nlattr *infoattr;
7663
11f78ac3
JB
7664 /* skip radio stats if userspace didn't request them */
7665 if (!survey->channel && !allow_radio_stats)
7666 return 0;
7667
15e47304 7668 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
7669 NL80211_CMD_NEW_SURVEY_RESULTS);
7670 if (!hdr)
7671 return -ENOMEM;
7672
9360ffd1
DM
7673 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
7674 goto nla_put_failure;
61fa713c
HS
7675
7676 infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
7677 if (!infoattr)
7678 goto nla_put_failure;
7679
11f78ac3
JB
7680 if (survey->channel &&
7681 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
7682 survey->channel->center_freq))
7683 goto nla_put_failure;
7684
7685 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
7686 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
7687 goto nla_put_failure;
7688 if ((survey->filled & SURVEY_INFO_IN_USE) &&
7689 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
7690 goto nla_put_failure;
4ed20beb 7691 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
7692 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
7693 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 7694 goto nla_put_failure;
4ed20beb 7695 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
7696 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
7697 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 7698 goto nla_put_failure;
4ed20beb 7699 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
7700 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
7701 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 7702 goto nla_put_failure;
4ed20beb 7703 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
7704 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
7705 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 7706 goto nla_put_failure;
4ed20beb 7707 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
7708 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
7709 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 7710 goto nla_put_failure;
052536ab 7711 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
7712 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
7713 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 7714 goto nla_put_failure;
61fa713c
HS
7715
7716 nla_nest_end(msg, infoattr);
7717
053c095a
JB
7718 genlmsg_end(msg, hdr);
7719 return 0;
61fa713c
HS
7720
7721 nla_put_failure:
7722 genlmsg_cancel(msg, hdr);
7723 return -EMSGSIZE;
7724}
7725
11f78ac3 7726static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c 7727{
c90c39da 7728 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
61fa713c 7729 struct survey_info survey;
1b8ec87a 7730 struct cfg80211_registered_device *rdev;
97990a06
JB
7731 struct wireless_dev *wdev;
7732 int survey_idx = cb->args[2];
61fa713c 7733 int res;
11f78ac3 7734 bool radio_stats;
61fa713c 7735
1b8ec87a 7736 res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
7737 if (res)
7738 return res;
61fa713c 7739
11f78ac3 7740 /* prepare_wdev_dump parsed the attributes */
c90c39da 7741 radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
11f78ac3 7742
97990a06
JB
7743 if (!wdev->netdev) {
7744 res = -EINVAL;
7745 goto out_err;
7746 }
7747
1b8ec87a 7748 if (!rdev->ops->dump_survey) {
61fa713c
HS
7749 res = -EOPNOTSUPP;
7750 goto out_err;
7751 }
7752
7753 while (1) {
1b8ec87a 7754 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
7755 if (res == -ENOENT)
7756 break;
7757 if (res)
7758 goto out_err;
7759
11f78ac3
JB
7760 /* don't send disabled channels, but do send non-channel data */
7761 if (survey.channel &&
7762 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
7763 survey_idx++;
7764 continue;
7765 }
7766
61fa713c 7767 if (nl80211_send_survey(skb,
15e47304 7768 NETLINK_CB(cb->skb).portid,
61fa713c 7769 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 7770 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
7771 goto out;
7772 survey_idx++;
7773 }
7774
7775 out:
97990a06 7776 cb->args[2] = survey_idx;
61fa713c
HS
7777 res = skb->len;
7778 out_err:
1b8ec87a 7779 nl80211_finish_wdev_dump(rdev);
61fa713c
HS
7780 return res;
7781}
7782
b23aa676
SO
7783static bool nl80211_valid_wpa_versions(u32 wpa_versions)
7784{
7785 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
7786 NL80211_WPA_VERSION_2));
7787}
7788
636a5d36
JM
7789static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
7790{
4c476991
JB
7791 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7792 struct net_device *dev = info->user_ptr[1];
19957bb3 7793 struct ieee80211_channel *chan;
11b6b5a4
JM
7794 const u8 *bssid, *ssid, *ie = NULL, *auth_data = NULL;
7795 int err, ssid_len, ie_len = 0, auth_data_len = 0;
19957bb3 7796 enum nl80211_auth_type auth_type;
fffd0934 7797 struct key_parse key;
d5cdfacb 7798 bool local_state_change;
636a5d36 7799
f4a11bb0
JB
7800 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
7801 return -EINVAL;
7802
7803 if (!info->attrs[NL80211_ATTR_MAC])
7804 return -EINVAL;
7805
1778092e
JM
7806 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
7807 return -EINVAL;
7808
19957bb3
JB
7809 if (!info->attrs[NL80211_ATTR_SSID])
7810 return -EINVAL;
7811
7812 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
7813 return -EINVAL;
7814
fffd0934
JB
7815 err = nl80211_parse_key(info, &key);
7816 if (err)
7817 return err;
7818
7819 if (key.idx >= 0) {
e31b8213
JB
7820 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
7821 return -EINVAL;
fffd0934
JB
7822 if (!key.p.key || !key.p.key_len)
7823 return -EINVAL;
7824 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
7825 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
7826 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
7827 key.p.key_len != WLAN_KEY_LEN_WEP104))
7828 return -EINVAL;
b6b5555b 7829 if (key.idx > 3)
fffd0934
JB
7830 return -EINVAL;
7831 } else {
7832 key.p.key_len = 0;
7833 key.p.key = NULL;
7834 }
7835
afea0b7a
JB
7836 if (key.idx >= 0) {
7837 int i;
7838 bool ok = false;
7a087e74 7839
afea0b7a
JB
7840 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
7841 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
7842 ok = true;
7843 break;
7844 }
7845 }
4c476991
JB
7846 if (!ok)
7847 return -EINVAL;
afea0b7a
JB
7848 }
7849
4c476991
JB
7850 if (!rdev->ops->auth)
7851 return -EOPNOTSUPP;
636a5d36 7852
074ac8df 7853 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7854 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
7855 return -EOPNOTSUPP;
eec60b03 7856
19957bb3 7857 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
664834de
JM
7858 chan = nl80211_get_valid_chan(&rdev->wiphy,
7859 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
7860 if (!chan)
4c476991 7861 return -EINVAL;
636a5d36 7862
19957bb3
JB
7863 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
7864 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
7865
7866 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
7867 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
7868 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
7869 }
7870
19957bb3 7871 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 7872 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 7873 return -EINVAL;
636a5d36 7874
63181060
JM
7875 if ((auth_type == NL80211_AUTHTYPE_SAE ||
7876 auth_type == NL80211_AUTHTYPE_FILS_SK ||
7877 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
7878 auth_type == NL80211_AUTHTYPE_FILS_PK) &&
11b6b5a4 7879 !info->attrs[NL80211_ATTR_AUTH_DATA])
e39e5b5e
JM
7880 return -EINVAL;
7881
11b6b5a4 7882 if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
63181060
JM
7883 if (auth_type != NL80211_AUTHTYPE_SAE &&
7884 auth_type != NL80211_AUTHTYPE_FILS_SK &&
7885 auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
7886 auth_type != NL80211_AUTHTYPE_FILS_PK)
e39e5b5e 7887 return -EINVAL;
11b6b5a4
JM
7888 auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
7889 auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
e39e5b5e 7890 /* need to include at least Auth Transaction and Status Code */
11b6b5a4 7891 if (auth_data_len < 4)
e39e5b5e
JM
7892 return -EINVAL;
7893 }
7894
d5cdfacb
JM
7895 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
7896
95de817b
JB
7897 /*
7898 * Since we no longer track auth state, ignore
7899 * requests to only change local state.
7900 */
7901 if (local_state_change)
7902 return 0;
7903
91bf9b26
JB
7904 wdev_lock(dev->ieee80211_ptr);
7905 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
7906 ssid, ssid_len, ie, ie_len,
7907 key.p.key, key.p.key_len, key.idx,
11b6b5a4 7908 auth_data, auth_data_len);
91bf9b26
JB
7909 wdev_unlock(dev->ieee80211_ptr);
7910 return err;
636a5d36
JM
7911}
7912
c0692b8f
JB
7913static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
7914 struct genl_info *info,
3dc27d25
JB
7915 struct cfg80211_crypto_settings *settings,
7916 int cipher_limit)
b23aa676 7917{
c0b2bbd8
JB
7918 memset(settings, 0, sizeof(*settings));
7919
b23aa676
SO
7920 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
7921
c0692b8f
JB
7922 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
7923 u16 proto;
7a087e74 7924
c0692b8f
JB
7925 proto = nla_get_u16(
7926 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
7927 settings->control_port_ethertype = cpu_to_be16(proto);
7928 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
7929 proto != ETH_P_PAE)
7930 return -EINVAL;
7931 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
7932 settings->control_port_no_encrypt = true;
7933 } else
7934 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
7935
b23aa676
SO
7936 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
7937 void *data;
7938 int len, i;
7939
7940 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
7941 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
7942 settings->n_ciphers_pairwise = len / sizeof(u32);
7943
7944 if (len % sizeof(u32))
7945 return -EINVAL;
7946
3dc27d25 7947 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
7948 return -EINVAL;
7949
7950 memcpy(settings->ciphers_pairwise, data, len);
7951
7952 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
7953 if (!cfg80211_supported_cipher_suite(
7954 &rdev->wiphy,
b23aa676
SO
7955 settings->ciphers_pairwise[i]))
7956 return -EINVAL;
7957 }
7958
7959 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
7960 settings->cipher_group =
7961 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
7962 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
7963 settings->cipher_group))
b23aa676
SO
7964 return -EINVAL;
7965 }
7966
7967 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
7968 settings->wpa_versions =
7969 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
7970 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
7971 return -EINVAL;
7972 }
7973
7974 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
7975 void *data;
6d30240e 7976 int len;
b23aa676
SO
7977
7978 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
7979 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
7980 settings->n_akm_suites = len / sizeof(u32);
7981
7982 if (len % sizeof(u32))
7983 return -EINVAL;
7984
1b9ca027
JM
7985 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
7986 return -EINVAL;
7987
b23aa676 7988 memcpy(settings->akm_suites, data, len);
b23aa676
SO
7989 }
7990
7991 return 0;
7992}
7993
636a5d36
JM
7994static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
7995{
4c476991
JB
7996 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7997 struct net_device *dev = info->user_ptr[1];
f444de05 7998 struct ieee80211_channel *chan;
f62fab73
JB
7999 struct cfg80211_assoc_request req = {};
8000 const u8 *bssid, *ssid;
8001 int err, ssid_len = 0;
636a5d36 8002
f4a11bb0
JB
8003 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8004 return -EINVAL;
8005
8006 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
8007 !info->attrs[NL80211_ATTR_SSID] ||
8008 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
8009 return -EINVAL;
8010
4c476991
JB
8011 if (!rdev->ops->assoc)
8012 return -EOPNOTSUPP;
636a5d36 8013
074ac8df 8014 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8015 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8016 return -EOPNOTSUPP;
eec60b03 8017
19957bb3 8018 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8019
664834de
JM
8020 chan = nl80211_get_valid_chan(&rdev->wiphy,
8021 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8022 if (!chan)
4c476991 8023 return -EINVAL;
636a5d36 8024
19957bb3
JB
8025 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8026 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
8027
8028 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
8029 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8030 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8031 }
8032
dc6382ce 8033 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 8034 enum nl80211_mfp mfp =
dc6382ce 8035 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 8036 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 8037 req.use_mfp = true;
4c476991
JB
8038 else if (mfp != NL80211_MFP_NO)
8039 return -EINVAL;
dc6382ce
JM
8040 }
8041
3e5d7649 8042 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 8043 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 8044
7e7c8926 8045 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 8046 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
8047
8048 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
8049 memcpy(&req.ht_capa_mask,
8050 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8051 sizeof(req.ht_capa_mask));
7e7c8926
BG
8052
8053 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 8054 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 8055 return -EINVAL;
f62fab73
JB
8056 memcpy(&req.ht_capa,
8057 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8058 sizeof(req.ht_capa));
7e7c8926
BG
8059 }
8060
ee2aca34 8061 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 8062 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34
JB
8063
8064 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
8065 memcpy(&req.vht_capa_mask,
8066 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
8067 sizeof(req.vht_capa_mask));
ee2aca34
JB
8068
8069 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 8070 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 8071 return -EINVAL;
f62fab73
JB
8072 memcpy(&req.vht_capa,
8073 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
8074 sizeof(req.vht_capa));
ee2aca34
JB
8075 }
8076
bab5ab7d 8077 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
8078 if (!((rdev->wiphy.features &
8079 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
8080 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
8081 !wiphy_ext_feature_isset(&rdev->wiphy,
8082 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
8083 return -EINVAL;
8084 req.flags |= ASSOC_REQ_USE_RRM;
8085 }
8086
348bd456
JM
8087 if (info->attrs[NL80211_ATTR_FILS_KEK]) {
8088 req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
8089 req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
8090 if (!info->attrs[NL80211_ATTR_FILS_NONCES])
8091 return -EINVAL;
8092 req.fils_nonces =
8093 nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
8094 }
8095
f62fab73 8096 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
8097 if (!err) {
8098 wdev_lock(dev->ieee80211_ptr);
bd2522b1 8099
f62fab73
JB
8100 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
8101 ssid, ssid_len, &req);
bd2522b1
AZ
8102
8103 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
8104 dev->ieee80211_ptr->conn_owner_nlportid =
8105 info->snd_portid;
8106 memcpy(dev->ieee80211_ptr->disconnect_bssid,
8107 bssid, ETH_ALEN);
8108 }
8109
91bf9b26
JB
8110 wdev_unlock(dev->ieee80211_ptr);
8111 }
636a5d36 8112
636a5d36
JM
8113 return err;
8114}
8115
8116static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
8117{
4c476991
JB
8118 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8119 struct net_device *dev = info->user_ptr[1];
19957bb3 8120 const u8 *ie = NULL, *bssid;
91bf9b26 8121 int ie_len = 0, err;
19957bb3 8122 u16 reason_code;
d5cdfacb 8123 bool local_state_change;
636a5d36 8124
f4a11bb0
JB
8125 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8126 return -EINVAL;
8127
8128 if (!info->attrs[NL80211_ATTR_MAC])
8129 return -EINVAL;
8130
8131 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8132 return -EINVAL;
8133
4c476991
JB
8134 if (!rdev->ops->deauth)
8135 return -EOPNOTSUPP;
636a5d36 8136
074ac8df 8137 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8138 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8139 return -EOPNOTSUPP;
eec60b03 8140
19957bb3 8141 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8142
19957bb3
JB
8143 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8144 if (reason_code == 0) {
f4a11bb0 8145 /* Reason Code 0 is reserved */
4c476991 8146 return -EINVAL;
255e737e 8147 }
636a5d36
JM
8148
8149 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8150 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8151 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8152 }
8153
d5cdfacb
JM
8154 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8155
91bf9b26
JB
8156 wdev_lock(dev->ieee80211_ptr);
8157 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
8158 local_state_change);
8159 wdev_unlock(dev->ieee80211_ptr);
8160 return err;
636a5d36
JM
8161}
8162
8163static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
8164{
4c476991
JB
8165 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8166 struct net_device *dev = info->user_ptr[1];
19957bb3 8167 const u8 *ie = NULL, *bssid;
91bf9b26 8168 int ie_len = 0, err;
19957bb3 8169 u16 reason_code;
d5cdfacb 8170 bool local_state_change;
636a5d36 8171
f4a11bb0
JB
8172 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8173 return -EINVAL;
8174
8175 if (!info->attrs[NL80211_ATTR_MAC])
8176 return -EINVAL;
8177
8178 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8179 return -EINVAL;
8180
4c476991
JB
8181 if (!rdev->ops->disassoc)
8182 return -EOPNOTSUPP;
636a5d36 8183
074ac8df 8184 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8185 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8186 return -EOPNOTSUPP;
eec60b03 8187
19957bb3 8188 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8189
19957bb3
JB
8190 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8191 if (reason_code == 0) {
f4a11bb0 8192 /* Reason Code 0 is reserved */
4c476991 8193 return -EINVAL;
255e737e 8194 }
636a5d36
JM
8195
8196 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8197 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8198 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8199 }
8200
d5cdfacb
JM
8201 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8202
91bf9b26
JB
8203 wdev_lock(dev->ieee80211_ptr);
8204 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
8205 local_state_change);
8206 wdev_unlock(dev->ieee80211_ptr);
8207 return err;
636a5d36
JM
8208}
8209
dd5b4cc7
FF
8210static bool
8211nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 8212 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
8213 int rateval)
8214{
8215 struct wiphy *wiphy = &rdev->wiphy;
8216 bool found = false;
8217 int band, i;
8218
57fbcce3 8219 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
8220 struct ieee80211_supported_band *sband;
8221
8222 sband = wiphy->bands[band];
8223 if (!sband)
8224 continue;
8225
8226 for (i = 0; i < sband->n_bitrates; i++) {
8227 if (sband->bitrates[i].bitrate == rateval) {
8228 mcast_rate[band] = i + 1;
8229 found = true;
8230 break;
8231 }
8232 }
8233 }
8234
8235 return found;
8236}
8237
04a773ad
JB
8238static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
8239{
4c476991
JB
8240 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8241 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
8242 struct cfg80211_ibss_params ibss;
8243 struct wiphy *wiphy;
fffd0934 8244 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
8245 int err;
8246
8e30bc55
JB
8247 memset(&ibss, 0, sizeof(ibss));
8248
04a773ad
JB
8249 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8250 return -EINVAL;
8251
683b6d3b 8252 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
8253 !nla_len(info->attrs[NL80211_ATTR_SSID]))
8254 return -EINVAL;
8255
8e30bc55
JB
8256 ibss.beacon_interval = 100;
8257
12d20fc9 8258 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
8259 ibss.beacon_interval =
8260 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 8261
0c317a02
PK
8262 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
8263 ibss.beacon_interval);
12d20fc9
PK
8264 if (err)
8265 return err;
8e30bc55 8266
4c476991
JB
8267 if (!rdev->ops->join_ibss)
8268 return -EOPNOTSUPP;
04a773ad 8269
4c476991
JB
8270 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
8271 return -EOPNOTSUPP;
04a773ad 8272
79c97e97 8273 wiphy = &rdev->wiphy;
04a773ad 8274
39193498 8275 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 8276 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
8277
8278 if (!is_valid_ether_addr(ibss.bssid))
8279 return -EINVAL;
8280 }
04a773ad
JB
8281 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8282 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
8283
8284 if (info->attrs[NL80211_ATTR_IE]) {
8285 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8286 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8287 }
8288
683b6d3b
JB
8289 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
8290 if (err)
8291 return err;
04a773ad 8292
174e0cd2
IP
8293 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
8294 NL80211_IFTYPE_ADHOC))
54858ee5
AS
8295 return -EINVAL;
8296
2f301ab2 8297 switch (ibss.chandef.width) {
bf372645
SW
8298 case NL80211_CHAN_WIDTH_5:
8299 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
8300 case NL80211_CHAN_WIDTH_20_NOHT:
8301 break;
8302 case NL80211_CHAN_WIDTH_20:
8303 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
8304 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8305 return -EINVAL;
8306 break;
8307 case NL80211_CHAN_WIDTH_80:
8308 case NL80211_CHAN_WIDTH_80P80:
8309 case NL80211_CHAN_WIDTH_160:
8310 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8311 return -EINVAL;
8312 if (!wiphy_ext_feature_isset(&rdev->wiphy,
8313 NL80211_EXT_FEATURE_VHT_IBSS))
8314 return -EINVAL;
8315 break;
2f301ab2 8316 default:
c04d6150 8317 return -EINVAL;
2f301ab2 8318 }
db9c64cf 8319
04a773ad 8320 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
8321 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
8322
fbd2c8dc
TP
8323 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
8324 u8 *rates =
8325 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8326 int n_rates =
8327 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8328 struct ieee80211_supported_band *sband =
683b6d3b 8329 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 8330
34850ab2
JB
8331 err = ieee80211_get_ratemask(sband, rates, n_rates,
8332 &ibss.basic_rates);
8333 if (err)
8334 return err;
fbd2c8dc 8335 }
dd5b4cc7 8336
803768f5
SW
8337 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8338 memcpy(&ibss.ht_capa_mask,
8339 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8340 sizeof(ibss.ht_capa_mask));
8341
8342 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
8343 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8344 return -EINVAL;
8345 memcpy(&ibss.ht_capa,
8346 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8347 sizeof(ibss.ht_capa));
8348 }
8349
dd5b4cc7
FF
8350 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
8351 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
8352 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
8353 return -EINVAL;
fbd2c8dc 8354
4c476991 8355 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
8356 bool no_ht = false;
8357
4c476991 8358 connkeys = nl80211_parse_connkeys(rdev,
de7044ee
SM
8359 info->attrs[NL80211_ATTR_KEYS],
8360 &no_ht);
4c476991
JB
8361 if (IS_ERR(connkeys))
8362 return PTR_ERR(connkeys);
de7044ee 8363
3d9d1d66
JB
8364 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
8365 no_ht) {
5e950a78 8366 kzfree(connkeys);
de7044ee
SM
8367 return -EINVAL;
8368 }
4c476991 8369 }
04a773ad 8370
267335d6
AQ
8371 ibss.control_port =
8372 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
8373
5336fa88
SW
8374 ibss.userspace_handles_dfs =
8375 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
8376
4c476991 8377 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 8378 if (err)
b47f610b 8379 kzfree(connkeys);
04a773ad
JB
8380 return err;
8381}
8382
8383static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
8384{
4c476991
JB
8385 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8386 struct net_device *dev = info->user_ptr[1];
04a773ad 8387
4c476991
JB
8388 if (!rdev->ops->leave_ibss)
8389 return -EOPNOTSUPP;
04a773ad 8390
4c476991
JB
8391 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
8392 return -EOPNOTSUPP;
04a773ad 8393
4c476991 8394 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
8395}
8396
f4e583c8
AQ
8397static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
8398{
8399 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8400 struct net_device *dev = info->user_ptr[1];
57fbcce3 8401 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
8402 u32 nla_rate;
8403 int err;
8404
8405 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
8406 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
8407 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
8408 return -EOPNOTSUPP;
8409
8410 if (!rdev->ops->set_mcast_rate)
8411 return -EOPNOTSUPP;
8412
8413 memset(mcast_rate, 0, sizeof(mcast_rate));
8414
8415 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
8416 return -EINVAL;
8417
8418 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
8419 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
8420 return -EINVAL;
8421
a1056b1b 8422 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
8423
8424 return err;
8425}
8426
ad7e718c
JB
8427static struct sk_buff *
8428__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
8429 struct wireless_dev *wdev, int approxlen,
8430 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
8431 enum nl80211_attrs attr,
8432 const struct nl80211_vendor_cmd_info *info,
8433 gfp_t gfp)
ad7e718c
JB
8434{
8435 struct sk_buff *skb;
8436 void *hdr;
8437 struct nlattr *data;
8438
8439 skb = nlmsg_new(approxlen + 100, gfp);
8440 if (!skb)
8441 return NULL;
8442
8443 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
8444 if (!hdr) {
8445 kfree_skb(skb);
8446 return NULL;
8447 }
8448
8449 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
8450 goto nla_put_failure;
567ffc35
JB
8451
8452 if (info) {
8453 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
8454 info->vendor_id))
8455 goto nla_put_failure;
8456 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
8457 info->subcmd))
8458 goto nla_put_failure;
8459 }
8460
6c09e791 8461 if (wdev) {
2dad624e
ND
8462 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
8463 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
8464 goto nla_put_failure;
8465 if (wdev->netdev &&
8466 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
8467 wdev->netdev->ifindex))
8468 goto nla_put_failure;
8469 }
8470
ad7e718c 8471 data = nla_nest_start(skb, attr);
76e1fb4b
JB
8472 if (!data)
8473 goto nla_put_failure;
ad7e718c
JB
8474
8475 ((void **)skb->cb)[0] = rdev;
8476 ((void **)skb->cb)[1] = hdr;
8477 ((void **)skb->cb)[2] = data;
8478
8479 return skb;
8480
8481 nla_put_failure:
8482 kfree_skb(skb);
8483 return NULL;
8484}
f4e583c8 8485
e03ad6ea 8486struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 8487 struct wireless_dev *wdev,
e03ad6ea
JB
8488 enum nl80211_commands cmd,
8489 enum nl80211_attrs attr,
8490 int vendor_event_idx,
8491 int approxlen, gfp_t gfp)
8492{
f26cbf40 8493 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
8494 const struct nl80211_vendor_cmd_info *info;
8495
8496 switch (cmd) {
8497 case NL80211_CMD_TESTMODE:
8498 if (WARN_ON(vendor_event_idx != -1))
8499 return NULL;
8500 info = NULL;
8501 break;
8502 case NL80211_CMD_VENDOR:
8503 if (WARN_ON(vendor_event_idx < 0 ||
8504 vendor_event_idx >= wiphy->n_vendor_events))
8505 return NULL;
8506 info = &wiphy->vendor_events[vendor_event_idx];
8507 break;
8508 default:
8509 WARN_ON(1);
8510 return NULL;
8511 }
8512
6c09e791 8513 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, 0, 0,
e03ad6ea
JB
8514 cmd, attr, info, gfp);
8515}
8516EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
8517
8518void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
8519{
8520 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
8521 void *hdr = ((void **)skb->cb)[1];
8522 struct nlattr *data = ((void **)skb->cb)[2];
8523 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
8524
bd8c78e7
JB
8525 /* clear CB data for netlink core to own from now on */
8526 memset(skb->cb, 0, sizeof(skb->cb));
8527
e03ad6ea
JB
8528 nla_nest_end(skb, data);
8529 genlmsg_end(skb, hdr);
8530
8531 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
8532 mcgrp = NL80211_MCGRP_VENDOR;
8533
8534 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0,
8535 mcgrp, gfp);
8536}
8537EXPORT_SYMBOL(__cfg80211_send_event_skb);
8538
aff89a9b 8539#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
8540static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
8541{
4c476991 8542 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fc73f11f
DS
8543 struct wireless_dev *wdev =
8544 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
aff89a9b
JB
8545 int err;
8546
fc73f11f
DS
8547 if (!rdev->ops->testmode_cmd)
8548 return -EOPNOTSUPP;
8549
8550 if (IS_ERR(wdev)) {
8551 err = PTR_ERR(wdev);
8552 if (err != -EINVAL)
8553 return err;
8554 wdev = NULL;
8555 } else if (wdev->wiphy != &rdev->wiphy) {
8556 return -EINVAL;
8557 }
8558
aff89a9b
JB
8559 if (!info->attrs[NL80211_ATTR_TESTDATA])
8560 return -EINVAL;
8561
ad7e718c 8562 rdev->cur_cmd_info = info;
fc73f11f 8563 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
8564 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
8565 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 8566 rdev->cur_cmd_info = NULL;
aff89a9b 8567
aff89a9b
JB
8568 return err;
8569}
8570
71063f0e
WYG
8571static int nl80211_testmode_dump(struct sk_buff *skb,
8572 struct netlink_callback *cb)
8573{
00918d33 8574 struct cfg80211_registered_device *rdev;
71063f0e
WYG
8575 int err;
8576 long phy_idx;
8577 void *data = NULL;
8578 int data_len = 0;
8579
5fe231e8
JB
8580 rtnl_lock();
8581
71063f0e
WYG
8582 if (cb->args[0]) {
8583 /*
8584 * 0 is a valid index, but not valid for args[0],
8585 * so we need to offset by 1.
8586 */
8587 phy_idx = cb->args[0] - 1;
8588 } else {
c90c39da
JB
8589 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
8590
71063f0e 8591 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
c90c39da 8592 attrbuf, nl80211_fam.maxattr, nl80211_policy);
71063f0e 8593 if (err)
5fe231e8 8594 goto out_err;
00918d33 8595
c90c39da 8596 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
2bd7e35d 8597 if (IS_ERR(rdev)) {
5fe231e8
JB
8598 err = PTR_ERR(rdev);
8599 goto out_err;
00918d33 8600 }
2bd7e35d
JB
8601 phy_idx = rdev->wiphy_idx;
8602 rdev = NULL;
2bd7e35d 8603
c90c39da
JB
8604 if (attrbuf[NL80211_ATTR_TESTDATA])
8605 cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
71063f0e
WYG
8606 }
8607
8608 if (cb->args[1]) {
8609 data = nla_data((void *)cb->args[1]);
8610 data_len = nla_len((void *)cb->args[1]);
8611 }
8612
00918d33
JB
8613 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
8614 if (!rdev) {
5fe231e8
JB
8615 err = -ENOENT;
8616 goto out_err;
71063f0e 8617 }
71063f0e 8618
00918d33 8619 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
8620 err = -EOPNOTSUPP;
8621 goto out_err;
8622 }
8623
8624 while (1) {
15e47304 8625 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
8626 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8627 NL80211_CMD_TESTMODE);
8628 struct nlattr *tmdata;
8629
cb35fba3
DC
8630 if (!hdr)
8631 break;
8632
9360ffd1 8633 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
8634 genlmsg_cancel(skb, hdr);
8635 break;
8636 }
8637
8638 tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
8639 if (!tmdata) {
8640 genlmsg_cancel(skb, hdr);
8641 break;
8642 }
e35e4d28 8643 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
8644 nla_nest_end(skb, tmdata);
8645
8646 if (err == -ENOBUFS || err == -ENOENT) {
8647 genlmsg_cancel(skb, hdr);
8648 break;
8649 } else if (err) {
8650 genlmsg_cancel(skb, hdr);
8651 goto out_err;
8652 }
8653
8654 genlmsg_end(skb, hdr);
8655 }
8656
8657 err = skb->len;
8658 /* see above */
8659 cb->args[0] = phy_idx + 1;
8660 out_err:
5fe231e8 8661 rtnl_unlock();
71063f0e
WYG
8662 return err;
8663}
aff89a9b
JB
8664#endif
8665
b23aa676
SO
8666static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
8667{
4c476991
JB
8668 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8669 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
8670 struct cfg80211_connect_params connect;
8671 struct wiphy *wiphy;
fffd0934 8672 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
8673 int err;
8674
8675 memset(&connect, 0, sizeof(connect));
8676
8677 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8678 return -EINVAL;
8679
8680 if (!info->attrs[NL80211_ATTR_SSID] ||
8681 !nla_len(info->attrs[NL80211_ATTR_SSID]))
8682 return -EINVAL;
8683
8684 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
8685 connect.auth_type =
8686 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
8687 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
8688 NL80211_CMD_CONNECT))
b23aa676
SO
8689 return -EINVAL;
8690 } else
8691 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
8692
8693 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
8694
c0692b8f 8695 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 8696 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
8697 if (err)
8698 return err;
b23aa676 8699
074ac8df 8700 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8701 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8702 return -EOPNOTSUPP;
b23aa676 8703
79c97e97 8704 wiphy = &rdev->wiphy;
b23aa676 8705
4486ea98
BS
8706 connect.bg_scan_period = -1;
8707 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
8708 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
8709 connect.bg_scan_period =
8710 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
8711 }
8712
b23aa676
SO
8713 if (info->attrs[NL80211_ATTR_MAC])
8714 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
8715 else if (info->attrs[NL80211_ATTR_MAC_HINT])
8716 connect.bssid_hint =
8717 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
8718 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8719 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
8720
8721 if (info->attrs[NL80211_ATTR_IE]) {
8722 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8723 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8724 }
8725
cee00a95
JM
8726 if (info->attrs[NL80211_ATTR_USE_MFP]) {
8727 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
8728 if (connect.mfp != NL80211_MFP_REQUIRED &&
8729 connect.mfp != NL80211_MFP_NO)
8730 return -EINVAL;
8731 } else {
8732 connect.mfp = NL80211_MFP_NO;
8733 }
8734
ba6fbacf
JM
8735 if (info->attrs[NL80211_ATTR_PREV_BSSID])
8736 connect.prev_bssid =
8737 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
8738
b23aa676 8739 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
664834de
JM
8740 connect.channel = nl80211_get_valid_chan(
8741 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8742 if (!connect.channel)
1df4a510
JM
8743 return -EINVAL;
8744 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
664834de
JM
8745 connect.channel_hint = nl80211_get_valid_chan(
8746 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
8747 if (!connect.channel_hint)
4c476991 8748 return -EINVAL;
b23aa676
SO
8749 }
8750
fffd0934
JB
8751 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
8752 connkeys = nl80211_parse_connkeys(rdev,
de7044ee 8753 info->attrs[NL80211_ATTR_KEYS], NULL);
4c476991
JB
8754 if (IS_ERR(connkeys))
8755 return PTR_ERR(connkeys);
fffd0934
JB
8756 }
8757
7e7c8926
BG
8758 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
8759 connect.flags |= ASSOC_REQ_DISABLE_HT;
8760
8761 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8762 memcpy(&connect.ht_capa_mask,
8763 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8764 sizeof(connect.ht_capa_mask));
8765
8766 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 8767 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
b47f610b 8768 kzfree(connkeys);
7e7c8926 8769 return -EINVAL;
b4e4f47e 8770 }
7e7c8926
BG
8771 memcpy(&connect.ht_capa,
8772 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8773 sizeof(connect.ht_capa));
8774 }
8775
ee2aca34
JB
8776 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
8777 connect.flags |= ASSOC_REQ_DISABLE_VHT;
8778
8779 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
8780 memcpy(&connect.vht_capa_mask,
8781 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
8782 sizeof(connect.vht_capa_mask));
8783
8784 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
8785 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
b47f610b 8786 kzfree(connkeys);
ee2aca34
JB
8787 return -EINVAL;
8788 }
8789 memcpy(&connect.vht_capa,
8790 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
8791 sizeof(connect.vht_capa));
8792 }
8793
bab5ab7d 8794 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
8795 if (!((rdev->wiphy.features &
8796 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
8797 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
8798 !wiphy_ext_feature_isset(&rdev->wiphy,
8799 NL80211_EXT_FEATURE_RRM)) {
707554b4 8800 kzfree(connkeys);
bab5ab7d 8801 return -EINVAL;
707554b4 8802 }
bab5ab7d
AK
8803 connect.flags |= ASSOC_REQ_USE_RRM;
8804 }
8805
34d50519 8806 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 8807 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
34d50519
LD
8808 kzfree(connkeys);
8809 return -EOPNOTSUPP;
8810 }
8811
38de03d2
AS
8812 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
8813 /* bss selection makes no sense if bssid is set */
8814 if (connect.bssid) {
8815 kzfree(connkeys);
8816 return -EINVAL;
8817 }
8818
8819 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
8820 wiphy, &connect.bss_select);
8821 if (err) {
8822 kzfree(connkeys);
8823 return err;
8824 }
8825 }
8826
83739b03 8827 wdev_lock(dev->ieee80211_ptr);
bd2522b1 8828
4ce2bd9c
JM
8829 err = cfg80211_connect(rdev, dev, &connect, connkeys,
8830 connect.prev_bssid);
fffd0934 8831 if (err)
b47f610b 8832 kzfree(connkeys);
bd2522b1
AZ
8833
8834 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
8835 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
8836 if (connect.bssid)
8837 memcpy(dev->ieee80211_ptr->disconnect_bssid,
8838 connect.bssid, ETH_ALEN);
8839 else
8840 memset(dev->ieee80211_ptr->disconnect_bssid,
8841 0, ETH_ALEN);
8842 }
8843
8844 wdev_unlock(dev->ieee80211_ptr);
8845
b23aa676
SO
8846 return err;
8847}
8848
088e8df8 8849static int nl80211_update_connect_params(struct sk_buff *skb,
8850 struct genl_info *info)
8851{
8852 struct cfg80211_connect_params connect = {};
8853 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8854 struct net_device *dev = info->user_ptr[1];
8855 struct wireless_dev *wdev = dev->ieee80211_ptr;
8856 u32 changed = 0;
8857 int ret;
8858
8859 if (!rdev->ops->update_connect_params)
8860 return -EOPNOTSUPP;
8861
8862 if (info->attrs[NL80211_ATTR_IE]) {
8863 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8864 return -EINVAL;
8865 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8866 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8867 changed |= UPDATE_ASSOC_IES;
8868 }
8869
8870 wdev_lock(dev->ieee80211_ptr);
8871 if (!wdev->current_bss)
8872 ret = -ENOLINK;
8873 else
8874 ret = rdev_update_connect_params(rdev, dev, &connect, changed);
8875 wdev_unlock(dev->ieee80211_ptr);
8876
8877 return ret;
8878}
8879
b23aa676
SO
8880static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
8881{
4c476991
JB
8882 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8883 struct net_device *dev = info->user_ptr[1];
b23aa676 8884 u16 reason;
83739b03 8885 int ret;
b23aa676
SO
8886
8887 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8888 reason = WLAN_REASON_DEAUTH_LEAVING;
8889 else
8890 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8891
8892 if (reason == 0)
8893 return -EINVAL;
8894
074ac8df 8895 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8896 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8897 return -EOPNOTSUPP;
b23aa676 8898
83739b03
JB
8899 wdev_lock(dev->ieee80211_ptr);
8900 ret = cfg80211_disconnect(rdev, dev, reason, true);
8901 wdev_unlock(dev->ieee80211_ptr);
8902 return ret;
b23aa676
SO
8903}
8904
463d0183
JB
8905static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
8906{
4c476991 8907 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
8908 struct net *net;
8909 int err;
463d0183 8910
4b681c82
VK
8911 if (info->attrs[NL80211_ATTR_PID]) {
8912 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
8913
8914 net = get_net_ns_by_pid(pid);
8915 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
8916 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 8917
4b681c82
VK
8918 net = get_net_ns_by_fd(fd);
8919 } else {
8920 return -EINVAL;
8921 }
463d0183 8922
4c476991
JB
8923 if (IS_ERR(net))
8924 return PTR_ERR(net);
463d0183
JB
8925
8926 err = 0;
8927
8928 /* check if anything to do */
4c476991
JB
8929 if (!net_eq(wiphy_net(&rdev->wiphy), net))
8930 err = cfg80211_switch_netns(rdev, net);
463d0183 8931
463d0183 8932 put_net(net);
463d0183
JB
8933 return err;
8934}
8935
67fbb16b
SO
8936static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
8937{
4c476991 8938 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
8939 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
8940 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 8941 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
8942 struct cfg80211_pmksa pmksa;
8943
8944 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
8945
8946 if (!info->attrs[NL80211_ATTR_MAC])
8947 return -EINVAL;
8948
8949 if (!info->attrs[NL80211_ATTR_PMKID])
8950 return -EINVAL;
8951
67fbb16b
SO
8952 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
8953 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
8954
074ac8df 8955 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8956 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8957 return -EOPNOTSUPP;
67fbb16b
SO
8958
8959 switch (info->genlhdr->cmd) {
8960 case NL80211_CMD_SET_PMKSA:
8961 rdev_ops = rdev->ops->set_pmksa;
8962 break;
8963 case NL80211_CMD_DEL_PMKSA:
8964 rdev_ops = rdev->ops->del_pmksa;
8965 break;
8966 default:
8967 WARN_ON(1);
8968 break;
8969 }
8970
4c476991
JB
8971 if (!rdev_ops)
8972 return -EOPNOTSUPP;
67fbb16b 8973
4c476991 8974 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
8975}
8976
8977static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
8978{
4c476991
JB
8979 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8980 struct net_device *dev = info->user_ptr[1];
67fbb16b 8981
074ac8df 8982 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8983 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8984 return -EOPNOTSUPP;
67fbb16b 8985
4c476991
JB
8986 if (!rdev->ops->flush_pmksa)
8987 return -EOPNOTSUPP;
67fbb16b 8988
e35e4d28 8989 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
8990}
8991
109086ce
AN
8992static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
8993{
8994 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8995 struct net_device *dev = info->user_ptr[1];
8996 u8 action_code, dialog_token;
df942e7b 8997 u32 peer_capability = 0;
109086ce
AN
8998 u16 status_code;
8999 u8 *peer;
31fa97c5 9000 bool initiator;
109086ce
AN
9001
9002 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
9003 !rdev->ops->tdls_mgmt)
9004 return -EOPNOTSUPP;
9005
9006 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
9007 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
9008 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
9009 !info->attrs[NL80211_ATTR_IE] ||
9010 !info->attrs[NL80211_ATTR_MAC])
9011 return -EINVAL;
9012
9013 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
9014 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
9015 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
9016 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 9017 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
9018 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
9019 peer_capability =
9020 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 9021
e35e4d28 9022 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 9023 dialog_token, status_code, peer_capability,
31fa97c5 9024 initiator,
e35e4d28
HG
9025 nla_data(info->attrs[NL80211_ATTR_IE]),
9026 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
9027}
9028
9029static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
9030{
9031 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9032 struct net_device *dev = info->user_ptr[1];
9033 enum nl80211_tdls_operation operation;
9034 u8 *peer;
9035
9036 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
9037 !rdev->ops->tdls_oper)
9038 return -EOPNOTSUPP;
9039
9040 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
9041 !info->attrs[NL80211_ATTR_MAC])
9042 return -EINVAL;
9043
9044 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
9045 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
9046
e35e4d28 9047 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
9048}
9049
9588bbd5
JM
9050static int nl80211_remain_on_channel(struct sk_buff *skb,
9051 struct genl_info *info)
9052{
4c476991 9053 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9054 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 9055 struct cfg80211_chan_def chandef;
9588bbd5
JM
9056 struct sk_buff *msg;
9057 void *hdr;
9058 u64 cookie;
683b6d3b 9059 u32 duration;
9588bbd5
JM
9060 int err;
9061
9062 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
9063 !info->attrs[NL80211_ATTR_DURATION])
9064 return -EINVAL;
9065
9066 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
9067
ebf348fc
JB
9068 if (!rdev->ops->remain_on_channel ||
9069 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
9070 return -EOPNOTSUPP;
9071
9588bbd5 9072 /*
ebf348fc
JB
9073 * We should be on that channel for at least a minimum amount of
9074 * time (10ms) but no longer than the driver supports.
9588bbd5 9075 */
ebf348fc 9076 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 9077 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
9078 return -EINVAL;
9079
683b6d3b
JB
9080 err = nl80211_parse_chandef(rdev, info, &chandef);
9081 if (err)
9082 return err;
9588bbd5
JM
9083
9084 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
9085 if (!msg)
9086 return -ENOMEM;
9588bbd5 9087
15e47304 9088 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 9089 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
9090 if (!hdr) {
9091 err = -ENOBUFS;
9588bbd5
JM
9092 goto free_msg;
9093 }
9094
683b6d3b
JB
9095 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
9096 duration, &cookie);
9588bbd5
JM
9097
9098 if (err)
9099 goto free_msg;
9100
2dad624e
ND
9101 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
9102 NL80211_ATTR_PAD))
9360ffd1 9103 goto nla_put_failure;
9588bbd5
JM
9104
9105 genlmsg_end(msg, hdr);
4c476991
JB
9106
9107 return genlmsg_reply(msg, info);
9588bbd5
JM
9108
9109 nla_put_failure:
9110 err = -ENOBUFS;
9111 free_msg:
9112 nlmsg_free(msg);
9588bbd5
JM
9113 return err;
9114}
9115
9116static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
9117 struct genl_info *info)
9118{
4c476991 9119 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9120 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 9121 u64 cookie;
9588bbd5
JM
9122
9123 if (!info->attrs[NL80211_ATTR_COOKIE])
9124 return -EINVAL;
9125
4c476991
JB
9126 if (!rdev->ops->cancel_remain_on_channel)
9127 return -EOPNOTSUPP;
9588bbd5 9128
9588bbd5
JM
9129 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9130
e35e4d28 9131 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
9132}
9133
13ae75b1
JM
9134static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
9135 struct genl_info *info)
9136{
13ae75b1 9137 struct cfg80211_bitrate_mask mask;
a7c7fbff 9138 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 9139 struct net_device *dev = info->user_ptr[1];
a7c7fbff 9140 int err;
13ae75b1 9141
4c476991
JB
9142 if (!rdev->ops->set_bitrate_mask)
9143 return -EOPNOTSUPP;
13ae75b1 9144
a7c7fbff
PK
9145 err = nl80211_parse_tx_bitrate_mask(info, &mask);
9146 if (err)
9147 return err;
13ae75b1 9148
e35e4d28 9149 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
9150}
9151
2e161f78 9152static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 9153{
4c476991 9154 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9155 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 9156 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
9157
9158 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
9159 return -EINVAL;
9160
2e161f78
JB
9161 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
9162 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 9163
71bbc994
JB
9164 switch (wdev->iftype) {
9165 case NL80211_IFTYPE_STATION:
9166 case NL80211_IFTYPE_ADHOC:
9167 case NL80211_IFTYPE_P2P_CLIENT:
9168 case NL80211_IFTYPE_AP:
9169 case NL80211_IFTYPE_AP_VLAN:
9170 case NL80211_IFTYPE_MESH_POINT:
9171 case NL80211_IFTYPE_P2P_GO:
98104fde 9172 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 9173 break;
cb3b7d87 9174 case NL80211_IFTYPE_NAN:
71bbc994 9175 default:
4c476991 9176 return -EOPNOTSUPP;
71bbc994 9177 }
026331c4
JM
9178
9179 /* not much point in registering if we can't reply */
4c476991
JB
9180 if (!rdev->ops->mgmt_tx)
9181 return -EOPNOTSUPP;
026331c4 9182
15e47304 9183 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
026331c4
JM
9184 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
9185 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
026331c4
JM
9186}
9187
2e161f78 9188static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 9189{
4c476991 9190 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9191 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 9192 struct cfg80211_chan_def chandef;
026331c4 9193 int err;
d64d373f 9194 void *hdr = NULL;
026331c4 9195 u64 cookie;
e247bd90 9196 struct sk_buff *msg = NULL;
b176e629
AO
9197 struct cfg80211_mgmt_tx_params params = {
9198 .dont_wait_for_ack =
9199 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
9200 };
026331c4 9201
683b6d3b 9202 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
9203 return -EINVAL;
9204
4c476991
JB
9205 if (!rdev->ops->mgmt_tx)
9206 return -EOPNOTSUPP;
026331c4 9207
71bbc994 9208 switch (wdev->iftype) {
ea141b75
AQ
9209 case NL80211_IFTYPE_P2P_DEVICE:
9210 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
9211 return -EINVAL;
71bbc994
JB
9212 case NL80211_IFTYPE_STATION:
9213 case NL80211_IFTYPE_ADHOC:
9214 case NL80211_IFTYPE_P2P_CLIENT:
9215 case NL80211_IFTYPE_AP:
9216 case NL80211_IFTYPE_AP_VLAN:
9217 case NL80211_IFTYPE_MESH_POINT:
9218 case NL80211_IFTYPE_P2P_GO:
9219 break;
cb3b7d87 9220 case NL80211_IFTYPE_NAN:
71bbc994 9221 default:
4c476991 9222 return -EOPNOTSUPP;
71bbc994 9223 }
026331c4 9224
f7ca38df 9225 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 9226 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 9227 return -EINVAL;
b176e629 9228 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
9229
9230 /*
9231 * We should wait on the channel for at least a minimum amount
9232 * of time (10ms) but no longer than the driver supports.
9233 */
b176e629
AO
9234 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
9235 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 9236 return -EINVAL;
f7ca38df
JB
9237 }
9238
b176e629 9239 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 9240
b176e629 9241 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
9242 return -EINVAL;
9243
b176e629 9244 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 9245
ea141b75
AQ
9246 /* get the channel if any has been specified, otherwise pass NULL to
9247 * the driver. The latter will use the current one
9248 */
9249 chandef.chan = NULL;
9250 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
9251 err = nl80211_parse_chandef(rdev, info, &chandef);
9252 if (err)
9253 return err;
9254 }
9255
b176e629 9256 if (!chandef.chan && params.offchan)
ea141b75 9257 return -EINVAL;
026331c4 9258
34d22ce2
AO
9259 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
9260 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
9261
9262 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
9263 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
9264 int i;
9265
9266 if (len % sizeof(u16))
9267 return -EINVAL;
9268
9269 params.n_csa_offsets = len / sizeof(u16);
9270 params.csa_offsets =
9271 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
9272
9273 /* check that all the offsets fit the frame */
9274 for (i = 0; i < params.n_csa_offsets; i++) {
9275 if (params.csa_offsets[i] >= params.len)
9276 return -EINVAL;
9277 }
9278 }
9279
b176e629 9280 if (!params.dont_wait_for_ack) {
e247bd90
JB
9281 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9282 if (!msg)
9283 return -ENOMEM;
026331c4 9284
15e47304 9285 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 9286 NL80211_CMD_FRAME);
cb35fba3
DC
9287 if (!hdr) {
9288 err = -ENOBUFS;
e247bd90
JB
9289 goto free_msg;
9290 }
026331c4 9291 }
e247bd90 9292
b176e629
AO
9293 params.chan = chandef.chan;
9294 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
9295 if (err)
9296 goto free_msg;
9297
e247bd90 9298 if (msg) {
2dad624e
ND
9299 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
9300 NL80211_ATTR_PAD))
9360ffd1 9301 goto nla_put_failure;
026331c4 9302
e247bd90
JB
9303 genlmsg_end(msg, hdr);
9304 return genlmsg_reply(msg, info);
9305 }
9306
9307 return 0;
026331c4
JM
9308
9309 nla_put_failure:
9310 err = -ENOBUFS;
9311 free_msg:
9312 nlmsg_free(msg);
026331c4
JM
9313 return err;
9314}
9315
f7ca38df
JB
9316static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
9317{
9318 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9319 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
9320 u64 cookie;
9321
9322 if (!info->attrs[NL80211_ATTR_COOKIE])
9323 return -EINVAL;
9324
9325 if (!rdev->ops->mgmt_tx_cancel_wait)
9326 return -EOPNOTSUPP;
9327
71bbc994
JB
9328 switch (wdev->iftype) {
9329 case NL80211_IFTYPE_STATION:
9330 case NL80211_IFTYPE_ADHOC:
9331 case NL80211_IFTYPE_P2P_CLIENT:
9332 case NL80211_IFTYPE_AP:
9333 case NL80211_IFTYPE_AP_VLAN:
9334 case NL80211_IFTYPE_P2P_GO:
98104fde 9335 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 9336 break;
cb3b7d87 9337 case NL80211_IFTYPE_NAN:
71bbc994 9338 default:
f7ca38df 9339 return -EOPNOTSUPP;
71bbc994 9340 }
f7ca38df
JB
9341
9342 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9343
e35e4d28 9344 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
9345}
9346
ffb9eb3d
KV
9347static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
9348{
4c476991 9349 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 9350 struct wireless_dev *wdev;
4c476991 9351 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
9352 u8 ps_state;
9353 bool state;
9354 int err;
9355
4c476991
JB
9356 if (!info->attrs[NL80211_ATTR_PS_STATE])
9357 return -EINVAL;
ffb9eb3d
KV
9358
9359 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
9360
4c476991
JB
9361 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
9362 return -EINVAL;
ffb9eb3d
KV
9363
9364 wdev = dev->ieee80211_ptr;
9365
4c476991
JB
9366 if (!rdev->ops->set_power_mgmt)
9367 return -EOPNOTSUPP;
ffb9eb3d
KV
9368
9369 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
9370
9371 if (state == wdev->ps)
4c476991 9372 return 0;
ffb9eb3d 9373
e35e4d28 9374 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
9375 if (!err)
9376 wdev->ps = state;
ffb9eb3d
KV
9377 return err;
9378}
9379
9380static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
9381{
4c476991 9382 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
9383 enum nl80211_ps_state ps_state;
9384 struct wireless_dev *wdev;
4c476991 9385 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
9386 struct sk_buff *msg;
9387 void *hdr;
9388 int err;
9389
ffb9eb3d
KV
9390 wdev = dev->ieee80211_ptr;
9391
4c476991
JB
9392 if (!rdev->ops->set_power_mgmt)
9393 return -EOPNOTSUPP;
ffb9eb3d
KV
9394
9395 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
9396 if (!msg)
9397 return -ENOMEM;
ffb9eb3d 9398
15e47304 9399 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
9400 NL80211_CMD_GET_POWER_SAVE);
9401 if (!hdr) {
4c476991 9402 err = -ENOBUFS;
ffb9eb3d
KV
9403 goto free_msg;
9404 }
9405
9406 if (wdev->ps)
9407 ps_state = NL80211_PS_ENABLED;
9408 else
9409 ps_state = NL80211_PS_DISABLED;
9410
9360ffd1
DM
9411 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
9412 goto nla_put_failure;
ffb9eb3d
KV
9413
9414 genlmsg_end(msg, hdr);
4c476991 9415 return genlmsg_reply(msg, info);
ffb9eb3d 9416
4c476991 9417 nla_put_failure:
ffb9eb3d 9418 err = -ENOBUFS;
4c476991 9419 free_msg:
ffb9eb3d 9420 nlmsg_free(msg);
ffb9eb3d
KV
9421 return err;
9422}
9423
94e860f1
JB
9424static const struct nla_policy
9425nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
d6dc1a38
JO
9426 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
9427 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
9428 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
9429 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
9430 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
9431 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
d6dc1a38
JO
9432};
9433
84f10708 9434static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 9435 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
9436{
9437 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 9438 struct net_device *dev = info->user_ptr[1];
1da5fcc8 9439 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 9440
d9d8b019 9441 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
9442 return -EINVAL;
9443
84f10708
TP
9444 if (!rdev->ops->set_cqm_txe_config)
9445 return -EOPNOTSUPP;
9446
9447 if (wdev->iftype != NL80211_IFTYPE_STATION &&
9448 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
9449 return -EOPNOTSUPP;
9450
e35e4d28 9451 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
9452}
9453
d6dc1a38
JO
9454static int nl80211_set_cqm_rssi(struct genl_info *info,
9455 s32 threshold, u32 hysteresis)
9456{
4c476991 9457 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 9458 struct net_device *dev = info->user_ptr[1];
1da5fcc8 9459 struct wireless_dev *wdev = dev->ieee80211_ptr;
d6dc1a38
JO
9460
9461 if (threshold > 0)
9462 return -EINVAL;
9463
1da5fcc8
JB
9464 /* disabling - hysteresis should also be zero then */
9465 if (threshold == 0)
9466 hysteresis = 0;
d6dc1a38 9467
4c476991
JB
9468 if (!rdev->ops->set_cqm_rssi_config)
9469 return -EOPNOTSUPP;
d6dc1a38 9470
074ac8df 9471 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9472 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
9473 return -EOPNOTSUPP;
d6dc1a38 9474
e35e4d28 9475 return rdev_set_cqm_rssi_config(rdev, dev, threshold, hysteresis);
d6dc1a38
JO
9476}
9477
9478static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
9479{
9480 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
9481 struct nlattr *cqm;
9482 int err;
9483
9484 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
9485 if (!cqm)
9486 return -EINVAL;
d6dc1a38
JO
9487
9488 err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
9489 nl80211_attr_cqm_policy);
9490 if (err)
1da5fcc8 9491 return err;
d6dc1a38
JO
9492
9493 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
9494 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
1da5fcc8
JB
9495 s32 threshold = nla_get_s32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
9496 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 9497
1da5fcc8
JB
9498 return nl80211_set_cqm_rssi(info, threshold, hysteresis);
9499 }
9500
9501 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
9502 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
9503 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
9504 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
9505 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
9506 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
9507
9508 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
9509 }
9510
9511 return -EINVAL;
d6dc1a38
JO
9512}
9513
6e0bd6c3
RL
9514static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
9515{
9516 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9517 struct net_device *dev = info->user_ptr[1];
9518 struct ocb_setup setup = {};
9519 int err;
9520
9521 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
9522 if (err)
9523 return err;
9524
9525 return cfg80211_join_ocb(rdev, dev, &setup);
9526}
9527
9528static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
9529{
9530 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9531 struct net_device *dev = info->user_ptr[1];
9532
9533 return cfg80211_leave_ocb(rdev, dev);
9534}
9535
29cbe68c
JB
9536static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
9537{
9538 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9539 struct net_device *dev = info->user_ptr[1];
9540 struct mesh_config cfg;
c80d545d 9541 struct mesh_setup setup;
29cbe68c
JB
9542 int err;
9543
9544 /* start with default */
9545 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 9546 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 9547
24bdd9f4 9548 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 9549 /* and parse parameters if given */
24bdd9f4 9550 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
9551 if (err)
9552 return err;
9553 }
9554
9555 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
9556 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
9557 return -EINVAL;
9558
c80d545d
JC
9559 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
9560 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
9561
4bb62344
CYY
9562 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
9563 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
9564 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
9565 return -EINVAL;
9566
9bdbf04d
MP
9567 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
9568 setup.beacon_interval =
9569 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 9570
0c317a02
PK
9571 err = cfg80211_validate_beacon_int(rdev,
9572 NL80211_IFTYPE_MESH_POINT,
9573 setup.beacon_interval);
12d20fc9
PK
9574 if (err)
9575 return err;
9bdbf04d
MP
9576 }
9577
9578 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
9579 setup.dtim_period =
9580 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
9581 if (setup.dtim_period < 1 || setup.dtim_period > 100)
9582 return -EINVAL;
9583 }
9584
c80d545d
JC
9585 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
9586 /* parse additional setup parameters if given */
9587 err = nl80211_parse_mesh_setup(info, &setup);
9588 if (err)
9589 return err;
9590 }
9591
d37bb18a
TP
9592 if (setup.user_mpm)
9593 cfg.auto_open_plinks = false;
9594
cc1d2806 9595 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
9596 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
9597 if (err)
9598 return err;
cc1d2806
JB
9599 } else {
9600 /* cfg80211_join_mesh() will sort it out */
683b6d3b 9601 setup.chandef.chan = NULL;
cc1d2806
JB
9602 }
9603
ffb3cf30
AN
9604 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
9605 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9606 int n_rates =
9607 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9608 struct ieee80211_supported_band *sband;
9609
9610 if (!setup.chandef.chan)
9611 return -EINVAL;
9612
9613 sband = rdev->wiphy.bands[setup.chandef.chan->band];
9614
9615 err = ieee80211_get_ratemask(sband, rates, n_rates,
9616 &setup.basic_rates);
9617 if (err)
9618 return err;
9619 }
9620
8564e382
JB
9621 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9622 err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate);
9623 if (err)
9624 return err;
9625
9626 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
9627 &setup.beacon_rate);
9628 if (err)
9629 return err;
9630 }
9631
c80d545d 9632 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
29cbe68c
JB
9633}
9634
9635static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
9636{
9637 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9638 struct net_device *dev = info->user_ptr[1];
9639
9640 return cfg80211_leave_mesh(rdev, dev);
9641}
9642
dfb89c56 9643#ifdef CONFIG_PM
bb92d199
AK
9644static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
9645 struct cfg80211_registered_device *rdev)
9646{
6abb9cb9 9647 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
9648 struct nlattr *nl_pats, *nl_pat;
9649 int i, pat_len;
9650
6abb9cb9 9651 if (!wowlan->n_patterns)
bb92d199
AK
9652 return 0;
9653
9654 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
9655 if (!nl_pats)
9656 return -ENOBUFS;
9657
6abb9cb9 9658 for (i = 0; i < wowlan->n_patterns; i++) {
bb92d199
AK
9659 nl_pat = nla_nest_start(msg, i + 1);
9660 if (!nl_pat)
9661 return -ENOBUFS;
6abb9cb9 9662 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 9663 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 9664 wowlan->patterns[i].mask) ||
50ac6607
AK
9665 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
9666 wowlan->patterns[i].pattern) ||
9667 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 9668 wowlan->patterns[i].pkt_offset))
bb92d199
AK
9669 return -ENOBUFS;
9670 nla_nest_end(msg, nl_pat);
9671 }
9672 nla_nest_end(msg, nl_pats);
9673
9674 return 0;
9675}
9676
2a0e047e
JB
9677static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
9678 struct cfg80211_wowlan_tcp *tcp)
9679{
9680 struct nlattr *nl_tcp;
9681
9682 if (!tcp)
9683 return 0;
9684
9685 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
9686 if (!nl_tcp)
9687 return -ENOBUFS;
9688
930345ea
JB
9689 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
9690 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
9691 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
9692 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
9693 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
9694 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
9695 tcp->payload_len, tcp->payload) ||
9696 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
9697 tcp->data_interval) ||
9698 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
9699 tcp->wake_len, tcp->wake_data) ||
9700 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
9701 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
9702 return -ENOBUFS;
9703
9704 if (tcp->payload_seq.len &&
9705 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
9706 sizeof(tcp->payload_seq), &tcp->payload_seq))
9707 return -ENOBUFS;
9708
9709 if (tcp->payload_tok.len &&
9710 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
9711 sizeof(tcp->payload_tok) + tcp->tokens_size,
9712 &tcp->payload_tok))
9713 return -ENOBUFS;
9714
e248ad30
JB
9715 nla_nest_end(msg, nl_tcp);
9716
2a0e047e
JB
9717 return 0;
9718}
9719
75453ccb
LC
9720static int nl80211_send_wowlan_nd(struct sk_buff *msg,
9721 struct cfg80211_sched_scan_request *req)
9722{
3b06d277 9723 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
9724 int i;
9725
9726 if (!req)
9727 return 0;
9728
9729 nd = nla_nest_start(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
9730 if (!nd)
9731 return -ENOBUFS;
9732
3b06d277
AS
9733 if (req->n_scan_plans == 1 &&
9734 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
9735 req->scan_plans[0].interval * 1000))
75453ccb
LC
9736 return -ENOBUFS;
9737
21fea567
LC
9738 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
9739 return -ENOBUFS;
9740
bf95ecdb 9741 if (req->relative_rssi_set) {
9742 struct nl80211_bss_select_rssi_adjust rssi_adjust;
9743
9744 if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
9745 req->relative_rssi))
9746 return -ENOBUFS;
9747
9748 rssi_adjust.band = req->rssi_adjust.band;
9749 rssi_adjust.delta = req->rssi_adjust.delta;
9750 if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
9751 sizeof(rssi_adjust), &rssi_adjust))
9752 return -ENOBUFS;
9753 }
9754
75453ccb
LC
9755 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
9756 if (!freqs)
9757 return -ENOBUFS;
9758
53b18980
JB
9759 for (i = 0; i < req->n_channels; i++) {
9760 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
9761 return -ENOBUFS;
9762 }
75453ccb
LC
9763
9764 nla_nest_end(msg, freqs);
9765
9766 if (req->n_match_sets) {
9767 matches = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
9768 if (!matches)
9769 return -ENOBUFS;
9770
75453ccb
LC
9771 for (i = 0; i < req->n_match_sets; i++) {
9772 match = nla_nest_start(msg, i);
76e1fb4b
JB
9773 if (!match)
9774 return -ENOBUFS;
9775
53b18980
JB
9776 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
9777 req->match_sets[i].ssid.ssid_len,
9778 req->match_sets[i].ssid.ssid))
9779 return -ENOBUFS;
75453ccb
LC
9780 nla_nest_end(msg, match);
9781 }
9782 nla_nest_end(msg, matches);
9783 }
9784
3b06d277
AS
9785 scan_plans = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
9786 if (!scan_plans)
9787 return -ENOBUFS;
9788
9789 for (i = 0; i < req->n_scan_plans; i++) {
9790 scan_plan = nla_nest_start(msg, i + 1);
76e1fb4b
JB
9791 if (!scan_plan)
9792 return -ENOBUFS;
9793
3b06d277
AS
9794 if (!scan_plan ||
9795 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
9796 req->scan_plans[i].interval) ||
9797 (req->scan_plans[i].iterations &&
9798 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
9799 req->scan_plans[i].iterations)))
9800 return -ENOBUFS;
9801 nla_nest_end(msg, scan_plan);
9802 }
9803 nla_nest_end(msg, scan_plans);
9804
75453ccb
LC
9805 nla_nest_end(msg, nd);
9806
9807 return 0;
9808}
9809
ff1b6e69
JB
9810static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
9811{
9812 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9813 struct sk_buff *msg;
9814 void *hdr;
2a0e047e 9815 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 9816
964dc9e2 9817 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
9818 return -EOPNOTSUPP;
9819
6abb9cb9 9820 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 9821 /* adjust size to have room for all the data */
6abb9cb9
JB
9822 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
9823 rdev->wiphy.wowlan_config->tcp->payload_len +
9824 rdev->wiphy.wowlan_config->tcp->wake_len +
9825 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
9826 }
9827
9828 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
9829 if (!msg)
9830 return -ENOMEM;
9831
15e47304 9832 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
9833 NL80211_CMD_GET_WOWLAN);
9834 if (!hdr)
9835 goto nla_put_failure;
9836
6abb9cb9 9837 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
9838 struct nlattr *nl_wowlan;
9839
9840 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
9841 if (!nl_wowlan)
9842 goto nla_put_failure;
9843
6abb9cb9 9844 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 9845 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 9846 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 9847 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 9848 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 9849 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 9850 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 9851 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 9852 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 9853 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 9854 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 9855 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 9856 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
9857 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
9858 goto nla_put_failure;
2a0e047e 9859
bb92d199
AK
9860 if (nl80211_send_wowlan_patterns(msg, rdev))
9861 goto nla_put_failure;
2a0e047e 9862
6abb9cb9
JB
9863 if (nl80211_send_wowlan_tcp(msg,
9864 rdev->wiphy.wowlan_config->tcp))
2a0e047e 9865 goto nla_put_failure;
75453ccb
LC
9866
9867 if (nl80211_send_wowlan_nd(
9868 msg,
9869 rdev->wiphy.wowlan_config->nd_config))
9870 goto nla_put_failure;
2a0e047e 9871
ff1b6e69
JB
9872 nla_nest_end(msg, nl_wowlan);
9873 }
9874
9875 genlmsg_end(msg, hdr);
9876 return genlmsg_reply(msg, info);
9877
9878nla_put_failure:
9879 nlmsg_free(msg);
9880 return -ENOBUFS;
9881}
9882
2a0e047e
JB
9883static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
9884 struct nlattr *attr,
9885 struct cfg80211_wowlan *trig)
9886{
9887 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
9888 struct cfg80211_wowlan_tcp *cfg;
9889 struct nl80211_wowlan_tcp_data_token *tok = NULL;
9890 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
9891 u32 size;
9892 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
9893 int err, port;
9894
964dc9e2 9895 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
9896 return -EINVAL;
9897
bfe2c7b1
JB
9898 err = nla_parse_nested(tb, MAX_NL80211_WOWLAN_TCP, attr,
9899 nl80211_wowlan_tcp_policy);
2a0e047e
JB
9900 if (err)
9901 return err;
9902
9903 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
9904 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
9905 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
9906 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
9907 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
9908 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
9909 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
9910 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
9911 return -EINVAL;
9912
9913 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 9914 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
9915 return -EINVAL;
9916
9917 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 9918 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 9919 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
9920 return -EINVAL;
9921
9922 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 9923 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
9924 return -EINVAL;
9925
9926 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
9927 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
9928 return -EINVAL;
9929
9930 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
9931 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
9932
9933 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
9934 tokens_size = tokln - sizeof(*tok);
9935
9936 if (!tok->len || tokens_size % tok->len)
9937 return -EINVAL;
964dc9e2 9938 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 9939 return -EINVAL;
964dc9e2 9940 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 9941 return -EINVAL;
964dc9e2 9942 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 9943 return -EINVAL;
964dc9e2 9944 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
9945 return -EINVAL;
9946 if (tok->offset + tok->len > data_size)
9947 return -EINVAL;
9948 }
9949
9950 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
9951 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 9952 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
9953 return -EINVAL;
9954 if (seq->len == 0 || seq->len > 4)
9955 return -EINVAL;
9956 if (seq->len + seq->offset > data_size)
9957 return -EINVAL;
9958 }
9959
9960 size = sizeof(*cfg);
9961 size += data_size;
9962 size += wake_size + wake_mask_size;
9963 size += tokens_size;
9964
9965 cfg = kzalloc(size, GFP_KERNEL);
9966 if (!cfg)
9967 return -ENOMEM;
67b61f6c
JB
9968 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
9969 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
9970 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
9971 ETH_ALEN);
9972 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
9973 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
9974 else
9975 port = 0;
9976#ifdef CONFIG_INET
9977 /* allocate a socket and port for it and use it */
9978 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
9979 IPPROTO_TCP, &cfg->sock, 1);
9980 if (err) {
9981 kfree(cfg);
9982 return err;
9983 }
9984 if (inet_csk_get_port(cfg->sock->sk, port)) {
9985 sock_release(cfg->sock);
9986 kfree(cfg);
9987 return -EADDRINUSE;
9988 }
9989 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
9990#else
9991 if (!port) {
9992 kfree(cfg);
9993 return -EINVAL;
9994 }
9995 cfg->src_port = port;
9996#endif
9997
9998 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
9999 cfg->payload_len = data_size;
10000 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
10001 memcpy((void *)cfg->payload,
10002 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
10003 data_size);
10004 if (seq)
10005 cfg->payload_seq = *seq;
10006 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
10007 cfg->wake_len = wake_size;
10008 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
10009 memcpy((void *)cfg->wake_data,
10010 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
10011 wake_size);
10012 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
10013 data_size + wake_size;
10014 memcpy((void *)cfg->wake_mask,
10015 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
10016 wake_mask_size);
10017 if (tok) {
10018 cfg->tokens_size = tokens_size;
10019 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
10020 }
10021
10022 trig->tcp = cfg;
10023
10024 return 0;
10025}
10026
8cd4d456
LC
10027static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
10028 const struct wiphy_wowlan_support *wowlan,
10029 struct nlattr *attr,
10030 struct cfg80211_wowlan *trig)
10031{
10032 struct nlattr **tb;
10033 int err;
10034
10035 tb = kzalloc(NUM_NL80211_ATTR * sizeof(*tb), GFP_KERNEL);
10036 if (!tb)
10037 return -ENOMEM;
10038
10039 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
10040 err = -EOPNOTSUPP;
10041 goto out;
10042 }
10043
bfe2c7b1 10044 err = nla_parse_nested(tb, NL80211_ATTR_MAX, attr, nl80211_policy);
8cd4d456
LC
10045 if (err)
10046 goto out;
10047
ad2b26ab 10048 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb);
8cd4d456
LC
10049 err = PTR_ERR_OR_ZERO(trig->nd_config);
10050 if (err)
10051 trig->nd_config = NULL;
10052
10053out:
10054 kfree(tb);
10055 return err;
10056}
10057
ff1b6e69
JB
10058static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
10059{
10060 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10061 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 10062 struct cfg80211_wowlan new_triggers = {};
ae33bd81 10063 struct cfg80211_wowlan *ntrig;
964dc9e2 10064 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 10065 int err, i;
6abb9cb9 10066 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 10067 bool regular = false;
ff1b6e69 10068
964dc9e2 10069 if (!wowlan)
ff1b6e69
JB
10070 return -EOPNOTSUPP;
10071
ae33bd81
JB
10072 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
10073 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 10074 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
10075 goto set_wakeup;
10076 }
ff1b6e69 10077
bfe2c7b1
JB
10078 err = nla_parse_nested(tb, MAX_NL80211_WOWLAN_TRIG,
10079 info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
10080 nl80211_wowlan_policy);
ff1b6e69
JB
10081 if (err)
10082 return err;
10083
10084 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
10085 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
10086 return -EINVAL;
10087 new_triggers.any = true;
10088 }
10089
10090 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
10091 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
10092 return -EINVAL;
10093 new_triggers.disconnect = true;
98fc4386 10094 regular = true;
ff1b6e69
JB
10095 }
10096
10097 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
10098 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
10099 return -EINVAL;
10100 new_triggers.magic_pkt = true;
98fc4386 10101 regular = true;
ff1b6e69
JB
10102 }
10103
77dbbb13
JB
10104 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
10105 return -EINVAL;
10106
10107 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
10108 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
10109 return -EINVAL;
10110 new_triggers.gtk_rekey_failure = true;
98fc4386 10111 regular = true;
77dbbb13
JB
10112 }
10113
10114 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
10115 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
10116 return -EINVAL;
10117 new_triggers.eap_identity_req = true;
98fc4386 10118 regular = true;
77dbbb13
JB
10119 }
10120
10121 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
10122 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
10123 return -EINVAL;
10124 new_triggers.four_way_handshake = true;
98fc4386 10125 regular = true;
77dbbb13
JB
10126 }
10127
10128 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
10129 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
10130 return -EINVAL;
10131 new_triggers.rfkill_release = true;
98fc4386 10132 regular = true;
77dbbb13
JB
10133 }
10134
ff1b6e69
JB
10135 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
10136 struct nlattr *pat;
10137 int n_patterns = 0;
bb92d199 10138 int rem, pat_len, mask_len, pkt_offset;
50ac6607 10139 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 10140
98fc4386
JB
10141 regular = true;
10142
ff1b6e69
JB
10143 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
10144 rem)
10145 n_patterns++;
10146 if (n_patterns > wowlan->n_patterns)
10147 return -EINVAL;
10148
10149 new_triggers.patterns = kcalloc(n_patterns,
10150 sizeof(new_triggers.patterns[0]),
10151 GFP_KERNEL);
10152 if (!new_triggers.patterns)
10153 return -ENOMEM;
10154
10155 new_triggers.n_patterns = n_patterns;
10156 i = 0;
10157
10158 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
10159 rem) {
922bd80f
JB
10160 u8 *mask_pat;
10161
bfe2c7b1
JB
10162 nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat,
10163 NULL);
ff1b6e69 10164 err = -EINVAL;
50ac6607
AK
10165 if (!pat_tb[NL80211_PKTPAT_MASK] ||
10166 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 10167 goto error;
50ac6607 10168 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 10169 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 10170 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
10171 goto error;
10172 if (pat_len > wowlan->pattern_max_len ||
10173 pat_len < wowlan->pattern_min_len)
10174 goto error;
10175
50ac6607 10176 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
10177 pkt_offset = 0;
10178 else
10179 pkt_offset = nla_get_u32(
50ac6607 10180 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
10181 if (pkt_offset > wowlan->max_pkt_offset)
10182 goto error;
10183 new_triggers.patterns[i].pkt_offset = pkt_offset;
10184
922bd80f
JB
10185 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
10186 if (!mask_pat) {
ff1b6e69
JB
10187 err = -ENOMEM;
10188 goto error;
10189 }
922bd80f
JB
10190 new_triggers.patterns[i].mask = mask_pat;
10191 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 10192 mask_len);
922bd80f
JB
10193 mask_pat += mask_len;
10194 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 10195 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 10196 memcpy(mask_pat,
50ac6607 10197 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
10198 pat_len);
10199 i++;
10200 }
10201 }
10202
2a0e047e 10203 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 10204 regular = true;
2a0e047e
JB
10205 err = nl80211_parse_wowlan_tcp(
10206 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
10207 &new_triggers);
10208 if (err)
10209 goto error;
10210 }
10211
8cd4d456 10212 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 10213 regular = true;
8cd4d456
LC
10214 err = nl80211_parse_wowlan_nd(
10215 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
10216 &new_triggers);
10217 if (err)
10218 goto error;
10219 }
10220
98fc4386
JB
10221 /* The 'any' trigger means the device continues operating more or less
10222 * as in its normal operation mode and wakes up the host on most of the
10223 * normal interrupts (like packet RX, ...)
10224 * It therefore makes little sense to combine with the more constrained
10225 * wakeup trigger modes.
10226 */
10227 if (new_triggers.any && regular) {
10228 err = -EINVAL;
10229 goto error;
10230 }
10231
ae33bd81
JB
10232 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
10233 if (!ntrig) {
10234 err = -ENOMEM;
10235 goto error;
ff1b6e69 10236 }
ae33bd81 10237 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 10238 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 10239
ae33bd81 10240 set_wakeup:
6abb9cb9
JB
10241 if (rdev->ops->set_wakeup &&
10242 prev_enabled != !!rdev->wiphy.wowlan_config)
10243 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 10244
ff1b6e69
JB
10245 return 0;
10246 error:
10247 for (i = 0; i < new_triggers.n_patterns; i++)
10248 kfree(new_triggers.patterns[i].mask);
10249 kfree(new_triggers.patterns);
2a0e047e
JB
10250 if (new_triggers.tcp && new_triggers.tcp->sock)
10251 sock_release(new_triggers.tcp->sock);
10252 kfree(new_triggers.tcp);
e5dbe070 10253 kfree(new_triggers.nd_config);
ff1b6e69
JB
10254 return err;
10255}
dfb89c56 10256#endif
ff1b6e69 10257
be29b99a
AK
10258static int nl80211_send_coalesce_rules(struct sk_buff *msg,
10259 struct cfg80211_registered_device *rdev)
10260{
10261 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
10262 int i, j, pat_len;
10263 struct cfg80211_coalesce_rules *rule;
10264
10265 if (!rdev->coalesce->n_rules)
10266 return 0;
10267
10268 nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
10269 if (!nl_rules)
10270 return -ENOBUFS;
10271
10272 for (i = 0; i < rdev->coalesce->n_rules; i++) {
10273 nl_rule = nla_nest_start(msg, i + 1);
10274 if (!nl_rule)
10275 return -ENOBUFS;
10276
10277 rule = &rdev->coalesce->rules[i];
10278 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
10279 rule->delay))
10280 return -ENOBUFS;
10281
10282 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
10283 rule->condition))
10284 return -ENOBUFS;
10285
10286 nl_pats = nla_nest_start(msg,
10287 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
10288 if (!nl_pats)
10289 return -ENOBUFS;
10290
10291 for (j = 0; j < rule->n_patterns; j++) {
10292 nl_pat = nla_nest_start(msg, j + 1);
10293 if (!nl_pat)
10294 return -ENOBUFS;
10295 pat_len = rule->patterns[j].pattern_len;
10296 if (nla_put(msg, NL80211_PKTPAT_MASK,
10297 DIV_ROUND_UP(pat_len, 8),
10298 rule->patterns[j].mask) ||
10299 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
10300 rule->patterns[j].pattern) ||
10301 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
10302 rule->patterns[j].pkt_offset))
10303 return -ENOBUFS;
10304 nla_nest_end(msg, nl_pat);
10305 }
10306 nla_nest_end(msg, nl_pats);
10307 nla_nest_end(msg, nl_rule);
10308 }
10309 nla_nest_end(msg, nl_rules);
10310
10311 return 0;
10312}
10313
10314static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
10315{
10316 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10317 struct sk_buff *msg;
10318 void *hdr;
10319
10320 if (!rdev->wiphy.coalesce)
10321 return -EOPNOTSUPP;
10322
10323 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10324 if (!msg)
10325 return -ENOMEM;
10326
10327 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
10328 NL80211_CMD_GET_COALESCE);
10329 if (!hdr)
10330 goto nla_put_failure;
10331
10332 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
10333 goto nla_put_failure;
10334
10335 genlmsg_end(msg, hdr);
10336 return genlmsg_reply(msg, info);
10337
10338nla_put_failure:
10339 nlmsg_free(msg);
10340 return -ENOBUFS;
10341}
10342
10343void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
10344{
10345 struct cfg80211_coalesce *coalesce = rdev->coalesce;
10346 int i, j;
10347 struct cfg80211_coalesce_rules *rule;
10348
10349 if (!coalesce)
10350 return;
10351
10352 for (i = 0; i < coalesce->n_rules; i++) {
10353 rule = &coalesce->rules[i];
10354 for (j = 0; j < rule->n_patterns; j++)
10355 kfree(rule->patterns[j].mask);
10356 kfree(rule->patterns);
10357 }
10358 kfree(coalesce->rules);
10359 kfree(coalesce);
10360 rdev->coalesce = NULL;
10361}
10362
10363static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
10364 struct nlattr *rule,
10365 struct cfg80211_coalesce_rules *new_rule)
10366{
10367 int err, i;
10368 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
10369 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
10370 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
10371 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
10372
bfe2c7b1
JB
10373 err = nla_parse_nested(tb, NL80211_ATTR_COALESCE_RULE_MAX, rule,
10374 nl80211_coalesce_policy);
be29b99a
AK
10375 if (err)
10376 return err;
10377
10378 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
10379 new_rule->delay =
10380 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
10381 if (new_rule->delay > coalesce->max_delay)
10382 return -EINVAL;
10383
10384 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
10385 new_rule->condition =
10386 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
10387 if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH &&
10388 new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH)
10389 return -EINVAL;
10390
10391 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
10392 return -EINVAL;
10393
10394 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
10395 rem)
10396 n_patterns++;
10397 if (n_patterns > coalesce->n_patterns)
10398 return -EINVAL;
10399
10400 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
10401 GFP_KERNEL);
10402 if (!new_rule->patterns)
10403 return -ENOMEM;
10404
10405 new_rule->n_patterns = n_patterns;
10406 i = 0;
10407
10408 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
10409 rem) {
922bd80f
JB
10410 u8 *mask_pat;
10411
bfe2c7b1 10412 nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat, NULL);
be29b99a
AK
10413 if (!pat_tb[NL80211_PKTPAT_MASK] ||
10414 !pat_tb[NL80211_PKTPAT_PATTERN])
10415 return -EINVAL;
10416 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
10417 mask_len = DIV_ROUND_UP(pat_len, 8);
10418 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
10419 return -EINVAL;
10420 if (pat_len > coalesce->pattern_max_len ||
10421 pat_len < coalesce->pattern_min_len)
10422 return -EINVAL;
10423
10424 if (!pat_tb[NL80211_PKTPAT_OFFSET])
10425 pkt_offset = 0;
10426 else
10427 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
10428 if (pkt_offset > coalesce->max_pkt_offset)
10429 return -EINVAL;
10430 new_rule->patterns[i].pkt_offset = pkt_offset;
10431
922bd80f
JB
10432 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
10433 if (!mask_pat)
be29b99a 10434 return -ENOMEM;
922bd80f
JB
10435
10436 new_rule->patterns[i].mask = mask_pat;
10437 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
10438 mask_len);
10439
10440 mask_pat += mask_len;
10441 new_rule->patterns[i].pattern = mask_pat;
be29b99a 10442 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
10443 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
10444 pat_len);
be29b99a
AK
10445 i++;
10446 }
10447
10448 return 0;
10449}
10450
10451static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
10452{
10453 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10454 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
10455 struct cfg80211_coalesce new_coalesce = {};
10456 struct cfg80211_coalesce *n_coalesce;
10457 int err, rem_rule, n_rules = 0, i, j;
10458 struct nlattr *rule;
10459 struct cfg80211_coalesce_rules *tmp_rule;
10460
10461 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
10462 return -EOPNOTSUPP;
10463
10464 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
10465 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 10466 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
10467 return 0;
10468 }
10469
10470 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
10471 rem_rule)
10472 n_rules++;
10473 if (n_rules > coalesce->n_rules)
10474 return -EINVAL;
10475
10476 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
10477 GFP_KERNEL);
10478 if (!new_coalesce.rules)
10479 return -ENOMEM;
10480
10481 new_coalesce.n_rules = n_rules;
10482 i = 0;
10483
10484 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
10485 rem_rule) {
10486 err = nl80211_parse_coalesce_rule(rdev, rule,
10487 &new_coalesce.rules[i]);
10488 if (err)
10489 goto error;
10490
10491 i++;
10492 }
10493
a1056b1b 10494 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
10495 if (err)
10496 goto error;
10497
10498 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
10499 if (!n_coalesce) {
10500 err = -ENOMEM;
10501 goto error;
10502 }
10503 cfg80211_rdev_free_coalesce(rdev);
10504 rdev->coalesce = n_coalesce;
10505
10506 return 0;
10507error:
10508 for (i = 0; i < new_coalesce.n_rules; i++) {
10509 tmp_rule = &new_coalesce.rules[i];
10510 for (j = 0; j < tmp_rule->n_patterns; j++)
10511 kfree(tmp_rule->patterns[j].mask);
10512 kfree(tmp_rule->patterns);
10513 }
10514 kfree(new_coalesce.rules);
10515
10516 return err;
10517}
10518
e5497d76
JB
10519static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
10520{
10521 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10522 struct net_device *dev = info->user_ptr[1];
10523 struct wireless_dev *wdev = dev->ieee80211_ptr;
10524 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
10525 struct cfg80211_gtk_rekey_data rekey_data;
10526 int err;
10527
10528 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
10529 return -EINVAL;
10530
bfe2c7b1
JB
10531 err = nla_parse_nested(tb, MAX_NL80211_REKEY_DATA,
10532 info->attrs[NL80211_ATTR_REKEY_DATA],
10533 nl80211_rekey_policy);
e5497d76
JB
10534 if (err)
10535 return err;
10536
10537 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
10538 return -ERANGE;
10539 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
10540 return -ERANGE;
10541 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
10542 return -ERANGE;
10543
78f686ca
JB
10544 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
10545 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
10546 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
e5497d76
JB
10547
10548 wdev_lock(wdev);
10549 if (!wdev->current_bss) {
10550 err = -ENOTCONN;
10551 goto out;
10552 }
10553
10554 if (!rdev->ops->set_rekey_data) {
10555 err = -EOPNOTSUPP;
10556 goto out;
10557 }
10558
e35e4d28 10559 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
10560 out:
10561 wdev_unlock(wdev);
10562 return err;
10563}
10564
28946da7
JB
10565static int nl80211_register_unexpected_frame(struct sk_buff *skb,
10566 struct genl_info *info)
10567{
10568 struct net_device *dev = info->user_ptr[1];
10569 struct wireless_dev *wdev = dev->ieee80211_ptr;
10570
10571 if (wdev->iftype != NL80211_IFTYPE_AP &&
10572 wdev->iftype != NL80211_IFTYPE_P2P_GO)
10573 return -EINVAL;
10574
15e47304 10575 if (wdev->ap_unexpected_nlportid)
28946da7
JB
10576 return -EBUSY;
10577
15e47304 10578 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
10579 return 0;
10580}
10581
7f6cf311
JB
10582static int nl80211_probe_client(struct sk_buff *skb,
10583 struct genl_info *info)
10584{
10585 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10586 struct net_device *dev = info->user_ptr[1];
10587 struct wireless_dev *wdev = dev->ieee80211_ptr;
10588 struct sk_buff *msg;
10589 void *hdr;
10590 const u8 *addr;
10591 u64 cookie;
10592 int err;
10593
10594 if (wdev->iftype != NL80211_IFTYPE_AP &&
10595 wdev->iftype != NL80211_IFTYPE_P2P_GO)
10596 return -EOPNOTSUPP;
10597
10598 if (!info->attrs[NL80211_ATTR_MAC])
10599 return -EINVAL;
10600
10601 if (!rdev->ops->probe_client)
10602 return -EOPNOTSUPP;
10603
10604 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10605 if (!msg)
10606 return -ENOMEM;
10607
15e47304 10608 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 10609 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
10610 if (!hdr) {
10611 err = -ENOBUFS;
7f6cf311
JB
10612 goto free_msg;
10613 }
10614
10615 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
10616
e35e4d28 10617 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
10618 if (err)
10619 goto free_msg;
10620
2dad624e
ND
10621 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
10622 NL80211_ATTR_PAD))
9360ffd1 10623 goto nla_put_failure;
7f6cf311
JB
10624
10625 genlmsg_end(msg, hdr);
10626
10627 return genlmsg_reply(msg, info);
10628
10629 nla_put_failure:
10630 err = -ENOBUFS;
10631 free_msg:
10632 nlmsg_free(msg);
10633 return err;
10634}
10635
5e760230
JB
10636static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
10637{
10638 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
10639 struct cfg80211_beacon_registration *reg, *nreg;
10640 int rv;
5e760230
JB
10641
10642 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
10643 return -EOPNOTSUPP;
10644
37c73b5f
BG
10645 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
10646 if (!nreg)
10647 return -ENOMEM;
10648
10649 /* First, check if already registered. */
10650 spin_lock_bh(&rdev->beacon_registrations_lock);
10651 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
10652 if (reg->nlportid == info->snd_portid) {
10653 rv = -EALREADY;
10654 goto out_err;
10655 }
10656 }
10657 /* Add it to the list */
10658 nreg->nlportid = info->snd_portid;
10659 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 10660
37c73b5f 10661 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
10662
10663 return 0;
37c73b5f
BG
10664out_err:
10665 spin_unlock_bh(&rdev->beacon_registrations_lock);
10666 kfree(nreg);
10667 return rv;
5e760230
JB
10668}
10669
98104fde
JB
10670static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
10671{
10672 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10673 struct wireless_dev *wdev = info->user_ptr[1];
10674 int err;
10675
10676 if (!rdev->ops->start_p2p_device)
10677 return -EOPNOTSUPP;
10678
10679 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
10680 return -EOPNOTSUPP;
10681
73c7da3d 10682 if (wdev_running(wdev))
98104fde
JB
10683 return 0;
10684
b6a55015
LC
10685 if (rfkill_blocked(rdev->rfkill))
10686 return -ERFKILL;
98104fde 10687
eeb126e9 10688 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
10689 if (err)
10690 return err;
10691
73c7da3d 10692 wdev->is_running = true;
98104fde 10693 rdev->opencount++;
98104fde
JB
10694
10695 return 0;
10696}
10697
10698static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
10699{
10700 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10701 struct wireless_dev *wdev = info->user_ptr[1];
10702
10703 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
10704 return -EOPNOTSUPP;
10705
10706 if (!rdev->ops->stop_p2p_device)
10707 return -EOPNOTSUPP;
10708
f9f47529 10709 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
10710
10711 return 0;
10712}
10713
cb3b7d87
AB
10714static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
10715{
10716 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10717 struct wireless_dev *wdev = info->user_ptr[1];
10718 struct cfg80211_nan_conf conf = {};
10719 int err;
10720
10721 if (wdev->iftype != NL80211_IFTYPE_NAN)
10722 return -EOPNOTSUPP;
10723
eeb04a96 10724 if (wdev_running(wdev))
cb3b7d87
AB
10725 return -EEXIST;
10726
10727 if (rfkill_blocked(rdev->rfkill))
10728 return -ERFKILL;
10729
10730 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
10731 return -EINVAL;
10732
10733 if (!info->attrs[NL80211_ATTR_NAN_DUAL])
10734 return -EINVAL;
10735
10736 conf.master_pref =
10737 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
10738 if (!conf.master_pref)
10739 return -EINVAL;
10740
10741 conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]);
10742
10743 err = rdev_start_nan(rdev, wdev, &conf);
10744 if (err)
10745 return err;
10746
73c7da3d 10747 wdev->is_running = true;
cb3b7d87
AB
10748 rdev->opencount++;
10749
10750 return 0;
10751}
10752
10753static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
10754{
10755 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10756 struct wireless_dev *wdev = info->user_ptr[1];
10757
10758 if (wdev->iftype != NL80211_IFTYPE_NAN)
10759 return -EOPNOTSUPP;
10760
10761 cfg80211_stop_nan(rdev, wdev);
10762
10763 return 0;
10764}
10765
a442b761
AB
10766static int validate_nan_filter(struct nlattr *filter_attr)
10767{
10768 struct nlattr *attr;
10769 int len = 0, n_entries = 0, rem;
10770
10771 nla_for_each_nested(attr, filter_attr, rem) {
10772 len += nla_len(attr);
10773 n_entries++;
10774 }
10775
10776 if (len >= U8_MAX)
10777 return -EINVAL;
10778
10779 return n_entries;
10780}
10781
10782static int handle_nan_filter(struct nlattr *attr_filter,
10783 struct cfg80211_nan_func *func,
10784 bool tx)
10785{
10786 struct nlattr *attr;
10787 int n_entries, rem, i;
10788 struct cfg80211_nan_func_filter *filter;
10789
10790 n_entries = validate_nan_filter(attr_filter);
10791 if (n_entries < 0)
10792 return n_entries;
10793
10794 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
10795
10796 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
10797 if (!filter)
10798 return -ENOMEM;
10799
10800 i = 0;
10801 nla_for_each_nested(attr, attr_filter, rem) {
b15ca182 10802 filter[i].filter = nla_memdup(attr, GFP_KERNEL);
a442b761
AB
10803 filter[i].len = nla_len(attr);
10804 i++;
10805 }
10806 if (tx) {
10807 func->num_tx_filters = n_entries;
10808 func->tx_filters = filter;
10809 } else {
10810 func->num_rx_filters = n_entries;
10811 func->rx_filters = filter;
10812 }
10813
10814 return 0;
10815}
10816
10817static int nl80211_nan_add_func(struct sk_buff *skb,
10818 struct genl_info *info)
10819{
10820 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10821 struct wireless_dev *wdev = info->user_ptr[1];
10822 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
10823 struct cfg80211_nan_func *func;
10824 struct sk_buff *msg = NULL;
10825 void *hdr = NULL;
10826 int err = 0;
10827
10828 if (wdev->iftype != NL80211_IFTYPE_NAN)
10829 return -EOPNOTSUPP;
10830
73c7da3d 10831 if (!wdev_running(wdev))
a442b761
AB
10832 return -ENOTCONN;
10833
10834 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
10835 return -EINVAL;
10836
10837 if (wdev->owner_nlportid &&
10838 wdev->owner_nlportid != info->snd_portid)
10839 return -ENOTCONN;
10840
bfe2c7b1
JB
10841 err = nla_parse_nested(tb, NL80211_NAN_FUNC_ATTR_MAX,
10842 info->attrs[NL80211_ATTR_NAN_FUNC],
10843 nl80211_nan_func_policy);
a442b761
AB
10844 if (err)
10845 return err;
10846
10847 func = kzalloc(sizeof(*func), GFP_KERNEL);
10848 if (!func)
10849 return -ENOMEM;
10850
10851 func->cookie = wdev->wiphy->cookie_counter++;
10852
10853 if (!tb[NL80211_NAN_FUNC_TYPE] ||
10854 nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
10855 err = -EINVAL;
10856 goto out;
10857 }
10858
10859
10860 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
10861
10862 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
10863 err = -EINVAL;
10864 goto out;
10865 }
10866
10867 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
10868 sizeof(func->service_id));
10869
10870 func->close_range =
10871 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
10872
10873 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
10874 func->serv_spec_info_len =
10875 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
10876 func->serv_spec_info =
10877 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
10878 func->serv_spec_info_len,
10879 GFP_KERNEL);
10880 if (!func->serv_spec_info) {
10881 err = -ENOMEM;
10882 goto out;
10883 }
10884 }
10885
10886 if (tb[NL80211_NAN_FUNC_TTL])
10887 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
10888
10889 switch (func->type) {
10890 case NL80211_NAN_FUNC_PUBLISH:
10891 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
10892 err = -EINVAL;
10893 goto out;
10894 }
10895
10896 func->publish_type =
10897 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
10898 func->publish_bcast =
10899 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
10900
10901 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
10902 func->publish_bcast) {
10903 err = -EINVAL;
10904 goto out;
10905 }
10906 break;
10907 case NL80211_NAN_FUNC_SUBSCRIBE:
10908 func->subscribe_active =
10909 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
10910 break;
10911 case NL80211_NAN_FUNC_FOLLOW_UP:
10912 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
10913 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]) {
10914 err = -EINVAL;
10915 goto out;
10916 }
10917
10918 func->followup_id =
10919 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
10920 func->followup_reqid =
10921 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
10922 memcpy(func->followup_dest.addr,
10923 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
10924 sizeof(func->followup_dest.addr));
10925 if (func->ttl) {
10926 err = -EINVAL;
10927 goto out;
10928 }
10929 break;
10930 default:
10931 err = -EINVAL;
10932 goto out;
10933 }
10934
10935 if (tb[NL80211_NAN_FUNC_SRF]) {
10936 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
10937
bfe2c7b1
JB
10938 err = nla_parse_nested(srf_tb, NL80211_NAN_SRF_ATTR_MAX,
10939 tb[NL80211_NAN_FUNC_SRF],
10940 nl80211_nan_srf_policy);
a442b761
AB
10941 if (err)
10942 goto out;
10943
10944 func->srf_include =
10945 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
10946
10947 if (srf_tb[NL80211_NAN_SRF_BF]) {
10948 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
10949 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
10950 err = -EINVAL;
10951 goto out;
10952 }
10953
10954 func->srf_bf_len =
10955 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
10956 func->srf_bf =
10957 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
10958 func->srf_bf_len, GFP_KERNEL);
10959 if (!func->srf_bf) {
10960 err = -ENOMEM;
10961 goto out;
10962 }
10963
10964 func->srf_bf_idx =
10965 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
10966 } else {
10967 struct nlattr *attr, *mac_attr =
10968 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
10969 int n_entries, rem, i = 0;
10970
10971 if (!mac_attr) {
10972 err = -EINVAL;
10973 goto out;
10974 }
10975
10976 n_entries = validate_acl_mac_addrs(mac_attr);
10977 if (n_entries <= 0) {
10978 err = -EINVAL;
10979 goto out;
10980 }
10981
10982 func->srf_num_macs = n_entries;
10983 func->srf_macs =
10984 kzalloc(sizeof(*func->srf_macs) * n_entries,
10985 GFP_KERNEL);
10986 if (!func->srf_macs) {
10987 err = -ENOMEM;
10988 goto out;
10989 }
10990
10991 nla_for_each_nested(attr, mac_attr, rem)
10992 memcpy(func->srf_macs[i++].addr, nla_data(attr),
10993 sizeof(*func->srf_macs));
10994 }
10995 }
10996
10997 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
10998 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
10999 func, true);
11000 if (err)
11001 goto out;
11002 }
11003
11004 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
11005 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
11006 func, false);
11007 if (err)
11008 goto out;
11009 }
11010
11011 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11012 if (!msg) {
11013 err = -ENOMEM;
11014 goto out;
11015 }
11016
11017 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11018 NL80211_CMD_ADD_NAN_FUNCTION);
11019 /* This can't really happen - we just allocated 4KB */
11020 if (WARN_ON(!hdr)) {
11021 err = -ENOMEM;
11022 goto out;
11023 }
11024
11025 err = rdev_add_nan_func(rdev, wdev, func);
11026out:
11027 if (err < 0) {
11028 cfg80211_free_nan_func(func);
11029 nlmsg_free(msg);
11030 return err;
11031 }
11032
11033 /* propagate the instance id and cookie to userspace */
11034 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
11035 NL80211_ATTR_PAD))
11036 goto nla_put_failure;
11037
11038 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
11039 if (!func_attr)
11040 goto nla_put_failure;
11041
11042 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
11043 func->instance_id))
11044 goto nla_put_failure;
11045
11046 nla_nest_end(msg, func_attr);
11047
11048 genlmsg_end(msg, hdr);
11049 return genlmsg_reply(msg, info);
11050
11051nla_put_failure:
11052 nlmsg_free(msg);
11053 return -ENOBUFS;
11054}
11055
11056static int nl80211_nan_del_func(struct sk_buff *skb,
11057 struct genl_info *info)
11058{
11059 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11060 struct wireless_dev *wdev = info->user_ptr[1];
11061 u64 cookie;
11062
11063 if (wdev->iftype != NL80211_IFTYPE_NAN)
11064 return -EOPNOTSUPP;
11065
73c7da3d 11066 if (!wdev_running(wdev))
a442b761
AB
11067 return -ENOTCONN;
11068
11069 if (!info->attrs[NL80211_ATTR_COOKIE])
11070 return -EINVAL;
11071
11072 if (wdev->owner_nlportid &&
11073 wdev->owner_nlportid != info->snd_portid)
11074 return -ENOTCONN;
11075
11076 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
11077
11078 rdev_del_nan_func(rdev, wdev, cookie);
11079
11080 return 0;
11081}
11082
a5a9dcf2
AB
11083static int nl80211_nan_change_config(struct sk_buff *skb,
11084 struct genl_info *info)
11085{
11086 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11087 struct wireless_dev *wdev = info->user_ptr[1];
11088 struct cfg80211_nan_conf conf = {};
11089 u32 changed = 0;
11090
11091 if (wdev->iftype != NL80211_IFTYPE_NAN)
11092 return -EOPNOTSUPP;
11093
73c7da3d 11094 if (!wdev_running(wdev))
a5a9dcf2
AB
11095 return -ENOTCONN;
11096
11097 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
11098 conf.master_pref =
11099 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
11100 if (conf.master_pref <= 1 || conf.master_pref == 255)
11101 return -EINVAL;
11102
11103 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
11104 }
11105
11106 if (info->attrs[NL80211_ATTR_NAN_DUAL]) {
11107 conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]);
11108 changed |= CFG80211_NAN_CONF_CHANGED_DUAL;
11109 }
11110
11111 if (!changed)
11112 return -EINVAL;
11113
11114 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
11115}
11116
50bcd31d
AB
11117void cfg80211_nan_match(struct wireless_dev *wdev,
11118 struct cfg80211_nan_match_params *match, gfp_t gfp)
11119{
11120 struct wiphy *wiphy = wdev->wiphy;
11121 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11122 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
11123 struct sk_buff *msg;
11124 void *hdr;
11125
11126 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
11127 return;
11128
11129 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11130 if (!msg)
11131 return;
11132
11133 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
11134 if (!hdr) {
11135 nlmsg_free(msg);
11136 return;
11137 }
11138
11139 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11140 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
11141 wdev->netdev->ifindex)) ||
11142 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
11143 NL80211_ATTR_PAD))
11144 goto nla_put_failure;
11145
11146 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
11147 NL80211_ATTR_PAD) ||
11148 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
11149 goto nla_put_failure;
11150
11151 match_attr = nla_nest_start(msg, NL80211_ATTR_NAN_MATCH);
11152 if (!match_attr)
11153 goto nla_put_failure;
11154
11155 local_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_LOCAL);
11156 if (!local_func_attr)
11157 goto nla_put_failure;
11158
11159 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
11160 goto nla_put_failure;
11161
11162 nla_nest_end(msg, local_func_attr);
11163
11164 peer_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_PEER);
11165 if (!peer_func_attr)
11166 goto nla_put_failure;
11167
11168 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
11169 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
11170 goto nla_put_failure;
11171
11172 if (match->info && match->info_len &&
11173 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
11174 match->info))
11175 goto nla_put_failure;
11176
11177 nla_nest_end(msg, peer_func_attr);
11178 nla_nest_end(msg, match_attr);
11179 genlmsg_end(msg, hdr);
11180
11181 if (!wdev->owner_nlportid)
11182 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11183 msg, 0, NL80211_MCGRP_NAN, gfp);
11184 else
11185 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
11186 wdev->owner_nlportid);
11187
11188 return;
11189
11190nla_put_failure:
11191 nlmsg_free(msg);
11192}
11193EXPORT_SYMBOL(cfg80211_nan_match);
11194
368e5a7b
AB
11195void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
11196 u8 inst_id,
11197 enum nl80211_nan_func_term_reason reason,
11198 u64 cookie, gfp_t gfp)
11199{
11200 struct wiphy *wiphy = wdev->wiphy;
11201 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11202 struct sk_buff *msg;
11203 struct nlattr *func_attr;
11204 void *hdr;
11205
11206 if (WARN_ON(!inst_id))
11207 return;
11208
11209 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11210 if (!msg)
11211 return;
11212
11213 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
11214 if (!hdr) {
11215 nlmsg_free(msg);
11216 return;
11217 }
11218
11219 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11220 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
11221 wdev->netdev->ifindex)) ||
11222 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
11223 NL80211_ATTR_PAD))
11224 goto nla_put_failure;
11225
11226 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11227 NL80211_ATTR_PAD))
11228 goto nla_put_failure;
11229
11230 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
11231 if (!func_attr)
11232 goto nla_put_failure;
11233
11234 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
11235 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
11236 goto nla_put_failure;
11237
11238 nla_nest_end(msg, func_attr);
11239 genlmsg_end(msg, hdr);
11240
11241 if (!wdev->owner_nlportid)
11242 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11243 msg, 0, NL80211_MCGRP_NAN, gfp);
11244 else
11245 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
11246 wdev->owner_nlportid);
11247
11248 return;
11249
11250nla_put_failure:
11251 nlmsg_free(msg);
11252}
11253EXPORT_SYMBOL(cfg80211_nan_func_terminated);
11254
3713b4e3
JB
11255static int nl80211_get_protocol_features(struct sk_buff *skb,
11256 struct genl_info *info)
11257{
11258 void *hdr;
11259 struct sk_buff *msg;
11260
11261 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11262 if (!msg)
11263 return -ENOMEM;
11264
11265 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11266 NL80211_CMD_GET_PROTOCOL_FEATURES);
11267 if (!hdr)
11268 goto nla_put_failure;
11269
11270 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
11271 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
11272 goto nla_put_failure;
11273
11274 genlmsg_end(msg, hdr);
11275 return genlmsg_reply(msg, info);
11276
11277 nla_put_failure:
11278 kfree_skb(msg);
11279 return -ENOBUFS;
11280}
11281
355199e0
JM
11282static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
11283{
11284 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11285 struct cfg80211_update_ft_ies_params ft_params;
11286 struct net_device *dev = info->user_ptr[1];
11287
11288 if (!rdev->ops->update_ft_ies)
11289 return -EOPNOTSUPP;
11290
11291 if (!info->attrs[NL80211_ATTR_MDID] ||
11292 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
11293 return -EINVAL;
11294
11295 memset(&ft_params, 0, sizeof(ft_params));
11296 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
11297 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11298 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11299
11300 return rdev_update_ft_ies(rdev, dev, &ft_params);
11301}
11302
5de17984
AS
11303static int nl80211_crit_protocol_start(struct sk_buff *skb,
11304 struct genl_info *info)
11305{
11306 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11307 struct wireless_dev *wdev = info->user_ptr[1];
11308 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
11309 u16 duration;
11310 int ret;
11311
11312 if (!rdev->ops->crit_proto_start)
11313 return -EOPNOTSUPP;
11314
11315 if (WARN_ON(!rdev->ops->crit_proto_stop))
11316 return -EINVAL;
11317
11318 if (rdev->crit_proto_nlportid)
11319 return -EBUSY;
11320
11321 /* determine protocol if provided */
11322 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
11323 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
11324
11325 if (proto >= NUM_NL80211_CRIT_PROTO)
11326 return -EINVAL;
11327
11328 /* timeout must be provided */
11329 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
11330 return -EINVAL;
11331
11332 duration =
11333 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
11334
11335 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
11336 return -ERANGE;
11337
11338 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
11339 if (!ret)
11340 rdev->crit_proto_nlportid = info->snd_portid;
11341
11342 return ret;
11343}
11344
11345static int nl80211_crit_protocol_stop(struct sk_buff *skb,
11346 struct genl_info *info)
11347{
11348 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11349 struct wireless_dev *wdev = info->user_ptr[1];
11350
11351 if (!rdev->ops->crit_proto_stop)
11352 return -EOPNOTSUPP;
11353
11354 if (rdev->crit_proto_nlportid) {
11355 rdev->crit_proto_nlportid = 0;
11356 rdev_crit_proto_stop(rdev, wdev);
11357 }
11358 return 0;
11359}
11360
ad7e718c
JB
11361static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
11362{
11363 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11364 struct wireless_dev *wdev =
11365 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
11366 int i, err;
11367 u32 vid, subcmd;
11368
11369 if (!rdev->wiphy.vendor_commands)
11370 return -EOPNOTSUPP;
11371
11372 if (IS_ERR(wdev)) {
11373 err = PTR_ERR(wdev);
11374 if (err != -EINVAL)
11375 return err;
11376 wdev = NULL;
11377 } else if (wdev->wiphy != &rdev->wiphy) {
11378 return -EINVAL;
11379 }
11380
11381 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
11382 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
11383 return -EINVAL;
11384
11385 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
11386 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
11387 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
11388 const struct wiphy_vendor_command *vcmd;
11389 void *data = NULL;
11390 int len = 0;
11391
11392 vcmd = &rdev->wiphy.vendor_commands[i];
11393
11394 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11395 continue;
11396
11397 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11398 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11399 if (!wdev)
11400 return -EINVAL;
11401 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11402 !wdev->netdev)
11403 return -EINVAL;
11404
11405 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 11406 if (!wdev_running(wdev))
ad7e718c
JB
11407 return -ENETDOWN;
11408 }
7bdbe400
JB
11409
11410 if (!vcmd->doit)
11411 return -EOPNOTSUPP;
ad7e718c
JB
11412 } else {
11413 wdev = NULL;
11414 }
11415
11416 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
11417 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11418 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11419 }
11420
11421 rdev->cur_cmd_info = info;
11422 err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
11423 data, len);
11424 rdev->cur_cmd_info = NULL;
11425 return err;
11426 }
11427
11428 return -EOPNOTSUPP;
11429}
11430
7bdbe400
JB
11431static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
11432 struct netlink_callback *cb,
11433 struct cfg80211_registered_device **rdev,
11434 struct wireless_dev **wdev)
11435{
c90c39da 11436 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
7bdbe400
JB
11437 u32 vid, subcmd;
11438 unsigned int i;
11439 int vcmd_idx = -1;
11440 int err;
11441 void *data = NULL;
11442 unsigned int data_len = 0;
11443
11444 rtnl_lock();
11445
11446 if (cb->args[0]) {
11447 /* subtract the 1 again here */
11448 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
11449 struct wireless_dev *tmp;
11450
11451 if (!wiphy) {
11452 err = -ENODEV;
11453 goto out_unlock;
11454 }
11455 *rdev = wiphy_to_rdev(wiphy);
11456 *wdev = NULL;
11457
11458 if (cb->args[1]) {
53873f13 11459 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
11460 if (tmp->identifier == cb->args[1] - 1) {
11461 *wdev = tmp;
11462 break;
11463 }
11464 }
11465 }
11466
11467 /* keep rtnl locked in successful case */
11468 return 0;
11469 }
11470
11471 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
c90c39da 11472 attrbuf, nl80211_fam.maxattr, nl80211_policy);
7bdbe400
JB
11473 if (err)
11474 goto out_unlock;
11475
c90c39da
JB
11476 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
11477 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
7bdbe400
JB
11478 err = -EINVAL;
11479 goto out_unlock;
11480 }
11481
c90c39da 11482 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
7bdbe400
JB
11483 if (IS_ERR(*wdev))
11484 *wdev = NULL;
11485
c90c39da 11486 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
7bdbe400
JB
11487 if (IS_ERR(*rdev)) {
11488 err = PTR_ERR(*rdev);
11489 goto out_unlock;
11490 }
11491
c90c39da
JB
11492 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
11493 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
7bdbe400
JB
11494
11495 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
11496 const struct wiphy_vendor_command *vcmd;
11497
11498 vcmd = &(*rdev)->wiphy.vendor_commands[i];
11499
11500 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11501 continue;
11502
11503 if (!vcmd->dumpit) {
11504 err = -EOPNOTSUPP;
11505 goto out_unlock;
11506 }
11507
11508 vcmd_idx = i;
11509 break;
11510 }
11511
11512 if (vcmd_idx < 0) {
11513 err = -EOPNOTSUPP;
11514 goto out_unlock;
11515 }
11516
c90c39da
JB
11517 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
11518 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
11519 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
7bdbe400
JB
11520 }
11521
11522 /* 0 is the first index - add 1 to parse only once */
11523 cb->args[0] = (*rdev)->wiphy_idx + 1;
11524 /* add 1 to know if it was NULL */
11525 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
11526 cb->args[2] = vcmd_idx;
11527 cb->args[3] = (unsigned long)data;
11528 cb->args[4] = data_len;
11529
11530 /* keep rtnl locked in successful case */
11531 return 0;
11532 out_unlock:
11533 rtnl_unlock();
11534 return err;
11535}
11536
11537static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
11538 struct netlink_callback *cb)
11539{
11540 struct cfg80211_registered_device *rdev;
11541 struct wireless_dev *wdev;
11542 unsigned int vcmd_idx;
11543 const struct wiphy_vendor_command *vcmd;
11544 void *data;
11545 int data_len;
11546 int err;
11547 struct nlattr *vendor_data;
11548
11549 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
11550 if (err)
11551 return err;
11552
11553 vcmd_idx = cb->args[2];
11554 data = (void *)cb->args[3];
11555 data_len = cb->args[4];
11556 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
11557
11558 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11559 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11560 if (!wdev)
11561 return -EINVAL;
11562 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11563 !wdev->netdev)
11564 return -EINVAL;
11565
11566 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 11567 if (!wdev_running(wdev))
7bdbe400
JB
11568 return -ENETDOWN;
11569 }
11570 }
11571
11572 while (1) {
11573 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
11574 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11575 NL80211_CMD_VENDOR);
11576 if (!hdr)
11577 break;
11578
11579 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
11580 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
11581 wdev_id(wdev),
11582 NL80211_ATTR_PAD))) {
7bdbe400
JB
11583 genlmsg_cancel(skb, hdr);
11584 break;
11585 }
11586
11587 vendor_data = nla_nest_start(skb, NL80211_ATTR_VENDOR_DATA);
11588 if (!vendor_data) {
11589 genlmsg_cancel(skb, hdr);
11590 break;
11591 }
11592
11593 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
11594 (unsigned long *)&cb->args[5]);
11595 nla_nest_end(skb, vendor_data);
11596
11597 if (err == -ENOBUFS || err == -ENOENT) {
11598 genlmsg_cancel(skb, hdr);
11599 break;
11600 } else if (err) {
11601 genlmsg_cancel(skb, hdr);
11602 goto out;
11603 }
11604
11605 genlmsg_end(skb, hdr);
11606 }
11607
11608 err = skb->len;
11609 out:
11610 rtnl_unlock();
11611 return err;
11612}
11613
ad7e718c
JB
11614struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
11615 enum nl80211_commands cmd,
11616 enum nl80211_attrs attr,
11617 int approxlen)
11618{
f26cbf40 11619 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
11620
11621 if (WARN_ON(!rdev->cur_cmd_info))
11622 return NULL;
11623
6c09e791 11624 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
11625 rdev->cur_cmd_info->snd_portid,
11626 rdev->cur_cmd_info->snd_seq,
567ffc35 11627 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
11628}
11629EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
11630
11631int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
11632{
11633 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
11634 void *hdr = ((void **)skb->cb)[1];
11635 struct nlattr *data = ((void **)skb->cb)[2];
11636
bd8c78e7
JB
11637 /* clear CB data for netlink core to own from now on */
11638 memset(skb->cb, 0, sizeof(skb->cb));
11639
ad7e718c
JB
11640 if (WARN_ON(!rdev->cur_cmd_info)) {
11641 kfree_skb(skb);
11642 return -EINVAL;
11643 }
11644
11645 nla_nest_end(skb, data);
11646 genlmsg_end(skb, hdr);
11647 return genlmsg_reply(skb, rdev->cur_cmd_info);
11648}
11649EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
11650
fa9ffc74
KP
11651static int nl80211_set_qos_map(struct sk_buff *skb,
11652 struct genl_info *info)
11653{
11654 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11655 struct cfg80211_qos_map *qos_map = NULL;
11656 struct net_device *dev = info->user_ptr[1];
11657 u8 *pos, len, num_des, des_len, des;
11658 int ret;
11659
11660 if (!rdev->ops->set_qos_map)
11661 return -EOPNOTSUPP;
11662
11663 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
11664 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
11665 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
11666
11667 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
11668 len > IEEE80211_QOS_MAP_LEN_MAX)
11669 return -EINVAL;
11670
11671 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
11672 if (!qos_map)
11673 return -ENOMEM;
11674
11675 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
11676 if (num_des) {
11677 des_len = num_des *
11678 sizeof(struct cfg80211_dscp_exception);
11679 memcpy(qos_map->dscp_exception, pos, des_len);
11680 qos_map->num_des = num_des;
11681 for (des = 0; des < num_des; des++) {
11682 if (qos_map->dscp_exception[des].up > 7) {
11683 kfree(qos_map);
11684 return -EINVAL;
11685 }
11686 }
11687 pos += des_len;
11688 }
11689 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
11690 }
11691
11692 wdev_lock(dev->ieee80211_ptr);
11693 ret = nl80211_key_allowed(dev->ieee80211_ptr);
11694 if (!ret)
11695 ret = rdev_set_qos_map(rdev, dev, qos_map);
11696 wdev_unlock(dev->ieee80211_ptr);
11697
11698 kfree(qos_map);
11699 return ret;
11700}
11701
960d01ac
JB
11702static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
11703{
11704 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11705 struct net_device *dev = info->user_ptr[1];
11706 struct wireless_dev *wdev = dev->ieee80211_ptr;
11707 const u8 *peer;
11708 u8 tsid, up;
11709 u16 admitted_time = 0;
11710 int err;
11711
723e73ac 11712 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
11713 return -EOPNOTSUPP;
11714
11715 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
11716 !info->attrs[NL80211_ATTR_USER_PRIO])
11717 return -EINVAL;
11718
11719 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
11720 if (tsid >= IEEE80211_NUM_TIDS)
11721 return -EINVAL;
11722
11723 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
11724 if (up >= IEEE80211_NUM_UPS)
11725 return -EINVAL;
11726
11727 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 11728 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 11729 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
11730 * need more attributes for that (e.g. BA session requirement);
11731 * change the WMM adminssion test above to allow both then
960d01ac
JB
11732 */
11733 return -EINVAL;
11734 }
11735
11736 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11737
11738 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
11739 admitted_time =
11740 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
11741 if (!admitted_time)
11742 return -EINVAL;
11743 }
11744
11745 wdev_lock(wdev);
11746 switch (wdev->iftype) {
11747 case NL80211_IFTYPE_STATION:
11748 case NL80211_IFTYPE_P2P_CLIENT:
11749 if (wdev->current_bss)
11750 break;
11751 err = -ENOTCONN;
11752 goto out;
11753 default:
11754 err = -EOPNOTSUPP;
11755 goto out;
11756 }
11757
11758 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
11759
11760 out:
11761 wdev_unlock(wdev);
11762 return err;
11763}
11764
11765static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
11766{
11767 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11768 struct net_device *dev = info->user_ptr[1];
11769 struct wireless_dev *wdev = dev->ieee80211_ptr;
11770 const u8 *peer;
11771 u8 tsid;
11772 int err;
11773
11774 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
11775 return -EINVAL;
11776
11777 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
11778 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11779
11780 wdev_lock(wdev);
11781 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
11782 wdev_unlock(wdev);
11783
11784 return err;
11785}
11786
1057d35e
AN
11787static int nl80211_tdls_channel_switch(struct sk_buff *skb,
11788 struct genl_info *info)
11789{
11790 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11791 struct net_device *dev = info->user_ptr[1];
11792 struct wireless_dev *wdev = dev->ieee80211_ptr;
11793 struct cfg80211_chan_def chandef = {};
11794 const u8 *addr;
11795 u8 oper_class;
11796 int err;
11797
11798 if (!rdev->ops->tdls_channel_switch ||
11799 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
11800 return -EOPNOTSUPP;
11801
11802 switch (dev->ieee80211_ptr->iftype) {
11803 case NL80211_IFTYPE_STATION:
11804 case NL80211_IFTYPE_P2P_CLIENT:
11805 break;
11806 default:
11807 return -EOPNOTSUPP;
11808 }
11809
11810 if (!info->attrs[NL80211_ATTR_MAC] ||
11811 !info->attrs[NL80211_ATTR_OPER_CLASS])
11812 return -EINVAL;
11813
11814 err = nl80211_parse_chandef(rdev, info, &chandef);
11815 if (err)
11816 return err;
11817
11818 /*
11819 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
11820 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
11821 * specification is not defined for them.
11822 */
57fbcce3 11823 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
11824 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
11825 chandef.width != NL80211_CHAN_WIDTH_20)
11826 return -EINVAL;
11827
11828 /* we will be active on the TDLS link */
923b352f
AN
11829 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
11830 wdev->iftype))
1057d35e
AN
11831 return -EINVAL;
11832
11833 /* don't allow switching to DFS channels */
11834 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
11835 return -EINVAL;
11836
11837 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11838 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
11839
11840 wdev_lock(wdev);
11841 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
11842 wdev_unlock(wdev);
11843
11844 return err;
11845}
11846
11847static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
11848 struct genl_info *info)
11849{
11850 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11851 struct net_device *dev = info->user_ptr[1];
11852 struct wireless_dev *wdev = dev->ieee80211_ptr;
11853 const u8 *addr;
11854
11855 if (!rdev->ops->tdls_channel_switch ||
11856 !rdev->ops->tdls_cancel_channel_switch ||
11857 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
11858 return -EOPNOTSUPP;
11859
11860 switch (dev->ieee80211_ptr->iftype) {
11861 case NL80211_IFTYPE_STATION:
11862 case NL80211_IFTYPE_P2P_CLIENT:
11863 break;
11864 default:
11865 return -EOPNOTSUPP;
11866 }
11867
11868 if (!info->attrs[NL80211_ATTR_MAC])
11869 return -EINVAL;
11870
11871 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11872
11873 wdev_lock(wdev);
11874 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
11875 wdev_unlock(wdev);
11876
11877 return 0;
11878}
11879
ce0ce13a
MB
11880static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
11881 struct genl_info *info)
11882{
11883 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11884 struct net_device *dev = info->user_ptr[1];
11885 struct wireless_dev *wdev = dev->ieee80211_ptr;
11886 const struct nlattr *nla;
11887 bool enabled;
11888
ce0ce13a
MB
11889 if (!rdev->ops->set_multicast_to_unicast)
11890 return -EOPNOTSUPP;
11891
11892 if (wdev->iftype != NL80211_IFTYPE_AP &&
11893 wdev->iftype != NL80211_IFTYPE_P2P_GO)
11894 return -EOPNOTSUPP;
11895
11896 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
11897 enabled = nla_get_flag(nla);
11898
11899 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
11900}
11901
4c476991
JB
11902#define NL80211_FLAG_NEED_WIPHY 0x01
11903#define NL80211_FLAG_NEED_NETDEV 0x02
11904#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
11905#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
11906#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
11907 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 11908#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 11909/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
11910#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
11911 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 11912#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 11913
f84f771d 11914static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
11915 struct genl_info *info)
11916{
11917 struct cfg80211_registered_device *rdev;
89a54e48 11918 struct wireless_dev *wdev;
4c476991 11919 struct net_device *dev;
4c476991
JB
11920 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
11921
11922 if (rtnl)
11923 rtnl_lock();
11924
11925 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 11926 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
11927 if (IS_ERR(rdev)) {
11928 if (rtnl)
11929 rtnl_unlock();
11930 return PTR_ERR(rdev);
11931 }
11932 info->user_ptr[0] = rdev;
1bf614ef
JB
11933 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
11934 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
11935 ASSERT_RTNL();
11936
89a54e48
JB
11937 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
11938 info->attrs);
11939 if (IS_ERR(wdev)) {
4c476991
JB
11940 if (rtnl)
11941 rtnl_unlock();
89a54e48 11942 return PTR_ERR(wdev);
4c476991 11943 }
89a54e48 11944
89a54e48 11945 dev = wdev->netdev;
f26cbf40 11946 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 11947
1bf614ef
JB
11948 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
11949 if (!dev) {
1bf614ef
JB
11950 if (rtnl)
11951 rtnl_unlock();
11952 return -EINVAL;
11953 }
11954
11955 info->user_ptr[1] = dev;
11956 } else {
11957 info->user_ptr[1] = wdev;
41265714 11958 }
1bf614ef 11959
73c7da3d
AVS
11960 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
11961 !wdev_running(wdev)) {
11962 if (rtnl)
11963 rtnl_unlock();
11964 return -ENETDOWN;
11965 }
1bf614ef 11966
73c7da3d 11967 if (dev)
1bf614ef 11968 dev_hold(dev);
89a54e48 11969
4c476991 11970 info->user_ptr[0] = rdev;
4c476991
JB
11971 }
11972
11973 return 0;
11974}
11975
f84f771d 11976static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
11977 struct genl_info *info)
11978{
1bf614ef
JB
11979 if (info->user_ptr[1]) {
11980 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
11981 struct wireless_dev *wdev = info->user_ptr[1];
11982
11983 if (wdev->netdev)
11984 dev_put(wdev->netdev);
11985 } else {
11986 dev_put(info->user_ptr[1]);
11987 }
11988 }
5393b917 11989
4c476991
JB
11990 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
11991 rtnl_unlock();
5393b917
JB
11992
11993 /* If needed, clear the netlink message payload from the SKB
11994 * as it might contain key data that shouldn't stick around on
11995 * the heap after the SKB is freed. The netlink message header
11996 * is still needed for further processing, so leave it intact.
11997 */
11998 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
11999 struct nlmsghdr *nlh = nlmsg_hdr(skb);
12000
12001 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
12002 }
4c476991
JB
12003}
12004
4534de83 12005static const struct genl_ops nl80211_ops[] = {
55682965
JB
12006 {
12007 .cmd = NL80211_CMD_GET_WIPHY,
12008 .doit = nl80211_get_wiphy,
12009 .dumpit = nl80211_dump_wiphy,
86e8cf98 12010 .done = nl80211_dump_wiphy_done,
55682965
JB
12011 .policy = nl80211_policy,
12012 /* can be retrieved by unprivileged users */
5fe231e8
JB
12013 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12014 NL80211_FLAG_NEED_RTNL,
55682965
JB
12015 },
12016 {
12017 .cmd = NL80211_CMD_SET_WIPHY,
12018 .doit = nl80211_set_wiphy,
12019 .policy = nl80211_policy,
5617c6cd 12020 .flags = GENL_UNS_ADMIN_PERM,
4c476991 12021 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
12022 },
12023 {
12024 .cmd = NL80211_CMD_GET_INTERFACE,
12025 .doit = nl80211_get_interface,
12026 .dumpit = nl80211_dump_interface,
12027 .policy = nl80211_policy,
12028 /* can be retrieved by unprivileged users */
5fe231e8
JB
12029 .internal_flags = NL80211_FLAG_NEED_WDEV |
12030 NL80211_FLAG_NEED_RTNL,
55682965
JB
12031 },
12032 {
12033 .cmd = NL80211_CMD_SET_INTERFACE,
12034 .doit = nl80211_set_interface,
12035 .policy = nl80211_policy,
5617c6cd 12036 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12037 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12038 NL80211_FLAG_NEED_RTNL,
55682965
JB
12039 },
12040 {
12041 .cmd = NL80211_CMD_NEW_INTERFACE,
12042 .doit = nl80211_new_interface,
12043 .policy = nl80211_policy,
5617c6cd 12044 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12045 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12046 NL80211_FLAG_NEED_RTNL,
55682965
JB
12047 },
12048 {
12049 .cmd = NL80211_CMD_DEL_INTERFACE,
12050 .doit = nl80211_del_interface,
12051 .policy = nl80211_policy,
5617c6cd 12052 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 12053 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 12054 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
12055 },
12056 {
12057 .cmd = NL80211_CMD_GET_KEY,
12058 .doit = nl80211_get_key,
12059 .policy = nl80211_policy,
5617c6cd 12060 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12061 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12062 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
12063 },
12064 {
12065 .cmd = NL80211_CMD_SET_KEY,
12066 .doit = nl80211_set_key,
12067 .policy = nl80211_policy,
5617c6cd 12068 .flags = GENL_UNS_ADMIN_PERM,
41265714 12069 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12070 NL80211_FLAG_NEED_RTNL |
12071 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
12072 },
12073 {
12074 .cmd = NL80211_CMD_NEW_KEY,
12075 .doit = nl80211_new_key,
12076 .policy = nl80211_policy,
5617c6cd 12077 .flags = GENL_UNS_ADMIN_PERM,
41265714 12078 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12079 NL80211_FLAG_NEED_RTNL |
12080 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
12081 },
12082 {
12083 .cmd = NL80211_CMD_DEL_KEY,
12084 .doit = nl80211_del_key,
12085 .policy = nl80211_policy,
5617c6cd 12086 .flags = GENL_UNS_ADMIN_PERM,
41265714 12087 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12088 NL80211_FLAG_NEED_RTNL,
55682965 12089 },
ed1b6cc7
JB
12090 {
12091 .cmd = NL80211_CMD_SET_BEACON,
12092 .policy = nl80211_policy,
5617c6cd 12093 .flags = GENL_UNS_ADMIN_PERM,
8860020e 12094 .doit = nl80211_set_beacon,
2b5f8b0b 12095 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12096 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
12097 },
12098 {
8860020e 12099 .cmd = NL80211_CMD_START_AP,
ed1b6cc7 12100 .policy = nl80211_policy,
5617c6cd 12101 .flags = GENL_UNS_ADMIN_PERM,
8860020e 12102 .doit = nl80211_start_ap,
2b5f8b0b 12103 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12104 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
12105 },
12106 {
8860020e 12107 .cmd = NL80211_CMD_STOP_AP,
ed1b6cc7 12108 .policy = nl80211_policy,
5617c6cd 12109 .flags = GENL_UNS_ADMIN_PERM,
8860020e 12110 .doit = nl80211_stop_ap,
2b5f8b0b 12111 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12112 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 12113 },
5727ef1b
JB
12114 {
12115 .cmd = NL80211_CMD_GET_STATION,
12116 .doit = nl80211_get_station,
2ec600d6 12117 .dumpit = nl80211_dump_station,
5727ef1b 12118 .policy = nl80211_policy,
4c476991
JB
12119 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12120 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
12121 },
12122 {
12123 .cmd = NL80211_CMD_SET_STATION,
12124 .doit = nl80211_set_station,
12125 .policy = nl80211_policy,
5617c6cd 12126 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12127 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12128 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
12129 },
12130 {
12131 .cmd = NL80211_CMD_NEW_STATION,
12132 .doit = nl80211_new_station,
12133 .policy = nl80211_policy,
5617c6cd 12134 .flags = GENL_UNS_ADMIN_PERM,
41265714 12135 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12136 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
12137 },
12138 {
12139 .cmd = NL80211_CMD_DEL_STATION,
12140 .doit = nl80211_del_station,
12141 .policy = nl80211_policy,
5617c6cd 12142 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12143 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12144 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12145 },
12146 {
12147 .cmd = NL80211_CMD_GET_MPATH,
12148 .doit = nl80211_get_mpath,
12149 .dumpit = nl80211_dump_mpath,
12150 .policy = nl80211_policy,
5617c6cd 12151 .flags = GENL_UNS_ADMIN_PERM,
41265714 12152 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12153 NL80211_FLAG_NEED_RTNL,
2ec600d6 12154 },
66be7d2b
HR
12155 {
12156 .cmd = NL80211_CMD_GET_MPP,
12157 .doit = nl80211_get_mpp,
12158 .dumpit = nl80211_dump_mpp,
12159 .policy = nl80211_policy,
5617c6cd 12160 .flags = GENL_UNS_ADMIN_PERM,
66be7d2b
HR
12161 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12162 NL80211_FLAG_NEED_RTNL,
12163 },
2ec600d6
LCC
12164 {
12165 .cmd = NL80211_CMD_SET_MPATH,
12166 .doit = nl80211_set_mpath,
12167 .policy = nl80211_policy,
5617c6cd 12168 .flags = GENL_UNS_ADMIN_PERM,
41265714 12169 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12170 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12171 },
12172 {
12173 .cmd = NL80211_CMD_NEW_MPATH,
12174 .doit = nl80211_new_mpath,
12175 .policy = nl80211_policy,
5617c6cd 12176 .flags = GENL_UNS_ADMIN_PERM,
41265714 12177 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12178 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12179 },
12180 {
12181 .cmd = NL80211_CMD_DEL_MPATH,
12182 .doit = nl80211_del_mpath,
12183 .policy = nl80211_policy,
5617c6cd 12184 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12185 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12186 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
12187 },
12188 {
12189 .cmd = NL80211_CMD_SET_BSS,
12190 .doit = nl80211_set_bss,
12191 .policy = nl80211_policy,
5617c6cd 12192 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12193 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12194 NL80211_FLAG_NEED_RTNL,
b2e1b302 12195 },
f130347c
LR
12196 {
12197 .cmd = NL80211_CMD_GET_REG,
ad30ca2c
AN
12198 .doit = nl80211_get_reg_do,
12199 .dumpit = nl80211_get_reg_dump,
f130347c 12200 .policy = nl80211_policy,
5fe231e8 12201 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
12202 /* can be retrieved by unprivileged users */
12203 },
b6863036 12204#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
12205 {
12206 .cmd = NL80211_CMD_SET_REG,
12207 .doit = nl80211_set_reg,
12208 .policy = nl80211_policy,
12209 .flags = GENL_ADMIN_PERM,
5fe231e8 12210 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302 12211 },
b6863036 12212#endif
b2e1b302
LR
12213 {
12214 .cmd = NL80211_CMD_REQ_SET_REG,
12215 .doit = nl80211_req_set_reg,
12216 .policy = nl80211_policy,
93da9cc1 12217 .flags = GENL_ADMIN_PERM,
12218 },
12219 {
24bdd9f4
JC
12220 .cmd = NL80211_CMD_GET_MESH_CONFIG,
12221 .doit = nl80211_get_mesh_config,
93da9cc1 12222 .policy = nl80211_policy,
12223 /* can be retrieved by unprivileged users */
2b5f8b0b 12224 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12225 NL80211_FLAG_NEED_RTNL,
93da9cc1 12226 },
12227 {
24bdd9f4
JC
12228 .cmd = NL80211_CMD_SET_MESH_CONFIG,
12229 .doit = nl80211_update_mesh_config,
93da9cc1 12230 .policy = nl80211_policy,
5617c6cd 12231 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c 12232 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12233 NL80211_FLAG_NEED_RTNL,
9aed3cc1 12234 },
2a519311
JB
12235 {
12236 .cmd = NL80211_CMD_TRIGGER_SCAN,
12237 .doit = nl80211_trigger_scan,
12238 .policy = nl80211_policy,
5617c6cd 12239 .flags = GENL_UNS_ADMIN_PERM,
fd014284 12240 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12241 NL80211_FLAG_NEED_RTNL,
2a519311 12242 },
91d3ab46
VK
12243 {
12244 .cmd = NL80211_CMD_ABORT_SCAN,
12245 .doit = nl80211_abort_scan,
12246 .policy = nl80211_policy,
5617c6cd 12247 .flags = GENL_UNS_ADMIN_PERM,
91d3ab46
VK
12248 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12249 NL80211_FLAG_NEED_RTNL,
12250 },
2a519311
JB
12251 {
12252 .cmd = NL80211_CMD_GET_SCAN,
12253 .policy = nl80211_policy,
12254 .dumpit = nl80211_dump_scan,
12255 },
807f8a8c
LC
12256 {
12257 .cmd = NL80211_CMD_START_SCHED_SCAN,
12258 .doit = nl80211_start_sched_scan,
12259 .policy = nl80211_policy,
5617c6cd 12260 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
12261 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12262 NL80211_FLAG_NEED_RTNL,
12263 },
12264 {
12265 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
12266 .doit = nl80211_stop_sched_scan,
12267 .policy = nl80211_policy,
5617c6cd 12268 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
12269 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12270 NL80211_FLAG_NEED_RTNL,
12271 },
636a5d36
JM
12272 {
12273 .cmd = NL80211_CMD_AUTHENTICATE,
12274 .doit = nl80211_authenticate,
12275 .policy = nl80211_policy,
5617c6cd 12276 .flags = GENL_UNS_ADMIN_PERM,
41265714 12277 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12278 NL80211_FLAG_NEED_RTNL |
12279 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
12280 },
12281 {
12282 .cmd = NL80211_CMD_ASSOCIATE,
12283 .doit = nl80211_associate,
12284 .policy = nl80211_policy,
5617c6cd 12285 .flags = GENL_UNS_ADMIN_PERM,
41265714 12286 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12287 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
12288 },
12289 {
12290 .cmd = NL80211_CMD_DEAUTHENTICATE,
12291 .doit = nl80211_deauthenticate,
12292 .policy = nl80211_policy,
5617c6cd 12293 .flags = GENL_UNS_ADMIN_PERM,
41265714 12294 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12295 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
12296 },
12297 {
12298 .cmd = NL80211_CMD_DISASSOCIATE,
12299 .doit = nl80211_disassociate,
12300 .policy = nl80211_policy,
5617c6cd 12301 .flags = GENL_UNS_ADMIN_PERM,
41265714 12302 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12303 NL80211_FLAG_NEED_RTNL,
636a5d36 12304 },
04a773ad
JB
12305 {
12306 .cmd = NL80211_CMD_JOIN_IBSS,
12307 .doit = nl80211_join_ibss,
12308 .policy = nl80211_policy,
5617c6cd 12309 .flags = GENL_UNS_ADMIN_PERM,
41265714 12310 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12311 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
12312 },
12313 {
12314 .cmd = NL80211_CMD_LEAVE_IBSS,
12315 .doit = nl80211_leave_ibss,
12316 .policy = nl80211_policy,
5617c6cd 12317 .flags = GENL_UNS_ADMIN_PERM,
41265714 12318 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12319 NL80211_FLAG_NEED_RTNL,
04a773ad 12320 },
aff89a9b
JB
12321#ifdef CONFIG_NL80211_TESTMODE
12322 {
12323 .cmd = NL80211_CMD_TESTMODE,
12324 .doit = nl80211_testmode_do,
71063f0e 12325 .dumpit = nl80211_testmode_dump,
aff89a9b 12326 .policy = nl80211_policy,
5617c6cd 12327 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12328 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12329 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
12330 },
12331#endif
b23aa676
SO
12332 {
12333 .cmd = NL80211_CMD_CONNECT,
12334 .doit = nl80211_connect,
12335 .policy = nl80211_policy,
5617c6cd 12336 .flags = GENL_UNS_ADMIN_PERM,
41265714 12337 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12338 NL80211_FLAG_NEED_RTNL,
b23aa676 12339 },
088e8df8 12340 {
12341 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
12342 .doit = nl80211_update_connect_params,
12343 .policy = nl80211_policy,
12344 .flags = GENL_ADMIN_PERM,
12345 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12346 NL80211_FLAG_NEED_RTNL,
12347 },
b23aa676
SO
12348 {
12349 .cmd = NL80211_CMD_DISCONNECT,
12350 .doit = nl80211_disconnect,
12351 .policy = nl80211_policy,
5617c6cd 12352 .flags = GENL_UNS_ADMIN_PERM,
41265714 12353 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12354 NL80211_FLAG_NEED_RTNL,
b23aa676 12355 },
463d0183
JB
12356 {
12357 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
12358 .doit = nl80211_wiphy_netns,
12359 .policy = nl80211_policy,
5617c6cd 12360 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12361 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12362 NL80211_FLAG_NEED_RTNL,
463d0183 12363 },
61fa713c
HS
12364 {
12365 .cmd = NL80211_CMD_GET_SURVEY,
12366 .policy = nl80211_policy,
12367 .dumpit = nl80211_dump_survey,
12368 },
67fbb16b
SO
12369 {
12370 .cmd = NL80211_CMD_SET_PMKSA,
12371 .doit = nl80211_setdel_pmksa,
12372 .policy = nl80211_policy,
5617c6cd 12373 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12374 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12375 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12376 },
12377 {
12378 .cmd = NL80211_CMD_DEL_PMKSA,
12379 .doit = nl80211_setdel_pmksa,
12380 .policy = nl80211_policy,
5617c6cd 12381 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12382 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12383 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12384 },
12385 {
12386 .cmd = NL80211_CMD_FLUSH_PMKSA,
12387 .doit = nl80211_flush_pmksa,
12388 .policy = nl80211_policy,
5617c6cd 12389 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12390 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12391 NL80211_FLAG_NEED_RTNL,
67fbb16b 12392 },
9588bbd5
JM
12393 {
12394 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
12395 .doit = nl80211_remain_on_channel,
12396 .policy = nl80211_policy,
5617c6cd 12397 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12398 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12399 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
12400 },
12401 {
12402 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
12403 .doit = nl80211_cancel_remain_on_channel,
12404 .policy = nl80211_policy,
5617c6cd 12405 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12406 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12407 NL80211_FLAG_NEED_RTNL,
9588bbd5 12408 },
13ae75b1
JM
12409 {
12410 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
12411 .doit = nl80211_set_tx_bitrate_mask,
12412 .policy = nl80211_policy,
5617c6cd 12413 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12414 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12415 NL80211_FLAG_NEED_RTNL,
13ae75b1 12416 },
026331c4 12417 {
2e161f78
JB
12418 .cmd = NL80211_CMD_REGISTER_FRAME,
12419 .doit = nl80211_register_mgmt,
026331c4 12420 .policy = nl80211_policy,
5617c6cd 12421 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12422 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 12423 NL80211_FLAG_NEED_RTNL,
026331c4
JM
12424 },
12425 {
2e161f78
JB
12426 .cmd = NL80211_CMD_FRAME,
12427 .doit = nl80211_tx_mgmt,
026331c4 12428 .policy = nl80211_policy,
5617c6cd 12429 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12430 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
12431 NL80211_FLAG_NEED_RTNL,
12432 },
12433 {
12434 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
12435 .doit = nl80211_tx_mgmt_cancel_wait,
12436 .policy = nl80211_policy,
5617c6cd 12437 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12438 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12439 NL80211_FLAG_NEED_RTNL,
026331c4 12440 },
ffb9eb3d
KV
12441 {
12442 .cmd = NL80211_CMD_SET_POWER_SAVE,
12443 .doit = nl80211_set_power_save,
12444 .policy = nl80211_policy,
5617c6cd 12445 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12446 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12447 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
12448 },
12449 {
12450 .cmd = NL80211_CMD_GET_POWER_SAVE,
12451 .doit = nl80211_get_power_save,
12452 .policy = nl80211_policy,
12453 /* can be retrieved by unprivileged users */
4c476991
JB
12454 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12455 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 12456 },
d6dc1a38
JO
12457 {
12458 .cmd = NL80211_CMD_SET_CQM,
12459 .doit = nl80211_set_cqm,
12460 .policy = nl80211_policy,
5617c6cd 12461 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12462 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12463 NL80211_FLAG_NEED_RTNL,
d6dc1a38 12464 },
f444de05
JB
12465 {
12466 .cmd = NL80211_CMD_SET_CHANNEL,
12467 .doit = nl80211_set_channel,
12468 .policy = nl80211_policy,
5617c6cd 12469 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12470 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12471 NL80211_FLAG_NEED_RTNL,
f444de05 12472 },
e8347eba
BJ
12473 {
12474 .cmd = NL80211_CMD_SET_WDS_PEER,
12475 .doit = nl80211_set_wds_peer,
12476 .policy = nl80211_policy,
5617c6cd 12477 .flags = GENL_UNS_ADMIN_PERM,
43b19952
JB
12478 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12479 NL80211_FLAG_NEED_RTNL,
e8347eba 12480 },
29cbe68c
JB
12481 {
12482 .cmd = NL80211_CMD_JOIN_MESH,
12483 .doit = nl80211_join_mesh,
12484 .policy = nl80211_policy,
5617c6cd 12485 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
12486 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12487 NL80211_FLAG_NEED_RTNL,
12488 },
12489 {
12490 .cmd = NL80211_CMD_LEAVE_MESH,
12491 .doit = nl80211_leave_mesh,
12492 .policy = nl80211_policy,
5617c6cd 12493 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
12494 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12495 NL80211_FLAG_NEED_RTNL,
12496 },
6e0bd6c3
RL
12497 {
12498 .cmd = NL80211_CMD_JOIN_OCB,
12499 .doit = nl80211_join_ocb,
12500 .policy = nl80211_policy,
5617c6cd 12501 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
12502 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12503 NL80211_FLAG_NEED_RTNL,
12504 },
12505 {
12506 .cmd = NL80211_CMD_LEAVE_OCB,
12507 .doit = nl80211_leave_ocb,
12508 .policy = nl80211_policy,
5617c6cd 12509 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
12510 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12511 NL80211_FLAG_NEED_RTNL,
12512 },
dfb89c56 12513#ifdef CONFIG_PM
ff1b6e69
JB
12514 {
12515 .cmd = NL80211_CMD_GET_WOWLAN,
12516 .doit = nl80211_get_wowlan,
12517 .policy = nl80211_policy,
12518 /* can be retrieved by unprivileged users */
12519 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12520 NL80211_FLAG_NEED_RTNL,
12521 },
12522 {
12523 .cmd = NL80211_CMD_SET_WOWLAN,
12524 .doit = nl80211_set_wowlan,
12525 .policy = nl80211_policy,
5617c6cd 12526 .flags = GENL_UNS_ADMIN_PERM,
ff1b6e69
JB
12527 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12528 NL80211_FLAG_NEED_RTNL,
12529 },
dfb89c56 12530#endif
e5497d76
JB
12531 {
12532 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
12533 .doit = nl80211_set_rekey_data,
12534 .policy = nl80211_policy,
5617c6cd 12535 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 12536 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12537 NL80211_FLAG_NEED_RTNL |
12538 NL80211_FLAG_CLEAR_SKB,
e5497d76 12539 },
109086ce
AN
12540 {
12541 .cmd = NL80211_CMD_TDLS_MGMT,
12542 .doit = nl80211_tdls_mgmt,
12543 .policy = nl80211_policy,
5617c6cd 12544 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
12545 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12546 NL80211_FLAG_NEED_RTNL,
12547 },
12548 {
12549 .cmd = NL80211_CMD_TDLS_OPER,
12550 .doit = nl80211_tdls_oper,
12551 .policy = nl80211_policy,
5617c6cd 12552 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
12553 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12554 NL80211_FLAG_NEED_RTNL,
12555 },
28946da7
JB
12556 {
12557 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
12558 .doit = nl80211_register_unexpected_frame,
12559 .policy = nl80211_policy,
5617c6cd 12560 .flags = GENL_UNS_ADMIN_PERM,
28946da7
JB
12561 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12562 NL80211_FLAG_NEED_RTNL,
12563 },
7f6cf311
JB
12564 {
12565 .cmd = NL80211_CMD_PROBE_CLIENT,
12566 .doit = nl80211_probe_client,
12567 .policy = nl80211_policy,
5617c6cd 12568 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12569 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
12570 NL80211_FLAG_NEED_RTNL,
12571 },
5e760230
JB
12572 {
12573 .cmd = NL80211_CMD_REGISTER_BEACONS,
12574 .doit = nl80211_register_beacons,
12575 .policy = nl80211_policy,
5617c6cd 12576 .flags = GENL_UNS_ADMIN_PERM,
5e760230
JB
12577 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12578 NL80211_FLAG_NEED_RTNL,
12579 },
1d9d9213
SW
12580 {
12581 .cmd = NL80211_CMD_SET_NOACK_MAP,
12582 .doit = nl80211_set_noack_map,
12583 .policy = nl80211_policy,
5617c6cd 12584 .flags = GENL_UNS_ADMIN_PERM,
1d9d9213
SW
12585 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12586 NL80211_FLAG_NEED_RTNL,
12587 },
98104fde
JB
12588 {
12589 .cmd = NL80211_CMD_START_P2P_DEVICE,
12590 .doit = nl80211_start_p2p_device,
12591 .policy = nl80211_policy,
5617c6cd 12592 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
12593 .internal_flags = NL80211_FLAG_NEED_WDEV |
12594 NL80211_FLAG_NEED_RTNL,
12595 },
12596 {
12597 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
12598 .doit = nl80211_stop_p2p_device,
12599 .policy = nl80211_policy,
5617c6cd 12600 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
12601 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12602 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
12603 },
12604 {
12605 .cmd = NL80211_CMD_START_NAN,
12606 .doit = nl80211_start_nan,
12607 .policy = nl80211_policy,
12608 .flags = GENL_ADMIN_PERM,
12609 .internal_flags = NL80211_FLAG_NEED_WDEV |
12610 NL80211_FLAG_NEED_RTNL,
12611 },
12612 {
12613 .cmd = NL80211_CMD_STOP_NAN,
12614 .doit = nl80211_stop_nan,
12615 .policy = nl80211_policy,
12616 .flags = GENL_ADMIN_PERM,
12617 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12618 NL80211_FLAG_NEED_RTNL,
a442b761
AB
12619 },
12620 {
12621 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
12622 .doit = nl80211_nan_add_func,
12623 .policy = nl80211_policy,
12624 .flags = GENL_ADMIN_PERM,
12625 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12626 NL80211_FLAG_NEED_RTNL,
12627 },
12628 {
12629 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
12630 .doit = nl80211_nan_del_func,
12631 .policy = nl80211_policy,
12632 .flags = GENL_ADMIN_PERM,
12633 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12634 NL80211_FLAG_NEED_RTNL,
a5a9dcf2
AB
12635 },
12636 {
12637 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
12638 .doit = nl80211_nan_change_config,
12639 .policy = nl80211_policy,
12640 .flags = GENL_ADMIN_PERM,
12641 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12642 NL80211_FLAG_NEED_RTNL,
98104fde 12643 },
f4e583c8
AQ
12644 {
12645 .cmd = NL80211_CMD_SET_MCAST_RATE,
12646 .doit = nl80211_set_mcast_rate,
77765eaf 12647 .policy = nl80211_policy,
5617c6cd 12648 .flags = GENL_UNS_ADMIN_PERM,
77765eaf
VT
12649 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12650 NL80211_FLAG_NEED_RTNL,
12651 },
12652 {
12653 .cmd = NL80211_CMD_SET_MAC_ACL,
12654 .doit = nl80211_set_mac_acl,
f4e583c8 12655 .policy = nl80211_policy,
5617c6cd 12656 .flags = GENL_UNS_ADMIN_PERM,
f4e583c8
AQ
12657 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12658 NL80211_FLAG_NEED_RTNL,
12659 },
04f39047
SW
12660 {
12661 .cmd = NL80211_CMD_RADAR_DETECT,
12662 .doit = nl80211_start_radar_detection,
12663 .policy = nl80211_policy,
5617c6cd 12664 .flags = GENL_UNS_ADMIN_PERM,
04f39047
SW
12665 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12666 NL80211_FLAG_NEED_RTNL,
12667 },
3713b4e3
JB
12668 {
12669 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
12670 .doit = nl80211_get_protocol_features,
12671 .policy = nl80211_policy,
12672 },
355199e0
JM
12673 {
12674 .cmd = NL80211_CMD_UPDATE_FT_IES,
12675 .doit = nl80211_update_ft_ies,
12676 .policy = nl80211_policy,
5617c6cd 12677 .flags = GENL_UNS_ADMIN_PERM,
355199e0
JM
12678 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12679 NL80211_FLAG_NEED_RTNL,
12680 },
5de17984
AS
12681 {
12682 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
12683 .doit = nl80211_crit_protocol_start,
12684 .policy = nl80211_policy,
5617c6cd 12685 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
12686 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12687 NL80211_FLAG_NEED_RTNL,
12688 },
12689 {
12690 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
12691 .doit = nl80211_crit_protocol_stop,
12692 .policy = nl80211_policy,
5617c6cd 12693 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
12694 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12695 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
12696 },
12697 {
12698 .cmd = NL80211_CMD_GET_COALESCE,
12699 .doit = nl80211_get_coalesce,
12700 .policy = nl80211_policy,
12701 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12702 NL80211_FLAG_NEED_RTNL,
12703 },
12704 {
12705 .cmd = NL80211_CMD_SET_COALESCE,
12706 .doit = nl80211_set_coalesce,
12707 .policy = nl80211_policy,
5617c6cd 12708 .flags = GENL_UNS_ADMIN_PERM,
be29b99a
AK
12709 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12710 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
12711 },
12712 {
12713 .cmd = NL80211_CMD_CHANNEL_SWITCH,
12714 .doit = nl80211_channel_switch,
12715 .policy = nl80211_policy,
5617c6cd 12716 .flags = GENL_UNS_ADMIN_PERM,
16ef1fe2
SW
12717 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12718 NL80211_FLAG_NEED_RTNL,
12719 },
ad7e718c
JB
12720 {
12721 .cmd = NL80211_CMD_VENDOR,
12722 .doit = nl80211_vendor_cmd,
7bdbe400 12723 .dumpit = nl80211_vendor_cmd_dump,
ad7e718c 12724 .policy = nl80211_policy,
5617c6cd 12725 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c
JB
12726 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12727 NL80211_FLAG_NEED_RTNL,
12728 },
fa9ffc74
KP
12729 {
12730 .cmd = NL80211_CMD_SET_QOS_MAP,
12731 .doit = nl80211_set_qos_map,
12732 .policy = nl80211_policy,
5617c6cd 12733 .flags = GENL_UNS_ADMIN_PERM,
fa9ffc74
KP
12734 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12735 NL80211_FLAG_NEED_RTNL,
12736 },
960d01ac
JB
12737 {
12738 .cmd = NL80211_CMD_ADD_TX_TS,
12739 .doit = nl80211_add_tx_ts,
12740 .policy = nl80211_policy,
5617c6cd 12741 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
12742 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12743 NL80211_FLAG_NEED_RTNL,
12744 },
12745 {
12746 .cmd = NL80211_CMD_DEL_TX_TS,
12747 .doit = nl80211_del_tx_ts,
12748 .policy = nl80211_policy,
5617c6cd 12749 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
12750 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12751 NL80211_FLAG_NEED_RTNL,
12752 },
1057d35e
AN
12753 {
12754 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
12755 .doit = nl80211_tdls_channel_switch,
12756 .policy = nl80211_policy,
5617c6cd 12757 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
12758 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12759 NL80211_FLAG_NEED_RTNL,
12760 },
12761 {
12762 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
12763 .doit = nl80211_tdls_cancel_channel_switch,
12764 .policy = nl80211_policy,
5617c6cd 12765 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
12766 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12767 NL80211_FLAG_NEED_RTNL,
12768 },
ce0ce13a
MB
12769 {
12770 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
12771 .doit = nl80211_set_multicast_to_unicast,
12772 .policy = nl80211_policy,
12773 .flags = GENL_UNS_ADMIN_PERM,
12774 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12775 NL80211_FLAG_NEED_RTNL,
12776 },
55682965 12777};
9588bbd5 12778
56989f6d 12779static struct genl_family nl80211_fam __ro_after_init = {
489111e5
JB
12780 .name = NL80211_GENL_NAME, /* have users key off the name instead */
12781 .hdrsize = 0, /* no private header */
12782 .version = 1, /* no particular meaning now */
12783 .maxattr = NL80211_ATTR_MAX,
12784 .netnsok = true,
12785 .pre_doit = nl80211_pre_doit,
12786 .post_doit = nl80211_post_doit,
12787 .module = THIS_MODULE,
12788 .ops = nl80211_ops,
12789 .n_ops = ARRAY_SIZE(nl80211_ops),
12790 .mcgrps = nl80211_mcgrps,
12791 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
12792};
12793
55682965
JB
12794/* notification functions */
12795
3bb20556
JB
12796void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
12797 enum nl80211_commands cmd)
55682965
JB
12798{
12799 struct sk_buff *msg;
86e8cf98 12800 struct nl80211_dump_wiphy_state state = {};
55682965 12801
3bb20556
JB
12802 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
12803 cmd != NL80211_CMD_DEL_WIPHY);
12804
fd2120ca 12805 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
12806 if (!msg)
12807 return;
12808
3bb20556 12809 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
12810 nlmsg_free(msg);
12811 return;
12812 }
12813
68eb5503 12814 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12815 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
12816}
12817
896ff063
DK
12818void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
12819 struct wireless_dev *wdev,
12820 enum nl80211_commands cmd)
12821{
12822 struct sk_buff *msg;
12823
12824 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
12825 cmd != NL80211_CMD_DEL_INTERFACE);
12826
12827 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12828 if (!msg)
12829 return;
12830
12831 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev,
12832 cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
12833 nlmsg_free(msg);
12834 return;
12835 }
12836
12837 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
12838 NL80211_MCGRP_CONFIG, GFP_KERNEL);
12839}
12840
362a415d
JB
12841static int nl80211_add_scan_req(struct sk_buff *msg,
12842 struct cfg80211_registered_device *rdev)
12843{
12844 struct cfg80211_scan_request *req = rdev->scan_req;
12845 struct nlattr *nest;
12846 int i;
12847
12848 if (WARN_ON(!req))
12849 return 0;
12850
12851 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
12852 if (!nest)
12853 goto nla_put_failure;
9360ffd1
DM
12854 for (i = 0; i < req->n_ssids; i++) {
12855 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
12856 goto nla_put_failure;
12857 }
362a415d
JB
12858 nla_nest_end(msg, nest);
12859
12860 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
12861 if (!nest)
12862 goto nla_put_failure;
9360ffd1
DM
12863 for (i = 0; i < req->n_channels; i++) {
12864 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
12865 goto nla_put_failure;
12866 }
362a415d
JB
12867 nla_nest_end(msg, nest);
12868
9360ffd1
DM
12869 if (req->ie &&
12870 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
12871 goto nla_put_failure;
362a415d 12872
ae917c9f
JB
12873 if (req->flags &&
12874 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
12875 goto nla_put_failure;
ed473771 12876
1d76250b
AS
12877 if (req->info.scan_start_tsf &&
12878 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
12879 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
12880 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
12881 req->info.tsf_bssid)))
12882 goto nla_put_failure;
12883
362a415d
JB
12884 return 0;
12885 nla_put_failure:
12886 return -ENOBUFS;
12887}
12888
505a2e88 12889static int nl80211_prep_scan_msg(struct sk_buff *msg,
a538e2d5 12890 struct cfg80211_registered_device *rdev,
fd014284 12891 struct wireless_dev *wdev,
15e47304 12892 u32 portid, u32 seq, int flags,
a538e2d5 12893 u32 cmd)
2a519311
JB
12894{
12895 void *hdr;
12896
15e47304 12897 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
12898 if (!hdr)
12899 return -1;
12900
9360ffd1 12901 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
12902 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12903 wdev->netdev->ifindex)) ||
2dad624e
ND
12904 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12905 NL80211_ATTR_PAD))
9360ffd1 12906 goto nla_put_failure;
2a519311 12907
362a415d
JB
12908 /* ignore errors and send incomplete event anyway */
12909 nl80211_add_scan_req(msg, rdev);
2a519311 12910
053c095a
JB
12911 genlmsg_end(msg, hdr);
12912 return 0;
2a519311
JB
12913
12914 nla_put_failure:
12915 genlmsg_cancel(msg, hdr);
12916 return -EMSGSIZE;
12917}
12918
807f8a8c 12919static int
505a2e88 12920nl80211_prep_sched_scan_msg(struct sk_buff *msg,
807f8a8c
LC
12921 struct cfg80211_registered_device *rdev,
12922 struct net_device *netdev,
15e47304 12923 u32 portid, u32 seq, int flags, u32 cmd)
807f8a8c
LC
12924{
12925 void *hdr;
12926
15e47304 12927 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
807f8a8c
LC
12928 if (!hdr)
12929 return -1;
12930
9360ffd1
DM
12931 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12932 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
12933 goto nla_put_failure;
807f8a8c 12934
053c095a
JB
12935 genlmsg_end(msg, hdr);
12936 return 0;
807f8a8c
LC
12937
12938 nla_put_failure:
12939 genlmsg_cancel(msg, hdr);
12940 return -EMSGSIZE;
12941}
12942
a538e2d5 12943void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 12944 struct wireless_dev *wdev)
a538e2d5
JB
12945{
12946 struct sk_buff *msg;
12947
58050fce 12948 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
12949 if (!msg)
12950 return;
12951
505a2e88 12952 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
12953 NL80211_CMD_TRIGGER_SCAN) < 0) {
12954 nlmsg_free(msg);
12955 return;
12956 }
12957
68eb5503 12958 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12959 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
12960}
12961
f9d15d16
JB
12962struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
12963 struct wireless_dev *wdev, bool aborted)
2a519311
JB
12964{
12965 struct sk_buff *msg;
12966
fd2120ca 12967 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 12968 if (!msg)
f9d15d16 12969 return NULL;
2a519311 12970
505a2e88 12971 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
12972 aborted ? NL80211_CMD_SCAN_ABORTED :
12973 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 12974 nlmsg_free(msg);
f9d15d16 12975 return NULL;
2a519311
JB
12976 }
12977
f9d15d16 12978 return msg;
2a519311
JB
12979}
12980
505a2e88
AVS
12981/* send message created by nl80211_build_scan_msg() */
12982void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
12983 struct sk_buff *msg)
807f8a8c 12984{
807f8a8c
LC
12985 if (!msg)
12986 return;
12987
68eb5503 12988 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12989 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
12990}
12991
12992void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
12993 struct net_device *netdev, u32 cmd)
12994{
12995 struct sk_buff *msg;
12996
58050fce 12997 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
12998 if (!msg)
12999 return;
13000
505a2e88 13001 if (nl80211_prep_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
807f8a8c
LC
13002 nlmsg_free(msg);
13003 return;
13004 }
13005
68eb5503 13006 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13007 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
13008}
13009
b0d7aa59
JD
13010static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
13011 struct regulatory_request *request)
73d54c9e 13012{
73d54c9e 13013 /* Userspace can always count this one always being set */
9360ffd1
DM
13014 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
13015 goto nla_put_failure;
13016
13017 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
13018 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13019 NL80211_REGDOM_TYPE_WORLD))
13020 goto nla_put_failure;
13021 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
13022 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13023 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
13024 goto nla_put_failure;
13025 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
13026 request->intersect) {
13027 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13028 NL80211_REGDOM_TYPE_INTERSECTION))
13029 goto nla_put_failure;
13030 } else {
13031 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
13032 NL80211_REGDOM_TYPE_COUNTRY) ||
13033 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
13034 request->alpha2))
13035 goto nla_put_failure;
13036 }
13037
ad30ca2c
AN
13038 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
13039 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
13040
13041 if (wiphy &&
13042 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
13043 goto nla_put_failure;
1bdd716c
AN
13044
13045 if (wiphy &&
13046 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
13047 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
13048 goto nla_put_failure;
ad30ca2c 13049 }
73d54c9e 13050
b0d7aa59
JD
13051 return true;
13052
13053nla_put_failure:
13054 return false;
13055}
13056
13057/*
13058 * This can happen on global regulatory changes or device specific settings
13059 * based on custom regulatory domains.
13060 */
13061void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
13062 struct regulatory_request *request)
13063{
13064 struct sk_buff *msg;
13065 void *hdr;
13066
13067 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13068 if (!msg)
13069 return;
13070
13071 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
13072 if (!hdr) {
13073 nlmsg_free(msg);
13074 return;
13075 }
13076
13077 if (nl80211_reg_change_event_fill(msg, request) == false)
13078 goto nla_put_failure;
13079
3b7b72ee 13080 genlmsg_end(msg, hdr);
73d54c9e 13081
bc43b28c 13082 rcu_read_lock();
68eb5503 13083 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 13084 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 13085 rcu_read_unlock();
73d54c9e
LR
13086
13087 return;
13088
13089nla_put_failure:
13090 genlmsg_cancel(msg, hdr);
13091 nlmsg_free(msg);
13092}
13093
6039f6d2
JM
13094static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
13095 struct net_device *netdev,
13096 const u8 *buf, size_t len,
b0b6aa2c
EP
13097 enum nl80211_commands cmd, gfp_t gfp,
13098 int uapsd_queues)
6039f6d2
JM
13099{
13100 struct sk_buff *msg;
13101 void *hdr;
13102
4ef8c1c9 13103 msg = nlmsg_new(100 + len, gfp);
6039f6d2
JM
13104 if (!msg)
13105 return;
13106
13107 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13108 if (!hdr) {
13109 nlmsg_free(msg);
13110 return;
13111 }
13112
9360ffd1
DM
13113 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13114 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13115 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
13116 goto nla_put_failure;
6039f6d2 13117
b0b6aa2c
EP
13118 if (uapsd_queues >= 0) {
13119 struct nlattr *nla_wmm =
13120 nla_nest_start(msg, NL80211_ATTR_STA_WME);
13121 if (!nla_wmm)
13122 goto nla_put_failure;
13123
13124 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
13125 uapsd_queues))
13126 goto nla_put_failure;
13127
13128 nla_nest_end(msg, nla_wmm);
13129 }
13130
3b7b72ee 13131 genlmsg_end(msg, hdr);
6039f6d2 13132
68eb5503 13133 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13134 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
13135 return;
13136
13137 nla_put_failure:
13138 genlmsg_cancel(msg, hdr);
13139 nlmsg_free(msg);
13140}
13141
13142void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13143 struct net_device *netdev, const u8 *buf,
13144 size_t len, gfp_t gfp)
6039f6d2
JM
13145{
13146 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13147 NL80211_CMD_AUTHENTICATE, gfp, -1);
6039f6d2
JM
13148}
13149
13150void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
13151 struct net_device *netdev, const u8 *buf,
b0b6aa2c 13152 size_t len, gfp_t gfp, int uapsd_queues)
6039f6d2 13153{
e6d6e342 13154 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13155 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues);
6039f6d2
JM
13156}
13157
53b46b84 13158void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13159 struct net_device *netdev, const u8 *buf,
13160 size_t len, gfp_t gfp)
6039f6d2
JM
13161{
13162 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13163 NL80211_CMD_DEAUTHENTICATE, gfp, -1);
6039f6d2
JM
13164}
13165
53b46b84
JM
13166void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
13167 struct net_device *netdev, const u8 *buf,
e6d6e342 13168 size_t len, gfp_t gfp)
6039f6d2
JM
13169{
13170 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13171 NL80211_CMD_DISASSOCIATE, gfp, -1);
6039f6d2
JM
13172}
13173
6ff57cf8
JB
13174void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
13175 size_t len)
cf4e594e 13176{
947add36
JB
13177 struct wireless_dev *wdev = dev->ieee80211_ptr;
13178 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13179 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
13180 const struct ieee80211_mgmt *mgmt = (void *)buf;
13181 u32 cmd;
947add36 13182
6ff57cf8
JB
13183 if (WARN_ON(len < 2))
13184 return;
cf4e594e 13185
6ff57cf8
JB
13186 if (ieee80211_is_deauth(mgmt->frame_control))
13187 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
13188 else
13189 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 13190
6ff57cf8 13191 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
b0b6aa2c 13192 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1);
cf4e594e 13193}
6ff57cf8 13194EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 13195
1b06bb40
LR
13196static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
13197 struct net_device *netdev, int cmd,
e6d6e342 13198 const u8 *addr, gfp_t gfp)
1965c853
JM
13199{
13200 struct sk_buff *msg;
13201 void *hdr;
13202
e6d6e342 13203 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
13204 if (!msg)
13205 return;
13206
13207 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13208 if (!hdr) {
13209 nlmsg_free(msg);
13210 return;
13211 }
13212
9360ffd1
DM
13213 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13214 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13215 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
13216 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
13217 goto nla_put_failure;
1965c853 13218
3b7b72ee 13219 genlmsg_end(msg, hdr);
1965c853 13220
68eb5503 13221 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13222 NL80211_MCGRP_MLME, gfp);
1965c853
JM
13223 return;
13224
13225 nla_put_failure:
13226 genlmsg_cancel(msg, hdr);
13227 nlmsg_free(msg);
13228}
13229
13230void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13231 struct net_device *netdev, const u8 *addr,
13232 gfp_t gfp)
1965c853
JM
13233{
13234 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 13235 addr, gfp);
1965c853
JM
13236}
13237
13238void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13239 struct net_device *netdev, const u8 *addr,
13240 gfp_t gfp)
1965c853 13241{
e6d6e342
JB
13242 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
13243 addr, gfp);
1965c853
JM
13244}
13245
b23aa676
SO
13246void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
13247 struct net_device *netdev, const u8 *bssid,
13248 const u8 *req_ie, size_t req_ie_len,
13249 const u8 *resp_ie, size_t resp_ie_len,
3093ebbe
PK
13250 int status,
13251 enum nl80211_timeout_reason timeout_reason,
13252 gfp_t gfp)
b23aa676
SO
13253{
13254 struct sk_buff *msg;
13255 void *hdr;
13256
4ef8c1c9 13257 msg = nlmsg_new(100 + req_ie_len + resp_ie_len, gfp);
b23aa676
SO
13258 if (!msg)
13259 return;
13260
13261 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
13262 if (!hdr) {
13263 nlmsg_free(msg);
13264 return;
13265 }
13266
9360ffd1
DM
13267 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13268 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13269 (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) ||
bf1ecd21
JM
13270 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
13271 status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
13272 status) ||
3093ebbe
PK
13273 (status < 0 &&
13274 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
13275 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON, timeout_reason))) ||
9360ffd1
DM
13276 (req_ie &&
13277 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
13278 (resp_ie &&
13279 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
13280 goto nla_put_failure;
b23aa676 13281
3b7b72ee 13282 genlmsg_end(msg, hdr);
b23aa676 13283
68eb5503 13284 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13285 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
13286 return;
13287
13288 nla_put_failure:
13289 genlmsg_cancel(msg, hdr);
13290 nlmsg_free(msg);
b23aa676
SO
13291}
13292
13293void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
13294 struct net_device *netdev, const u8 *bssid,
13295 const u8 *req_ie, size_t req_ie_len,
13296 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
13297{
13298 struct sk_buff *msg;
13299 void *hdr;
13300
4ef8c1c9 13301 msg = nlmsg_new(100 + req_ie_len + resp_ie_len, gfp);
b23aa676
SO
13302 if (!msg)
13303 return;
13304
13305 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
13306 if (!hdr) {
13307 nlmsg_free(msg);
13308 return;
13309 }
13310
9360ffd1
DM
13311 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13312 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13313 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
13314 (req_ie &&
13315 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
13316 (resp_ie &&
13317 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
13318 goto nla_put_failure;
b23aa676 13319
3b7b72ee 13320 genlmsg_end(msg, hdr);
b23aa676 13321
68eb5503 13322 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13323 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
13324 return;
13325
13326 nla_put_failure:
13327 genlmsg_cancel(msg, hdr);
13328 nlmsg_free(msg);
b23aa676
SO
13329}
13330
13331void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
13332 struct net_device *netdev, u16 reason,
667503dd 13333 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
13334{
13335 struct sk_buff *msg;
13336 void *hdr;
13337
4ef8c1c9 13338 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
b23aa676
SO
13339 if (!msg)
13340 return;
13341
13342 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
13343 if (!hdr) {
13344 nlmsg_free(msg);
13345 return;
13346 }
13347
9360ffd1
DM
13348 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13349 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13350 (from_ap && reason &&
13351 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
13352 (from_ap &&
13353 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
13354 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
13355 goto nla_put_failure;
b23aa676 13356
3b7b72ee 13357 genlmsg_end(msg, hdr);
b23aa676 13358
68eb5503 13359 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13360 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
13361 return;
13362
13363 nla_put_failure:
13364 genlmsg_cancel(msg, hdr);
13365 nlmsg_free(msg);
b23aa676
SO
13366}
13367
04a773ad
JB
13368void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
13369 struct net_device *netdev, const u8 *bssid,
13370 gfp_t gfp)
13371{
13372 struct sk_buff *msg;
13373 void *hdr;
13374
fd2120ca 13375 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
13376 if (!msg)
13377 return;
13378
13379 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
13380 if (!hdr) {
13381 nlmsg_free(msg);
13382 return;
13383 }
13384
9360ffd1
DM
13385 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13386 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13387 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13388 goto nla_put_failure;
04a773ad 13389
3b7b72ee 13390 genlmsg_end(msg, hdr);
04a773ad 13391
68eb5503 13392 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13393 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
13394 return;
13395
13396 nla_put_failure:
13397 genlmsg_cancel(msg, hdr);
13398 nlmsg_free(msg);
13399}
13400
947add36
JB
13401void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
13402 const u8* ie, u8 ie_len, gfp_t gfp)
c93b5e71 13403{
947add36 13404 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13405 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
13406 struct sk_buff *msg;
13407 void *hdr;
13408
947add36
JB
13409 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
13410 return;
13411
13412 trace_cfg80211_notify_new_peer_candidate(dev, addr);
13413
4ef8c1c9 13414 msg = nlmsg_new(100 + ie_len, gfp);
c93b5e71
JC
13415 if (!msg)
13416 return;
13417
13418 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
13419 if (!hdr) {
13420 nlmsg_free(msg);
13421 return;
13422 }
13423
9360ffd1 13424 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
13425 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13426 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1
DM
13427 (ie_len && ie &&
13428 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
13429 goto nla_put_failure;
c93b5e71 13430
3b7b72ee 13431 genlmsg_end(msg, hdr);
c93b5e71 13432
68eb5503 13433 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13434 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
13435 return;
13436
13437 nla_put_failure:
13438 genlmsg_cancel(msg, hdr);
13439 nlmsg_free(msg);
13440}
947add36 13441EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 13442
a3b8b056
JM
13443void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
13444 struct net_device *netdev, const u8 *addr,
13445 enum nl80211_key_type key_type, int key_id,
e6d6e342 13446 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
13447{
13448 struct sk_buff *msg;
13449 void *hdr;
13450
e6d6e342 13451 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
13452 if (!msg)
13453 return;
13454
13455 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
13456 if (!hdr) {
13457 nlmsg_free(msg);
13458 return;
13459 }
13460
9360ffd1
DM
13461 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13462 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13463 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
13464 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
13465 (key_id != -1 &&
13466 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
13467 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
13468 goto nla_put_failure;
a3b8b056 13469
3b7b72ee 13470 genlmsg_end(msg, hdr);
a3b8b056 13471
68eb5503 13472 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13473 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
13474 return;
13475
13476 nla_put_failure:
13477 genlmsg_cancel(msg, hdr);
13478 nlmsg_free(msg);
13479}
13480
6bad8766
LR
13481void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
13482 struct ieee80211_channel *channel_before,
13483 struct ieee80211_channel *channel_after)
13484{
13485 struct sk_buff *msg;
13486 void *hdr;
13487 struct nlattr *nl_freq;
13488
fd2120ca 13489 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
13490 if (!msg)
13491 return;
13492
13493 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
13494 if (!hdr) {
13495 nlmsg_free(msg);
13496 return;
13497 }
13498
13499 /*
13500 * Since we are applying the beacon hint to a wiphy we know its
13501 * wiphy_idx is valid
13502 */
9360ffd1
DM
13503 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
13504 goto nla_put_failure;
6bad8766
LR
13505
13506 /* Before */
13507 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
13508 if (!nl_freq)
13509 goto nla_put_failure;
cdc89b97 13510 if (nl80211_msg_put_channel(msg, channel_before, false))
6bad8766
LR
13511 goto nla_put_failure;
13512 nla_nest_end(msg, nl_freq);
13513
13514 /* After */
13515 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
13516 if (!nl_freq)
13517 goto nla_put_failure;
cdc89b97 13518 if (nl80211_msg_put_channel(msg, channel_after, false))
6bad8766
LR
13519 goto nla_put_failure;
13520 nla_nest_end(msg, nl_freq);
13521
3b7b72ee 13522 genlmsg_end(msg, hdr);
6bad8766 13523
463d0183 13524 rcu_read_lock();
68eb5503 13525 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 13526 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 13527 rcu_read_unlock();
6bad8766
LR
13528
13529 return;
13530
13531nla_put_failure:
13532 genlmsg_cancel(msg, hdr);
13533 nlmsg_free(msg);
13534}
13535
9588bbd5
JM
13536static void nl80211_send_remain_on_chan_event(
13537 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 13538 struct wireless_dev *wdev, u64 cookie,
9588bbd5 13539 struct ieee80211_channel *chan,
9588bbd5
JM
13540 unsigned int duration, gfp_t gfp)
13541{
13542 struct sk_buff *msg;
13543 void *hdr;
13544
13545 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13546 if (!msg)
13547 return;
13548
13549 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13550 if (!hdr) {
13551 nlmsg_free(msg);
13552 return;
13553 }
13554
9360ffd1 13555 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13556 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13557 wdev->netdev->ifindex)) ||
2dad624e
ND
13558 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13559 NL80211_ATTR_PAD) ||
9360ffd1 13560 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
13561 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
13562 NL80211_CHAN_NO_HT) ||
2dad624e
ND
13563 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13564 NL80211_ATTR_PAD))
9360ffd1 13565 goto nla_put_failure;
9588bbd5 13566
9360ffd1
DM
13567 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
13568 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
13569 goto nla_put_failure;
9588bbd5 13570
3b7b72ee 13571 genlmsg_end(msg, hdr);
9588bbd5 13572
68eb5503 13573 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13574 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
13575 return;
13576
13577 nla_put_failure:
13578 genlmsg_cancel(msg, hdr);
13579 nlmsg_free(msg);
13580}
13581
947add36
JB
13582void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
13583 struct ieee80211_channel *chan,
13584 unsigned int duration, gfp_t gfp)
9588bbd5 13585{
947add36 13586 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13587 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13588
13589 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 13590 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 13591 rdev, wdev, cookie, chan,
42d97a59 13592 duration, gfp);
9588bbd5 13593}
947add36 13594EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 13595
947add36
JB
13596void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
13597 struct ieee80211_channel *chan,
13598 gfp_t gfp)
9588bbd5 13599{
947add36 13600 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13601 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13602
13603 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 13604 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 13605 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 13606}
947add36 13607EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 13608
947add36
JB
13609void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
13610 struct station_info *sinfo, gfp_t gfp)
98b62183 13611{
947add36 13612 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13613 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
13614 struct sk_buff *msg;
13615
947add36
JB
13616 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
13617
58050fce 13618 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
13619 if (!msg)
13620 return;
13621
cf5ead82 13622 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 13623 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
13624 nlmsg_free(msg);
13625 return;
13626 }
13627
68eb5503 13628 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13629 NL80211_MCGRP_MLME, gfp);
98b62183 13630}
947add36 13631EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 13632
cf5ead82
JB
13633void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
13634 struct station_info *sinfo, gfp_t gfp)
ec15e68b 13635{
947add36 13636 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13637 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 13638 struct sk_buff *msg;
cf5ead82
JB
13639 struct station_info empty_sinfo = {};
13640
13641 if (!sinfo)
13642 sinfo = &empty_sinfo;
ec15e68b 13643
947add36
JB
13644 trace_cfg80211_del_sta(dev, mac_addr);
13645
58050fce 13646 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
ec15e68b
JM
13647 if (!msg)
13648 return;
13649
cf5ead82 13650 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 13651 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b
JM
13652 nlmsg_free(msg);
13653 return;
13654 }
13655
68eb5503 13656 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13657 NL80211_MCGRP_MLME, gfp);
ec15e68b 13658}
cf5ead82 13659EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 13660
947add36
JB
13661void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
13662 enum nl80211_connect_failed_reason reason,
13663 gfp_t gfp)
ed44a951 13664{
947add36 13665 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13666 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
13667 struct sk_buff *msg;
13668 void *hdr;
13669
13670 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
13671 if (!msg)
13672 return;
13673
13674 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
13675 if (!hdr) {
13676 nlmsg_free(msg);
13677 return;
13678 }
13679
13680 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13681 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
13682 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
13683 goto nla_put_failure;
13684
13685 genlmsg_end(msg, hdr);
13686
68eb5503 13687 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13688 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
13689 return;
13690
13691 nla_put_failure:
13692 genlmsg_cancel(msg, hdr);
13693 nlmsg_free(msg);
13694}
947add36 13695EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 13696
b92ab5d8
JB
13697static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
13698 const u8 *addr, gfp_t gfp)
28946da7
JB
13699{
13700 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13701 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
13702 struct sk_buff *msg;
13703 void *hdr;
15e47304 13704 u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid);
28946da7 13705
15e47304 13706 if (!nlportid)
28946da7
JB
13707 return false;
13708
13709 msg = nlmsg_new(100, gfp);
13710 if (!msg)
13711 return true;
13712
b92ab5d8 13713 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
13714 if (!hdr) {
13715 nlmsg_free(msg);
13716 return true;
13717 }
13718
9360ffd1
DM
13719 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13720 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13721 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
13722 goto nla_put_failure;
28946da7 13723
9c90a9f6 13724 genlmsg_end(msg, hdr);
15e47304 13725 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
13726 return true;
13727
13728 nla_put_failure:
13729 genlmsg_cancel(msg, hdr);
13730 nlmsg_free(msg);
13731 return true;
13732}
13733
947add36
JB
13734bool cfg80211_rx_spurious_frame(struct net_device *dev,
13735 const u8 *addr, gfp_t gfp)
b92ab5d8 13736{
947add36
JB
13737 struct wireless_dev *wdev = dev->ieee80211_ptr;
13738 bool ret;
13739
13740 trace_cfg80211_rx_spurious_frame(dev, addr);
13741
13742 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
13743 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
13744 trace_cfg80211_return_bool(false);
13745 return false;
13746 }
13747 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
13748 addr, gfp);
13749 trace_cfg80211_return_bool(ret);
13750 return ret;
b92ab5d8 13751}
947add36 13752EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 13753
947add36
JB
13754bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
13755 const u8 *addr, gfp_t gfp)
b92ab5d8 13756{
947add36
JB
13757 struct wireless_dev *wdev = dev->ieee80211_ptr;
13758 bool ret;
13759
13760 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
13761
13762 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
13763 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
13764 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
13765 trace_cfg80211_return_bool(false);
13766 return false;
13767 }
13768 ret = __nl80211_unexpected_frame(dev,
13769 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
13770 addr, gfp);
13771 trace_cfg80211_return_bool(ret);
13772 return ret;
b92ab5d8 13773}
947add36 13774EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 13775
2e161f78 13776int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 13777 struct wireless_dev *wdev, u32 nlportid,
804483e9 13778 int freq, int sig_dbm,
19504cf5 13779 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 13780{
71bbc994 13781 struct net_device *netdev = wdev->netdev;
026331c4
JM
13782 struct sk_buff *msg;
13783 void *hdr;
026331c4 13784
4ef8c1c9 13785 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
13786 if (!msg)
13787 return -ENOMEM;
13788
2e161f78 13789 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
13790 if (!hdr) {
13791 nlmsg_free(msg);
13792 return -ENOMEM;
13793 }
13794
9360ffd1 13795 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13796 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13797 netdev->ifindex)) ||
2dad624e
ND
13798 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13799 NL80211_ATTR_PAD) ||
9360ffd1
DM
13800 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
13801 (sig_dbm &&
13802 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
13803 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
13804 (flags &&
13805 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 13806 goto nla_put_failure;
026331c4 13807
3b7b72ee 13808 genlmsg_end(msg, hdr);
026331c4 13809
15e47304 13810 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
13811
13812 nla_put_failure:
13813 genlmsg_cancel(msg, hdr);
13814 nlmsg_free(msg);
13815 return -ENOBUFS;
13816}
13817
947add36
JB
13818void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
13819 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 13820{
947add36 13821 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13822 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 13823 struct net_device *netdev = wdev->netdev;
026331c4
JM
13824 struct sk_buff *msg;
13825 void *hdr;
13826
947add36
JB
13827 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
13828
4ef8c1c9 13829 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
13830 if (!msg)
13831 return;
13832
2e161f78 13833 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
13834 if (!hdr) {
13835 nlmsg_free(msg);
13836 return;
13837 }
13838
9360ffd1 13839 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13840 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13841 netdev->ifindex)) ||
2dad624e
ND
13842 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13843 NL80211_ATTR_PAD) ||
9360ffd1 13844 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
13845 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13846 NL80211_ATTR_PAD) ||
9360ffd1
DM
13847 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
13848 goto nla_put_failure;
026331c4 13849
3b7b72ee 13850 genlmsg_end(msg, hdr);
026331c4 13851
68eb5503 13852 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13853 NL80211_MCGRP_MLME, gfp);
026331c4
JM
13854 return;
13855
13856 nla_put_failure:
13857 genlmsg_cancel(msg, hdr);
13858 nlmsg_free(msg);
13859}
947add36 13860EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 13861
5b97f49d
JB
13862static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
13863 const char *mac, gfp_t gfp)
d6dc1a38 13864{
947add36 13865 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
13866 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
13867 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13868 void **cb;
947add36 13869
d6dc1a38 13870 if (!msg)
5b97f49d 13871 return NULL;
d6dc1a38 13872
5b97f49d
JB
13873 cb = (void **)msg->cb;
13874
13875 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
13876 if (!cb[0]) {
d6dc1a38 13877 nlmsg_free(msg);
5b97f49d 13878 return NULL;
d6dc1a38
JO
13879 }
13880
9360ffd1 13881 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 13882 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 13883 goto nla_put_failure;
d6dc1a38 13884
5b97f49d 13885 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
13886 goto nla_put_failure;
13887
5b97f49d
JB
13888 cb[1] = nla_nest_start(msg, NL80211_ATTR_CQM);
13889 if (!cb[1])
9360ffd1 13890 goto nla_put_failure;
d6dc1a38 13891
5b97f49d 13892 cb[2] = rdev;
d6dc1a38 13893
5b97f49d
JB
13894 return msg;
13895 nla_put_failure:
13896 nlmsg_free(msg);
13897 return NULL;
13898}
13899
13900static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
13901{
13902 void **cb = (void **)msg->cb;
13903 struct cfg80211_registered_device *rdev = cb[2];
13904
13905 nla_nest_end(msg, cb[1]);
13906 genlmsg_end(msg, cb[0]);
13907
13908 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 13909
68eb5503 13910 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13911 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
13912}
13913
13914void cfg80211_cqm_rssi_notify(struct net_device *dev,
13915 enum nl80211_cqm_rssi_threshold_event rssi_event,
13916 gfp_t gfp)
13917{
13918 struct sk_buff *msg;
13919
13920 trace_cfg80211_cqm_rssi_notify(dev, rssi_event);
13921
98f03342
JB
13922 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
13923 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
13924 return;
13925
5b97f49d
JB
13926 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
13927 if (!msg)
13928 return;
13929
13930 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
13931 rssi_event))
13932 goto nla_put_failure;
13933
13934 cfg80211_send_cqm(msg, gfp);
13935
d6dc1a38
JO
13936 return;
13937
13938 nla_put_failure:
d6dc1a38
JO
13939 nlmsg_free(msg);
13940}
947add36 13941EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 13942
5b97f49d
JB
13943void cfg80211_cqm_txe_notify(struct net_device *dev,
13944 const u8 *peer, u32 num_packets,
13945 u32 rate, u32 intvl, gfp_t gfp)
13946{
13947 struct sk_buff *msg;
13948
13949 msg = cfg80211_prepare_cqm(dev, peer, gfp);
13950 if (!msg)
13951 return;
13952
13953 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
13954 goto nla_put_failure;
13955
13956 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
13957 goto nla_put_failure;
13958
13959 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
13960 goto nla_put_failure;
13961
13962 cfg80211_send_cqm(msg, gfp);
13963 return;
13964
13965 nla_put_failure:
13966 nlmsg_free(msg);
13967}
13968EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
13969
13970void cfg80211_cqm_pktloss_notify(struct net_device *dev,
13971 const u8 *peer, u32 num_packets, gfp_t gfp)
13972{
13973 struct sk_buff *msg;
13974
13975 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
13976
13977 msg = cfg80211_prepare_cqm(dev, peer, gfp);
13978 if (!msg)
13979 return;
13980
13981 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
13982 goto nla_put_failure;
13983
13984 cfg80211_send_cqm(msg, gfp);
13985 return;
13986
13987 nla_put_failure:
13988 nlmsg_free(msg);
13989}
13990EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
13991
98f03342
JB
13992void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
13993{
13994 struct sk_buff *msg;
13995
13996 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
13997 if (!msg)
13998 return;
13999
14000 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
14001 goto nla_put_failure;
14002
14003 cfg80211_send_cqm(msg, gfp);
14004 return;
14005
14006 nla_put_failure:
14007 nlmsg_free(msg);
14008}
14009EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
14010
947add36
JB
14011static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
14012 struct net_device *netdev, const u8 *bssid,
14013 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
14014{
14015 struct sk_buff *msg;
14016 struct nlattr *rekey_attr;
14017 void *hdr;
14018
58050fce 14019 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
14020 if (!msg)
14021 return;
14022
14023 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
14024 if (!hdr) {
14025 nlmsg_free(msg);
14026 return;
14027 }
14028
9360ffd1
DM
14029 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14030 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14031 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
14032 goto nla_put_failure;
e5497d76
JB
14033
14034 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
14035 if (!rekey_attr)
14036 goto nla_put_failure;
14037
9360ffd1
DM
14038 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
14039 NL80211_REPLAY_CTR_LEN, replay_ctr))
14040 goto nla_put_failure;
e5497d76
JB
14041
14042 nla_nest_end(msg, rekey_attr);
14043
3b7b72ee 14044 genlmsg_end(msg, hdr);
e5497d76 14045
68eb5503 14046 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14047 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
14048 return;
14049
14050 nla_put_failure:
14051 genlmsg_cancel(msg, hdr);
14052 nlmsg_free(msg);
14053}
14054
947add36
JB
14055void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
14056 const u8 *replay_ctr, gfp_t gfp)
14057{
14058 struct wireless_dev *wdev = dev->ieee80211_ptr;
14059 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14060 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14061
14062 trace_cfg80211_gtk_rekey_notify(dev, bssid);
14063 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
14064}
14065EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
14066
14067static void
14068nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
14069 struct net_device *netdev, int index,
14070 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
14071{
14072 struct sk_buff *msg;
14073 struct nlattr *attr;
14074 void *hdr;
14075
58050fce 14076 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
14077 if (!msg)
14078 return;
14079
14080 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
14081 if (!hdr) {
14082 nlmsg_free(msg);
14083 return;
14084 }
14085
9360ffd1
DM
14086 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14087 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
14088 goto nla_put_failure;
c9df56b4
JM
14089
14090 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
14091 if (!attr)
14092 goto nla_put_failure;
14093
9360ffd1
DM
14094 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
14095 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
14096 (preauth &&
14097 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
14098 goto nla_put_failure;
c9df56b4
JM
14099
14100 nla_nest_end(msg, attr);
14101
3b7b72ee 14102 genlmsg_end(msg, hdr);
c9df56b4 14103
68eb5503 14104 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14105 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
14106 return;
14107
14108 nla_put_failure:
14109 genlmsg_cancel(msg, hdr);
14110 nlmsg_free(msg);
14111}
14112
947add36
JB
14113void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
14114 const u8 *bssid, bool preauth, gfp_t gfp)
14115{
14116 struct wireless_dev *wdev = dev->ieee80211_ptr;
14117 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14118 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
14119
14120 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
14121 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
14122}
14123EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
14124
14125static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
14126 struct net_device *netdev,
14127 struct cfg80211_chan_def *chandef,
f8d7552e
LC
14128 gfp_t gfp,
14129 enum nl80211_commands notif,
14130 u8 count)
5314526b
TP
14131{
14132 struct sk_buff *msg;
14133 void *hdr;
14134
58050fce 14135 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
14136 if (!msg)
14137 return;
14138
f8d7552e 14139 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
14140 if (!hdr) {
14141 nlmsg_free(msg);
14142 return;
14143 }
14144
683b6d3b
JB
14145 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
14146 goto nla_put_failure;
14147
14148 if (nl80211_send_chandef(msg, chandef))
7eab0f64 14149 goto nla_put_failure;
5314526b 14150
f8d7552e
LC
14151 if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
14152 (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
14153 goto nla_put_failure;
14154
5314526b
TP
14155 genlmsg_end(msg, hdr);
14156
68eb5503 14157 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14158 NL80211_MCGRP_MLME, gfp);
5314526b
TP
14159 return;
14160
14161 nla_put_failure:
14162 genlmsg_cancel(msg, hdr);
14163 nlmsg_free(msg);
14164}
14165
947add36
JB
14166void cfg80211_ch_switch_notify(struct net_device *dev,
14167 struct cfg80211_chan_def *chandef)
84f10708 14168{
947add36
JB
14169 struct wireless_dev *wdev = dev->ieee80211_ptr;
14170 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14171 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 14172
e487eaeb 14173 ASSERT_WDEV_LOCK(wdev);
947add36 14174
e487eaeb 14175 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 14176
9e0e2961 14177 wdev->chandef = *chandef;
96f55f12 14178 wdev->preset_chandef = *chandef;
f8d7552e
LC
14179 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
14180 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
947add36
JB
14181}
14182EXPORT_SYMBOL(cfg80211_ch_switch_notify);
14183
f8d7552e
LC
14184void cfg80211_ch_switch_started_notify(struct net_device *dev,
14185 struct cfg80211_chan_def *chandef,
14186 u8 count)
14187{
14188 struct wireless_dev *wdev = dev->ieee80211_ptr;
14189 struct wiphy *wiphy = wdev->wiphy;
14190 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14191
14192 trace_cfg80211_ch_switch_started_notify(dev, chandef);
14193
14194 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
14195 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
14196}
14197EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
14198
04f39047
SW
14199void
14200nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 14201 const struct cfg80211_chan_def *chandef,
04f39047
SW
14202 enum nl80211_radar_event event,
14203 struct net_device *netdev, gfp_t gfp)
14204{
14205 struct sk_buff *msg;
14206 void *hdr;
14207
14208 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14209 if (!msg)
14210 return;
14211
14212 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
14213 if (!hdr) {
14214 nlmsg_free(msg);
14215 return;
14216 }
14217
14218 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
14219 goto nla_put_failure;
14220
14221 /* NOP and radar events don't need a netdev parameter */
14222 if (netdev) {
14223 struct wireless_dev *wdev = netdev->ieee80211_ptr;
14224
14225 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
14226 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14227 NL80211_ATTR_PAD))
04f39047
SW
14228 goto nla_put_failure;
14229 }
14230
14231 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
14232 goto nla_put_failure;
14233
14234 if (nl80211_send_chandef(msg, chandef))
14235 goto nla_put_failure;
14236
9c90a9f6 14237 genlmsg_end(msg, hdr);
04f39047 14238
68eb5503 14239 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14240 NL80211_MCGRP_MLME, gfp);
04f39047
SW
14241 return;
14242
14243 nla_put_failure:
14244 genlmsg_cancel(msg, hdr);
14245 nlmsg_free(msg);
14246}
14247
7f6cf311
JB
14248void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
14249 u64 cookie, bool acked, gfp_t gfp)
14250{
14251 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14252 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
14253 struct sk_buff *msg;
14254 void *hdr;
7f6cf311 14255
4ee3e063
BL
14256 trace_cfg80211_probe_status(dev, addr, cookie, acked);
14257
58050fce 14258 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 14259
7f6cf311
JB
14260 if (!msg)
14261 return;
14262
14263 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
14264 if (!hdr) {
14265 nlmsg_free(msg);
14266 return;
14267 }
14268
9360ffd1
DM
14269 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14270 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14271 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
14272 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14273 NL80211_ATTR_PAD) ||
9360ffd1
DM
14274 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
14275 goto nla_put_failure;
7f6cf311 14276
9c90a9f6 14277 genlmsg_end(msg, hdr);
7f6cf311 14278
68eb5503 14279 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14280 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
14281 return;
14282
14283 nla_put_failure:
14284 genlmsg_cancel(msg, hdr);
14285 nlmsg_free(msg);
14286}
14287EXPORT_SYMBOL(cfg80211_probe_status);
14288
5e760230
JB
14289void cfg80211_report_obss_beacon(struct wiphy *wiphy,
14290 const u8 *frame, size_t len,
37c73b5f 14291 int freq, int sig_dbm)
5e760230 14292{
f26cbf40 14293 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
14294 struct sk_buff *msg;
14295 void *hdr;
37c73b5f 14296 struct cfg80211_beacon_registration *reg;
5e760230 14297
4ee3e063
BL
14298 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
14299
37c73b5f
BG
14300 spin_lock_bh(&rdev->beacon_registrations_lock);
14301 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
14302 msg = nlmsg_new(len + 100, GFP_ATOMIC);
14303 if (!msg) {
14304 spin_unlock_bh(&rdev->beacon_registrations_lock);
14305 return;
14306 }
5e760230 14307
37c73b5f
BG
14308 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
14309 if (!hdr)
14310 goto nla_put_failure;
5e760230 14311
37c73b5f
BG
14312 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14313 (freq &&
14314 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
14315 (sig_dbm &&
14316 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
14317 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
14318 goto nla_put_failure;
5e760230 14319
37c73b5f 14320 genlmsg_end(msg, hdr);
5e760230 14321
37c73b5f
BG
14322 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
14323 }
14324 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
14325 return;
14326
14327 nla_put_failure:
37c73b5f
BG
14328 spin_unlock_bh(&rdev->beacon_registrations_lock);
14329 if (hdr)
14330 genlmsg_cancel(msg, hdr);
5e760230
JB
14331 nlmsg_free(msg);
14332}
14333EXPORT_SYMBOL(cfg80211_report_obss_beacon);
14334
cd8f7cb4 14335#ifdef CONFIG_PM
8cd4d456
LC
14336static int cfg80211_net_detect_results(struct sk_buff *msg,
14337 struct cfg80211_wowlan_wakeup *wakeup)
14338{
14339 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
14340 struct nlattr *nl_results, *nl_match, *nl_freqs;
14341 int i, j;
14342
14343 nl_results = nla_nest_start(
14344 msg, NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
14345 if (!nl_results)
14346 return -EMSGSIZE;
14347
14348 for (i = 0; i < nd->n_matches; i++) {
14349 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
14350
14351 nl_match = nla_nest_start(msg, i);
14352 if (!nl_match)
14353 break;
14354
14355 /* The SSID attribute is optional in nl80211, but for
14356 * simplicity reasons it's always present in the
14357 * cfg80211 structure. If a driver can't pass the
14358 * SSID, that needs to be changed. A zero length SSID
14359 * is still a valid SSID (wildcard), so it cannot be
14360 * used for this purpose.
14361 */
14362 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
14363 match->ssid.ssid)) {
14364 nla_nest_cancel(msg, nl_match);
14365 goto out;
14366 }
14367
14368 if (match->n_channels) {
14369 nl_freqs = nla_nest_start(
14370 msg, NL80211_ATTR_SCAN_FREQUENCIES);
14371 if (!nl_freqs) {
14372 nla_nest_cancel(msg, nl_match);
14373 goto out;
14374 }
14375
14376 for (j = 0; j < match->n_channels; j++) {
5528fae8 14377 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
14378 nla_nest_cancel(msg, nl_freqs);
14379 nla_nest_cancel(msg, nl_match);
14380 goto out;
14381 }
14382 }
14383
14384 nla_nest_end(msg, nl_freqs);
14385 }
14386
14387 nla_nest_end(msg, nl_match);
14388 }
14389
14390out:
14391 nla_nest_end(msg, nl_results);
14392 return 0;
14393}
14394
cd8f7cb4
JB
14395void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
14396 struct cfg80211_wowlan_wakeup *wakeup,
14397 gfp_t gfp)
14398{
f26cbf40 14399 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
14400 struct sk_buff *msg;
14401 void *hdr;
9c90a9f6 14402 int size = 200;
cd8f7cb4
JB
14403
14404 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
14405
14406 if (wakeup)
14407 size += wakeup->packet_present_len;
14408
14409 msg = nlmsg_new(size, gfp);
14410 if (!msg)
14411 return;
14412
14413 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
14414 if (!hdr)
14415 goto free_msg;
14416
14417 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
14418 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14419 NL80211_ATTR_PAD))
cd8f7cb4
JB
14420 goto free_msg;
14421
14422 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14423 wdev->netdev->ifindex))
14424 goto free_msg;
14425
14426 if (wakeup) {
14427 struct nlattr *reasons;
14428
14429 reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
14430 if (!reasons)
14431 goto free_msg;
cd8f7cb4
JB
14432
14433 if (wakeup->disconnect &&
14434 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
14435 goto free_msg;
14436 if (wakeup->magic_pkt &&
14437 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
14438 goto free_msg;
14439 if (wakeup->gtk_rekey_failure &&
14440 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
14441 goto free_msg;
14442 if (wakeup->eap_identity_req &&
14443 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
14444 goto free_msg;
14445 if (wakeup->four_way_handshake &&
14446 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
14447 goto free_msg;
14448 if (wakeup->rfkill_release &&
14449 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
14450 goto free_msg;
14451
14452 if (wakeup->pattern_idx >= 0 &&
14453 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
14454 wakeup->pattern_idx))
14455 goto free_msg;
14456
ae917c9f
JB
14457 if (wakeup->tcp_match &&
14458 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
14459 goto free_msg;
2a0e047e 14460
ae917c9f
JB
14461 if (wakeup->tcp_connlost &&
14462 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
14463 goto free_msg;
2a0e047e 14464
ae917c9f
JB
14465 if (wakeup->tcp_nomoretokens &&
14466 nla_put_flag(msg,
14467 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
14468 goto free_msg;
2a0e047e 14469
cd8f7cb4
JB
14470 if (wakeup->packet) {
14471 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
14472 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
14473
14474 if (!wakeup->packet_80211) {
14475 pkt_attr =
14476 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
14477 len_attr =
14478 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
14479 }
14480
14481 if (wakeup->packet_len &&
14482 nla_put_u32(msg, len_attr, wakeup->packet_len))
14483 goto free_msg;
14484
14485 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
14486 wakeup->packet))
14487 goto free_msg;
14488 }
14489
8cd4d456
LC
14490 if (wakeup->net_detect &&
14491 cfg80211_net_detect_results(msg, wakeup))
14492 goto free_msg;
14493
cd8f7cb4
JB
14494 nla_nest_end(msg, reasons);
14495 }
14496
9c90a9f6 14497 genlmsg_end(msg, hdr);
cd8f7cb4 14498
68eb5503 14499 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14500 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
14501 return;
14502
14503 free_msg:
14504 nlmsg_free(msg);
14505}
14506EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
14507#endif
14508
3475b094
JM
14509void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
14510 enum nl80211_tdls_operation oper,
14511 u16 reason_code, gfp_t gfp)
14512{
14513 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14514 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
14515 struct sk_buff *msg;
14516 void *hdr;
3475b094
JM
14517
14518 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
14519 reason_code);
14520
14521 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14522 if (!msg)
14523 return;
14524
14525 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
14526 if (!hdr) {
14527 nlmsg_free(msg);
14528 return;
14529 }
14530
14531 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14532 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14533 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
14534 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
14535 (reason_code > 0 &&
14536 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
14537 goto nla_put_failure;
14538
9c90a9f6 14539 genlmsg_end(msg, hdr);
3475b094 14540
68eb5503 14541 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14542 NL80211_MCGRP_MLME, gfp);
3475b094
JM
14543 return;
14544
14545 nla_put_failure:
14546 genlmsg_cancel(msg, hdr);
14547 nlmsg_free(msg);
14548}
14549EXPORT_SYMBOL(cfg80211_tdls_oper_request);
14550
026331c4
JM
14551static int nl80211_netlink_notify(struct notifier_block * nb,
14552 unsigned long state,
14553 void *_notify)
14554{
14555 struct netlink_notify *notify = _notify;
14556 struct cfg80211_registered_device *rdev;
14557 struct wireless_dev *wdev;
37c73b5f 14558 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 14559
8f815cdd 14560 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
14561 return NOTIFY_DONE;
14562
14563 rcu_read_lock();
14564
5e760230 14565 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
78f22b6a 14566 bool schedule_destroy_work = false;
93a1e86c
JR
14567 struct cfg80211_sched_scan_request *sched_scan_req =
14568 rcu_dereference(rdev->sched_scan_req);
14569
14570 if (sched_scan_req && notify->portid &&
753aacfd
JB
14571 sched_scan_req->owner_nlportid == notify->portid) {
14572 sched_scan_req->owner_nlportid = 0;
14573
14574 if (rdev->ops->sched_scan_stop &&
14575 rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
14576 schedule_work(&rdev->sched_scan_stop_wk);
14577 }
78f22b6a 14578
53873f13 14579 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 14580 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 14581
78f22b6a
JB
14582 if (wdev->owner_nlportid == notify->portid)
14583 schedule_destroy_work = true;
bd2522b1
AZ
14584 else if (wdev->conn_owner_nlportid == notify->portid)
14585 schedule_work(&wdev->disconnect_wk);
78f22b6a
JB
14586 }
14587
37c73b5f
BG
14588 spin_lock_bh(&rdev->beacon_registrations_lock);
14589 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
14590 list) {
14591 if (reg->nlportid == notify->portid) {
14592 list_del(&reg->list);
14593 kfree(reg);
14594 break;
14595 }
14596 }
14597 spin_unlock_bh(&rdev->beacon_registrations_lock);
78f22b6a
JB
14598
14599 if (schedule_destroy_work) {
14600 struct cfg80211_iface_destroy *destroy;
14601
14602 destroy = kzalloc(sizeof(*destroy), GFP_ATOMIC);
14603 if (destroy) {
14604 destroy->nlportid = notify->portid;
14605 spin_lock(&rdev->destroy_list_lock);
14606 list_add(&destroy->list, &rdev->destroy_list);
14607 spin_unlock(&rdev->destroy_list_lock);
14608 schedule_work(&rdev->destroy_work);
14609 }
14610 }
5e760230 14611 }
026331c4
JM
14612
14613 rcu_read_unlock();
14614
05050753
I
14615 /*
14616 * It is possible that the user space process that is controlling the
14617 * indoor setting disappeared, so notify the regulatory core.
14618 */
14619 regulatory_netlink_notify(notify->portid);
6784c7db 14620 return NOTIFY_OK;
026331c4
JM
14621}
14622
14623static struct notifier_block nl80211_netlink_notifier = {
14624 .notifier_call = nl80211_netlink_notify,
14625};
14626
355199e0
JM
14627void cfg80211_ft_event(struct net_device *netdev,
14628 struct cfg80211_ft_event_params *ft_event)
14629{
14630 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 14631 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
14632 struct sk_buff *msg;
14633 void *hdr;
355199e0
JM
14634
14635 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
14636
14637 if (!ft_event->target_ap)
14638 return;
14639
4ef8c1c9 14640 msg = nlmsg_new(100 + ft_event->ric_ies_len, GFP_KERNEL);
355199e0
JM
14641 if (!msg)
14642 return;
14643
14644 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
14645 if (!hdr)
14646 goto out;
355199e0 14647
ae917c9f
JB
14648 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14649 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14650 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
14651 goto out;
355199e0 14652
ae917c9f
JB
14653 if (ft_event->ies &&
14654 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
14655 goto out;
14656 if (ft_event->ric_ies &&
14657 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
14658 ft_event->ric_ies))
14659 goto out;
355199e0 14660
9c90a9f6 14661 genlmsg_end(msg, hdr);
355199e0 14662
68eb5503 14663 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14664 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
14665 return;
14666 out:
14667 nlmsg_free(msg);
355199e0
JM
14668}
14669EXPORT_SYMBOL(cfg80211_ft_event);
14670
5de17984
AS
14671void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
14672{
14673 struct cfg80211_registered_device *rdev;
14674 struct sk_buff *msg;
14675 void *hdr;
14676 u32 nlportid;
14677
f26cbf40 14678 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
14679 if (!rdev->crit_proto_nlportid)
14680 return;
14681
14682 nlportid = rdev->crit_proto_nlportid;
14683 rdev->crit_proto_nlportid = 0;
14684
14685 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14686 if (!msg)
14687 return;
14688
14689 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
14690 if (!hdr)
14691 goto nla_put_failure;
14692
14693 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
14694 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14695 NL80211_ATTR_PAD))
5de17984
AS
14696 goto nla_put_failure;
14697
14698 genlmsg_end(msg, hdr);
14699
14700 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
14701 return;
14702
14703 nla_put_failure:
14704 if (hdr)
14705 genlmsg_cancel(msg, hdr);
14706 nlmsg_free(msg);
5de17984
AS
14707}
14708EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
14709
348baf0e
JB
14710void nl80211_send_ap_stopped(struct wireless_dev *wdev)
14711{
14712 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14713 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
14714 struct sk_buff *msg;
14715 void *hdr;
14716
14717 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14718 if (!msg)
14719 return;
14720
14721 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
14722 if (!hdr)
14723 goto out;
14724
14725 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14726 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
14727 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14728 NL80211_ATTR_PAD))
348baf0e
JB
14729 goto out;
14730
14731 genlmsg_end(msg, hdr);
14732
14733 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
14734 NL80211_MCGRP_MLME, GFP_KERNEL);
14735 return;
14736 out:
14737 nlmsg_free(msg);
14738}
14739
55682965
JB
14740/* initialisation/exit functions */
14741
56989f6d 14742int __init nl80211_init(void)
55682965 14743{
0d63cbb5 14744 int err;
55682965 14745
489111e5 14746 err = genl_register_family(&nl80211_fam);
55682965
JB
14747 if (err)
14748 return err;
14749
026331c4
JM
14750 err = netlink_register_notifier(&nl80211_netlink_notifier);
14751 if (err)
14752 goto err_out;
14753
55682965
JB
14754 return 0;
14755 err_out:
14756 genl_unregister_family(&nl80211_fam);
14757 return err;
14758}
14759
14760void nl80211_exit(void)
14761{
026331c4 14762 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
14763 genl_unregister_family(&nl80211_fam);
14764}