]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - net/wireless/nl80211.c
cfg80211: allow the user space to change current NAN configuration
[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
f84f771d 35static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991 36 struct genl_info *info);
f84f771d 37static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
38 struct genl_info *info);
39
55682965
JB
40/* the netlink family */
41static struct genl_family nl80211_fam = {
fb4e1568
MH
42 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
43 .name = NL80211_GENL_NAME, /* have users key off the name instead */
44 .hdrsize = 0, /* no private header */
45 .version = 1, /* no particular meaning now */
55682965 46 .maxattr = NL80211_ATTR_MAX,
463d0183 47 .netnsok = true,
4c476991
JB
48 .pre_doit = nl80211_pre_doit,
49 .post_doit = nl80211_post_doit,
55682965
JB
50};
51
2a94fe48
JB
52/* multicast groups */
53enum nl80211_multicast_groups {
54 NL80211_MCGRP_CONFIG,
55 NL80211_MCGRP_SCAN,
56 NL80211_MCGRP_REGULATORY,
57 NL80211_MCGRP_MLME,
567ffc35 58 NL80211_MCGRP_VENDOR,
2a94fe48
JB
59 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
60};
61
62static const struct genl_multicast_group nl80211_mcgrps[] = {
71b836ec
JB
63 [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
64 [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
65 [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
66 [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
67 [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
2a94fe48 68#ifdef CONFIG_NL80211_TESTMODE
71b836ec 69 [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
2a94fe48
JB
70#endif
71};
72
89a54e48
JB
73/* returns ERR_PTR values */
74static struct wireless_dev *
75__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
55682965 76{
89a54e48
JB
77 struct cfg80211_registered_device *rdev;
78 struct wireless_dev *result = NULL;
79 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
80 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
81 u64 wdev_id;
82 int wiphy_idx = -1;
83 int ifidx = -1;
55682965 84
5fe231e8 85 ASSERT_RTNL();
55682965 86
89a54e48
JB
87 if (!have_ifidx && !have_wdev_id)
88 return ERR_PTR(-EINVAL);
55682965 89
89a54e48
JB
90 if (have_ifidx)
91 ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
92 if (have_wdev_id) {
93 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
94 wiphy_idx = wdev_id >> 32;
55682965
JB
95 }
96
89a54e48
JB
97 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
98 struct wireless_dev *wdev;
99
100 if (wiphy_net(&rdev->wiphy) != netns)
101 continue;
102
103 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
104 continue;
105
53873f13 106 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
89a54e48
JB
107 if (have_ifidx && wdev->netdev &&
108 wdev->netdev->ifindex == ifidx) {
109 result = wdev;
110 break;
111 }
112 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
113 result = wdev;
114 break;
115 }
116 }
89a54e48
JB
117
118 if (result)
119 break;
120 }
121
122 if (result)
123 return result;
124 return ERR_PTR(-ENODEV);
55682965
JB
125}
126
a9455408 127static struct cfg80211_registered_device *
878d9ec7 128__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
a9455408 129{
7fee4778
JB
130 struct cfg80211_registered_device *rdev = NULL, *tmp;
131 struct net_device *netdev;
a9455408 132
5fe231e8 133 ASSERT_RTNL();
a9455408 134
878d9ec7 135 if (!attrs[NL80211_ATTR_WIPHY] &&
89a54e48
JB
136 !attrs[NL80211_ATTR_IFINDEX] &&
137 !attrs[NL80211_ATTR_WDEV])
7fee4778
JB
138 return ERR_PTR(-EINVAL);
139
878d9ec7 140 if (attrs[NL80211_ATTR_WIPHY])
7fee4778 141 rdev = cfg80211_rdev_by_wiphy_idx(
878d9ec7 142 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
a9455408 143
89a54e48
JB
144 if (attrs[NL80211_ATTR_WDEV]) {
145 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
146 struct wireless_dev *wdev;
147 bool found = false;
148
149 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
150 if (tmp) {
151 /* make sure wdev exists */
53873f13 152 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
89a54e48
JB
153 if (wdev->identifier != (u32)wdev_id)
154 continue;
155 found = true;
156 break;
157 }
89a54e48
JB
158
159 if (!found)
160 tmp = NULL;
161
162 if (rdev && tmp != rdev)
163 return ERR_PTR(-EINVAL);
164 rdev = tmp;
165 }
166 }
167
878d9ec7
JB
168 if (attrs[NL80211_ATTR_IFINDEX]) {
169 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
7a087e74 170
7f2b8562 171 netdev = __dev_get_by_index(netns, ifindex);
7fee4778
JB
172 if (netdev) {
173 if (netdev->ieee80211_ptr)
f26cbf40
ZG
174 tmp = wiphy_to_rdev(
175 netdev->ieee80211_ptr->wiphy);
7fee4778
JB
176 else
177 tmp = NULL;
178
7fee4778
JB
179 /* not wireless device -- return error */
180 if (!tmp)
181 return ERR_PTR(-EINVAL);
182
183 /* mismatch -- return error */
184 if (rdev && tmp != rdev)
185 return ERR_PTR(-EINVAL);
186
187 rdev = tmp;
a9455408 188 }
a9455408 189 }
a9455408 190
4f7eff10
JB
191 if (!rdev)
192 return ERR_PTR(-ENODEV);
a9455408 193
4f7eff10
JB
194 if (netns != wiphy_net(&rdev->wiphy))
195 return ERR_PTR(-ENODEV);
196
197 return rdev;
a9455408
JB
198}
199
200/*
201 * This function returns a pointer to the driver
202 * that the genl_info item that is passed refers to.
a9455408
JB
203 *
204 * The result of this can be a PTR_ERR and hence must
205 * be checked with IS_ERR() for errors.
206 */
207static struct cfg80211_registered_device *
4f7eff10 208cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
a9455408 209{
5fe231e8 210 return __cfg80211_rdev_from_attrs(netns, info->attrs);
a9455408
JB
211}
212
55682965 213/* policy for the attributes */
8cd4d456 214static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
55682965
JB
215 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
216 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 217 .len = 20-1 },
31888487 218 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 219
72bdcf34 220 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 221 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
3d9d1d66
JB
222 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
223 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
224 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
225
b9a5f8ca
JM
226 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
227 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
228 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
229 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 230 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
3057dbfd 231 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
55682965
JB
232
233 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
234 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
235 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 236
e007b857
EP
237 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
238 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
41ade00f 239
b9454e83 240 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
241 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
242 .len = WLAN_MAX_KEY_LEN },
243 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
244 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
245 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 246 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
e31b8213 247 [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
ed1b6cc7
JB
248
249 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
250 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
251 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
252 .len = IEEE80211_MAX_DATA_LEN },
253 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
254 .len = IEEE80211_MAX_DATA_LEN },
5727ef1b
JB
255 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
256 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
257 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
258 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
259 .len = NL80211_MAX_SUPP_RATES },
2ec600d6 260 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
5727ef1b 261 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 262 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 263 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 264 .len = IEEE80211_MAX_MESH_ID_LEN },
2ec600d6 265 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
9f1ba906 266
b2e1b302
LR
267 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
268 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
269
9f1ba906
JM
270 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
271 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
272 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
273 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
274 .len = NL80211_MAX_SUPP_RATES },
50b12f59 275 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 276
24bdd9f4 277 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 278 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 279
6c739419 280 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
9aed3cc1
JM
281
282 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
283 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
284 .len = IEEE80211_MAX_DATA_LEN },
2a519311
JB
285 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
286 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
287
288 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
289 .len = IEEE80211_MAX_SSID_LEN },
290 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
291 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 292 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 293 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
dc6382ce 294 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
eccb8e8f
JB
295 [NL80211_ATTR_STA_FLAGS2] = {
296 .len = sizeof(struct nl80211_sta_flag_update),
297 },
3f77316c 298 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
299 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
300 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
b23aa676
SO
301 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
302 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
303 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 304 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 305 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
67fbb16b
SO
306 [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
307 .len = WLAN_PMKID_LEN },
9588bbd5
JM
308 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
309 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 310 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
311 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
312 .len = IEEE80211_MAX_DATA_LEN },
313 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ffb9eb3d 314 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
d6dc1a38 315 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 316 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 317 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
318 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
319 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 320 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
321 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
322 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 323 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 324 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 325 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 326 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
9c3990aa 327 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
bbe6ad6d 328 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 329 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 330 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
32e9de84 331 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
9946ecfb
JM
332 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
333 .len = IEEE80211_MAX_DATA_LEN },
334 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
335 .len = IEEE80211_MAX_DATA_LEN },
f4b34b55 336 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 337 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 338 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
339 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
340 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
341 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
342 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
343 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 344 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 345 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
346 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
347 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 348 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
349 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
350 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
351 .len = NL80211_HT_CAPABILITY_LEN
352 },
1d9d9213 353 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 354 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 355 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 356 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 357 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
e39e5b5e 358 [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, },
f461be3e 359 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
ed473771 360 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
53cabad7
JB
361 [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
362 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
77765eaf
VT
363 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
364 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
365 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
366 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 367 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
368 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
369 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
370 .len = NL80211_VHT_CAPABILITY_LEN,
371 },
355199e0
JM
372 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
373 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
374 .len = IEEE80211_MAX_DATA_LEN },
5e4b6f56 375 [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
16ef1fe2
SW
376 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
377 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
378 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
9a774c78
AO
379 [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY },
380 [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY },
c01fc9ad
SD
381 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
382 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
5336fa88 383 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 384 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
385 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
386 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
387 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
fa9ffc74
KP
388 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
389 .len = IEEE80211_QOS_MAP_LEN_MAX },
1df4a510
JM
390 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
391 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
df942e7b 392 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
18e5ca65 393 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
34d22ce2 394 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
bab5ab7d 395 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
960d01ac
JB
396 [NL80211_ATTR_TSID] = { .type = NLA_U8 },
397 [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
398 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
18998c38 399 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
ad2b26ab 400 [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
1bdd716c 401 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
4b681c82 402 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
9c748934 403 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
05050753 404 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
34d50519 405 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
38de03d2 406 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
17b94247 407 [NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 },
c6e6a0c8
AE
408 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
409 .len = VHT_MUMIMO_GROUPS_DATA_LEN
410 },
411 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
cb3b7d87
AB
412 [NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 },
413 [NL80211_ATTR_NAN_DUAL] = { .type = NLA_U8 },
a442b761 414 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
55682965
JB
415};
416
e31b8213 417/* policy for the key attributes */
b54452b0 418static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 419 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
420 [NL80211_KEY_IDX] = { .type = NLA_U8 },
421 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 422 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
423 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
424 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
e31b8213 425 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
dbd2fd65
JB
426 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
427};
428
429/* policy for the key default flags */
430static const struct nla_policy
431nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
432 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
433 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
434};
435
ff1b6e69
JB
436/* policy for WoWLAN attributes */
437static const struct nla_policy
438nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
439 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
440 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
441 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
442 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
443 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
444 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
445 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
446 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 447 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 448 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
449};
450
451static const struct nla_policy
452nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
453 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
454 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
455 [NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
456 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
457 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
458 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
459 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
460 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
461 },
462 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
463 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
464 },
465 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
466 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
467 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
ff1b6e69
JB
468};
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,
552 nl80211_fam.attrbuf, nl80211_fam.maxattr,
553 nl80211_policy);
554 if (err)
555 goto out_unlock;
67748893 556
97990a06
JB
557 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
558 nl80211_fam.attrbuf);
559 if (IS_ERR(*wdev)) {
560 err = PTR_ERR(*wdev);
561 goto out_unlock;
562 }
f26cbf40 563 *rdev = wiphy_to_rdev((*wdev)->wiphy);
c319d50b
JB
564 /* 0 is the first index - add 1 to parse only once */
565 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
566 cb->args[1] = (*wdev)->identifier;
567 } else {
c319d50b
JB
568 /* subtract the 1 again here */
569 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
97990a06 570 struct wireless_dev *tmp;
67748893 571
97990a06
JB
572 if (!wiphy) {
573 err = -ENODEV;
574 goto out_unlock;
575 }
f26cbf40 576 *rdev = wiphy_to_rdev(wiphy);
97990a06 577 *wdev = NULL;
67748893 578
53873f13 579 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
580 if (tmp->identifier == cb->args[1]) {
581 *wdev = tmp;
582 break;
583 }
584 }
67748893 585
97990a06
JB
586 if (!*wdev) {
587 err = -ENODEV;
588 goto out_unlock;
589 }
67748893
JB
590 }
591
67748893 592 return 0;
97990a06 593 out_unlock:
67748893
JB
594 rtnl_unlock();
595 return err;
596}
597
97990a06 598static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
67748893 599{
67748893
JB
600 rtnl_unlock();
601}
602
f4a11bb0
JB
603/* IE validation */
604static bool is_valid_ie_attr(const struct nlattr *attr)
605{
606 const u8 *pos;
607 int len;
608
609 if (!attr)
610 return true;
611
612 pos = nla_data(attr);
613 len = nla_len(attr);
614
615 while (len) {
616 u8 elemlen;
617
618 if (len < 2)
619 return false;
620 len -= 2;
621
622 elemlen = pos[1];
623 if (elemlen > len)
624 return false;
625
626 len -= elemlen;
627 pos += 2 + elemlen;
628 }
629
630 return true;
631}
632
55682965 633/* message building helper */
15e47304 634static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
55682965
JB
635 int flags, u8 cmd)
636{
637 /* since there is no private header just add the generic one */
15e47304 638 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
639}
640
5dab3b8a 641static int nl80211_msg_put_channel(struct sk_buff *msg,
cdc89b97
JB
642 struct ieee80211_channel *chan,
643 bool large)
5dab3b8a 644{
ea077c1c
RL
645 /* Some channels must be completely excluded from the
646 * list to protect old user-space tools from breaking
647 */
648 if (!large && chan->flags &
649 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
650 return 0;
651
9360ffd1
DM
652 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
653 chan->center_freq))
654 goto nla_put_failure;
5dab3b8a 655
9360ffd1
DM
656 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
657 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
658 goto nla_put_failure;
8fe02e16
LR
659 if (chan->flags & IEEE80211_CHAN_NO_IR) {
660 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
661 goto nla_put_failure;
662 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
663 goto nla_put_failure;
664 }
cdc89b97
JB
665 if (chan->flags & IEEE80211_CHAN_RADAR) {
666 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
667 goto nla_put_failure;
668 if (large) {
669 u32 time;
670
671 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
672
673 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
674 chan->dfs_state))
675 goto nla_put_failure;
676 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
677 time))
678 goto nla_put_failure;
089027e5
JD
679 if (nla_put_u32(msg,
680 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
681 chan->dfs_cac_ms))
682 goto nla_put_failure;
cdc89b97
JB
683 }
684 }
5dab3b8a 685
fe1abafd
JB
686 if (large) {
687 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
688 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
689 goto nla_put_failure;
690 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
691 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
692 goto nla_put_failure;
693 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
694 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
695 goto nla_put_failure;
696 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
697 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
698 goto nla_put_failure;
570dbde1
DS
699 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
700 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
701 goto nla_put_failure;
06f207fc
AN
702 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
703 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 704 goto nla_put_failure;
ea077c1c
RL
705 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
706 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
707 goto nla_put_failure;
708 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
709 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
710 goto nla_put_failure;
fe1abafd
JB
711 }
712
9360ffd1
DM
713 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
714 DBM_TO_MBM(chan->max_power)))
715 goto nla_put_failure;
5dab3b8a
LR
716
717 return 0;
718
719 nla_put_failure:
720 return -ENOBUFS;
721}
722
55682965
JB
723/* netlink command implementations */
724
b9454e83
JB
725struct key_parse {
726 struct key_params p;
727 int idx;
e31b8213 728 int type;
b9454e83 729 bool def, defmgmt;
dbd2fd65 730 bool def_uni, def_multi;
b9454e83
JB
731};
732
733static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
734{
735 struct nlattr *tb[NL80211_KEY_MAX + 1];
736 int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
737 nl80211_key_policy);
738 if (err)
739 return err;
740
741 k->def = !!tb[NL80211_KEY_DEFAULT];
742 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
743
dbd2fd65
JB
744 if (k->def) {
745 k->def_uni = true;
746 k->def_multi = true;
747 }
748 if (k->defmgmt)
749 k->def_multi = true;
750
b9454e83
JB
751 if (tb[NL80211_KEY_IDX])
752 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
753
754 if (tb[NL80211_KEY_DATA]) {
755 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
756 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
757 }
758
759 if (tb[NL80211_KEY_SEQ]) {
760 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
761 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
762 }
763
764 if (tb[NL80211_KEY_CIPHER])
765 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
766
e31b8213
JB
767 if (tb[NL80211_KEY_TYPE]) {
768 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
769 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
770 return -EINVAL;
771 }
772
dbd2fd65
JB
773 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
774 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 775
2da8f419
JB
776 err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
777 tb[NL80211_KEY_DEFAULT_TYPES],
778 nl80211_key_default_policy);
dbd2fd65
JB
779 if (err)
780 return err;
781
782 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
783 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
784 }
785
b9454e83
JB
786 return 0;
787}
788
789static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
790{
791 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
792 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
793 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
794 }
795
796 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
797 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
798 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
799 }
800
801 if (info->attrs[NL80211_ATTR_KEY_IDX])
802 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
803
804 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
805 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
806
807 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
808 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
809
dbd2fd65
JB
810 if (k->def) {
811 k->def_uni = true;
812 k->def_multi = true;
813 }
814 if (k->defmgmt)
815 k->def_multi = true;
816
e31b8213
JB
817 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
818 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
819 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
820 return -EINVAL;
821 }
822
dbd2fd65
JB
823 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
824 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
825 int err = nla_parse_nested(
826 kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
827 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
828 nl80211_key_default_policy);
829 if (err)
830 return err;
831
832 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
833 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
834 }
835
b9454e83
JB
836 return 0;
837}
838
839static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
840{
841 int err;
842
843 memset(k, 0, sizeof(*k));
844 k->idx = -1;
e31b8213 845 k->type = -1;
b9454e83
JB
846
847 if (info->attrs[NL80211_ATTR_KEY])
848 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
849 else
850 err = nl80211_parse_key_old(info, k);
851
852 if (err)
853 return err;
854
855 if (k->def && k->defmgmt)
856 return -EINVAL;
857
dbd2fd65
JB
858 if (k->defmgmt) {
859 if (k->def_uni || !k->def_multi)
860 return -EINVAL;
861 }
862
b9454e83
JB
863 if (k->idx != -1) {
864 if (k->defmgmt) {
865 if (k->idx < 4 || k->idx > 5)
866 return -EINVAL;
867 } else if (k->def) {
868 if (k->idx < 0 || k->idx > 3)
869 return -EINVAL;
870 } else {
871 if (k->idx < 0 || k->idx > 5)
872 return -EINVAL;
873 }
874 }
875
876 return 0;
877}
878
fffd0934
JB
879static struct cfg80211_cached_keys *
880nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
de7044ee 881 struct nlattr *keys, bool *no_ht)
fffd0934
JB
882{
883 struct key_parse parse;
884 struct nlattr *key;
885 struct cfg80211_cached_keys *result;
886 int rem, err, def = 0;
f1c1f17a
JB
887 bool have_key = false;
888
889 nla_for_each_nested(key, keys, rem) {
890 have_key = true;
891 break;
892 }
893
894 if (!have_key)
895 return NULL;
fffd0934
JB
896
897 result = kzalloc(sizeof(*result), GFP_KERNEL);
898 if (!result)
899 return ERR_PTR(-ENOMEM);
900
901 result->def = -1;
fffd0934
JB
902
903 nla_for_each_nested(key, keys, rem) {
904 memset(&parse, 0, sizeof(parse));
905 parse.idx = -1;
906
907 err = nl80211_parse_key_new(key, &parse);
908 if (err)
909 goto error;
910 err = -EINVAL;
911 if (!parse.p.key)
912 goto error;
42ee231c 913 if (parse.idx < 0 || parse.idx > 3)
fffd0934
JB
914 goto error;
915 if (parse.def) {
916 if (def)
917 goto error;
918 def = 1;
919 result->def = parse.idx;
dbd2fd65
JB
920 if (!parse.def_uni || !parse.def_multi)
921 goto error;
fffd0934
JB
922 } else if (parse.defmgmt)
923 goto error;
924 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 925 parse.idx, false, NULL);
fffd0934
JB
926 if (err)
927 goto error;
386b1f27
JB
928 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
929 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
930 err = -EINVAL;
931 goto error;
932 }
fffd0934
JB
933 result->params[parse.idx].cipher = parse.p.cipher;
934 result->params[parse.idx].key_len = parse.p.key_len;
935 result->params[parse.idx].key = result->data[parse.idx];
936 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 937
386b1f27
JB
938 /* must be WEP key if we got here */
939 if (no_ht)
940 *no_ht = true;
fffd0934
JB
941 }
942
f1c1f17a
JB
943 if (result->def < 0) {
944 err = -EINVAL;
945 goto error;
946 }
947
fffd0934
JB
948 return result;
949 error:
950 kfree(result);
951 return ERR_PTR(err);
952}
953
954static int nl80211_key_allowed(struct wireless_dev *wdev)
955{
956 ASSERT_WDEV_LOCK(wdev);
957
fffd0934
JB
958 switch (wdev->iftype) {
959 case NL80211_IFTYPE_AP:
960 case NL80211_IFTYPE_AP_VLAN:
074ac8df 961 case NL80211_IFTYPE_P2P_GO:
ff973af7 962 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
963 break;
964 case NL80211_IFTYPE_ADHOC:
fffd0934 965 case NL80211_IFTYPE_STATION:
074ac8df 966 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 967 if (!wdev->current_bss)
fffd0934
JB
968 return -ENOLINK;
969 break;
de4fcbad 970 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 971 case NL80211_IFTYPE_OCB:
de4fcbad 972 case NL80211_IFTYPE_MONITOR:
cb3b7d87 973 case NL80211_IFTYPE_NAN:
de4fcbad
JB
974 case NL80211_IFTYPE_P2P_DEVICE:
975 case NL80211_IFTYPE_WDS:
976 case NUM_NL80211_IFTYPES:
fffd0934
JB
977 return -EINVAL;
978 }
979
980 return 0;
981}
982
664834de
JM
983static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
984 struct nlattr *tb)
985{
986 struct ieee80211_channel *chan;
987
988 if (tb == NULL)
989 return NULL;
990 chan = ieee80211_get_channel(wiphy, nla_get_u32(tb));
991 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
992 return NULL;
993 return chan;
994}
995
7527a782
JB
996static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
997{
998 struct nlattr *nl_modes = nla_nest_start(msg, attr);
999 int i;
1000
1001 if (!nl_modes)
1002 goto nla_put_failure;
1003
1004 i = 0;
1005 while (ifmodes) {
9360ffd1
DM
1006 if ((ifmodes & 1) && nla_put_flag(msg, i))
1007 goto nla_put_failure;
7527a782
JB
1008 ifmodes >>= 1;
1009 i++;
1010 }
1011
1012 nla_nest_end(msg, nl_modes);
1013 return 0;
1014
1015nla_put_failure:
1016 return -ENOBUFS;
1017}
1018
1019static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1020 struct sk_buff *msg,
1021 bool large)
7527a782
JB
1022{
1023 struct nlattr *nl_combis;
1024 int i, j;
1025
1026 nl_combis = nla_nest_start(msg,
1027 NL80211_ATTR_INTERFACE_COMBINATIONS);
1028 if (!nl_combis)
1029 goto nla_put_failure;
1030
1031 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1032 const struct ieee80211_iface_combination *c;
1033 struct nlattr *nl_combi, *nl_limits;
1034
1035 c = &wiphy->iface_combinations[i];
1036
1037 nl_combi = nla_nest_start(msg, i + 1);
1038 if (!nl_combi)
1039 goto nla_put_failure;
1040
1041 nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
1042 if (!nl_limits)
1043 goto nla_put_failure;
1044
1045 for (j = 0; j < c->n_limits; j++) {
1046 struct nlattr *nl_limit;
1047
1048 nl_limit = nla_nest_start(msg, j + 1);
1049 if (!nl_limit)
1050 goto nla_put_failure;
9360ffd1
DM
1051 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1052 c->limits[j].max))
1053 goto nla_put_failure;
7527a782
JB
1054 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1055 c->limits[j].types))
1056 goto nla_put_failure;
1057 nla_nest_end(msg, nl_limit);
1058 }
1059
1060 nla_nest_end(msg, nl_limits);
1061
9360ffd1
DM
1062 if (c->beacon_int_infra_match &&
1063 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1064 goto nla_put_failure;
1065 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1066 c->num_different_channels) ||
1067 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1068 c->max_interfaces))
1069 goto nla_put_failure;
cdc89b97 1070 if (large &&
8c48b50a
FF
1071 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1072 c->radar_detect_widths) ||
1073 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1074 c->radar_detect_regions)))
cdc89b97 1075 goto nla_put_failure;
7527a782
JB
1076
1077 nla_nest_end(msg, nl_combi);
1078 }
1079
1080 nla_nest_end(msg, nl_combis);
1081
1082 return 0;
1083nla_put_failure:
1084 return -ENOBUFS;
1085}
1086
3713b4e3 1087#ifdef CONFIG_PM
b56cf720
JB
1088static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1089 struct sk_buff *msg)
1090{
964dc9e2 1091 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1092 struct nlattr *nl_tcp;
1093
1094 if (!tcp)
1095 return 0;
1096
1097 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
1098 if (!nl_tcp)
1099 return -ENOBUFS;
1100
1101 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1102 tcp->data_payload_max))
1103 return -ENOBUFS;
1104
1105 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1106 tcp->data_payload_max))
1107 return -ENOBUFS;
1108
1109 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1110 return -ENOBUFS;
1111
1112 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1113 sizeof(*tcp->tok), tcp->tok))
1114 return -ENOBUFS;
1115
1116 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1117 tcp->data_interval_max))
1118 return -ENOBUFS;
1119
1120 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1121 tcp->wake_payload_max))
1122 return -ENOBUFS;
1123
1124 nla_nest_end(msg, nl_tcp);
1125 return 0;
1126}
1127
3713b4e3 1128static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1129 struct cfg80211_registered_device *rdev,
b56cf720 1130 bool large)
55682965 1131{
3713b4e3 1132 struct nlattr *nl_wowlan;
55682965 1133
1b8ec87a 1134 if (!rdev->wiphy.wowlan)
3713b4e3 1135 return 0;
55682965 1136
3713b4e3
JB
1137 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
1138 if (!nl_wowlan)
1139 return -ENOBUFS;
9360ffd1 1140
1b8ec87a 1141 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1142 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1143 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1144 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1145 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1146 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1147 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1148 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1149 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1150 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1151 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1152 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1153 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1154 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1155 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1156 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1157 return -ENOBUFS;
9360ffd1 1158
1b8ec87a 1159 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1160 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1161 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1162 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1163 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1164 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1165 };
9360ffd1 1166
3713b4e3
JB
1167 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1168 sizeof(pat), &pat))
1169 return -ENOBUFS;
1170 }
9360ffd1 1171
75453ccb
LC
1172 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1173 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1174 rdev->wiphy.wowlan->max_nd_match_sets))
1175 return -ENOBUFS;
1176
1b8ec87a 1177 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1178 return -ENOBUFS;
1179
3713b4e3 1180 nla_nest_end(msg, nl_wowlan);
9360ffd1 1181
3713b4e3
JB
1182 return 0;
1183}
1184#endif
9360ffd1 1185
be29b99a 1186static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1187 struct cfg80211_registered_device *rdev)
be29b99a
AK
1188{
1189 struct nl80211_coalesce_rule_support rule;
1190
1b8ec87a 1191 if (!rdev->wiphy.coalesce)
be29b99a
AK
1192 return 0;
1193
1b8ec87a
ZG
1194 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1195 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1196 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1197 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1198 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1199 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1200
1201 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1202 return -ENOBUFS;
1203
1204 return 0;
1205}
1206
3713b4e3
JB
1207static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1208 struct ieee80211_supported_band *sband)
1209{
1210 struct nlattr *nl_rates, *nl_rate;
1211 struct ieee80211_rate *rate;
1212 int i;
87bbbe22 1213
3713b4e3
JB
1214 /* add HT info */
1215 if (sband->ht_cap.ht_supported &&
1216 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1217 sizeof(sband->ht_cap.mcs),
1218 &sband->ht_cap.mcs) ||
1219 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1220 sband->ht_cap.cap) ||
1221 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1222 sband->ht_cap.ampdu_factor) ||
1223 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1224 sband->ht_cap.ampdu_density)))
1225 return -ENOBUFS;
afe0cbf8 1226
3713b4e3
JB
1227 /* add VHT info */
1228 if (sband->vht_cap.vht_supported &&
1229 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1230 sizeof(sband->vht_cap.vht_mcs),
1231 &sband->vht_cap.vht_mcs) ||
1232 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1233 sband->vht_cap.cap)))
1234 return -ENOBUFS;
f59ac048 1235
3713b4e3
JB
1236 /* add bitrates */
1237 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
1238 if (!nl_rates)
1239 return -ENOBUFS;
ee688b00 1240
3713b4e3
JB
1241 for (i = 0; i < sband->n_bitrates; i++) {
1242 nl_rate = nla_nest_start(msg, i);
1243 if (!nl_rate)
1244 return -ENOBUFS;
ee688b00 1245
3713b4e3
JB
1246 rate = &sband->bitrates[i];
1247 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1248 rate->bitrate))
1249 return -ENOBUFS;
1250 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1251 nla_put_flag(msg,
1252 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1253 return -ENOBUFS;
ee688b00 1254
3713b4e3
JB
1255 nla_nest_end(msg, nl_rate);
1256 }
d51626df 1257
3713b4e3 1258 nla_nest_end(msg, nl_rates);
bf0c111e 1259
3713b4e3
JB
1260 return 0;
1261}
ee688b00 1262
3713b4e3
JB
1263static int
1264nl80211_send_mgmt_stypes(struct sk_buff *msg,
1265 const struct ieee80211_txrx_stypes *mgmt_stypes)
1266{
1267 u16 stypes;
1268 struct nlattr *nl_ftypes, *nl_ifs;
1269 enum nl80211_iftype ift;
1270 int i;
ee688b00 1271
3713b4e3
JB
1272 if (!mgmt_stypes)
1273 return 0;
5dab3b8a 1274
3713b4e3
JB
1275 nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES);
1276 if (!nl_ifs)
1277 return -ENOBUFS;
e2f367f2 1278
3713b4e3
JB
1279 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1280 nl_ftypes = nla_nest_start(msg, ift);
1281 if (!nl_ftypes)
1282 return -ENOBUFS;
1283 i = 0;
1284 stypes = mgmt_stypes[ift].tx;
1285 while (stypes) {
1286 if ((stypes & 1) &&
1287 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1288 (i << 4) | IEEE80211_FTYPE_MGMT))
1289 return -ENOBUFS;
1290 stypes >>= 1;
1291 i++;
ee688b00 1292 }
3713b4e3
JB
1293 nla_nest_end(msg, nl_ftypes);
1294 }
ee688b00 1295
3713b4e3 1296 nla_nest_end(msg, nl_ifs);
ee688b00 1297
3713b4e3
JB
1298 nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES);
1299 if (!nl_ifs)
1300 return -ENOBUFS;
ee688b00 1301
3713b4e3
JB
1302 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1303 nl_ftypes = nla_nest_start(msg, ift);
1304 if (!nl_ftypes)
1305 return -ENOBUFS;
1306 i = 0;
1307 stypes = mgmt_stypes[ift].rx;
1308 while (stypes) {
1309 if ((stypes & 1) &&
1310 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1311 (i << 4) | IEEE80211_FTYPE_MGMT))
1312 return -ENOBUFS;
1313 stypes >>= 1;
1314 i++;
1315 }
1316 nla_nest_end(msg, nl_ftypes);
1317 }
1318 nla_nest_end(msg, nl_ifs);
ee688b00 1319
3713b4e3
JB
1320 return 0;
1321}
ee688b00 1322
86e8cf98
JB
1323struct nl80211_dump_wiphy_state {
1324 s64 filter_wiphy;
1325 long start;
019ae3a9 1326 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
1327 bool split;
1328};
1329
1b8ec87a 1330static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 1331 enum nl80211_commands cmd,
3713b4e3 1332 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 1333 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
1334{
1335 void *hdr;
1336 struct nlattr *nl_bands, *nl_band;
1337 struct nlattr *nl_freqs, *nl_freq;
1338 struct nlattr *nl_cmds;
57fbcce3 1339 enum nl80211_band band;
3713b4e3
JB
1340 struct ieee80211_channel *chan;
1341 int i;
1342 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 1343 rdev->wiphy.mgmt_stypes;
fe1abafd 1344 u32 features;
ee688b00 1345
3bb20556 1346 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
1347 if (!hdr)
1348 return -ENOBUFS;
ee688b00 1349
86e8cf98
JB
1350 if (WARN_ON(!state))
1351 return -EINVAL;
ee688b00 1352
1b8ec87a 1353 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 1354 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 1355 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
1356 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1357 cfg80211_rdev_list_generation))
8fdc621d
JB
1358 goto nla_put_failure;
1359
3bb20556
JB
1360 if (cmd != NL80211_CMD_NEW_WIPHY)
1361 goto finish;
1362
86e8cf98 1363 switch (state->split_start) {
3713b4e3
JB
1364 case 0:
1365 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 1366 rdev->wiphy.retry_short) ||
3713b4e3 1367 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 1368 rdev->wiphy.retry_long) ||
3713b4e3 1369 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 1370 rdev->wiphy.frag_threshold) ||
3713b4e3 1371 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 1372 rdev->wiphy.rts_threshold) ||
3713b4e3 1373 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 1374 rdev->wiphy.coverage_class) ||
3713b4e3 1375 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 1376 rdev->wiphy.max_scan_ssids) ||
3713b4e3 1377 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 1378 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 1379 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 1380 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 1381 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 1382 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 1383 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
3b06d277
AS
1384 rdev->wiphy.max_match_sets) ||
1385 nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
1386 rdev->wiphy.max_sched_scan_plans) ||
1387 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
1388 rdev->wiphy.max_sched_scan_plan_interval) ||
1389 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
1390 rdev->wiphy.max_sched_scan_plan_iterations))
9360ffd1 1391 goto nla_put_failure;
3713b4e3 1392
1b8ec87a 1393 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 1394 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 1395 goto nla_put_failure;
1b8ec87a 1396 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
1397 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
1398 goto nla_put_failure;
1b8ec87a 1399 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
1400 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
1401 goto nla_put_failure;
1b8ec87a 1402 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
1403 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
1404 goto nla_put_failure;
1b8ec87a 1405 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
1406 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
1407 goto nla_put_failure;
1b8ec87a 1408 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 1409 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 1410 goto nla_put_failure;
86e8cf98
JB
1411 state->split_start++;
1412 if (state->split)
3713b4e3
JB
1413 break;
1414 case 1:
1415 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
1416 sizeof(u32) * rdev->wiphy.n_cipher_suites,
1417 rdev->wiphy.cipher_suites))
3713b4e3 1418 goto nla_put_failure;
4745fc09 1419
3713b4e3 1420 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 1421 rdev->wiphy.max_num_pmkids))
3713b4e3 1422 goto nla_put_failure;
b23aa676 1423
1b8ec87a 1424 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 1425 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 1426 goto nla_put_failure;
b23aa676 1427
3713b4e3 1428 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 1429 rdev->wiphy.available_antennas_tx) ||
3713b4e3 1430 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 1431 rdev->wiphy.available_antennas_rx))
9360ffd1 1432 goto nla_put_failure;
b23aa676 1433
1b8ec87a 1434 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 1435 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 1436 rdev->wiphy.probe_resp_offload))
3713b4e3 1437 goto nla_put_failure;
8fdc621d 1438
1b8ec87a
ZG
1439 if ((rdev->wiphy.available_antennas_tx ||
1440 rdev->wiphy.available_antennas_rx) &&
1441 rdev->ops->get_antenna) {
3713b4e3
JB
1442 u32 tx_ant = 0, rx_ant = 0;
1443 int res;
7a087e74 1444
1b8ec87a 1445 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
1446 if (!res) {
1447 if (nla_put_u32(msg,
1448 NL80211_ATTR_WIPHY_ANTENNA_TX,
1449 tx_ant) ||
1450 nla_put_u32(msg,
1451 NL80211_ATTR_WIPHY_ANTENNA_RX,
1452 rx_ant))
1453 goto nla_put_failure;
1454 }
1455 }
a293911d 1456
86e8cf98
JB
1457 state->split_start++;
1458 if (state->split)
3713b4e3
JB
1459 break;
1460 case 2:
1461 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 1462 rdev->wiphy.interface_modes))
3713b4e3 1463 goto nla_put_failure;
86e8cf98
JB
1464 state->split_start++;
1465 if (state->split)
3713b4e3
JB
1466 break;
1467 case 3:
1468 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1469 if (!nl_bands)
1470 goto nla_put_failure;
f7ca38df 1471
86e8cf98 1472 for (band = state->band_start;
57fbcce3 1473 band < NUM_NL80211_BANDS; band++) {
3713b4e3 1474 struct ieee80211_supported_band *sband;
2e161f78 1475
1b8ec87a 1476 sband = rdev->wiphy.bands[band];
2e161f78 1477
3713b4e3
JB
1478 if (!sband)
1479 continue;
1480
1481 nl_band = nla_nest_start(msg, band);
1482 if (!nl_band)
2e161f78 1483 goto nla_put_failure;
3713b4e3 1484
86e8cf98 1485 switch (state->chan_start) {
3713b4e3
JB
1486 case 0:
1487 if (nl80211_send_band_rateinfo(msg, sband))
9360ffd1 1488 goto nla_put_failure;
86e8cf98
JB
1489 state->chan_start++;
1490 if (state->split)
3713b4e3
JB
1491 break;
1492 default:
1493 /* add frequencies */
1494 nl_freqs = nla_nest_start(
1495 msg, NL80211_BAND_ATTR_FREQS);
1496 if (!nl_freqs)
1497 goto nla_put_failure;
1498
86e8cf98 1499 for (i = state->chan_start - 1;
3713b4e3
JB
1500 i < sband->n_channels;
1501 i++) {
1502 nl_freq = nla_nest_start(msg, i);
1503 if (!nl_freq)
1504 goto nla_put_failure;
1505
1506 chan = &sband->channels[i];
1507
86e8cf98
JB
1508 if (nl80211_msg_put_channel(
1509 msg, chan,
1510 state->split))
3713b4e3
JB
1511 goto nla_put_failure;
1512
1513 nla_nest_end(msg, nl_freq);
86e8cf98 1514 if (state->split)
3713b4e3
JB
1515 break;
1516 }
1517 if (i < sband->n_channels)
86e8cf98 1518 state->chan_start = i + 2;
3713b4e3 1519 else
86e8cf98 1520 state->chan_start = 0;
3713b4e3
JB
1521 nla_nest_end(msg, nl_freqs);
1522 }
1523
1524 nla_nest_end(msg, nl_band);
1525
86e8cf98 1526 if (state->split) {
3713b4e3 1527 /* start again here */
86e8cf98 1528 if (state->chan_start)
3713b4e3
JB
1529 band--;
1530 break;
2e161f78 1531 }
2e161f78 1532 }
3713b4e3 1533 nla_nest_end(msg, nl_bands);
2e161f78 1534
57fbcce3 1535 if (band < NUM_NL80211_BANDS)
86e8cf98 1536 state->band_start = band + 1;
3713b4e3 1537 else
86e8cf98 1538 state->band_start = 0;
74b70a4e 1539
3713b4e3 1540 /* if bands & channels are done, continue outside */
86e8cf98
JB
1541 if (state->band_start == 0 && state->chan_start == 0)
1542 state->split_start++;
1543 if (state->split)
3713b4e3
JB
1544 break;
1545 case 4:
1546 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
1547 if (!nl_cmds)
2e161f78
JB
1548 goto nla_put_failure;
1549
3713b4e3
JB
1550 i = 0;
1551#define CMD(op, n) \
1552 do { \
1b8ec87a 1553 if (rdev->ops->op) { \
3713b4e3
JB
1554 i++; \
1555 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1556 goto nla_put_failure; \
1557 } \
1558 } while (0)
1559
1560 CMD(add_virtual_intf, NEW_INTERFACE);
1561 CMD(change_virtual_intf, SET_INTERFACE);
1562 CMD(add_key, NEW_KEY);
1563 CMD(start_ap, START_AP);
1564 CMD(add_station, NEW_STATION);
1565 CMD(add_mpath, NEW_MPATH);
1566 CMD(update_mesh_config, SET_MESH_CONFIG);
1567 CMD(change_bss, SET_BSS);
1568 CMD(auth, AUTHENTICATE);
1569 CMD(assoc, ASSOCIATE);
1570 CMD(deauth, DEAUTHENTICATE);
1571 CMD(disassoc, DISASSOCIATE);
1572 CMD(join_ibss, JOIN_IBSS);
1573 CMD(join_mesh, JOIN_MESH);
1574 CMD(set_pmksa, SET_PMKSA);
1575 CMD(del_pmksa, DEL_PMKSA);
1576 CMD(flush_pmksa, FLUSH_PMKSA);
1b8ec87a 1577 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
3713b4e3
JB
1578 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1579 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1580 CMD(mgmt_tx, FRAME);
1581 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1b8ec87a 1582 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
3713b4e3
JB
1583 i++;
1584 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
2e161f78 1585 goto nla_put_failure;
2e161f78 1586 }
1b8ec87a
ZG
1587 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
1588 rdev->ops->join_mesh) {
3713b4e3
JB
1589 i++;
1590 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1591 goto nla_put_failure;
1592 }
1593 CMD(set_wds_peer, SET_WDS_PEER);
1b8ec87a 1594 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
3713b4e3
JB
1595 CMD(tdls_mgmt, TDLS_MGMT);
1596 CMD(tdls_oper, TDLS_OPER);
1597 }
1b8ec87a 1598 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
3713b4e3
JB
1599 CMD(sched_scan_start, START_SCHED_SCAN);
1600 CMD(probe_client, PROBE_CLIENT);
1601 CMD(set_noack_map, SET_NOACK_MAP);
1b8ec87a 1602 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
3713b4e3
JB
1603 i++;
1604 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1605 goto nla_put_failure;
1606 }
1607 CMD(start_p2p_device, START_P2P_DEVICE);
1608 CMD(set_mcast_rate, SET_MCAST_RATE);
02df00eb
JB
1609#ifdef CONFIG_NL80211_TESTMODE
1610 CMD(testmode_cmd, TESTMODE);
1611#endif
86e8cf98 1612 if (state->split) {
5de17984
AS
1613 CMD(crit_proto_start, CRIT_PROTOCOL_START);
1614 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 1615 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 1616 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 1617 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
1618 if (rdev->wiphy.features &
1619 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 1620 CMD(add_tx_ts, ADD_TX_TS);
5de17984 1621 }
02df00eb 1622 /* add into the if now */
3713b4e3 1623#undef CMD
ff1b6e69 1624
1b8ec87a 1625 if (rdev->ops->connect || rdev->ops->auth) {
3713b4e3
JB
1626 i++;
1627 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
9360ffd1 1628 goto nla_put_failure;
ff1b6e69
JB
1629 }
1630
1b8ec87a 1631 if (rdev->ops->disconnect || rdev->ops->deauth) {
3713b4e3
JB
1632 i++;
1633 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1634 goto nla_put_failure;
1635 }
1636
1637 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
1638 state->split_start++;
1639 if (state->split)
3713b4e3
JB
1640 break;
1641 case 5:
1b8ec87a
ZG
1642 if (rdev->ops->remain_on_channel &&
1643 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
1644 nla_put_u32(msg,
1645 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 1646 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
1647 goto nla_put_failure;
1648
1b8ec87a 1649 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
1650 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
1651 goto nla_put_failure;
1652
1653 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
1654 goto nla_put_failure;
86e8cf98
JB
1655 state->split_start++;
1656 if (state->split)
3713b4e3
JB
1657 break;
1658 case 6:
1659#ifdef CONFIG_PM
1b8ec87a 1660 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 1661 goto nla_put_failure;
86e8cf98
JB
1662 state->split_start++;
1663 if (state->split)
3713b4e3
JB
1664 break;
1665#else
86e8cf98 1666 state->split_start++;
dfb89c56 1667#endif
3713b4e3
JB
1668 case 7:
1669 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 1670 rdev->wiphy.software_iftypes))
3713b4e3 1671 goto nla_put_failure;
ff1b6e69 1672
1b8ec87a 1673 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 1674 state->split))
3713b4e3 1675 goto nla_put_failure;
7527a782 1676
86e8cf98
JB
1677 state->split_start++;
1678 if (state->split)
3713b4e3
JB
1679 break;
1680 case 8:
1b8ec87a 1681 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 1682 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 1683 rdev->wiphy.ap_sme_capa))
3713b4e3 1684 goto nla_put_failure;
7527a782 1685
1b8ec87a 1686 features = rdev->wiphy.features;
fe1abafd
JB
1687 /*
1688 * We can only add the per-channel limit information if the
1689 * dump is split, otherwise it makes it too big. Therefore
1690 * only advertise it in that case.
1691 */
86e8cf98 1692 if (state->split)
fe1abafd
JB
1693 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
1694 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 1695 goto nla_put_failure;
562a7480 1696
1b8ec87a 1697 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 1698 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
1699 sizeof(*rdev->wiphy.ht_capa_mod_mask),
1700 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 1701 goto nla_put_failure;
1f074bd8 1702
1b8ec87a
ZG
1703 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
1704 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 1705 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 1706 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 1707 goto nla_put_failure;
7e7c8926 1708
3713b4e3
JB
1709 /*
1710 * Any information below this point is only available to
1711 * applications that can deal with it being split. This
1712 * helps ensure that newly added capabilities don't break
1713 * older tools by overrunning their buffers.
1714 *
1715 * We still increment split_start so that in the split
1716 * case we'll continue with more data in the next round,
1717 * but break unconditionally so unsplit data stops here.
1718 */
86e8cf98 1719 state->split_start++;
3713b4e3
JB
1720 break;
1721 case 9:
1b8ec87a 1722 if (rdev->wiphy.extended_capabilities &&
fe1abafd 1723 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
1724 rdev->wiphy.extended_capabilities_len,
1725 rdev->wiphy.extended_capabilities) ||
fe1abafd 1726 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
1727 rdev->wiphy.extended_capabilities_len,
1728 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 1729 goto nla_put_failure;
a50df0c4 1730
1b8ec87a 1731 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 1732 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
1733 sizeof(*rdev->wiphy.vht_capa_mod_mask),
1734 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
1735 goto nla_put_failure;
1736
be29b99a
AK
1737 state->split_start++;
1738 break;
1739 case 10:
1b8ec87a 1740 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
1741 goto nla_put_failure;
1742
1b8ec87a 1743 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
1744 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
1745 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
1746 goto nla_put_failure;
b43504cf 1747
1b8ec87a 1748 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 1749 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 1750 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
1751 goto nla_put_failure;
1752
ad7e718c
JB
1753 state->split_start++;
1754 break;
1755 case 11:
1b8ec87a 1756 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
1757 const struct nl80211_vendor_cmd_info *info;
1758 struct nlattr *nested;
1759
1760 nested = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1761 if (!nested)
1762 goto nla_put_failure;
1763
1b8ec87a
ZG
1764 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
1765 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
1766 if (nla_put(msg, i + 1, sizeof(*info), info))
1767 goto nla_put_failure;
1768 }
1769 nla_nest_end(msg, nested);
1770 }
1771
1b8ec87a 1772 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
1773 const struct nl80211_vendor_cmd_info *info;
1774 struct nlattr *nested;
ad7e718c 1775
567ffc35
JB
1776 nested = nla_nest_start(msg,
1777 NL80211_ATTR_VENDOR_EVENTS);
1778 if (!nested)
ad7e718c 1779 goto nla_put_failure;
567ffc35 1780
1b8ec87a
ZG
1781 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
1782 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
1783 if (nla_put(msg, i + 1, sizeof(*info), info))
1784 goto nla_put_failure;
1785 }
1786 nla_nest_end(msg, nested);
1787 }
9a774c78
AO
1788 state->split_start++;
1789 break;
1790 case 12:
1791 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
1792 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
1793 rdev->wiphy.max_num_csa_counters))
1794 goto nla_put_failure;
01e0daa4 1795
1bdd716c
AN
1796 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
1797 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
1798 goto nla_put_failure;
1799
d75bb06b
GKS
1800 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
1801 sizeof(rdev->wiphy.ext_features),
1802 rdev->wiphy.ext_features))
1803 goto nla_put_failure;
1804
38de03d2
AS
1805 if (rdev->wiphy.bss_select_support) {
1806 struct nlattr *nested;
1807 u32 bss_select_support = rdev->wiphy.bss_select_support;
1808
1809 nested = nla_nest_start(msg, NL80211_ATTR_BSS_SELECT);
1810 if (!nested)
1811 goto nla_put_failure;
1812
1813 i = 0;
1814 while (bss_select_support) {
1815 if ((bss_select_support & 1) &&
1816 nla_put_flag(msg, i))
1817 goto nla_put_failure;
1818 i++;
1819 bss_select_support >>= 1;
1820 }
1821 nla_nest_end(msg, nested);
1822 }
1823
019ae3a9
KV
1824 state->split_start++;
1825 break;
1826 case 13:
1827 if (rdev->wiphy.num_iftype_ext_capab &&
1828 rdev->wiphy.iftype_ext_capab) {
1829 struct nlattr *nested_ext_capab, *nested;
1830
1831 nested = nla_nest_start(msg,
1832 NL80211_ATTR_IFTYPE_EXT_CAPA);
1833 if (!nested)
1834 goto nla_put_failure;
1835
1836 for (i = state->capa_start;
1837 i < rdev->wiphy.num_iftype_ext_capab; i++) {
1838 const struct wiphy_iftype_ext_capab *capab;
1839
1840 capab = &rdev->wiphy.iftype_ext_capab[i];
1841
1842 nested_ext_capab = nla_nest_start(msg, i);
1843 if (!nested_ext_capab ||
1844 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
1845 capab->iftype) ||
1846 nla_put(msg, NL80211_ATTR_EXT_CAPA,
1847 capab->extended_capabilities_len,
1848 capab->extended_capabilities) ||
1849 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1850 capab->extended_capabilities_len,
1851 capab->extended_capabilities_mask))
1852 goto nla_put_failure;
1853
1854 nla_nest_end(msg, nested_ext_capab);
1855 if (state->split)
1856 break;
1857 }
1858 nla_nest_end(msg, nested);
1859 if (i < rdev->wiphy.num_iftype_ext_capab) {
1860 state->capa_start = i + 1;
1861 break;
1862 }
1863 }
1864
3713b4e3 1865 /* done */
86e8cf98 1866 state->split_start = 0;
3713b4e3
JB
1867 break;
1868 }
3bb20556 1869 finish:
053c095a
JB
1870 genlmsg_end(msg, hdr);
1871 return 0;
55682965
JB
1872
1873 nla_put_failure:
bc3ed28c
TG
1874 genlmsg_cancel(msg, hdr);
1875 return -EMSGSIZE;
55682965
JB
1876}
1877
86e8cf98
JB
1878static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
1879 struct netlink_callback *cb,
1880 struct nl80211_dump_wiphy_state *state)
1881{
1882 struct nlattr **tb = nl80211_fam.attrbuf;
1883 int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1884 tb, nl80211_fam.maxattr, nl80211_policy);
1885 /* ignore parse errors for backward compatibility */
1886 if (ret)
1887 return 0;
1888
1889 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
1890 if (tb[NL80211_ATTR_WIPHY])
1891 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1892 if (tb[NL80211_ATTR_WDEV])
1893 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
1894 if (tb[NL80211_ATTR_IFINDEX]) {
1895 struct net_device *netdev;
1896 struct cfg80211_registered_device *rdev;
1897 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1898
7f2b8562 1899 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
86e8cf98
JB
1900 if (!netdev)
1901 return -ENODEV;
1902 if (netdev->ieee80211_ptr) {
f26cbf40 1903 rdev = wiphy_to_rdev(
86e8cf98
JB
1904 netdev->ieee80211_ptr->wiphy);
1905 state->filter_wiphy = rdev->wiphy_idx;
1906 }
86e8cf98
JB
1907 }
1908
1909 return 0;
1910}
1911
55682965
JB
1912static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1913{
645e77de 1914 int idx = 0, ret;
86e8cf98 1915 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 1916 struct cfg80211_registered_device *rdev;
3a5a423b 1917
5fe231e8 1918 rtnl_lock();
86e8cf98
JB
1919 if (!state) {
1920 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
1921 if (!state) {
1922 rtnl_unlock();
86e8cf98 1923 return -ENOMEM;
3713b4e3 1924 }
86e8cf98
JB
1925 state->filter_wiphy = -1;
1926 ret = nl80211_dump_wiphy_parse(skb, cb, state);
1927 if (ret) {
1928 kfree(state);
1929 rtnl_unlock();
1930 return ret;
3713b4e3 1931 }
86e8cf98 1932 cb->args[0] = (long)state;
3713b4e3
JB
1933 }
1934
1b8ec87a
ZG
1935 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1936 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 1937 continue;
86e8cf98 1938 if (++idx <= state->start)
55682965 1939 continue;
86e8cf98 1940 if (state->filter_wiphy != -1 &&
1b8ec87a 1941 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
1942 continue;
1943 /* attempt to fit multiple wiphy data chunks into the skb */
1944 do {
3bb20556
JB
1945 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
1946 skb,
3713b4e3
JB
1947 NETLINK_CB(cb->skb).portid,
1948 cb->nlh->nlmsg_seq,
86e8cf98 1949 NLM_F_MULTI, state);
3713b4e3
JB
1950 if (ret < 0) {
1951 /*
1952 * If sending the wiphy data didn't fit (ENOBUFS
1953 * or EMSGSIZE returned), this SKB is still
1954 * empty (so it's not too big because another
1955 * wiphy dataset is already in the skb) and
1956 * we've not tried to adjust the dump allocation
1957 * yet ... then adjust the alloc size to be
1958 * bigger, and return 1 but with the empty skb.
1959 * This results in an empty message being RX'ed
1960 * in userspace, but that is ignored.
1961 *
1962 * We can then retry with the larger buffer.
1963 */
1964 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 1965 !skb->len && !state->split &&
3713b4e3
JB
1966 cb->min_dump_alloc < 4096) {
1967 cb->min_dump_alloc = 4096;
f12cb289 1968 state->split_start = 0;
d98cae64 1969 rtnl_unlock();
3713b4e3
JB
1970 return 1;
1971 }
1972 idx--;
1973 break;
645e77de 1974 }
86e8cf98 1975 } while (state->split_start > 0);
3713b4e3 1976 break;
55682965 1977 }
5fe231e8 1978 rtnl_unlock();
55682965 1979
86e8cf98 1980 state->start = idx;
55682965
JB
1981
1982 return skb->len;
1983}
1984
86e8cf98
JB
1985static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
1986{
1987 kfree((void *)cb->args[0]);
1988 return 0;
1989}
1990
55682965
JB
1991static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
1992{
1993 struct sk_buff *msg;
1b8ec87a 1994 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 1995 struct nl80211_dump_wiphy_state state = {};
55682965 1996
645e77de 1997 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 1998 if (!msg)
4c476991 1999 return -ENOMEM;
55682965 2000
3bb20556
JB
2001 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
2002 info->snd_portid, info->snd_seq, 0,
86e8cf98 2003 &state) < 0) {
4c476991
JB
2004 nlmsg_free(msg);
2005 return -ENOBUFS;
2006 }
55682965 2007
134e6375 2008 return genlmsg_reply(msg, info);
55682965
JB
2009}
2010
31888487
JM
2011static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
2012 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
2013 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
2014 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
2015 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
2016 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
2017};
2018
2019static int parse_txq_params(struct nlattr *tb[],
2020 struct ieee80211_txq_params *txq_params)
2021{
a3304b0a 2022 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
2023 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
2024 !tb[NL80211_TXQ_ATTR_AIFS])
2025 return -EINVAL;
2026
a3304b0a 2027 txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
2028 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
2029 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
2030 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
2031 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
2032
a3304b0a
JB
2033 if (txq_params->ac >= NL80211_NUM_ACS)
2034 return -EINVAL;
2035
31888487
JM
2036 return 0;
2037}
2038
f444de05
JB
2039static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2040{
2041 /*
cc1d2806
JB
2042 * You can only set the channel explicitly for WDS interfaces,
2043 * all others have their channel managed via their respective
2044 * "establish a connection" command (connect, join, ...)
2045 *
2046 * For AP/GO and mesh mode, the channel can be set with the
2047 * channel userspace API, but is only stored and passed to the
2048 * low-level driver when the AP starts or the mesh is joined.
2049 * This is for backward compatibility, userspace can also give
2050 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
2051 *
2052 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
2053 * whatever else is going on, so they have their own special
2054 * operation to set the monitor channel if possible.
f444de05
JB
2055 */
2056 return !wdev ||
2057 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 2058 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
2059 wdev->iftype == NL80211_IFTYPE_MONITOR ||
2060 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
2061}
2062
683b6d3b
JB
2063static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2064 struct genl_info *info,
2065 struct cfg80211_chan_def *chandef)
2066{
dbeca2ea 2067 u32 control_freq;
683b6d3b
JB
2068
2069 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
2070 return -EINVAL;
2071
2072 control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
2073
2074 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
3d9d1d66
JB
2075 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
2076 chandef->center_freq1 = control_freq;
2077 chandef->center_freq2 = 0;
683b6d3b
JB
2078
2079 /* Primary channel not allowed */
2080 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
2081 return -EINVAL;
2082
3d9d1d66
JB
2083 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2084 enum nl80211_channel_type chantype;
2085
2086 chantype = nla_get_u32(
2087 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
2088
2089 switch (chantype) {
2090 case NL80211_CHAN_NO_HT:
2091 case NL80211_CHAN_HT20:
2092 case NL80211_CHAN_HT40PLUS:
2093 case NL80211_CHAN_HT40MINUS:
2094 cfg80211_chandef_create(chandef, chandef->chan,
2095 chantype);
2096 break;
2097 default:
2098 return -EINVAL;
2099 }
2100 } else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
2101 chandef->width =
2102 nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
2103 if (info->attrs[NL80211_ATTR_CENTER_FREQ1])
2104 chandef->center_freq1 =
2105 nla_get_u32(
2106 info->attrs[NL80211_ATTR_CENTER_FREQ1]);
2107 if (info->attrs[NL80211_ATTR_CENTER_FREQ2])
2108 chandef->center_freq2 =
2109 nla_get_u32(
2110 info->attrs[NL80211_ATTR_CENTER_FREQ2]);
2111 }
2112
9f5e8f6e 2113 if (!cfg80211_chandef_valid(chandef))
3d9d1d66
JB
2114 return -EINVAL;
2115
9f5e8f6e
JB
2116 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
2117 IEEE80211_CHAN_DISABLED))
3d9d1d66
JB
2118 return -EINVAL;
2119
2f301ab2
SW
2120 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
2121 chandef->width == NL80211_CHAN_WIDTH_10) &&
2122 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ))
2123 return -EINVAL;
2124
683b6d3b
JB
2125 return 0;
2126}
2127
f444de05 2128static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 2129 struct net_device *dev,
f444de05
JB
2130 struct genl_info *info)
2131{
683b6d3b 2132 struct cfg80211_chan_def chandef;
f444de05 2133 int result;
e8c9bd5b 2134 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 2135 struct wireless_dev *wdev = NULL;
e8c9bd5b 2136
e16821bc
JM
2137 if (dev)
2138 wdev = dev->ieee80211_ptr;
f444de05
JB
2139 if (!nl80211_can_set_dev_channel(wdev))
2140 return -EOPNOTSUPP;
e16821bc
JM
2141 if (wdev)
2142 iftype = wdev->iftype;
f444de05 2143
683b6d3b
JB
2144 result = nl80211_parse_chandef(rdev, info, &chandef);
2145 if (result)
2146 return result;
f444de05 2147
e8c9bd5b 2148 switch (iftype) {
aa430da4
JB
2149 case NL80211_IFTYPE_AP:
2150 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
2151 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
2152 iftype)) {
aa430da4
JB
2153 result = -EINVAL;
2154 break;
2155 }
e16821bc
JM
2156 if (wdev->beacon_interval) {
2157 if (!dev || !rdev->ops->set_ap_chanwidth ||
2158 !(rdev->wiphy.features &
2159 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
2160 result = -EBUSY;
2161 break;
2162 }
2163
2164 /* Only allow dynamic channel width changes */
2165 if (chandef.chan != wdev->preset_chandef.chan) {
2166 result = -EBUSY;
2167 break;
2168 }
2169 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
2170 if (result)
2171 break;
2172 }
683b6d3b 2173 wdev->preset_chandef = chandef;
aa430da4
JB
2174 result = 0;
2175 break;
cc1d2806 2176 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 2177 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 2178 break;
e8c9bd5b 2179 case NL80211_IFTYPE_MONITOR:
683b6d3b 2180 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 2181 break;
aa430da4 2182 default:
e8c9bd5b 2183 result = -EINVAL;
f444de05 2184 }
f444de05
JB
2185
2186 return result;
2187}
2188
2189static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
2190{
4c476991
JB
2191 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2192 struct net_device *netdev = info->user_ptr[1];
f444de05 2193
e16821bc 2194 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
2195}
2196
e8347eba
BJ
2197static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
2198{
43b19952
JB
2199 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2200 struct net_device *dev = info->user_ptr[1];
2201 struct wireless_dev *wdev = dev->ieee80211_ptr;
388ac775 2202 const u8 *bssid;
e8347eba
BJ
2203
2204 if (!info->attrs[NL80211_ATTR_MAC])
2205 return -EINVAL;
2206
43b19952
JB
2207 if (netif_running(dev))
2208 return -EBUSY;
e8347eba 2209
43b19952
JB
2210 if (!rdev->ops->set_wds_peer)
2211 return -EOPNOTSUPP;
e8347eba 2212
43b19952
JB
2213 if (wdev->iftype != NL80211_IFTYPE_WDS)
2214 return -EOPNOTSUPP;
e8347eba
BJ
2215
2216 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
e35e4d28 2217 return rdev_set_wds_peer(rdev, dev, bssid);
e8347eba
BJ
2218}
2219
55682965
JB
2220static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2221{
2222 struct cfg80211_registered_device *rdev;
f444de05
JB
2223 struct net_device *netdev = NULL;
2224 struct wireless_dev *wdev;
a1e567c8 2225 int result = 0, rem_txq_params = 0;
31888487 2226 struct nlattr *nl_txq_params;
b9a5f8ca
JM
2227 u32 changed;
2228 u8 retry_short = 0, retry_long = 0;
2229 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 2230 u8 coverage_class = 0;
55682965 2231
5fe231e8
JB
2232 ASSERT_RTNL();
2233
f444de05
JB
2234 /*
2235 * Try to find the wiphy and netdev. Normally this
2236 * function shouldn't need the netdev, but this is
2237 * done for backward compatibility -- previously
2238 * setting the channel was done per wiphy, but now
2239 * it is per netdev. Previous userland like hostapd
2240 * also passed a netdev to set_wiphy, so that it is
2241 * possible to let that go to the right netdev!
2242 */
4bbf4d56 2243
f444de05
JB
2244 if (info->attrs[NL80211_ATTR_IFINDEX]) {
2245 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
2246
7f2b8562 2247 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 2248 if (netdev && netdev->ieee80211_ptr)
f26cbf40 2249 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 2250 else
f444de05 2251 netdev = NULL;
4bbf4d56
JB
2252 }
2253
f444de05 2254 if (!netdev) {
878d9ec7
JB
2255 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
2256 info->attrs);
5fe231e8 2257 if (IS_ERR(rdev))
4c476991 2258 return PTR_ERR(rdev);
f444de05
JB
2259 wdev = NULL;
2260 netdev = NULL;
2261 result = 0;
71fe96bf 2262 } else
f444de05 2263 wdev = netdev->ieee80211_ptr;
f444de05
JB
2264
2265 /*
2266 * end workaround code, by now the rdev is available
2267 * and locked, and wdev may or may not be NULL.
2268 */
4bbf4d56
JB
2269
2270 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
2271 result = cfg80211_dev_rename(
2272 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56 2273
4bbf4d56 2274 if (result)
7f2b8562 2275 return result;
31888487
JM
2276
2277 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
2278 struct ieee80211_txq_params txq_params;
2279 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
2280
7f2b8562
YX
2281 if (!rdev->ops->set_txq_params)
2282 return -EOPNOTSUPP;
31888487 2283
7f2b8562
YX
2284 if (!netdev)
2285 return -EINVAL;
f70f01c2 2286
133a3ff2 2287 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
7f2b8562
YX
2288 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2289 return -EINVAL;
133a3ff2 2290
7f2b8562
YX
2291 if (!netif_running(netdev))
2292 return -ENETDOWN;
2b5f8b0b 2293
31888487
JM
2294 nla_for_each_nested(nl_txq_params,
2295 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
2296 rem_txq_params) {
ae811e21
JB
2297 result = nla_parse(tb, NL80211_TXQ_ATTR_MAX,
2298 nla_data(nl_txq_params),
2299 nla_len(nl_txq_params),
2300 txq_params_policy);
2301 if (result)
2302 return result;
31888487
JM
2303 result = parse_txq_params(tb, &txq_params);
2304 if (result)
7f2b8562 2305 return result;
31888487 2306
e35e4d28
HG
2307 result = rdev_set_txq_params(rdev, netdev,
2308 &txq_params);
31888487 2309 if (result)
7f2b8562 2310 return result;
31888487
JM
2311 }
2312 }
55682965 2313
72bdcf34 2314 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
2315 result = __nl80211_set_channel(
2316 rdev,
2317 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
2318 info);
72bdcf34 2319 if (result)
7f2b8562 2320 return result;
72bdcf34
JM
2321 }
2322
98d2ff8b 2323 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 2324 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
2325 enum nl80211_tx_power_setting type;
2326 int idx, mbm = 0;
2327
c8442118
JB
2328 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
2329 txp_wdev = NULL;
2330
7f2b8562
YX
2331 if (!rdev->ops->set_tx_power)
2332 return -EOPNOTSUPP;
98d2ff8b
JO
2333
2334 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
2335 type = nla_get_u32(info->attrs[idx]);
2336
2337 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
7f2b8562
YX
2338 (type != NL80211_TX_POWER_AUTOMATIC))
2339 return -EINVAL;
98d2ff8b
JO
2340
2341 if (type != NL80211_TX_POWER_AUTOMATIC) {
2342 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
2343 mbm = nla_get_u32(info->attrs[idx]);
2344 }
2345
c8442118 2346 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 2347 if (result)
7f2b8562 2348 return result;
98d2ff8b
JO
2349 }
2350
afe0cbf8
BR
2351 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
2352 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
2353 u32 tx_ant, rx_ant;
7a087e74 2354
7f531e03
BR
2355 if ((!rdev->wiphy.available_antennas_tx &&
2356 !rdev->wiphy.available_antennas_rx) ||
7f2b8562
YX
2357 !rdev->ops->set_antenna)
2358 return -EOPNOTSUPP;
afe0cbf8
BR
2359
2360 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
2361 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
2362
a7ffac95 2363 /* reject antenna configurations which don't match the
7f531e03
BR
2364 * available antenna masks, except for the "all" mask */
2365 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
7f2b8562
YX
2366 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
2367 return -EINVAL;
a7ffac95 2368
7f531e03
BR
2369 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
2370 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 2371
e35e4d28 2372 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 2373 if (result)
7f2b8562 2374 return result;
afe0cbf8
BR
2375 }
2376
b9a5f8ca
JM
2377 changed = 0;
2378
2379 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
2380 retry_short = nla_get_u8(
2381 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562
YX
2382 if (retry_short == 0)
2383 return -EINVAL;
2384
b9a5f8ca
JM
2385 changed |= WIPHY_PARAM_RETRY_SHORT;
2386 }
2387
2388 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
2389 retry_long = nla_get_u8(
2390 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562
YX
2391 if (retry_long == 0)
2392 return -EINVAL;
2393
b9a5f8ca
JM
2394 changed |= WIPHY_PARAM_RETRY_LONG;
2395 }
2396
2397 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
2398 frag_threshold = nla_get_u32(
2399 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
7f2b8562
YX
2400 if (frag_threshold < 256)
2401 return -EINVAL;
2402
b9a5f8ca
JM
2403 if (frag_threshold != (u32) -1) {
2404 /*
2405 * Fragments (apart from the last one) are required to
2406 * have even length. Make the fragmentation code
2407 * simpler by stripping LSB should someone try to use
2408 * odd threshold value.
2409 */
2410 frag_threshold &= ~0x1;
2411 }
2412 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
2413 }
2414
2415 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
2416 rts_threshold = nla_get_u32(
2417 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
2418 changed |= WIPHY_PARAM_RTS_THRESHOLD;
2419 }
2420
81077e82 2421 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
3057dbfd
LB
2422 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK])
2423 return -EINVAL;
2424
81077e82
LT
2425 coverage_class = nla_get_u8(
2426 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
2427 changed |= WIPHY_PARAM_COVERAGE_CLASS;
2428 }
2429
3057dbfd
LB
2430 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
2431 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION))
2432 return -EOPNOTSUPP;
2433
2434 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
2435 }
2436
b9a5f8ca
JM
2437 if (changed) {
2438 u8 old_retry_short, old_retry_long;
2439 u32 old_frag_threshold, old_rts_threshold;
81077e82 2440 u8 old_coverage_class;
b9a5f8ca 2441
7f2b8562
YX
2442 if (!rdev->ops->set_wiphy_params)
2443 return -EOPNOTSUPP;
b9a5f8ca
JM
2444
2445 old_retry_short = rdev->wiphy.retry_short;
2446 old_retry_long = rdev->wiphy.retry_long;
2447 old_frag_threshold = rdev->wiphy.frag_threshold;
2448 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 2449 old_coverage_class = rdev->wiphy.coverage_class;
b9a5f8ca
JM
2450
2451 if (changed & WIPHY_PARAM_RETRY_SHORT)
2452 rdev->wiphy.retry_short = retry_short;
2453 if (changed & WIPHY_PARAM_RETRY_LONG)
2454 rdev->wiphy.retry_long = retry_long;
2455 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
2456 rdev->wiphy.frag_threshold = frag_threshold;
2457 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
2458 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
2459 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
2460 rdev->wiphy.coverage_class = coverage_class;
b9a5f8ca 2461
e35e4d28 2462 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
2463 if (result) {
2464 rdev->wiphy.retry_short = old_retry_short;
2465 rdev->wiphy.retry_long = old_retry_long;
2466 rdev->wiphy.frag_threshold = old_frag_threshold;
2467 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 2468 rdev->wiphy.coverage_class = old_coverage_class;
9189ee31 2469 return result;
b9a5f8ca
JM
2470 }
2471 }
7f2b8562 2472 return 0;
55682965
JB
2473}
2474
71bbc994
JB
2475static inline u64 wdev_id(struct wireless_dev *wdev)
2476{
2477 return (u64)wdev->identifier |
f26cbf40 2478 ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32);
71bbc994 2479}
55682965 2480
683b6d3b 2481static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 2482 const struct cfg80211_chan_def *chandef)
683b6d3b 2483{
601555cd
JB
2484 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
2485 return -EINVAL;
3d9d1d66 2486
683b6d3b
JB
2487 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
2488 chandef->chan->center_freq))
2489 return -ENOBUFS;
3d9d1d66
JB
2490 switch (chandef->width) {
2491 case NL80211_CHAN_WIDTH_20_NOHT:
2492 case NL80211_CHAN_WIDTH_20:
2493 case NL80211_CHAN_WIDTH_40:
2494 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2495 cfg80211_get_chandef_type(chandef)))
2496 return -ENOBUFS;
2497 break;
2498 default:
2499 break;
2500 }
2501 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
2502 return -ENOBUFS;
2503 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
2504 return -ENOBUFS;
2505 if (chandef->center_freq2 &&
2506 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
2507 return -ENOBUFS;
2508 return 0;
2509}
2510
15e47304 2511static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 2512 struct cfg80211_registered_device *rdev,
8f894be2 2513 struct wireless_dev *wdev, bool removal)
55682965 2514{
72fb2abc 2515 struct net_device *dev = wdev->netdev;
8f894be2 2516 u8 cmd = NL80211_CMD_NEW_INTERFACE;
55682965
JB
2517 void *hdr;
2518
8f894be2
TB
2519 if (removal)
2520 cmd = NL80211_CMD_DEL_INTERFACE;
2521
2522 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
2523 if (!hdr)
2524 return -1;
2525
72fb2abc
JB
2526 if (dev &&
2527 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 2528 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
2529 goto nla_put_failure;
2530
2531 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2532 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
2533 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
2534 NL80211_ATTR_PAD) ||
98104fde 2535 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
2536 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2537 rdev->devlist_generation ^
2538 (cfg80211_rdev_list_generation << 2)))
2539 goto nla_put_failure;
f5ea9120 2540
5b7ccaf3 2541 if (rdev->ops->get_channel) {
683b6d3b
JB
2542 int ret;
2543 struct cfg80211_chan_def chandef;
2544
2545 ret = rdev_get_channel(rdev, wdev, &chandef);
2546 if (ret == 0) {
2547 if (nl80211_send_chandef(msg, &chandef))
2548 goto nla_put_failure;
2549 }
d91df0e3
PF
2550 }
2551
d55d0d59
RM
2552 if (rdev->ops->get_tx_power) {
2553 int dbm, ret;
2554
2555 ret = rdev_get_tx_power(rdev, wdev, &dbm);
2556 if (ret == 0 &&
2557 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
2558 DBM_TO_MBM(dbm)))
2559 goto nla_put_failure;
2560 }
2561
b84e7a05
AQ
2562 if (wdev->ssid_len) {
2563 if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
2564 goto nla_put_failure;
2565 }
2566
053c095a
JB
2567 genlmsg_end(msg, hdr);
2568 return 0;
55682965
JB
2569
2570 nla_put_failure:
bc3ed28c
TG
2571 genlmsg_cancel(msg, hdr);
2572 return -EMSGSIZE;
55682965
JB
2573}
2574
2575static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
2576{
2577 int wp_idx = 0;
2578 int if_idx = 0;
2579 int wp_start = cb->args[0];
2580 int if_start = cb->args[1];
b7fb44da 2581 int filter_wiphy = -1;
f5ea9120 2582 struct cfg80211_registered_device *rdev;
55682965
JB
2583 struct wireless_dev *wdev;
2584
5fe231e8 2585 rtnl_lock();
b7fb44da
DK
2586 if (!cb->args[2]) {
2587 struct nl80211_dump_wiphy_state state = {
2588 .filter_wiphy = -1,
2589 };
2590 int ret;
2591
2592 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
2593 if (ret)
2594 return ret;
2595
2596 filter_wiphy = state.filter_wiphy;
2597
2598 /*
2599 * if filtering, set cb->args[2] to +1 since 0 is the default
2600 * value needed to determine that parsing is necessary.
2601 */
2602 if (filter_wiphy >= 0)
2603 cb->args[2] = filter_wiphy + 1;
2604 else
2605 cb->args[2] = -1;
2606 } else if (cb->args[2] > 0) {
2607 filter_wiphy = cb->args[2] - 1;
2608 }
2609
f5ea9120
JB
2610 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2611 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2612 continue;
bba95fef
JB
2613 if (wp_idx < wp_start) {
2614 wp_idx++;
55682965 2615 continue;
bba95fef 2616 }
b7fb44da
DK
2617
2618 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
2619 continue;
2620
55682965
JB
2621 if_idx = 0;
2622
53873f13 2623 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
2624 if (if_idx < if_start) {
2625 if_idx++;
55682965 2626 continue;
bba95fef 2627 }
15e47304 2628 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 2629 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8f894be2 2630 rdev, wdev, false) < 0) {
bba95fef
JB
2631 goto out;
2632 }
2633 if_idx++;
55682965 2634 }
bba95fef
JB
2635
2636 wp_idx++;
55682965 2637 }
bba95fef 2638 out:
5fe231e8 2639 rtnl_unlock();
55682965
JB
2640
2641 cb->args[0] = wp_idx;
2642 cb->args[1] = if_idx;
2643
2644 return skb->len;
2645}
2646
2647static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
2648{
2649 struct sk_buff *msg;
1b8ec87a 2650 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 2651 struct wireless_dev *wdev = info->user_ptr[1];
55682965 2652
fd2120ca 2653 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 2654 if (!msg)
4c476991 2655 return -ENOMEM;
55682965 2656
15e47304 2657 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 2658 rdev, wdev, false) < 0) {
4c476991
JB
2659 nlmsg_free(msg);
2660 return -ENOBUFS;
2661 }
55682965 2662
134e6375 2663 return genlmsg_reply(msg, info);
55682965
JB
2664}
2665
66f7ac50
MW
2666static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
2667 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
2668 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
2669 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
2670 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
2671 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 2672 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
2673};
2674
2675static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
2676{
2677 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
2678 int flag;
2679
2680 *mntrflags = 0;
2681
2682 if (!nla)
2683 return -EINVAL;
2684
2685 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
2686 nla, mntr_flags_policy))
2687 return -EINVAL;
2688
2689 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
2690 if (flags[flag])
2691 *mntrflags |= (1<<flag);
2692
2693 return 0;
2694}
2695
9bc383de 2696static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
2697 struct net_device *netdev, u8 use_4addr,
2698 enum nl80211_iftype iftype)
9bc383de 2699{
ad4bb6f8 2700 if (!use_4addr) {
f350a0a8 2701 if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT))
ad4bb6f8 2702 return -EBUSY;
9bc383de 2703 return 0;
ad4bb6f8 2704 }
9bc383de
JB
2705
2706 switch (iftype) {
2707 case NL80211_IFTYPE_AP_VLAN:
2708 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
2709 return 0;
2710 break;
2711 case NL80211_IFTYPE_STATION:
2712 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
2713 return 0;
2714 break;
2715 default:
2716 break;
2717 }
2718
2719 return -EOPNOTSUPP;
2720}
2721
55682965
JB
2722static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
2723{
4c476991 2724 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2725 struct vif_params params;
e36d56b6 2726 int err;
04a773ad 2727 enum nl80211_iftype otype, ntype;
4c476991 2728 struct net_device *dev = info->user_ptr[1];
92ffe055 2729 u32 _flags, *flags = NULL;
ac7f9cfa 2730 bool change = false;
55682965 2731
2ec600d6
LCC
2732 memset(&params, 0, sizeof(params));
2733
04a773ad 2734 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 2735
723b038d 2736 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 2737 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 2738 if (otype != ntype)
ac7f9cfa 2739 change = true;
4c476991
JB
2740 if (ntype > NL80211_IFTYPE_MAX)
2741 return -EINVAL;
723b038d
JB
2742 }
2743
92ffe055 2744 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
2745 struct wireless_dev *wdev = dev->ieee80211_ptr;
2746
4c476991
JB
2747 if (ntype != NL80211_IFTYPE_MESH_POINT)
2748 return -EINVAL;
29cbe68c
JB
2749 if (netif_running(dev))
2750 return -EBUSY;
2751
2752 wdev_lock(wdev);
2753 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2754 IEEE80211_MAX_MESH_ID_LEN);
2755 wdev->mesh_id_up_len =
2756 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2757 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
2758 wdev->mesh_id_up_len);
2759 wdev_unlock(wdev);
2ec600d6
LCC
2760 }
2761
8b787643
FF
2762 if (info->attrs[NL80211_ATTR_4ADDR]) {
2763 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
2764 change = true;
ad4bb6f8 2765 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 2766 if (err)
4c476991 2767 return err;
8b787643
FF
2768 } else {
2769 params.use_4addr = -1;
2770 }
2771
92ffe055 2772 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
4c476991
JB
2773 if (ntype != NL80211_IFTYPE_MONITOR)
2774 return -EINVAL;
92ffe055
JB
2775 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
2776 &_flags);
ac7f9cfa 2777 if (err)
4c476991 2778 return err;
ac7f9cfa
JB
2779
2780 flags = &_flags;
2781 change = true;
92ffe055 2782 }
3b85875a 2783
c6e6a0c8
AE
2784 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
2785 const u8 *mumimo_groups;
2786 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2787
2788 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2789 return -EOPNOTSUPP;
2790
2791 mumimo_groups =
2792 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
2793
2794 /* bits 0 and 63 are reserved and must be zero */
2795 if ((mumimo_groups[0] & BIT(7)) ||
2796 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(0)))
2797 return -EINVAL;
2798
2799 memcpy(params.vht_mumimo_groups, mumimo_groups,
2800 VHT_MUMIMO_GROUPS_DATA_LEN);
2801 change = true;
2802 }
2803
2804 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
2805 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2806
2807 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2808 return -EOPNOTSUPP;
2809
2810 nla_memcpy(params.macaddr,
2811 info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR],
2812 ETH_ALEN);
2813 change = true;
2814 }
2815
18003297 2816 if (flags && (*flags & MONITOR_FLAG_ACTIVE) &&
e057d3c3
FF
2817 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2818 return -EOPNOTSUPP;
2819
ac7f9cfa 2820 if (change)
3d54d255 2821 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
ac7f9cfa
JB
2822 else
2823 err = 0;
60719ffd 2824
9bc383de
JB
2825 if (!err && params.use_4addr != -1)
2826 dev->ieee80211_ptr->use_4addr = params.use_4addr;
2827
55682965
JB
2828 return err;
2829}
2830
2831static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2832{
4c476991 2833 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2834 struct vif_params params;
84efbb84 2835 struct wireless_dev *wdev;
896ff063 2836 struct sk_buff *msg;
55682965
JB
2837 int err;
2838 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
66f7ac50 2839 u32 flags;
55682965 2840
78f22b6a
JB
2841 /* to avoid failing a new interface creation due to pending removal */
2842 cfg80211_destroy_ifaces(rdev);
2843
2ec600d6
LCC
2844 memset(&params, 0, sizeof(params));
2845
55682965
JB
2846 if (!info->attrs[NL80211_ATTR_IFNAME])
2847 return -EINVAL;
2848
2849 if (info->attrs[NL80211_ATTR_IFTYPE]) {
2850 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
2851 if (type > NL80211_IFTYPE_MAX)
2852 return -EINVAL;
2853 }
2854
79c97e97 2855 if (!rdev->ops->add_virtual_intf ||
4c476991
JB
2856 !(rdev->wiphy.interface_modes & (1 << type)))
2857 return -EOPNOTSUPP;
55682965 2858
cb3b7d87 2859 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
2860 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
2861 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
2862 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
2863 ETH_ALEN);
2864 if (!is_valid_ether_addr(params.macaddr))
2865 return -EADDRNOTAVAIL;
2866 }
2867
9bc383de 2868 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 2869 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 2870 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 2871 if (err)
4c476991 2872 return err;
9bc383de 2873 }
8b787643 2874
66f7ac50
MW
2875 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
2876 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
2877 &flags);
e057d3c3 2878
18003297 2879 if (!err && (flags & MONITOR_FLAG_ACTIVE) &&
e057d3c3
FF
2880 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2881 return -EOPNOTSUPP;
2882
a18c7192
JB
2883 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2884 if (!msg)
2885 return -ENOMEM;
2886
e35e4d28
HG
2887 wdev = rdev_add_virtual_intf(rdev,
2888 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
6bab2e19
TG
2889 NET_NAME_USER, type, err ? NULL : &flags,
2890 &params);
d687cbb7
RM
2891 if (WARN_ON(!wdev)) {
2892 nlmsg_free(msg);
2893 return -EPROTO;
2894 } else if (IS_ERR(wdev)) {
1c90f9d4 2895 nlmsg_free(msg);
84efbb84 2896 return PTR_ERR(wdev);
1c90f9d4 2897 }
2ec600d6 2898
18e5ca65 2899 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
2900 wdev->owner_nlportid = info->snd_portid;
2901
98104fde
JB
2902 switch (type) {
2903 case NL80211_IFTYPE_MESH_POINT:
2904 if (!info->attrs[NL80211_ATTR_MESH_ID])
2905 break;
29cbe68c
JB
2906 wdev_lock(wdev);
2907 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2908 IEEE80211_MAX_MESH_ID_LEN);
2909 wdev->mesh_id_up_len =
2910 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2911 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
2912 wdev->mesh_id_up_len);
2913 wdev_unlock(wdev);
98104fde 2914 break;
cb3b7d87 2915 case NL80211_IFTYPE_NAN:
98104fde
JB
2916 case NL80211_IFTYPE_P2P_DEVICE:
2917 /*
cb3b7d87 2918 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
2919 * through the netdev notifier and must be added here
2920 */
2921 mutex_init(&wdev->mtx);
2922 INIT_LIST_HEAD(&wdev->event_list);
2923 spin_lock_init(&wdev->event_lock);
2924 INIT_LIST_HEAD(&wdev->mgmt_registrations);
2925 spin_lock_init(&wdev->mgmt_registrations_lock);
2926
98104fde 2927 wdev->identifier = ++rdev->wdev_id;
53873f13 2928 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
98104fde 2929 rdev->devlist_generation++;
98104fde
JB
2930 break;
2931 default:
2932 break;
29cbe68c
JB
2933 }
2934
15e47304 2935 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 2936 rdev, wdev, false) < 0) {
1c90f9d4
JB
2937 nlmsg_free(msg);
2938 return -ENOBUFS;
2939 }
2940
896ff063
DK
2941 /*
2942 * For wdevs which have no associated netdev object (e.g. of type
2943 * NL80211_IFTYPE_P2P_DEVICE), emit the NEW_INTERFACE event here.
2944 * For all other types, the event will be generated from the
2945 * netdev notifier
2946 */
2947 if (!wdev->netdev)
2948 nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
8f894be2 2949
1c90f9d4 2950 return genlmsg_reply(msg, info);
55682965
JB
2951}
2952
2953static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
2954{
4c476991 2955 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 2956 struct wireless_dev *wdev = info->user_ptr[1];
55682965 2957
4c476991
JB
2958 if (!rdev->ops->del_virtual_intf)
2959 return -EOPNOTSUPP;
55682965 2960
84efbb84
JB
2961 /*
2962 * If we remove a wireless device without a netdev then clear
2963 * user_ptr[1] so that nl80211_post_doit won't dereference it
2964 * to check if it needs to do dev_put(). Otherwise it crashes
2965 * since the wdev has been freed, unlike with a netdev where
2966 * we need the dev_put() for the netdev to really be freed.
2967 */
2968 if (!wdev->netdev)
2969 info->user_ptr[1] = NULL;
2970
7f8ed01e 2971 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
2972}
2973
1d9d9213
SW
2974static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
2975{
2976 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2977 struct net_device *dev = info->user_ptr[1];
2978 u16 noack_map;
2979
2980 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
2981 return -EINVAL;
2982
2983 if (!rdev->ops->set_noack_map)
2984 return -EOPNOTSUPP;
2985
2986 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
2987
e35e4d28 2988 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
2989}
2990
41ade00f
JB
2991struct get_key_cookie {
2992 struct sk_buff *msg;
2993 int error;
b9454e83 2994 int idx;
41ade00f
JB
2995};
2996
2997static void get_key_callback(void *c, struct key_params *params)
2998{
b9454e83 2999 struct nlattr *key;
41ade00f
JB
3000 struct get_key_cookie *cookie = c;
3001
9360ffd1
DM
3002 if ((params->key &&
3003 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
3004 params->key_len, params->key)) ||
3005 (params->seq &&
3006 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
3007 params->seq_len, params->seq)) ||
3008 (params->cipher &&
3009 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
3010 params->cipher)))
3011 goto nla_put_failure;
41ade00f 3012
b9454e83
JB
3013 key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
3014 if (!key)
3015 goto nla_put_failure;
3016
9360ffd1
DM
3017 if ((params->key &&
3018 nla_put(cookie->msg, NL80211_KEY_DATA,
3019 params->key_len, params->key)) ||
3020 (params->seq &&
3021 nla_put(cookie->msg, NL80211_KEY_SEQ,
3022 params->seq_len, params->seq)) ||
3023 (params->cipher &&
3024 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
3025 params->cipher)))
3026 goto nla_put_failure;
b9454e83 3027
9360ffd1
DM
3028 if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx))
3029 goto nla_put_failure;
b9454e83
JB
3030
3031 nla_nest_end(cookie->msg, key);
3032
41ade00f
JB
3033 return;
3034 nla_put_failure:
3035 cookie->error = 1;
3036}
3037
3038static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
3039{
4c476991 3040 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3041 int err;
4c476991 3042 struct net_device *dev = info->user_ptr[1];
41ade00f 3043 u8 key_idx = 0;
e31b8213
JB
3044 const u8 *mac_addr = NULL;
3045 bool pairwise;
41ade00f
JB
3046 struct get_key_cookie cookie = {
3047 .error = 0,
3048 };
3049 void *hdr;
3050 struct sk_buff *msg;
3051
3052 if (info->attrs[NL80211_ATTR_KEY_IDX])
3053 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
3054
3cfcf6ac 3055 if (key_idx > 5)
41ade00f
JB
3056 return -EINVAL;
3057
3058 if (info->attrs[NL80211_ATTR_MAC])
3059 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3060
e31b8213
JB
3061 pairwise = !!mac_addr;
3062 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
3063 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 3064
e31b8213
JB
3065 if (kt >= NUM_NL80211_KEYTYPES)
3066 return -EINVAL;
3067 if (kt != NL80211_KEYTYPE_GROUP &&
3068 kt != NL80211_KEYTYPE_PAIRWISE)
3069 return -EINVAL;
3070 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
3071 }
3072
4c476991
JB
3073 if (!rdev->ops->get_key)
3074 return -EOPNOTSUPP;
41ade00f 3075
0fa7b391
JB
3076 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3077 return -ENOENT;
3078
fd2120ca 3079 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
3080 if (!msg)
3081 return -ENOMEM;
41ade00f 3082
15e47304 3083 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 3084 NL80211_CMD_NEW_KEY);
cb35fba3 3085 if (!hdr)
9fe271af 3086 goto nla_put_failure;
41ade00f
JB
3087
3088 cookie.msg = msg;
b9454e83 3089 cookie.idx = key_idx;
41ade00f 3090
9360ffd1
DM
3091 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3092 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
3093 goto nla_put_failure;
3094 if (mac_addr &&
3095 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
3096 goto nla_put_failure;
41ade00f 3097
e35e4d28
HG
3098 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
3099 get_key_callback);
41ade00f
JB
3100
3101 if (err)
6c95e2a2 3102 goto free_msg;
41ade00f
JB
3103
3104 if (cookie.error)
3105 goto nla_put_failure;
3106
3107 genlmsg_end(msg, hdr);
4c476991 3108 return genlmsg_reply(msg, info);
41ade00f
JB
3109
3110 nla_put_failure:
3111 err = -ENOBUFS;
6c95e2a2 3112 free_msg:
41ade00f 3113 nlmsg_free(msg);
41ade00f
JB
3114 return err;
3115}
3116
3117static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
3118{
4c476991 3119 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 3120 struct key_parse key;
41ade00f 3121 int err;
4c476991 3122 struct net_device *dev = info->user_ptr[1];
41ade00f 3123
b9454e83
JB
3124 err = nl80211_parse_key(info, &key);
3125 if (err)
3126 return err;
41ade00f 3127
b9454e83 3128 if (key.idx < 0)
41ade00f
JB
3129 return -EINVAL;
3130
b9454e83
JB
3131 /* only support setting default key */
3132 if (!key.def && !key.defmgmt)
41ade00f
JB
3133 return -EINVAL;
3134
dbd2fd65 3135 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 3136
dbd2fd65
JB
3137 if (key.def) {
3138 if (!rdev->ops->set_default_key) {
3139 err = -EOPNOTSUPP;
3140 goto out;
3141 }
41ade00f 3142
dbd2fd65
JB
3143 err = nl80211_key_allowed(dev->ieee80211_ptr);
3144 if (err)
3145 goto out;
3146
e35e4d28 3147 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
3148 key.def_uni, key.def_multi);
3149
3150 if (err)
3151 goto out;
fffd0934 3152
3d23e349 3153#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
3154 dev->ieee80211_ptr->wext.default_key = key.idx;
3155#endif
3156 } else {
3157 if (key.def_uni || !key.def_multi) {
3158 err = -EINVAL;
3159 goto out;
3160 }
3161
3162 if (!rdev->ops->set_default_mgmt_key) {
3163 err = -EOPNOTSUPP;
3164 goto out;
3165 }
3166
3167 err = nl80211_key_allowed(dev->ieee80211_ptr);
3168 if (err)
3169 goto out;
3170
e35e4d28 3171 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
3172 if (err)
3173 goto out;
3174
3175#ifdef CONFIG_CFG80211_WEXT
3176 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 3177#endif
dbd2fd65
JB
3178 }
3179
3180 out:
fffd0934 3181 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3182
41ade00f
JB
3183 return err;
3184}
3185
3186static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
3187{
4c476991 3188 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 3189 int err;
4c476991 3190 struct net_device *dev = info->user_ptr[1];
b9454e83 3191 struct key_parse key;
e31b8213 3192 const u8 *mac_addr = NULL;
41ade00f 3193
b9454e83
JB
3194 err = nl80211_parse_key(info, &key);
3195 if (err)
3196 return err;
41ade00f 3197
b9454e83 3198 if (!key.p.key)
41ade00f
JB
3199 return -EINVAL;
3200
41ade00f
JB
3201 if (info->attrs[NL80211_ATTR_MAC])
3202 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3203
e31b8213
JB
3204 if (key.type == -1) {
3205 if (mac_addr)
3206 key.type = NL80211_KEYTYPE_PAIRWISE;
3207 else
3208 key.type = NL80211_KEYTYPE_GROUP;
3209 }
3210
3211 /* for now */
3212 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3213 key.type != NL80211_KEYTYPE_GROUP)
3214 return -EINVAL;
3215
4c476991
JB
3216 if (!rdev->ops->add_key)
3217 return -EOPNOTSUPP;
25e47c18 3218
e31b8213
JB
3219 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
3220 key.type == NL80211_KEYTYPE_PAIRWISE,
3221 mac_addr))
4c476991 3222 return -EINVAL;
41ade00f 3223
fffd0934
JB
3224 wdev_lock(dev->ieee80211_ptr);
3225 err = nl80211_key_allowed(dev->ieee80211_ptr);
3226 if (!err)
e35e4d28
HG
3227 err = rdev_add_key(rdev, dev, key.idx,
3228 key.type == NL80211_KEYTYPE_PAIRWISE,
3229 mac_addr, &key.p);
fffd0934 3230 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3231
41ade00f
JB
3232 return err;
3233}
3234
3235static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
3236{
4c476991 3237 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3238 int err;
4c476991 3239 struct net_device *dev = info->user_ptr[1];
41ade00f 3240 u8 *mac_addr = NULL;
b9454e83 3241 struct key_parse key;
41ade00f 3242
b9454e83
JB
3243 err = nl80211_parse_key(info, &key);
3244 if (err)
3245 return err;
41ade00f
JB
3246
3247 if (info->attrs[NL80211_ATTR_MAC])
3248 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3249
e31b8213
JB
3250 if (key.type == -1) {
3251 if (mac_addr)
3252 key.type = NL80211_KEYTYPE_PAIRWISE;
3253 else
3254 key.type = NL80211_KEYTYPE_GROUP;
3255 }
3256
3257 /* for now */
3258 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3259 key.type != NL80211_KEYTYPE_GROUP)
3260 return -EINVAL;
3261
4c476991
JB
3262 if (!rdev->ops->del_key)
3263 return -EOPNOTSUPP;
41ade00f 3264
fffd0934
JB
3265 wdev_lock(dev->ieee80211_ptr);
3266 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 3267
0fa7b391 3268 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
3269 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3270 err = -ENOENT;
3271
fffd0934 3272 if (!err)
e35e4d28
HG
3273 err = rdev_del_key(rdev, dev, key.idx,
3274 key.type == NL80211_KEYTYPE_PAIRWISE,
3275 mac_addr);
41ade00f 3276
3d23e349 3277#ifdef CONFIG_CFG80211_WEXT
08645126 3278 if (!err) {
b9454e83 3279 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 3280 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 3281 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
3282 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
3283 }
3284#endif
fffd0934 3285 wdev_unlock(dev->ieee80211_ptr);
08645126 3286
41ade00f
JB
3287 return err;
3288}
3289
77765eaf
VT
3290/* This function returns an error or the number of nested attributes */
3291static int validate_acl_mac_addrs(struct nlattr *nl_attr)
3292{
3293 struct nlattr *attr;
3294 int n_entries = 0, tmp;
3295
3296 nla_for_each_nested(attr, nl_attr, tmp) {
3297 if (nla_len(attr) != ETH_ALEN)
3298 return -EINVAL;
3299
3300 n_entries++;
3301 }
3302
3303 return n_entries;
3304}
3305
3306/*
3307 * This function parses ACL information and allocates memory for ACL data.
3308 * On successful return, the calling function is responsible to free the
3309 * ACL buffer returned by this function.
3310 */
3311static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
3312 struct genl_info *info)
3313{
3314 enum nl80211_acl_policy acl_policy;
3315 struct nlattr *attr;
3316 struct cfg80211_acl_data *acl;
3317 int i = 0, n_entries, tmp;
3318
3319 if (!wiphy->max_acl_mac_addrs)
3320 return ERR_PTR(-EOPNOTSUPP);
3321
3322 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
3323 return ERR_PTR(-EINVAL);
3324
3325 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
3326 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
3327 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
3328 return ERR_PTR(-EINVAL);
3329
3330 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
3331 return ERR_PTR(-EINVAL);
3332
3333 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
3334 if (n_entries < 0)
3335 return ERR_PTR(n_entries);
3336
3337 if (n_entries > wiphy->max_acl_mac_addrs)
3338 return ERR_PTR(-ENOTSUPP);
3339
3340 acl = kzalloc(sizeof(*acl) + (sizeof(struct mac_address) * n_entries),
3341 GFP_KERNEL);
3342 if (!acl)
3343 return ERR_PTR(-ENOMEM);
3344
3345 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
3346 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
3347 i++;
3348 }
3349
3350 acl->n_acl_entries = n_entries;
3351 acl->acl_policy = acl_policy;
3352
3353 return acl;
3354}
3355
3356static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
3357{
3358 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3359 struct net_device *dev = info->user_ptr[1];
3360 struct cfg80211_acl_data *acl;
3361 int err;
3362
3363 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3364 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3365 return -EOPNOTSUPP;
3366
3367 if (!dev->ieee80211_ptr->beacon_interval)
3368 return -EINVAL;
3369
3370 acl = parse_acl_data(&rdev->wiphy, info);
3371 if (IS_ERR(acl))
3372 return PTR_ERR(acl);
3373
3374 err = rdev_set_mac_acl(rdev, dev, acl);
3375
3376 kfree(acl);
3377
3378 return err;
3379}
3380
a7c7fbff
PK
3381static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
3382 u8 *rates, u8 rates_len)
3383{
3384 u8 i;
3385 u32 mask = 0;
3386
3387 for (i = 0; i < rates_len; i++) {
3388 int rate = (rates[i] & 0x7f) * 5;
3389 int ridx;
3390
3391 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
3392 struct ieee80211_rate *srate =
3393 &sband->bitrates[ridx];
3394 if (rate == srate->bitrate) {
3395 mask |= 1 << ridx;
3396 break;
3397 }
3398 }
3399 if (ridx == sband->n_bitrates)
3400 return 0; /* rate not found */
3401 }
3402
3403 return mask;
3404}
3405
3406static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
3407 u8 *rates, u8 rates_len,
3408 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
3409{
3410 u8 i;
3411
3412 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
3413
3414 for (i = 0; i < rates_len; i++) {
3415 int ridx, rbit;
3416
3417 ridx = rates[i] / 8;
3418 rbit = BIT(rates[i] % 8);
3419
3420 /* check validity */
3421 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
3422 return false;
3423
3424 /* check availability */
3425 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
3426 mcs[ridx] |= rbit;
3427 else
3428 return false;
3429 }
3430
3431 return true;
3432}
3433
3434static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
3435{
3436 u16 mcs_mask = 0;
3437
3438 switch (vht_mcs_map) {
3439 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
3440 break;
3441 case IEEE80211_VHT_MCS_SUPPORT_0_7:
3442 mcs_mask = 0x00FF;
3443 break;
3444 case IEEE80211_VHT_MCS_SUPPORT_0_8:
3445 mcs_mask = 0x01FF;
3446 break;
3447 case IEEE80211_VHT_MCS_SUPPORT_0_9:
3448 mcs_mask = 0x03FF;
3449 break;
3450 default:
3451 break;
3452 }
3453
3454 return mcs_mask;
3455}
3456
3457static void vht_build_mcs_mask(u16 vht_mcs_map,
3458 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
3459{
3460 u8 nss;
3461
3462 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
3463 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
3464 vht_mcs_map >>= 2;
3465 }
3466}
3467
3468static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
3469 struct nl80211_txrate_vht *txrate,
3470 u16 mcs[NL80211_VHT_NSS_MAX])
3471{
3472 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3473 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
3474 u8 i;
3475
3476 if (!sband->vht_cap.vht_supported)
3477 return false;
3478
3479 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
3480
3481 /* Build vht_mcs_mask from VHT capabilities */
3482 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
3483
3484 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
3485 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
3486 mcs[i] = txrate->mcs[i];
3487 else
3488 return false;
3489 }
3490
3491 return true;
3492}
3493
3494static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
3495 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
3496 .len = NL80211_MAX_SUPP_RATES },
3497 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
3498 .len = NL80211_MAX_SUPP_HT_RATES },
3499 [NL80211_TXRATE_VHT] = { .len = sizeof(struct nl80211_txrate_vht)},
3500 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
3501};
3502
3503static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
3504 struct cfg80211_bitrate_mask *mask)
3505{
3506 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
3507 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3508 int rem, i;
3509 struct nlattr *tx_rates;
3510 struct ieee80211_supported_band *sband;
3511 u16 vht_tx_mcs_map;
3512
3513 memset(mask, 0, sizeof(*mask));
3514 /* Default to all rates enabled */
3515 for (i = 0; i < NUM_NL80211_BANDS; i++) {
3516 sband = rdev->wiphy.bands[i];
3517
3518 if (!sband)
3519 continue;
3520
3521 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
3522 memcpy(mask->control[i].ht_mcs,
3523 sband->ht_cap.mcs.rx_mask,
3524 sizeof(mask->control[i].ht_mcs));
3525
3526 if (!sband->vht_cap.vht_supported)
3527 continue;
3528
3529 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3530 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
3531 }
3532
3533 /* if no rates are given set it back to the defaults */
3534 if (!info->attrs[NL80211_ATTR_TX_RATES])
3535 goto out;
3536
3537 /* The nested attribute uses enum nl80211_band as the index. This maps
3538 * directly to the enum nl80211_band values used in cfg80211.
3539 */
3540 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
3541 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
3542 enum nl80211_band band = nla_type(tx_rates);
3543 int err;
3544
3545 if (band < 0 || band >= NUM_NL80211_BANDS)
3546 return -EINVAL;
3547 sband = rdev->wiphy.bands[band];
3548 if (sband == NULL)
3549 return -EINVAL;
3550 err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
3551 nla_len(tx_rates), nl80211_txattr_policy);
3552 if (err)
3553 return err;
3554 if (tb[NL80211_TXRATE_LEGACY]) {
3555 mask->control[band].legacy = rateset_to_mask(
3556 sband,
3557 nla_data(tb[NL80211_TXRATE_LEGACY]),
3558 nla_len(tb[NL80211_TXRATE_LEGACY]));
3559 if ((mask->control[band].legacy == 0) &&
3560 nla_len(tb[NL80211_TXRATE_LEGACY]))
3561 return -EINVAL;
3562 }
3563 if (tb[NL80211_TXRATE_HT]) {
3564 if (!ht_rateset_to_mask(
3565 sband,
3566 nla_data(tb[NL80211_TXRATE_HT]),
3567 nla_len(tb[NL80211_TXRATE_HT]),
3568 mask->control[band].ht_mcs))
3569 return -EINVAL;
3570 }
3571 if (tb[NL80211_TXRATE_VHT]) {
3572 if (!vht_set_mcs_mask(
3573 sband,
3574 nla_data(tb[NL80211_TXRATE_VHT]),
3575 mask->control[band].vht_mcs))
3576 return -EINVAL;
3577 }
3578 if (tb[NL80211_TXRATE_GI]) {
3579 mask->control[band].gi =
3580 nla_get_u8(tb[NL80211_TXRATE_GI]);
3581 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
3582 return -EINVAL;
3583 }
3584
3585 if (mask->control[band].legacy == 0) {
3586 /* don't allow empty legacy rates if HT or VHT
3587 * are not even supported.
3588 */
3589 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
3590 rdev->wiphy.bands[band]->vht_cap.vht_supported))
3591 return -EINVAL;
3592
3593 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
3594 if (mask->control[band].ht_mcs[i])
3595 goto out;
3596
3597 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
3598 if (mask->control[band].vht_mcs[i])
3599 goto out;
3600
3601 /* legacy and mcs rates may not be both empty */
3602 return -EINVAL;
3603 }
3604 }
3605
3606out:
3607 return 0;
3608}
3609
8564e382
JB
3610static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
3611 enum nl80211_band band,
3612 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 3613{
8564e382
JB
3614 u32 count_ht, count_vht, i;
3615 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
3616
3617 /* Allow only one rate */
3618 if (hweight32(rate) > 1)
3619 return -EINVAL;
3620
3621 count_ht = 0;
3622 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 3623 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 3624 return -EINVAL;
8564e382 3625 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
3626 count_ht++;
3627 if (count_ht > 1)
3628 return -EINVAL;
3629 }
3630 if (count_ht && rate)
3631 return -EINVAL;
3632 }
3633
3634 count_vht = 0;
3635 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 3636 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 3637 return -EINVAL;
8564e382 3638 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
3639 count_vht++;
3640 if (count_vht > 1)
3641 return -EINVAL;
3642 }
3643 if (count_vht && rate)
3644 return -EINVAL;
3645 }
3646
3647 if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht))
3648 return -EINVAL;
3649
8564e382
JB
3650 if (rate &&
3651 !wiphy_ext_feature_isset(&rdev->wiphy,
3652 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
3653 return -EINVAL;
3654 if (count_ht &&
3655 !wiphy_ext_feature_isset(&rdev->wiphy,
3656 NL80211_EXT_FEATURE_BEACON_RATE_HT))
3657 return -EINVAL;
3658 if (count_vht &&
3659 !wiphy_ext_feature_isset(&rdev->wiphy,
3660 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
3661 return -EINVAL;
3662
a7c7fbff
PK
3663 return 0;
3664}
3665
a1193be8 3666static int nl80211_parse_beacon(struct nlattr *attrs[],
8860020e 3667 struct cfg80211_beacon_data *bcn)
ed1b6cc7 3668{
8860020e 3669 bool haveinfo = false;
ed1b6cc7 3670
a1193be8
SW
3671 if (!is_valid_ie_attr(attrs[NL80211_ATTR_BEACON_TAIL]) ||
3672 !is_valid_ie_attr(attrs[NL80211_ATTR_IE]) ||
3673 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
3674 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_ASSOC_RESP]))
f4a11bb0
JB
3675 return -EINVAL;
3676
8860020e 3677 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 3678
a1193be8
SW
3679 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
3680 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
3681 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
3682 if (!bcn->head_len)
3683 return -EINVAL;
3684 haveinfo = true;
ed1b6cc7
JB
3685 }
3686
a1193be8
SW
3687 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
3688 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
3689 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 3690 haveinfo = true;
ed1b6cc7
JB
3691 }
3692
4c476991
JB
3693 if (!haveinfo)
3694 return -EINVAL;
3b85875a 3695
a1193be8
SW
3696 if (attrs[NL80211_ATTR_IE]) {
3697 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
3698 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
3699 }
3700
a1193be8 3701 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 3702 bcn->proberesp_ies =
a1193be8 3703 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 3704 bcn->proberesp_ies_len =
a1193be8 3705 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
3706 }
3707
a1193be8 3708 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 3709 bcn->assocresp_ies =
a1193be8 3710 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 3711 bcn->assocresp_ies_len =
a1193be8 3712 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
3713 }
3714
a1193be8
SW
3715 if (attrs[NL80211_ATTR_PROBE_RESP]) {
3716 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
3717 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
3718 }
3719
8860020e
JB
3720 return 0;
3721}
3722
46c1dd0c
FF
3723static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3724 struct cfg80211_ap_settings *params)
3725{
3726 struct wireless_dev *wdev;
3727 bool ret = false;
3728
53873f13 3729 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
3730 if (wdev->iftype != NL80211_IFTYPE_AP &&
3731 wdev->iftype != NL80211_IFTYPE_P2P_GO)
3732 continue;
3733
683b6d3b 3734 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
3735 continue;
3736
683b6d3b 3737 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
3738 ret = true;
3739 break;
3740 }
3741
46c1dd0c
FF
3742 return ret;
3743}
3744
e39e5b5e
JM
3745static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
3746 enum nl80211_auth_type auth_type,
3747 enum nl80211_commands cmd)
3748{
3749 if (auth_type > NL80211_AUTHTYPE_MAX)
3750 return false;
3751
3752 switch (cmd) {
3753 case NL80211_CMD_AUTHENTICATE:
3754 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
3755 auth_type == NL80211_AUTHTYPE_SAE)
3756 return false;
3757 return true;
3758 case NL80211_CMD_CONNECT:
3759 case NL80211_CMD_START_AP:
3760 /* SAE not supported yet */
3761 if (auth_type == NL80211_AUTHTYPE_SAE)
3762 return false;
3763 return true;
3764 default:
3765 return false;
3766 }
3767}
3768
8860020e
JB
3769static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3770{
3771 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3772 struct net_device *dev = info->user_ptr[1];
3773 struct wireless_dev *wdev = dev->ieee80211_ptr;
3774 struct cfg80211_ap_settings params;
3775 int err;
3776
3777 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3778 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3779 return -EOPNOTSUPP;
3780
3781 if (!rdev->ops->start_ap)
3782 return -EOPNOTSUPP;
3783
3784 if (wdev->beacon_interval)
3785 return -EALREADY;
3786
3787 memset(&params, 0, sizeof(params));
3788
3789 /* these are required for START_AP */
3790 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
3791 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
3792 !info->attrs[NL80211_ATTR_BEACON_HEAD])
3793 return -EINVAL;
3794
a1193be8 3795 err = nl80211_parse_beacon(info->attrs, &params.beacon);
8860020e
JB
3796 if (err)
3797 return err;
3798
3799 params.beacon_interval =
3800 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3801 params.dtim_period =
3802 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
3803
3804 err = cfg80211_validate_beacon_int(rdev, params.beacon_interval);
3805 if (err)
3806 return err;
3807
3808 /*
3809 * In theory, some of these attributes should be required here
3810 * but since they were not used when the command was originally
3811 * added, keep them optional for old user space programs to let
3812 * them continue to work with drivers that do not need the
3813 * additional information -- drivers must check!
3814 */
3815 if (info->attrs[NL80211_ATTR_SSID]) {
3816 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3817 params.ssid_len =
3818 nla_len(info->attrs[NL80211_ATTR_SSID]);
3819 if (params.ssid_len == 0 ||
3820 params.ssid_len > IEEE80211_MAX_SSID_LEN)
3821 return -EINVAL;
3822 }
3823
3824 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
3825 params.hidden_ssid = nla_get_u32(
3826 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
3827 if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
3828 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
3829 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
3830 return -EINVAL;
3831 }
3832
3833 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
3834
3835 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
3836 params.auth_type = nla_get_u32(
3837 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
3838 if (!nl80211_valid_auth_type(rdev, params.auth_type,
3839 NL80211_CMD_START_AP))
8860020e
JB
3840 return -EINVAL;
3841 } else
3842 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
3843
3844 err = nl80211_crypto_settings(rdev, info, &params.crypto,
3845 NL80211_MAX_NR_CIPHER_SUITES);
3846 if (err)
3847 return err;
3848
1b658f11
VT
3849 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
3850 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
3851 return -EOPNOTSUPP;
3852 params.inactivity_timeout = nla_get_u16(
3853 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
3854 }
3855
53cabad7
JB
3856 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
3857 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3858 return -EINVAL;
3859 params.p2p_ctwindow =
3860 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
3861 if (params.p2p_ctwindow > 127)
3862 return -EINVAL;
3863 if (params.p2p_ctwindow != 0 &&
3864 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
3865 return -EINVAL;
3866 }
3867
3868 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
3869 u8 tmp;
3870
3871 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3872 return -EINVAL;
3873 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
3874 if (tmp > 1)
3875 return -EINVAL;
3876 params.p2p_opp_ps = tmp;
3877 if (params.p2p_opp_ps != 0 &&
3878 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
3879 return -EINVAL;
3880 }
3881
aa430da4 3882 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
3883 err = nl80211_parse_chandef(rdev, info, &params.chandef);
3884 if (err)
3885 return err;
3886 } else if (wdev->preset_chandef.chan) {
3887 params.chandef = wdev->preset_chandef;
46c1dd0c 3888 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
3889 return -EINVAL;
3890
923b352f
AN
3891 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
3892 wdev->iftype))
aa430da4
JB
3893 return -EINVAL;
3894
a7c7fbff
PK
3895 if (info->attrs[NL80211_ATTR_TX_RATES]) {
3896 err = nl80211_parse_tx_bitrate_mask(info, &params.beacon_rate);
3897 if (err)
3898 return err;
3899
8564e382
JB
3900 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
3901 &params.beacon_rate);
a7c7fbff
PK
3902 if (err)
3903 return err;
3904 }
3905
18998c38
EP
3906 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
3907 params.smps_mode =
3908 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
3909 switch (params.smps_mode) {
3910 case NL80211_SMPS_OFF:
3911 break;
3912 case NL80211_SMPS_STATIC:
3913 if (!(rdev->wiphy.features &
3914 NL80211_FEATURE_STATIC_SMPS))
3915 return -EINVAL;
3916 break;
3917 case NL80211_SMPS_DYNAMIC:
3918 if (!(rdev->wiphy.features &
3919 NL80211_FEATURE_DYNAMIC_SMPS))
3920 return -EINVAL;
3921 break;
3922 default:
3923 return -EINVAL;
3924 }
3925 } else {
3926 params.smps_mode = NL80211_SMPS_OFF;
3927 }
3928
6e8ef842
PK
3929 params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
3930 if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
3931 return -EOPNOTSUPP;
3932
4baf6bea
OO
3933 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
3934 params.acl = parse_acl_data(&rdev->wiphy, info);
3935 if (IS_ERR(params.acl))
3936 return PTR_ERR(params.acl);
3937 }
3938
c56589ed 3939 wdev_lock(wdev);
e35e4d28 3940 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 3941 if (!err) {
683b6d3b 3942 wdev->preset_chandef = params.chandef;
8860020e 3943 wdev->beacon_interval = params.beacon_interval;
9e0e2961 3944 wdev->chandef = params.chandef;
06e191e2
AQ
3945 wdev->ssid_len = params.ssid_len;
3946 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
46c1dd0c 3947 }
c56589ed 3948 wdev_unlock(wdev);
77765eaf
VT
3949
3950 kfree(params.acl);
3951
56d1893d 3952 return err;
ed1b6cc7
JB
3953}
3954
8860020e
JB
3955static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
3956{
3957 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3958 struct net_device *dev = info->user_ptr[1];
3959 struct wireless_dev *wdev = dev->ieee80211_ptr;
3960 struct cfg80211_beacon_data params;
3961 int err;
3962
3963 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3964 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3965 return -EOPNOTSUPP;
3966
3967 if (!rdev->ops->change_beacon)
3968 return -EOPNOTSUPP;
3969
3970 if (!wdev->beacon_interval)
3971 return -EINVAL;
3972
a1193be8 3973 err = nl80211_parse_beacon(info->attrs, &params);
8860020e
JB
3974 if (err)
3975 return err;
3976
c56589ed
SW
3977 wdev_lock(wdev);
3978 err = rdev_change_beacon(rdev, dev, &params);
3979 wdev_unlock(wdev);
3980
3981 return err;
8860020e
JB
3982}
3983
3984static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 3985{
4c476991
JB
3986 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3987 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 3988
7c8d5e03 3989 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
3990}
3991
5727ef1b
JB
3992static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
3993 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
3994 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
3995 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 3996 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 3997 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 3998 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
3999};
4000
eccb8e8f 4001static int parse_station_flags(struct genl_info *info,
bdd3ae3d 4002 enum nl80211_iftype iftype,
eccb8e8f 4003 struct station_parameters *params)
5727ef1b
JB
4004{
4005 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 4006 struct nlattr *nla;
5727ef1b
JB
4007 int flag;
4008
eccb8e8f
JB
4009 /*
4010 * Try parsing the new attribute first so userspace
4011 * can specify both for older kernels.
4012 */
4013 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
4014 if (nla) {
4015 struct nl80211_sta_flag_update *sta_flags;
4016
4017 sta_flags = nla_data(nla);
4018 params->sta_flags_mask = sta_flags->mask;
4019 params->sta_flags_set = sta_flags->set;
77ee7c89 4020 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
4021 if ((params->sta_flags_mask |
4022 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
4023 return -EINVAL;
4024 return 0;
4025 }
4026
4027 /* if present, parse the old attribute */
5727ef1b 4028
eccb8e8f 4029 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
4030 if (!nla)
4031 return 0;
4032
4033 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
4034 nla, sta_flags_policy))
4035 return -EINVAL;
4036
bdd3ae3d
JB
4037 /*
4038 * Only allow certain flags for interface types so that
4039 * other attributes are silently ignored. Remember that
4040 * this is backward compatibility code with old userspace
4041 * and shouldn't be hit in other cases anyway.
4042 */
4043 switch (iftype) {
4044 case NL80211_IFTYPE_AP:
4045 case NL80211_IFTYPE_AP_VLAN:
4046 case NL80211_IFTYPE_P2P_GO:
4047 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4048 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4049 BIT(NL80211_STA_FLAG_WME) |
4050 BIT(NL80211_STA_FLAG_MFP);
4051 break;
4052 case NL80211_IFTYPE_P2P_CLIENT:
4053 case NL80211_IFTYPE_STATION:
4054 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4055 BIT(NL80211_STA_FLAG_TDLS_PEER);
4056 break;
4057 case NL80211_IFTYPE_MESH_POINT:
4058 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4059 BIT(NL80211_STA_FLAG_MFP) |
4060 BIT(NL80211_STA_FLAG_AUTHORIZED);
4061 default:
4062 return -EINVAL;
4063 }
5727ef1b 4064
3383b5a6
JB
4065 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
4066 if (flags[flag]) {
eccb8e8f 4067 params->sta_flags_set |= (1<<flag);
5727ef1b 4068
3383b5a6
JB
4069 /* no longer support new API additions in old API */
4070 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
4071 return -EINVAL;
4072 }
4073 }
4074
5727ef1b
JB
4075 return 0;
4076}
4077
c8dcfd8a
FF
4078static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
4079 int attr)
4080{
4081 struct nlattr *rate;
8eb41c8d
VK
4082 u32 bitrate;
4083 u16 bitrate_compat;
b51f3bee 4084 enum nl80211_attrs rate_flg;
c8dcfd8a
FF
4085
4086 rate = nla_nest_start(msg, attr);
4087 if (!rate)
db9c64cf 4088 return false;
c8dcfd8a
FF
4089
4090 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
4091 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
4092 /* report 16-bit bitrate only if we can */
4093 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
4094 if (bitrate > 0 &&
4095 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
4096 return false;
4097 if (bitrate_compat > 0 &&
4098 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
4099 return false;
4100
b51f3bee
JB
4101 switch (info->bw) {
4102 case RATE_INFO_BW_5:
4103 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
4104 break;
4105 case RATE_INFO_BW_10:
4106 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
4107 break;
4108 default:
4109 WARN_ON(1);
4110 /* fall through */
4111 case RATE_INFO_BW_20:
4112 rate_flg = 0;
4113 break;
4114 case RATE_INFO_BW_40:
4115 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
4116 break;
4117 case RATE_INFO_BW_80:
4118 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
4119 break;
4120 case RATE_INFO_BW_160:
4121 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
4122 break;
4123 }
4124
4125 if (rate_flg && nla_put_flag(msg, rate_flg))
4126 return false;
4127
db9c64cf
JB
4128 if (info->flags & RATE_INFO_FLAGS_MCS) {
4129 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
4130 return false;
db9c64cf
JB
4131 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4132 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4133 return false;
4134 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
4135 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
4136 return false;
4137 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
4138 return false;
db9c64cf
JB
4139 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4140 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4141 return false;
4142 }
c8dcfd8a
FF
4143
4144 nla_nest_end(msg, rate);
4145 return true;
c8dcfd8a
FF
4146}
4147
119363c7
FF
4148static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
4149 int id)
4150{
4151 void *attr;
4152 int i = 0;
4153
4154 if (!mask)
4155 return true;
4156
4157 attr = nla_nest_start(msg, id);
4158 if (!attr)
4159 return false;
4160
4161 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
4162 if (!(mask & BIT(i)))
4163 continue;
4164
4165 if (nla_put_u8(msg, i, signal[i]))
4166 return false;
4167 }
4168
4169 nla_nest_end(msg, attr);
4170
4171 return true;
4172}
4173
cf5ead82
JB
4174static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
4175 u32 seq, int flags,
66266b3a
JL
4176 struct cfg80211_registered_device *rdev,
4177 struct net_device *dev,
98b62183 4178 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
4179{
4180 void *hdr;
f4263c98 4181 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 4182
cf5ead82 4183 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
fd5b74dc
JB
4184 if (!hdr)
4185 return -1;
4186
9360ffd1
DM
4187 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4188 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
4189 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
4190 goto nla_put_failure;
f5ea9120 4191
2ec600d6
LCC
4192 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
4193 if (!sinfoattr)
fd5b74dc 4194 goto nla_put_failure;
319090bf
JB
4195
4196#define PUT_SINFO(attr, memb, type) do { \
d686b920 4197 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
739960f1 4198 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
319090bf
JB
4199 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
4200 sinfo->memb)) \
4201 goto nla_put_failure; \
4202 } while (0)
d686b920
JB
4203#define PUT_SINFO_U64(attr, memb) do { \
4204 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
4205 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
4206 sinfo->memb, NL80211_STA_INFO_PAD)) \
4207 goto nla_put_failure; \
4208 } while (0)
319090bf
JB
4209
4210 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
4211 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
4212
4213 if (sinfo->filled & (BIT(NL80211_STA_INFO_RX_BYTES) |
4214 BIT(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 4215 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 4216 (u32)sinfo->rx_bytes))
9360ffd1 4217 goto nla_put_failure;
319090bf
JB
4218
4219 if (sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES) |
4220 BIT(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 4221 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
4222 (u32)sinfo->tx_bytes))
4223 goto nla_put_failure;
319090bf 4224
d686b920
JB
4225 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
4226 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
4227 PUT_SINFO(LLID, llid, u16);
4228 PUT_SINFO(PLID, plid, u16);
4229 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 4230 PUT_SINFO_U64(RX_DURATION, rx_duration);
319090bf 4231
66266b3a
JL
4232 switch (rdev->wiphy.signal_type) {
4233 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
4234 PUT_SINFO(SIGNAL, signal, u8);
4235 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
4236 break;
4237 default:
4238 break;
4239 }
319090bf 4240 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
4241 if (!nl80211_put_signal(msg, sinfo->chains,
4242 sinfo->chain_signal,
4243 NL80211_STA_INFO_CHAIN_SIGNAL))
4244 goto nla_put_failure;
4245 }
319090bf 4246 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
4247 if (!nl80211_put_signal(msg, sinfo->chains,
4248 sinfo->chain_signal_avg,
4249 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
4250 goto nla_put_failure;
4251 }
319090bf 4252 if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
4253 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
4254 NL80211_STA_INFO_TX_BITRATE))
4255 goto nla_put_failure;
4256 }
319090bf 4257 if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
4258 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
4259 NL80211_STA_INFO_RX_BITRATE))
420e7fab 4260 goto nla_put_failure;
420e7fab 4261 }
319090bf
JB
4262
4263 PUT_SINFO(RX_PACKETS, rx_packets, u32);
4264 PUT_SINFO(TX_PACKETS, tx_packets, u32);
4265 PUT_SINFO(TX_RETRIES, tx_retries, u32);
4266 PUT_SINFO(TX_FAILED, tx_failed, u32);
4267 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
4268 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
4269 PUT_SINFO(LOCAL_PM, local_pm, u32);
4270 PUT_SINFO(PEER_PM, peer_pm, u32);
4271 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
4272
4273 if (sinfo->filled & BIT(NL80211_STA_INFO_BSS_PARAM)) {
f4263c98
PS
4274 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
4275 if (!bss_param)
4276 goto nla_put_failure;
4277
9360ffd1
DM
4278 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
4279 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
4280 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
4281 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
4282 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
4283 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
4284 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
4285 sinfo->bss_param.dtim_period) ||
4286 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
4287 sinfo->bss_param.beacon_interval))
4288 goto nla_put_failure;
f4263c98
PS
4289
4290 nla_nest_end(msg, bss_param);
4291 }
319090bf 4292 if ((sinfo->filled & BIT(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
4293 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
4294 sizeof(struct nl80211_sta_flag_update),
4295 &sinfo->sta_flags))
4296 goto nla_put_failure;
319090bf 4297
d686b920
JB
4298 PUT_SINFO_U64(T_OFFSET, t_offset);
4299 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
4300 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 4301 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
319090bf
JB
4302
4303#undef PUT_SINFO
d686b920 4304#undef PUT_SINFO_U64
6de39808
JB
4305
4306 if (sinfo->filled & BIT(NL80211_STA_INFO_TID_STATS)) {
4307 struct nlattr *tidsattr;
4308 int tid;
4309
4310 tidsattr = nla_nest_start(msg, NL80211_STA_INFO_TID_STATS);
4311 if (!tidsattr)
4312 goto nla_put_failure;
4313
4314 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
4315 struct cfg80211_tid_stats *tidstats;
4316 struct nlattr *tidattr;
4317
4318 tidstats = &sinfo->pertid[tid];
4319
4320 if (!tidstats->filled)
4321 continue;
4322
4323 tidattr = nla_nest_start(msg, tid + 1);
4324 if (!tidattr)
4325 goto nla_put_failure;
4326
d686b920 4327#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 4328 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
4329 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
4330 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
4331 goto nla_put_failure; \
4332 } while (0)
4333
d686b920
JB
4334 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
4335 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
4336 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
4337 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 4338
d686b920 4339#undef PUT_TIDVAL_U64
6de39808
JB
4340 nla_nest_end(msg, tidattr);
4341 }
4342
4343 nla_nest_end(msg, tidsattr);
4344 }
4345
2ec600d6 4346 nla_nest_end(msg, sinfoattr);
fd5b74dc 4347
319090bf 4348 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
4349 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
4350 sinfo->assoc_req_ies))
4351 goto nla_put_failure;
50d3dfb7 4352
053c095a
JB
4353 genlmsg_end(msg, hdr);
4354 return 0;
fd5b74dc
JB
4355
4356 nla_put_failure:
bc3ed28c
TG
4357 genlmsg_cancel(msg, hdr);
4358 return -EMSGSIZE;
fd5b74dc
JB
4359}
4360
2ec600d6 4361static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 4362 struct netlink_callback *cb)
2ec600d6 4363{
2ec600d6 4364 struct station_info sinfo;
1b8ec87a 4365 struct cfg80211_registered_device *rdev;
97990a06 4366 struct wireless_dev *wdev;
2ec600d6 4367 u8 mac_addr[ETH_ALEN];
97990a06 4368 int sta_idx = cb->args[2];
2ec600d6 4369 int err;
2ec600d6 4370
1b8ec87a 4371 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
4372 if (err)
4373 return err;
bba95fef 4374
97990a06
JB
4375 if (!wdev->netdev) {
4376 err = -EINVAL;
4377 goto out_err;
4378 }
4379
1b8ec87a 4380 if (!rdev->ops->dump_station) {
eec60b03 4381 err = -EOPNOTSUPP;
bba95fef
JB
4382 goto out_err;
4383 }
4384
bba95fef 4385 while (1) {
f612cedf 4386 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 4387 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
e35e4d28 4388 mac_addr, &sinfo);
bba95fef
JB
4389 if (err == -ENOENT)
4390 break;
4391 if (err)
3b85875a 4392 goto out_err;
bba95fef 4393
cf5ead82 4394 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 4395 NETLINK_CB(cb->skb).portid,
bba95fef 4396 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 4397 rdev, wdev->netdev, mac_addr,
bba95fef
JB
4398 &sinfo) < 0)
4399 goto out;
4400
4401 sta_idx++;
4402 }
4403
bba95fef 4404 out:
97990a06 4405 cb->args[2] = sta_idx;
bba95fef 4406 err = skb->len;
bba95fef 4407 out_err:
1b8ec87a 4408 nl80211_finish_wdev_dump(rdev);
bba95fef
JB
4409
4410 return err;
2ec600d6 4411}
fd5b74dc 4412
5727ef1b
JB
4413static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
4414{
4c476991
JB
4415 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4416 struct net_device *dev = info->user_ptr[1];
2ec600d6 4417 struct station_info sinfo;
fd5b74dc
JB
4418 struct sk_buff *msg;
4419 u8 *mac_addr = NULL;
4c476991 4420 int err;
fd5b74dc 4421
2ec600d6 4422 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc
JB
4423
4424 if (!info->attrs[NL80211_ATTR_MAC])
4425 return -EINVAL;
4426
4427 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4428
4c476991
JB
4429 if (!rdev->ops->get_station)
4430 return -EOPNOTSUPP;
3b85875a 4431
e35e4d28 4432 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 4433 if (err)
4c476991 4434 return err;
2ec600d6 4435
fd2120ca 4436 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
fd5b74dc 4437 if (!msg)
4c476991 4438 return -ENOMEM;
fd5b74dc 4439
cf5ead82
JB
4440 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
4441 info->snd_portid, info->snd_seq, 0,
66266b3a 4442 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991
JB
4443 nlmsg_free(msg);
4444 return -ENOBUFS;
4445 }
3b85875a 4446
4c476991 4447 return genlmsg_reply(msg, info);
5727ef1b
JB
4448}
4449
77ee7c89
JB
4450int cfg80211_check_station_change(struct wiphy *wiphy,
4451 struct station_parameters *params,
4452 enum cfg80211_station_type statype)
4453{
e4208427
AB
4454 if (params->listen_interval != -1 &&
4455 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 4456 return -EINVAL;
e4208427 4457
17b94247
AB
4458 if (params->support_p2p_ps != -1 &&
4459 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
4460 return -EINVAL;
4461
c72e1140 4462 if (params->aid &&
e4208427
AB
4463 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
4464 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
4465 return -EINVAL;
4466
4467 /* When you run into this, adjust the code below for the new flag */
4468 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
4469
4470 switch (statype) {
eef941e6
TP
4471 case CFG80211_STA_MESH_PEER_KERNEL:
4472 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
4473 /*
4474 * No ignoring the TDLS flag here -- the userspace mesh
4475 * code doesn't have the bug of including TDLS in the
4476 * mask everywhere.
4477 */
4478 if (params->sta_flags_mask &
4479 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4480 BIT(NL80211_STA_FLAG_MFP) |
4481 BIT(NL80211_STA_FLAG_AUTHORIZED)))
4482 return -EINVAL;
4483 break;
4484 case CFG80211_STA_TDLS_PEER_SETUP:
4485 case CFG80211_STA_TDLS_PEER_ACTIVE:
4486 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
4487 return -EINVAL;
4488 /* ignore since it can't change */
4489 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
4490 break;
4491 default:
4492 /* disallow mesh-specific things */
4493 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
4494 return -EINVAL;
4495 if (params->local_pm)
4496 return -EINVAL;
4497 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
4498 return -EINVAL;
4499 }
4500
4501 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
4502 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
4503 /* TDLS can't be set, ... */
4504 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
4505 return -EINVAL;
4506 /*
4507 * ... but don't bother the driver with it. This works around
4508 * a hostapd/wpa_supplicant issue -- it always includes the
4509 * TLDS_PEER flag in the mask even for AP mode.
4510 */
4511 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
4512 }
4513
47edb11b
AB
4514 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
4515 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
4516 /* reject other things that can't change */
4517 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
4518 return -EINVAL;
4519 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
4520 return -EINVAL;
4521 if (params->supported_rates)
4522 return -EINVAL;
4523 if (params->ext_capab || params->ht_capa || params->vht_capa)
4524 return -EINVAL;
4525 }
4526
47edb11b
AB
4527 if (statype != CFG80211_STA_AP_CLIENT &&
4528 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
4529 if (params->vlan)
4530 return -EINVAL;
4531 }
4532
4533 switch (statype) {
4534 case CFG80211_STA_AP_MLME_CLIENT:
4535 /* Use this only for authorizing/unauthorizing a station */
4536 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4537 return -EOPNOTSUPP;
4538 break;
4539 case CFG80211_STA_AP_CLIENT:
47edb11b 4540 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
4541 /* accept only the listed bits */
4542 if (params->sta_flags_mask &
4543 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
4544 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4545 BIT(NL80211_STA_FLAG_ASSOCIATED) |
4546 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4547 BIT(NL80211_STA_FLAG_WME) |
4548 BIT(NL80211_STA_FLAG_MFP)))
4549 return -EINVAL;
4550
4551 /* but authenticated/associated only if driver handles it */
4552 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
4553 params->sta_flags_mask &
4554 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4555 BIT(NL80211_STA_FLAG_ASSOCIATED)))
4556 return -EINVAL;
4557 break;
4558 case CFG80211_STA_IBSS:
4559 case CFG80211_STA_AP_STA:
4560 /* reject any changes other than AUTHORIZED */
4561 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
4562 return -EINVAL;
4563 break;
4564 case CFG80211_STA_TDLS_PEER_SETUP:
4565 /* reject any changes other than AUTHORIZED or WME */
4566 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
4567 BIT(NL80211_STA_FLAG_WME)))
4568 return -EINVAL;
4569 /* force (at least) rates when authorizing */
4570 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
4571 !params->supported_rates)
4572 return -EINVAL;
4573 break;
4574 case CFG80211_STA_TDLS_PEER_ACTIVE:
4575 /* reject any changes */
4576 return -EINVAL;
eef941e6 4577 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
4578 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
4579 return -EINVAL;
4580 break;
eef941e6 4581 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
4582 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
4583 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
4584 return -EINVAL;
4585 break;
4586 }
4587
4588 return 0;
4589}
4590EXPORT_SYMBOL(cfg80211_check_station_change);
4591
5727ef1b 4592/*
c258d2de 4593 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 4594 */
80b99899
JB
4595static struct net_device *get_vlan(struct genl_info *info,
4596 struct cfg80211_registered_device *rdev)
5727ef1b 4597{
463d0183 4598 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
4599 struct net_device *v;
4600 int ret;
4601
4602 if (!vlanattr)
4603 return NULL;
4604
4605 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
4606 if (!v)
4607 return ERR_PTR(-ENODEV);
4608
4609 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
4610 ret = -EINVAL;
4611 goto error;
5727ef1b 4612 }
80b99899 4613
77ee7c89
JB
4614 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4615 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4616 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
4617 ret = -EINVAL;
4618 goto error;
4619 }
4620
80b99899
JB
4621 if (!netif_running(v)) {
4622 ret = -ENETDOWN;
4623 goto error;
4624 }
4625
4626 return v;
4627 error:
4628 dev_put(v);
4629 return ERR_PTR(ret);
5727ef1b
JB
4630}
4631
94e860f1
JB
4632static const struct nla_policy
4633nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
4634 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
4635 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
4636};
4637
ff276691
JB
4638static int nl80211_parse_sta_wme(struct genl_info *info,
4639 struct station_parameters *params)
df881293 4640{
df881293
JM
4641 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
4642 struct nlattr *nla;
4643 int err;
4644
df881293
JM
4645 /* parse WME attributes if present */
4646 if (!info->attrs[NL80211_ATTR_STA_WME])
4647 return 0;
4648
4649 nla = info->attrs[NL80211_ATTR_STA_WME];
4650 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
4651 nl80211_sta_wme_policy);
4652 if (err)
4653 return err;
4654
4655 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
4656 params->uapsd_queues = nla_get_u8(
4657 tb[NL80211_STA_WME_UAPSD_QUEUES]);
4658 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
4659 return -EINVAL;
4660
4661 if (tb[NL80211_STA_WME_MAX_SP])
4662 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
4663
4664 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
4665 return -EINVAL;
4666
4667 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
4668
4669 return 0;
4670}
4671
c01fc9ad
SD
4672static int nl80211_parse_sta_channel_info(struct genl_info *info,
4673 struct station_parameters *params)
4674{
4675 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
4676 params->supported_channels =
4677 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
4678 params->supported_channels_len =
4679 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
4680 /*
4681 * Need to include at least one (first channel, number of
4682 * channels) tuple for each subband, and must have proper
4683 * tuples for the rest of the data as well.
4684 */
4685 if (params->supported_channels_len < 2)
4686 return -EINVAL;
4687 if (params->supported_channels_len % 2)
4688 return -EINVAL;
4689 }
4690
4691 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
4692 params->supported_oper_classes =
4693 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
4694 params->supported_oper_classes_len =
4695 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
4696 /*
4697 * The value of the Length field of the Supported Operating
4698 * Classes element is between 2 and 253.
4699 */
4700 if (params->supported_oper_classes_len < 2 ||
4701 params->supported_oper_classes_len > 253)
4702 return -EINVAL;
4703 }
4704 return 0;
4705}
4706
ff276691
JB
4707static int nl80211_set_station_tdls(struct genl_info *info,
4708 struct station_parameters *params)
4709{
c01fc9ad 4710 int err;
ff276691 4711 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
4712 if (info->attrs[NL80211_ATTR_PEER_AID])
4713 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
4714 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
4715 params->ht_capa =
4716 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
4717 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
4718 params->vht_capa =
4719 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
4720
c01fc9ad
SD
4721 err = nl80211_parse_sta_channel_info(info, params);
4722 if (err)
4723 return err;
4724
ff276691
JB
4725 return nl80211_parse_sta_wme(info, params);
4726}
4727
5727ef1b
JB
4728static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
4729{
4c476991 4730 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 4731 struct net_device *dev = info->user_ptr[1];
5727ef1b 4732 struct station_parameters params;
77ee7c89
JB
4733 u8 *mac_addr;
4734 int err;
5727ef1b
JB
4735
4736 memset(&params, 0, sizeof(params));
4737
77ee7c89
JB
4738 if (!rdev->ops->change_station)
4739 return -EOPNOTSUPP;
4740
e4208427
AB
4741 /*
4742 * AID and listen_interval properties can be set only for unassociated
4743 * station. Include these parameters here and will check them in
4744 * cfg80211_check_station_change().
4745 */
a9bc31e4
AB
4746 if (info->attrs[NL80211_ATTR_STA_AID])
4747 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427
AB
4748
4749 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
4750 params.listen_interval =
4751 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
4752 else
4753 params.listen_interval = -1;
5727ef1b 4754
17b94247
AB
4755 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
4756 u8 tmp;
4757
4758 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
4759 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
4760 return -EINVAL;
4761
4762 params.support_p2p_ps = tmp;
4763 } else {
4764 params.support_p2p_ps = -1;
4765 }
4766
5727ef1b
JB
4767 if (!info->attrs[NL80211_ATTR_MAC])
4768 return -EINVAL;
4769
4770 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4771
4772 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
4773 params.supported_rates =
4774 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4775 params.supported_rates_len =
4776 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4777 }
4778
9d62a986
JM
4779 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
4780 params.capability =
4781 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
4782 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
4783 }
4784
4785 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
4786 params.ext_capab =
4787 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4788 params.ext_capab_len =
4789 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4790 }
4791
bdd3ae3d 4792 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
4793 return -EINVAL;
4794
f8bacc21 4795 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
2ec600d6 4796 params.plink_action =
f8bacc21
JB
4797 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
4798 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
4799 return -EINVAL;
4800 }
2ec600d6 4801
f8bacc21 4802 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 4803 params.plink_state =
f8bacc21
JB
4804 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
4805 if (params.plink_state >= NUM_NL80211_PLINK_STATES)
4806 return -EINVAL;
7d27a0ba
MH
4807 if (info->attrs[NL80211_ATTR_MESH_PEER_AID]) {
4808 params.peer_aid = nla_get_u16(
4809 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
4810 if (params.peer_aid > IEEE80211_MAX_AID)
4811 return -EINVAL;
4812 }
f8bacc21
JB
4813 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
4814 }
9c3990aa 4815
3b1c5a53
MP
4816 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) {
4817 enum nl80211_mesh_power_mode pm = nla_get_u32(
4818 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
4819
4820 if (pm <= NL80211_MESH_POWER_UNKNOWN ||
4821 pm > NL80211_MESH_POWER_MAX)
4822 return -EINVAL;
4823
4824 params.local_pm = pm;
4825 }
4826
77ee7c89
JB
4827 /* Include parameters for TDLS peer (will check later) */
4828 err = nl80211_set_station_tdls(info, &params);
4829 if (err)
4830 return err;
4831
4832 params.vlan = get_vlan(info, rdev);
4833 if (IS_ERR(params.vlan))
4834 return PTR_ERR(params.vlan);
4835
a97f4424
JB
4836 switch (dev->ieee80211_ptr->iftype) {
4837 case NL80211_IFTYPE_AP:
4838 case NL80211_IFTYPE_AP_VLAN:
074ac8df 4839 case NL80211_IFTYPE_P2P_GO:
074ac8df 4840 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 4841 case NL80211_IFTYPE_STATION:
267335d6 4842 case NL80211_IFTYPE_ADHOC:
a97f4424 4843 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
4844 break;
4845 default:
77ee7c89
JB
4846 err = -EOPNOTSUPP;
4847 goto out_put_vlan;
034d655e
JB
4848 }
4849
77ee7c89 4850 /* driver will call cfg80211_check_station_change() */
e35e4d28 4851 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 4852
77ee7c89 4853 out_put_vlan:
5727ef1b
JB
4854 if (params.vlan)
4855 dev_put(params.vlan);
3b85875a 4856
5727ef1b
JB
4857 return err;
4858}
4859
4860static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
4861{
4c476991 4862 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 4863 int err;
4c476991 4864 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
4865 struct station_parameters params;
4866 u8 *mac_addr = NULL;
bda95eb1
JB
4867 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4868 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
4869
4870 memset(&params, 0, sizeof(params));
4871
984c311b
JB
4872 if (!rdev->ops->add_station)
4873 return -EOPNOTSUPP;
4874
5727ef1b
JB
4875 if (!info->attrs[NL80211_ATTR_MAC])
4876 return -EINVAL;
4877
5727ef1b
JB
4878 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
4879 return -EINVAL;
4880
4881 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
4882 return -EINVAL;
4883
5e4b6f56
JM
4884 if (!info->attrs[NL80211_ATTR_STA_AID] &&
4885 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
4886 return -EINVAL;
4887
5727ef1b
JB
4888 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4889 params.supported_rates =
4890 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4891 params.supported_rates_len =
4892 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4893 params.listen_interval =
4894 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 4895
17b94247
AB
4896 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
4897 u8 tmp;
4898
4899 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
4900 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
4901 return -EINVAL;
4902
4903 params.support_p2p_ps = tmp;
4904 } else {
4905 /*
4906 * if not specified, assume it's supported for P2P GO interface,
4907 * and is NOT supported for AP interface
4908 */
4909 params.support_p2p_ps =
4910 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
4911 }
4912
3d124ea2 4913 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 4914 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
4915 else
4916 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
0e956c13
TLSC
4917 if (!params.aid || params.aid > IEEE80211_MAX_AID)
4918 return -EINVAL;
51b50fbe 4919
9d62a986
JM
4920 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
4921 params.capability =
4922 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
4923 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
4924 }
4925
4926 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
4927 params.ext_capab =
4928 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4929 params.ext_capab_len =
4930 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4931 }
4932
36aedc90
JM
4933 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
4934 params.ht_capa =
4935 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 4936
f461be3e
MP
4937 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
4938 params.vht_capa =
4939 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
4940
60f4a7b1
MK
4941 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
4942 params.opmode_notif_used = true;
4943 params.opmode_notif =
4944 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
4945 }
4946
f8bacc21 4947 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
96b78dff 4948 params.plink_action =
f8bacc21
JB
4949 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
4950 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
4951 return -EINVAL;
4952 }
96b78dff 4953
c01fc9ad
SD
4954 err = nl80211_parse_sta_channel_info(info, &params);
4955 if (err)
4956 return err;
4957
ff276691
JB
4958 err = nl80211_parse_sta_wme(info, &params);
4959 if (err)
4960 return err;
bdd90d5e 4961
bdd3ae3d 4962 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
4963 return -EINVAL;
4964
496fcc29
JB
4965 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
4966 * as userspace might just pass through the capabilities from the IEs
4967 * directly, rather than enforcing this restriction and returning an
4968 * error in this case.
4969 */
4970 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
4971 params.ht_capa = NULL;
4972 params.vht_capa = NULL;
4973 }
4974
77ee7c89
JB
4975 /* When you run into this, adjust the code below for the new flag */
4976 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
4977
bdd90d5e
JB
4978 switch (dev->ieee80211_ptr->iftype) {
4979 case NL80211_IFTYPE_AP:
4980 case NL80211_IFTYPE_AP_VLAN:
4981 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
4982 /* ignore WME attributes if iface/sta is not capable */
4983 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
4984 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
4985 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 4986
bdd90d5e 4987 /* TDLS peers cannot be added */
3d124ea2
JM
4988 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
4989 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 4990 return -EINVAL;
bdd90d5e
JB
4991 /* but don't bother the driver with it */
4992 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 4993
d582cffb
JB
4994 /* allow authenticated/associated only if driver handles it */
4995 if (!(rdev->wiphy.features &
4996 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 4997 params.sta_flags_mask & auth_assoc)
d582cffb
JB
4998 return -EINVAL;
4999
bda95eb1
JB
5000 /* Older userspace, or userspace wanting to be compatible with
5001 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
5002 * and assoc flags in the mask, but assumes the station will be
5003 * added as associated anyway since this was the required driver
5004 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
5005 * introduced.
5006 * In order to not bother drivers with this quirk in the API
5007 * set the flags in both the mask and set for new stations in
5008 * this case.
5009 */
5010 if (!(params.sta_flags_mask & auth_assoc)) {
5011 params.sta_flags_mask |= auth_assoc;
5012 params.sta_flags_set |= auth_assoc;
5013 }
5014
bdd90d5e
JB
5015 /* must be last in here for error handling */
5016 params.vlan = get_vlan(info, rdev);
5017 if (IS_ERR(params.vlan))
5018 return PTR_ERR(params.vlan);
5019 break;
5020 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
5021 /* ignore uAPSD data */
5022 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5023
d582cffb
JB
5024 /* associated is disallowed */
5025 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
5026 return -EINVAL;
bdd90d5e 5027 /* TDLS peers cannot be added */
3d124ea2
JM
5028 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5029 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
5030 return -EINVAL;
5031 break;
5032 case NL80211_IFTYPE_STATION:
93d08f0b 5033 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
5034 /* ignore uAPSD data */
5035 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5036
77ee7c89
JB
5037 /* these are disallowed */
5038 if (params.sta_flags_mask &
5039 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
5040 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 5041 return -EINVAL;
bdd90d5e
JB
5042 /* Only TDLS peers can be added */
5043 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
5044 return -EINVAL;
5045 /* Can only add if TDLS ... */
5046 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
5047 return -EOPNOTSUPP;
5048 /* ... with external setup is supported */
5049 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
5050 return -EOPNOTSUPP;
77ee7c89
JB
5051 /*
5052 * Older wpa_supplicant versions always mark the TDLS peer
5053 * as authorized, but it shouldn't yet be.
5054 */
5055 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
5056 break;
5057 default:
5058 return -EOPNOTSUPP;
c75786c9
EP
5059 }
5060
bdd90d5e 5061 /* be aware of params.vlan when changing code here */
5727ef1b 5062
e35e4d28 5063 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 5064
5727ef1b
JB
5065 if (params.vlan)
5066 dev_put(params.vlan);
5727ef1b
JB
5067 return err;
5068}
5069
5070static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
5071{
4c476991
JB
5072 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5073 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
5074 struct station_del_parameters params;
5075
5076 memset(&params, 0, sizeof(params));
5727ef1b
JB
5077
5078 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 5079 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 5080
e80cf853 5081 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
d5d9de02 5082 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
074ac8df 5083 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
5084 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5085 return -EINVAL;
5727ef1b 5086
4c476991
JB
5087 if (!rdev->ops->del_station)
5088 return -EOPNOTSUPP;
3b85875a 5089
98856866
JM
5090 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
5091 params.subtype =
5092 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
5093 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
5094 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
5095 return -EINVAL;
5096 } else {
5097 /* Default to Deauthentication frame */
5098 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
5099 }
5100
5101 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
5102 params.reason_code =
5103 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
5104 if (params.reason_code == 0)
5105 return -EINVAL; /* 0 is reserved */
5106 } else {
5107 /* Default to reason code 2 */
5108 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
5109 }
5110
89c771e5 5111 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
5112}
5113
15e47304 5114static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
5115 int flags, struct net_device *dev,
5116 u8 *dst, u8 *next_hop,
5117 struct mpath_info *pinfo)
5118{
5119 void *hdr;
5120 struct nlattr *pinfoattr;
5121
1ef4c850 5122 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
5123 if (!hdr)
5124 return -1;
5125
9360ffd1
DM
5126 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5127 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
5128 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
5129 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
5130 goto nla_put_failure;
f5ea9120 5131
2ec600d6
LCC
5132 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
5133 if (!pinfoattr)
5134 goto nla_put_failure;
9360ffd1
DM
5135 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
5136 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
5137 pinfo->frame_qlen))
5138 goto nla_put_failure;
5139 if (((pinfo->filled & MPATH_INFO_SN) &&
5140 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
5141 ((pinfo->filled & MPATH_INFO_METRIC) &&
5142 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
5143 pinfo->metric)) ||
5144 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
5145 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
5146 pinfo->exptime)) ||
5147 ((pinfo->filled & MPATH_INFO_FLAGS) &&
5148 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
5149 pinfo->flags)) ||
5150 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
5151 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
5152 pinfo->discovery_timeout)) ||
5153 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
5154 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
5155 pinfo->discovery_retries)))
5156 goto nla_put_failure;
2ec600d6
LCC
5157
5158 nla_nest_end(msg, pinfoattr);
5159
053c095a
JB
5160 genlmsg_end(msg, hdr);
5161 return 0;
2ec600d6
LCC
5162
5163 nla_put_failure:
bc3ed28c
TG
5164 genlmsg_cancel(msg, hdr);
5165 return -EMSGSIZE;
2ec600d6
LCC
5166}
5167
5168static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 5169 struct netlink_callback *cb)
2ec600d6 5170{
2ec600d6 5171 struct mpath_info pinfo;
1b8ec87a 5172 struct cfg80211_registered_device *rdev;
97990a06 5173 struct wireless_dev *wdev;
2ec600d6
LCC
5174 u8 dst[ETH_ALEN];
5175 u8 next_hop[ETH_ALEN];
97990a06 5176 int path_idx = cb->args[2];
2ec600d6 5177 int err;
2ec600d6 5178
1b8ec87a 5179 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
5180 if (err)
5181 return err;
bba95fef 5182
1b8ec87a 5183 if (!rdev->ops->dump_mpath) {
eec60b03 5184 err = -EOPNOTSUPP;
bba95fef
JB
5185 goto out_err;
5186 }
5187
97990a06 5188 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 5189 err = -EOPNOTSUPP;
0448b5fc 5190 goto out_err;
eec60b03
JM
5191 }
5192
bba95fef 5193 while (1) {
1b8ec87a 5194 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 5195 next_hop, &pinfo);
bba95fef 5196 if (err == -ENOENT)
2ec600d6 5197 break;
bba95fef 5198 if (err)
3b85875a 5199 goto out_err;
2ec600d6 5200
15e47304 5201 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 5202 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 5203 wdev->netdev, dst, next_hop,
bba95fef
JB
5204 &pinfo) < 0)
5205 goto out;
2ec600d6 5206
bba95fef 5207 path_idx++;
2ec600d6 5208 }
2ec600d6 5209
bba95fef 5210 out:
97990a06 5211 cb->args[2] = path_idx;
bba95fef 5212 err = skb->len;
bba95fef 5213 out_err:
1b8ec87a 5214 nl80211_finish_wdev_dump(rdev);
bba95fef 5215 return err;
2ec600d6
LCC
5216}
5217
5218static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
5219{
4c476991 5220 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 5221 int err;
4c476991 5222 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5223 struct mpath_info pinfo;
5224 struct sk_buff *msg;
5225 u8 *dst = NULL;
5226 u8 next_hop[ETH_ALEN];
5227
5228 memset(&pinfo, 0, sizeof(pinfo));
5229
5230 if (!info->attrs[NL80211_ATTR_MAC])
5231 return -EINVAL;
5232
5233 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5234
4c476991
JB
5235 if (!rdev->ops->get_mpath)
5236 return -EOPNOTSUPP;
2ec600d6 5237
4c476991
JB
5238 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5239 return -EOPNOTSUPP;
eec60b03 5240
e35e4d28 5241 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 5242 if (err)
4c476991 5243 return err;
2ec600d6 5244
fd2120ca 5245 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 5246 if (!msg)
4c476991 5247 return -ENOMEM;
2ec600d6 5248
15e47304 5249 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
5250 dev, dst, next_hop, &pinfo) < 0) {
5251 nlmsg_free(msg);
5252 return -ENOBUFS;
5253 }
3b85875a 5254
4c476991 5255 return genlmsg_reply(msg, info);
2ec600d6
LCC
5256}
5257
5258static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
5259{
4c476991
JB
5260 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5261 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5262 u8 *dst = NULL;
5263 u8 *next_hop = NULL;
5264
5265 if (!info->attrs[NL80211_ATTR_MAC])
5266 return -EINVAL;
5267
5268 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5269 return -EINVAL;
5270
5271 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5272 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5273
4c476991
JB
5274 if (!rdev->ops->change_mpath)
5275 return -EOPNOTSUPP;
35a8efe1 5276
4c476991
JB
5277 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5278 return -EOPNOTSUPP;
2ec600d6 5279
e35e4d28 5280 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 5281}
4c476991 5282
2ec600d6
LCC
5283static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
5284{
4c476991
JB
5285 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5286 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5287 u8 *dst = NULL;
5288 u8 *next_hop = NULL;
5289
5290 if (!info->attrs[NL80211_ATTR_MAC])
5291 return -EINVAL;
5292
5293 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5294 return -EINVAL;
5295
5296 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5297 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5298
4c476991
JB
5299 if (!rdev->ops->add_mpath)
5300 return -EOPNOTSUPP;
35a8efe1 5301
4c476991
JB
5302 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5303 return -EOPNOTSUPP;
2ec600d6 5304
e35e4d28 5305 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
5306}
5307
5308static int nl80211_del_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
5314 if (info->attrs[NL80211_ATTR_MAC])
5315 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5316
4c476991
JB
5317 if (!rdev->ops->del_mpath)
5318 return -EOPNOTSUPP;
3b85875a 5319
e35e4d28 5320 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
5321}
5322
66be7d2b
HR
5323static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
5324{
5325 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5326 int err;
5327 struct net_device *dev = info->user_ptr[1];
5328 struct mpath_info pinfo;
5329 struct sk_buff *msg;
5330 u8 *dst = NULL;
5331 u8 mpp[ETH_ALEN];
5332
5333 memset(&pinfo, 0, sizeof(pinfo));
5334
5335 if (!info->attrs[NL80211_ATTR_MAC])
5336 return -EINVAL;
5337
5338 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5339
5340 if (!rdev->ops->get_mpp)
5341 return -EOPNOTSUPP;
5342
5343 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5344 return -EOPNOTSUPP;
5345
5346 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
5347 if (err)
5348 return err;
5349
5350 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5351 if (!msg)
5352 return -ENOMEM;
5353
5354 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
5355 dev, dst, mpp, &pinfo) < 0) {
5356 nlmsg_free(msg);
5357 return -ENOBUFS;
5358 }
5359
5360 return genlmsg_reply(msg, info);
5361}
5362
5363static int nl80211_dump_mpp(struct sk_buff *skb,
5364 struct netlink_callback *cb)
5365{
5366 struct mpath_info pinfo;
5367 struct cfg80211_registered_device *rdev;
5368 struct wireless_dev *wdev;
5369 u8 dst[ETH_ALEN];
5370 u8 mpp[ETH_ALEN];
5371 int path_idx = cb->args[2];
5372 int err;
5373
5374 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
5375 if (err)
5376 return err;
5377
5378 if (!rdev->ops->dump_mpp) {
5379 err = -EOPNOTSUPP;
5380 goto out_err;
5381 }
5382
5383 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
5384 err = -EOPNOTSUPP;
5385 goto out_err;
5386 }
5387
5388 while (1) {
5389 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
5390 mpp, &pinfo);
5391 if (err == -ENOENT)
5392 break;
5393 if (err)
5394 goto out_err;
5395
5396 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
5397 cb->nlh->nlmsg_seq, NLM_F_MULTI,
5398 wdev->netdev, dst, mpp,
5399 &pinfo) < 0)
5400 goto out;
5401
5402 path_idx++;
5403 }
5404
5405 out:
5406 cb->args[2] = path_idx;
5407 err = skb->len;
5408 out_err:
5409 nl80211_finish_wdev_dump(rdev);
5410 return err;
5411}
5412
9f1ba906
JM
5413static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
5414{
4c476991
JB
5415 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5416 struct net_device *dev = info->user_ptr[1];
c56589ed 5417 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 5418 struct bss_parameters params;
c56589ed 5419 int err;
9f1ba906
JM
5420
5421 memset(&params, 0, sizeof(params));
5422 /* default to not changing parameters */
5423 params.use_cts_prot = -1;
5424 params.use_short_preamble = -1;
5425 params.use_short_slot_time = -1;
fd8aaaf3 5426 params.ap_isolate = -1;
50b12f59 5427 params.ht_opmode = -1;
53cabad7
JB
5428 params.p2p_ctwindow = -1;
5429 params.p2p_opp_ps = -1;
9f1ba906
JM
5430
5431 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
5432 params.use_cts_prot =
5433 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
5434 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
5435 params.use_short_preamble =
5436 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
5437 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
5438 params.use_short_slot_time =
5439 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
5440 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
5441 params.basic_rates =
5442 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5443 params.basic_rates_len =
5444 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5445 }
fd8aaaf3
FF
5446 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
5447 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
5448 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
5449 params.ht_opmode =
5450 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 5451
53cabad7
JB
5452 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
5453 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5454 return -EINVAL;
5455 params.p2p_ctwindow =
5456 nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
5457 if (params.p2p_ctwindow < 0)
5458 return -EINVAL;
5459 if (params.p2p_ctwindow != 0 &&
5460 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
5461 return -EINVAL;
5462 }
5463
5464 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
5465 u8 tmp;
5466
5467 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5468 return -EINVAL;
5469 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
5470 if (tmp > 1)
5471 return -EINVAL;
5472 params.p2p_opp_ps = tmp;
5473 if (params.p2p_opp_ps &&
5474 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
5475 return -EINVAL;
5476 }
5477
4c476991
JB
5478 if (!rdev->ops->change_bss)
5479 return -EOPNOTSUPP;
9f1ba906 5480
074ac8df 5481 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
5482 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5483 return -EOPNOTSUPP;
3b85875a 5484
c56589ed
SW
5485 wdev_lock(wdev);
5486 err = rdev_change_bss(rdev, dev, &params);
5487 wdev_unlock(wdev);
5488
5489 return err;
9f1ba906
JM
5490}
5491
b2e1b302
LR
5492static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
5493{
b2e1b302 5494 char *data = NULL;
05050753 5495 bool is_indoor;
57b5ce07 5496 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
5497 u32 owner_nlportid;
5498
80778f18
LR
5499 /*
5500 * You should only get this when cfg80211 hasn't yet initialized
5501 * completely when built-in to the kernel right between the time
5502 * window between nl80211_init() and regulatory_init(), if that is
5503 * even possible.
5504 */
458f4f9e 5505 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 5506 return -EINPROGRESS;
80778f18 5507
57b5ce07
LR
5508 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
5509 user_reg_hint_type =
5510 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
5511 else
5512 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
5513
5514 switch (user_reg_hint_type) {
5515 case NL80211_USER_REG_HINT_USER:
5516 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
5517 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
5518 return -EINVAL;
5519
5520 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
5521 return regulatory_hint_user(data, user_reg_hint_type);
5522 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
5523 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
5524 owner_nlportid = info->snd_portid;
5525 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
5526 } else {
5527 owner_nlportid = 0;
5528 is_indoor = true;
5529 }
5530
5531 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
5532 default:
5533 return -EINVAL;
5534 }
b2e1b302
LR
5535}
5536
24bdd9f4 5537static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 5538 struct genl_info *info)
93da9cc1 5539{
4c476991 5540 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 5541 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
5542 struct wireless_dev *wdev = dev->ieee80211_ptr;
5543 struct mesh_config cur_params;
5544 int err = 0;
93da9cc1 5545 void *hdr;
5546 struct nlattr *pinfoattr;
5547 struct sk_buff *msg;
5548
29cbe68c
JB
5549 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
5550 return -EOPNOTSUPP;
5551
24bdd9f4 5552 if (!rdev->ops->get_mesh_config)
4c476991 5553 return -EOPNOTSUPP;
f3f92586 5554
29cbe68c
JB
5555 wdev_lock(wdev);
5556 /* If not connected, get default parameters */
5557 if (!wdev->mesh_id_len)
5558 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
5559 else
e35e4d28 5560 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
5561 wdev_unlock(wdev);
5562
93da9cc1 5563 if (err)
4c476991 5564 return err;
93da9cc1 5565
5566 /* Draw up a netlink message to send back */
fd2120ca 5567 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
5568 if (!msg)
5569 return -ENOMEM;
15e47304 5570 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 5571 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 5572 if (!hdr)
efe1cf0c 5573 goto out;
24bdd9f4 5574 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 5575 if (!pinfoattr)
5576 goto nla_put_failure;
9360ffd1
DM
5577 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5578 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
5579 cur_params.dot11MeshRetryTimeout) ||
5580 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
5581 cur_params.dot11MeshConfirmTimeout) ||
5582 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
5583 cur_params.dot11MeshHoldingTimeout) ||
5584 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
5585 cur_params.dot11MeshMaxPeerLinks) ||
5586 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
5587 cur_params.dot11MeshMaxRetries) ||
5588 nla_put_u8(msg, NL80211_MESHCONF_TTL,
5589 cur_params.dot11MeshTTL) ||
5590 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
5591 cur_params.element_ttl) ||
5592 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
5593 cur_params.auto_open_plinks) ||
7eab0f64
JL
5594 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
5595 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
5596 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
5597 cur_params.dot11MeshHWMPmaxPREQretries) ||
5598 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
5599 cur_params.path_refresh_time) ||
5600 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
5601 cur_params.min_discovery_timeout) ||
5602 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
5603 cur_params.dot11MeshHWMPactivePathTimeout) ||
5604 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
5605 cur_params.dot11MeshHWMPpreqMinInterval) ||
5606 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
5607 cur_params.dot11MeshHWMPperrMinInterval) ||
5608 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
5609 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
5610 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
5611 cur_params.dot11MeshHWMPRootMode) ||
5612 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
5613 cur_params.dot11MeshHWMPRannInterval) ||
5614 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
5615 cur_params.dot11MeshGateAnnouncementProtocol) ||
5616 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
5617 cur_params.dot11MeshForwarding) ||
5618 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
5619 cur_params.rssi_threshold) ||
5620 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
5621 cur_params.ht_opmode) ||
5622 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
5623 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
5624 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
5625 cur_params.dot11MeshHWMProotInterval) ||
5626 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
5627 cur_params.dot11MeshHWMPconfirmationInterval) ||
5628 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
5629 cur_params.power_mode) ||
5630 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
5631 cur_params.dot11MeshAwakeWindowDuration) ||
5632 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
5633 cur_params.plink_timeout))
9360ffd1 5634 goto nla_put_failure;
93da9cc1 5635 nla_nest_end(msg, pinfoattr);
5636 genlmsg_end(msg, hdr);
4c476991 5637 return genlmsg_reply(msg, info);
93da9cc1 5638
3b85875a 5639 nla_put_failure:
93da9cc1 5640 genlmsg_cancel(msg, hdr);
efe1cf0c 5641 out:
d080e275 5642 nlmsg_free(msg);
4c476991 5643 return -ENOBUFS;
93da9cc1 5644}
5645
b54452b0 5646static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
93da9cc1 5647 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
5648 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
5649 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
5650 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
5651 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
5652 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
45904f21 5653 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
93da9cc1 5654 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
d299a1f2 5655 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
93da9cc1 5656 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
5657 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
5658 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
5659 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
5660 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
dca7e943 5661 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 },
93da9cc1 5662 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
699403db 5663 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
0507e159 5664 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
16dd7267 5665 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
94f90656 5666 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
a4f606ea
CYY
5667 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
5668 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6
CYY
5669 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
5670 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
728b19e5 5671 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
3b1c5a53
MP
5672 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 },
5673 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 5674 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
93da9cc1 5675};
5676
c80d545d
JC
5677static const struct nla_policy
5678 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 5679 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
5680 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
5681 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 5682 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 5683 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 5684 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
581a8b0f 5685 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
a4f606ea 5686 .len = IEEE80211_MAX_DATA_LEN },
b130e5ce 5687 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
5688};
5689
f151d9db
AB
5690static int nl80211_check_bool(const struct nlattr *nla, u8 min, u8 max, bool *out)
5691{
5692 u8 val = nla_get_u8(nla);
5693 if (val < min || val > max)
5694 return -EINVAL;
5695 *out = val;
5696 return 0;
5697}
5698
5699static int nl80211_check_u8(const struct nlattr *nla, u8 min, u8 max, u8 *out)
5700{
5701 u8 val = nla_get_u8(nla);
5702 if (val < min || val > max)
5703 return -EINVAL;
5704 *out = val;
5705 return 0;
5706}
5707
5708static int nl80211_check_u16(const struct nlattr *nla, u16 min, u16 max, u16 *out)
5709{
5710 u16 val = nla_get_u16(nla);
5711 if (val < min || val > max)
5712 return -EINVAL;
5713 *out = val;
5714 return 0;
5715}
5716
5717static int nl80211_check_u32(const struct nlattr *nla, u32 min, u32 max, u32 *out)
5718{
5719 u32 val = nla_get_u32(nla);
5720 if (val < min || val > max)
5721 return -EINVAL;
5722 *out = val;
5723 return 0;
5724}
5725
5726static int nl80211_check_s32(const struct nlattr *nla, s32 min, s32 max, s32 *out)
5727{
5728 s32 val = nla_get_s32(nla);
5729 if (val < min || val > max)
5730 return -EINVAL;
5731 *out = val;
5732 return 0;
5733}
5734
ff9a71af
JB
5735static int nl80211_check_power_mode(const struct nlattr *nla,
5736 enum nl80211_mesh_power_mode min,
5737 enum nl80211_mesh_power_mode max,
5738 enum nl80211_mesh_power_mode *out)
5739{
5740 u32 val = nla_get_u32(nla);
5741 if (val < min || val > max)
5742 return -EINVAL;
5743 *out = val;
5744 return 0;
5745}
5746
24bdd9f4 5747static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
5748 struct mesh_config *cfg,
5749 u32 *mask_out)
93da9cc1 5750{
93da9cc1 5751 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 5752 u32 mask = 0;
9757235f 5753 u16 ht_opmode;
93da9cc1 5754
ea54fba2
MP
5755#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \
5756do { \
5757 if (tb[attr]) { \
f151d9db 5758 if (fn(tb[attr], min, max, &cfg->param)) \
ea54fba2 5759 return -EINVAL; \
ea54fba2
MP
5760 mask |= (1 << (attr - 1)); \
5761 } \
5762} while (0)
bd90fdcc 5763
24bdd9f4 5764 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 5765 return -EINVAL;
5766 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
24bdd9f4 5767 info->attrs[NL80211_ATTR_MESH_CONFIG],
bd90fdcc 5768 nl80211_meshconf_params_policy))
93da9cc1 5769 return -EINVAL;
5770
93da9cc1 5771 /* This makes sure that there aren't more than 32 mesh config
5772 * parameters (otherwise our bitfield scheme would not work.) */
5773 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
5774
5775 /* Fill in the params struct */
ea54fba2 5776 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255,
a4f606ea 5777 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
f151d9db 5778 nl80211_check_u16);
ea54fba2 5779 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255,
a4f606ea 5780 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
f151d9db 5781 nl80211_check_u16);
ea54fba2 5782 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255,
a4f606ea 5783 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
f151d9db 5784 nl80211_check_u16);
ea54fba2 5785 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255,
a4f606ea 5786 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
f151d9db 5787 nl80211_check_u16);
ea54fba2 5788 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16,
a4f606ea 5789 mask, NL80211_MESHCONF_MAX_RETRIES,
f151d9db 5790 nl80211_check_u8);
ea54fba2 5791 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255,
f151d9db 5792 mask, NL80211_MESHCONF_TTL, nl80211_check_u8);
ea54fba2 5793 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255,
a4f606ea 5794 mask, NL80211_MESHCONF_ELEMENT_TTL,
f151d9db 5795 nl80211_check_u8);
ea54fba2 5796 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1,
a4f606ea 5797 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
f151d9db 5798 nl80211_check_bool);
ea54fba2
MP
5799 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
5800 1, 255, mask,
a4f606ea 5801 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
f151d9db 5802 nl80211_check_u32);
ea54fba2 5803 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255,
a4f606ea 5804 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
f151d9db 5805 nl80211_check_u8);
ea54fba2 5806 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535,
a4f606ea 5807 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
f151d9db 5808 nl80211_check_u32);
ea54fba2 5809 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535,
a4f606ea 5810 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
f151d9db 5811 nl80211_check_u16);
ea54fba2
MP
5812 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
5813 1, 65535, mask,
a4f606ea 5814 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
f151d9db 5815 nl80211_check_u32);
93da9cc1 5816 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
ea54fba2
MP
5817 1, 65535, mask,
5818 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
f151d9db 5819 nl80211_check_u16);
dca7e943 5820 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
ea54fba2
MP
5821 1, 65535, mask,
5822 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
f151d9db 5823 nl80211_check_u16);
93da9cc1 5824 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
5825 dot11MeshHWMPnetDiameterTraversalTime,
5826 1, 65535, mask,
a4f606ea 5827 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
f151d9db 5828 nl80211_check_u16);
ea54fba2
MP
5829 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4,
5830 mask, NL80211_MESHCONF_HWMP_ROOTMODE,
f151d9db 5831 nl80211_check_u8);
ea54fba2
MP
5832 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535,
5833 mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
f151d9db 5834 nl80211_check_u16);
63c5723b 5835 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
5836 dot11MeshGateAnnouncementProtocol, 0, 1,
5837 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
f151d9db 5838 nl80211_check_bool);
ea54fba2 5839 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1,
a4f606ea 5840 mask, NL80211_MESHCONF_FORWARDING,
f151d9db 5841 nl80211_check_bool);
83374fe9 5842 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
a4f606ea 5843 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
f151d9db 5844 nl80211_check_s32);
9757235f
MH
5845 /*
5846 * Check HT operation mode based on
5847 * IEEE 802.11 2012 8.4.2.59 HT Operation element.
5848 */
5849 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
5850 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
5851
5852 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
5853 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
5854 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
5855 return -EINVAL;
5856
5857 if ((ht_opmode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) &&
5858 (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
5859 return -EINVAL;
5860
5861 switch (ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION) {
5862 case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
5863 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
5864 if (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)
5865 return -EINVAL;
5866 break;
5867 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
5868 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
5869 if (!(ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
5870 return -EINVAL;
5871 break;
5872 }
5873 cfg->ht_opmode = ht_opmode;
5874 }
ac1073a6 5875 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
ea54fba2 5876 1, 65535, mask,
ac1073a6 5877 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
f151d9db 5878 nl80211_check_u32);
ea54fba2 5879 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535,
ac1073a6 5880 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
f151d9db 5881 nl80211_check_u16);
728b19e5 5882 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
5883 dot11MeshHWMPconfirmationInterval,
5884 1, 65535, mask,
728b19e5 5885 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
f151d9db 5886 nl80211_check_u16);
3b1c5a53
MP
5887 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode,
5888 NL80211_MESH_POWER_ACTIVE,
5889 NL80211_MESH_POWER_MAX,
5890 mask, NL80211_MESHCONF_POWER_MODE,
ff9a71af 5891 nl80211_check_power_mode);
3b1c5a53
MP
5892 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration,
5893 0, 65535, mask,
f151d9db 5894 NL80211_MESHCONF_AWAKE_WINDOW, nl80211_check_u16);
31f909a2 5895 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 0, 0xffffffff,
8e7c0538 5896 mask, NL80211_MESHCONF_PLINK_TIMEOUT,
f151d9db 5897 nl80211_check_u32);
bd90fdcc
JB
5898 if (mask_out)
5899 *mask_out = mask;
c80d545d 5900
bd90fdcc
JB
5901 return 0;
5902
5903#undef FILL_IN_MESH_PARAM_IF_SET
5904}
5905
c80d545d
JC
5906static int nl80211_parse_mesh_setup(struct genl_info *info,
5907 struct mesh_setup *setup)
5908{
bb2798d4 5909 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
5910 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
5911
5912 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
5913 return -EINVAL;
5914 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
5915 info->attrs[NL80211_ATTR_MESH_SETUP],
5916 nl80211_mesh_setup_params_policy))
5917 return -EINVAL;
5918
d299a1f2
JC
5919 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
5920 setup->sync_method =
5921 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
5922 IEEE80211_SYNC_METHOD_VENDOR :
5923 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
5924
c80d545d
JC
5925 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
5926 setup->path_sel_proto =
5927 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
5928 IEEE80211_PATH_PROTOCOL_VENDOR :
5929 IEEE80211_PATH_PROTOCOL_HWMP;
5930
5931 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
5932 setup->path_metric =
5933 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
5934 IEEE80211_PATH_METRIC_VENDOR :
5935 IEEE80211_PATH_METRIC_AIRTIME;
5936
581a8b0f 5937 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 5938 struct nlattr *ieattr =
581a8b0f 5939 tb[NL80211_MESH_SETUP_IE];
c80d545d
JC
5940 if (!is_valid_ie_attr(ieattr))
5941 return -EINVAL;
581a8b0f
JC
5942 setup->ie = nla_data(ieattr);
5943 setup->ie_len = nla_len(ieattr);
c80d545d 5944 }
bb2798d4
TP
5945 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
5946 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
5947 return -EINVAL;
5948 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
5949 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
5950 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
5951 if (setup->is_secure)
5952 setup->user_mpm = true;
c80d545d 5953
6e16d90b
CT
5954 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
5955 if (!setup->user_mpm)
5956 return -EINVAL;
5957 setup->auth_id =
5958 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
5959 }
5960
c80d545d
JC
5961 return 0;
5962}
5963
24bdd9f4 5964static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 5965 struct genl_info *info)
bd90fdcc
JB
5966{
5967 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5968 struct net_device *dev = info->user_ptr[1];
29cbe68c 5969 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
5970 struct mesh_config cfg;
5971 u32 mask;
5972 int err;
5973
29cbe68c
JB
5974 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
5975 return -EOPNOTSUPP;
5976
24bdd9f4 5977 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
5978 return -EOPNOTSUPP;
5979
24bdd9f4 5980 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
5981 if (err)
5982 return err;
5983
29cbe68c
JB
5984 wdev_lock(wdev);
5985 if (!wdev->mesh_id_len)
5986 err = -ENOLINK;
5987
5988 if (!err)
e35e4d28 5989 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
5990
5991 wdev_unlock(wdev);
5992
5993 return err;
93da9cc1 5994}
5995
ad30ca2c
AN
5996static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
5997 struct sk_buff *msg)
f130347c 5998{
f130347c
LR
5999 struct nlattr *nl_reg_rules;
6000 unsigned int i;
f130347c 6001
458f4f9e
JB
6002 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
6003 (regdom->dfs_region &&
6004 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 6005 goto nla_put_failure;
458f4f9e 6006
f130347c
LR
6007 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
6008 if (!nl_reg_rules)
ad30ca2c 6009 goto nla_put_failure;
f130347c 6010
458f4f9e 6011 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
6012 struct nlattr *nl_reg_rule;
6013 const struct ieee80211_reg_rule *reg_rule;
6014 const struct ieee80211_freq_range *freq_range;
6015 const struct ieee80211_power_rule *power_rule;
97524820 6016 unsigned int max_bandwidth_khz;
f130347c 6017
458f4f9e 6018 reg_rule = &regdom->reg_rules[i];
f130347c
LR
6019 freq_range = &reg_rule->freq_range;
6020 power_rule = &reg_rule->power_rule;
6021
6022 nl_reg_rule = nla_nest_start(msg, i);
6023 if (!nl_reg_rule)
ad30ca2c 6024 goto nla_put_failure;
f130347c 6025
97524820
JD
6026 max_bandwidth_khz = freq_range->max_bandwidth_khz;
6027 if (!max_bandwidth_khz)
6028 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
6029 reg_rule);
6030
9360ffd1
DM
6031 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
6032 reg_rule->flags) ||
6033 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
6034 freq_range->start_freq_khz) ||
6035 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
6036 freq_range->end_freq_khz) ||
6037 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 6038 max_bandwidth_khz) ||
9360ffd1
DM
6039 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
6040 power_rule->max_antenna_gain) ||
6041 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
6042 power_rule->max_eirp) ||
6043 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
6044 reg_rule->dfs_cac_ms))
ad30ca2c 6045 goto nla_put_failure;
f130347c
LR
6046
6047 nla_nest_end(msg, nl_reg_rule);
6048 }
6049
6050 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
6051 return 0;
6052
6053nla_put_failure:
6054 return -EMSGSIZE;
6055}
6056
6057static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
6058{
6059 const struct ieee80211_regdomain *regdom = NULL;
6060 struct cfg80211_registered_device *rdev;
6061 struct wiphy *wiphy = NULL;
6062 struct sk_buff *msg;
6063 void *hdr;
6064
6065 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6066 if (!msg)
6067 return -ENOBUFS;
6068
6069 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
6070 NL80211_CMD_GET_REG);
6071 if (!hdr)
6072 goto put_failure;
6073
6074 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
6075 bool self_managed;
6076
ad30ca2c
AN
6077 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
6078 if (IS_ERR(rdev)) {
6079 nlmsg_free(msg);
6080 return PTR_ERR(rdev);
6081 }
6082
6083 wiphy = &rdev->wiphy;
1bdd716c
AN
6084 self_managed = wiphy->regulatory_flags &
6085 REGULATORY_WIPHY_SELF_MANAGED;
ad30ca2c
AN
6086 regdom = get_wiphy_regdom(wiphy);
6087
1bdd716c
AN
6088 /* a self-managed-reg device must have a private regdom */
6089 if (WARN_ON(!regdom && self_managed)) {
6090 nlmsg_free(msg);
6091 return -EINVAL;
6092 }
6093
ad30ca2c
AN
6094 if (regdom &&
6095 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6096 goto nla_put_failure;
6097 }
6098
6099 if (!wiphy && reg_last_request_cell_base() &&
6100 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6101 NL80211_USER_REG_HINT_CELL_BASE))
6102 goto nla_put_failure;
6103
6104 rcu_read_lock();
6105
6106 if (!regdom)
6107 regdom = rcu_dereference(cfg80211_regdomain);
6108
6109 if (nl80211_put_regdom(regdom, msg))
6110 goto nla_put_failure_rcu;
6111
6112 rcu_read_unlock();
f130347c
LR
6113
6114 genlmsg_end(msg, hdr);
5fe231e8 6115 return genlmsg_reply(msg, info);
f130347c 6116
458f4f9e
JB
6117nla_put_failure_rcu:
6118 rcu_read_unlock();
f130347c
LR
6119nla_put_failure:
6120 genlmsg_cancel(msg, hdr);
efe1cf0c 6121put_failure:
d080e275 6122 nlmsg_free(msg);
5fe231e8 6123 return -EMSGSIZE;
f130347c
LR
6124}
6125
ad30ca2c
AN
6126static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
6127 u32 seq, int flags, struct wiphy *wiphy,
6128 const struct ieee80211_regdomain *regdom)
6129{
6130 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
6131 NL80211_CMD_GET_REG);
6132
6133 if (!hdr)
6134 return -1;
6135
6136 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
6137
6138 if (nl80211_put_regdom(regdom, msg))
6139 goto nla_put_failure;
6140
6141 if (!wiphy && reg_last_request_cell_base() &&
6142 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6143 NL80211_USER_REG_HINT_CELL_BASE))
6144 goto nla_put_failure;
6145
6146 if (wiphy &&
6147 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6148 goto nla_put_failure;
6149
1bdd716c
AN
6150 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
6151 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
6152 goto nla_put_failure;
6153
053c095a
JB
6154 genlmsg_end(msg, hdr);
6155 return 0;
ad30ca2c
AN
6156
6157nla_put_failure:
6158 genlmsg_cancel(msg, hdr);
6159 return -EMSGSIZE;
6160}
6161
6162static int nl80211_get_reg_dump(struct sk_buff *skb,
6163 struct netlink_callback *cb)
6164{
6165 const struct ieee80211_regdomain *regdom = NULL;
6166 struct cfg80211_registered_device *rdev;
6167 int err, reg_idx, start = cb->args[2];
6168
6169 rtnl_lock();
6170
6171 if (cfg80211_regdomain && start == 0) {
6172 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6173 NLM_F_MULTI, NULL,
6174 rtnl_dereference(cfg80211_regdomain));
6175 if (err < 0)
6176 goto out_err;
6177 }
6178
6179 /* the global regdom is idx 0 */
6180 reg_idx = 1;
6181 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
6182 regdom = get_wiphy_regdom(&rdev->wiphy);
6183 if (!regdom)
6184 continue;
6185
6186 if (++reg_idx <= start)
6187 continue;
6188
6189 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6190 NLM_F_MULTI, &rdev->wiphy, regdom);
6191 if (err < 0) {
6192 reg_idx--;
6193 break;
6194 }
6195 }
6196
6197 cb->args[2] = reg_idx;
6198 err = skb->len;
6199out_err:
6200 rtnl_unlock();
6201 return err;
6202}
6203
b6863036
JB
6204#ifdef CONFIG_CFG80211_CRDA_SUPPORT
6205static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
6206 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
6207 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
6208 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
6209 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
6210 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
6211 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
6212 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
6213};
6214
6215static int parse_reg_rule(struct nlattr *tb[],
6216 struct ieee80211_reg_rule *reg_rule)
6217{
6218 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
6219 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
6220
6221 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
6222 return -EINVAL;
6223 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
6224 return -EINVAL;
6225 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
6226 return -EINVAL;
6227 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
6228 return -EINVAL;
6229 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6230 return -EINVAL;
6231
6232 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
6233
6234 freq_range->start_freq_khz =
6235 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
6236 freq_range->end_freq_khz =
6237 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
6238 freq_range->max_bandwidth_khz =
6239 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
6240
6241 power_rule->max_eirp =
6242 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
6243
6244 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
6245 power_rule->max_antenna_gain =
6246 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
6247
6248 if (tb[NL80211_ATTR_DFS_CAC_TIME])
6249 reg_rule->dfs_cac_ms =
6250 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
6251
6252 return 0;
6253}
6254
b2e1b302
LR
6255static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
6256{
6257 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
6258 struct nlattr *nl_reg_rule;
ea372c54
JB
6259 char *alpha2;
6260 int rem_reg_rules, r;
b2e1b302 6261 u32 num_rules = 0, rule_idx = 0, size_of_regd;
4c7d3982 6262 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 6263 struct ieee80211_regdomain *rd;
b2e1b302
LR
6264
6265 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
6266 return -EINVAL;
6267
6268 if (!info->attrs[NL80211_ATTR_REG_RULES])
6269 return -EINVAL;
6270
6271 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
6272
8b60b078
LR
6273 if (info->attrs[NL80211_ATTR_DFS_REGION])
6274 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
6275
b2e1b302 6276 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6277 rem_reg_rules) {
b2e1b302
LR
6278 num_rules++;
6279 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 6280 return -EINVAL;
b2e1b302
LR
6281 }
6282
e438768f
LR
6283 if (!reg_is_valid_request(alpha2))
6284 return -EINVAL;
6285
b2e1b302 6286 size_of_regd = sizeof(struct ieee80211_regdomain) +
1a919318 6287 num_rules * sizeof(struct ieee80211_reg_rule);
b2e1b302
LR
6288
6289 rd = kzalloc(size_of_regd, GFP_KERNEL);
6913b49a
JB
6290 if (!rd)
6291 return -ENOMEM;
b2e1b302
LR
6292
6293 rd->n_reg_rules = num_rules;
6294 rd->alpha2[0] = alpha2[0];
6295 rd->alpha2[1] = alpha2[1];
6296
8b60b078
LR
6297 /*
6298 * Disable DFS master mode if the DFS region was
6299 * not supported or known on this kernel.
6300 */
6301 if (reg_supported_dfs_region(dfs_region))
6302 rd->dfs_region = dfs_region;
6303
b2e1b302 6304 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6305 rem_reg_rules) {
ae811e21
JB
6306 r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
6307 nla_data(nl_reg_rule), nla_len(nl_reg_rule),
6308 reg_rule_policy);
6309 if (r)
6310 goto bad_reg;
b2e1b302
LR
6311 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
6312 if (r)
6313 goto bad_reg;
6314
6315 rule_idx++;
6316
d0e18f83
LR
6317 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
6318 r = -EINVAL;
b2e1b302 6319 goto bad_reg;
d0e18f83 6320 }
b2e1b302
LR
6321 }
6322
06627990
JB
6323 /* set_regdom takes ownership of rd */
6324 return set_regdom(rd, REGD_SOURCE_CRDA);
d2372b31 6325 bad_reg:
b2e1b302 6326 kfree(rd);
d0e18f83 6327 return r;
b2e1b302 6328}
b6863036 6329#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 6330
83f5e2cf
JB
6331static int validate_scan_freqs(struct nlattr *freqs)
6332{
6333 struct nlattr *attr1, *attr2;
6334 int n_channels = 0, tmp1, tmp2;
6335
6336 nla_for_each_nested(attr1, freqs, tmp1) {
6337 n_channels++;
6338 /*
6339 * Some hardware has a limited channel list for
6340 * scanning, and it is pretty much nonsensical
6341 * to scan for a channel twice, so disallow that
6342 * and don't require drivers to check that the
6343 * channel list they get isn't longer than what
6344 * they can scan, as long as they can scan all
6345 * the channels they registered at once.
6346 */
6347 nla_for_each_nested(attr2, freqs, tmp2)
6348 if (attr1 != attr2 &&
6349 nla_get_u32(attr1) == nla_get_u32(attr2))
6350 return 0;
6351 }
6352
6353 return n_channels;
6354}
6355
57fbcce3 6356static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 6357{
57fbcce3 6358 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
6359}
6360
6361static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
6362 struct cfg80211_bss_selection *bss_select)
6363{
6364 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
6365 struct nlattr *nest;
6366 int err;
6367 bool found = false;
6368 int i;
6369
6370 /* only process one nested attribute */
6371 nest = nla_data(nla);
6372 if (!nla_ok(nest, nla_len(nest)))
6373 return -EINVAL;
6374
6375 err = nla_parse(attr, NL80211_BSS_SELECT_ATTR_MAX, nla_data(nest),
6376 nla_len(nest), nl80211_bss_select_policy);
6377 if (err)
6378 return err;
6379
6380 /* only one attribute may be given */
6381 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
6382 if (attr[i]) {
6383 if (found)
6384 return -EINVAL;
6385 found = true;
6386 }
6387 }
6388
6389 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
6390
6391 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
6392 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
6393
6394 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
6395 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
6396 bss_select->param.band_pref =
6397 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
6398 if (!is_band_valid(wiphy, bss_select->param.band_pref))
6399 return -EINVAL;
6400 }
6401
6402 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
6403 struct nl80211_bss_select_rssi_adjust *adj_param;
6404
6405 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
6406 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
6407 bss_select->param.adjust.band = adj_param->band;
6408 bss_select->param.adjust.delta = adj_param->delta;
6409 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
6410 return -EINVAL;
6411 }
6412
6413 /* user-space did not provide behaviour attribute */
6414 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
6415 return -EINVAL;
6416
6417 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
6418 return -EINVAL;
6419
6420 return 0;
6421}
6422
ad2b26ab
JB
6423static int nl80211_parse_random_mac(struct nlattr **attrs,
6424 u8 *mac_addr, u8 *mac_addr_mask)
6425{
6426 int i;
6427
6428 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
6429 eth_zero_addr(mac_addr);
6430 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
6431 mac_addr[0] = 0x2;
6432 mac_addr_mask[0] = 0x3;
6433
6434 return 0;
6435 }
6436
6437 /* need both or none */
6438 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
6439 return -EINVAL;
6440
6441 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
6442 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
6443
6444 /* don't allow or configure an mcast address */
6445 if (!is_multicast_ether_addr(mac_addr_mask) ||
6446 is_multicast_ether_addr(mac_addr))
6447 return -EINVAL;
6448
6449 /*
6450 * allow users to pass a MAC address that has bits set outside
6451 * of the mask, but don't bother drivers with having to deal
6452 * with such bits
6453 */
6454 for (i = 0; i < ETH_ALEN; i++)
6455 mac_addr[i] &= mac_addr_mask[i];
6456
6457 return 0;
6458}
6459
2a519311
JB
6460static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
6461{
4c476991 6462 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 6463 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 6464 struct cfg80211_scan_request *request;
2a519311
JB
6465 struct nlattr *attr;
6466 struct wiphy *wiphy;
83f5e2cf 6467 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 6468 size_t ie_len;
2a519311 6469
f4a11bb0
JB
6470 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
6471 return -EINVAL;
6472
79c97e97 6473 wiphy = &rdev->wiphy;
2a519311 6474
cb3b7d87
AB
6475 if (wdev->iftype == NL80211_IFTYPE_NAN)
6476 return -EOPNOTSUPP;
6477
4c476991
JB
6478 if (!rdev->ops->scan)
6479 return -EOPNOTSUPP;
2a519311 6480
f9d15d16 6481 if (rdev->scan_req || rdev->scan_msg) {
f9f47529
JB
6482 err = -EBUSY;
6483 goto unlock;
6484 }
2a519311
JB
6485
6486 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
6487 n_channels = validate_scan_freqs(
6488 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
f9f47529
JB
6489 if (!n_channels) {
6490 err = -EINVAL;
6491 goto unlock;
6492 }
2a519311 6493 } else {
bdfbec2d 6494 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
6495 }
6496
6497 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
6498 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
6499 n_ssids++;
6500
f9f47529
JB
6501 if (n_ssids > wiphy->max_scan_ssids) {
6502 err = -EINVAL;
6503 goto unlock;
6504 }
2a519311 6505
70692ad2
JM
6506 if (info->attrs[NL80211_ATTR_IE])
6507 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
6508 else
6509 ie_len = 0;
6510
f9f47529
JB
6511 if (ie_len > wiphy->max_scan_ie_len) {
6512 err = -EINVAL;
6513 goto unlock;
6514 }
18a83659 6515
2a519311 6516 request = kzalloc(sizeof(*request)
a2cd43c5
LC
6517 + sizeof(*request->ssids) * n_ssids
6518 + sizeof(*request->channels) * n_channels
70692ad2 6519 + ie_len, GFP_KERNEL);
f9f47529
JB
6520 if (!request) {
6521 err = -ENOMEM;
6522 goto unlock;
6523 }
2a519311 6524
2a519311 6525 if (n_ssids)
5ba63533 6526 request->ssids = (void *)&request->channels[n_channels];
2a519311 6527 request->n_ssids = n_ssids;
70692ad2 6528 if (ie_len) {
13874e4b 6529 if (n_ssids)
70692ad2
JM
6530 request->ie = (void *)(request->ssids + n_ssids);
6531 else
6532 request->ie = (void *)(request->channels + n_channels);
6533 }
2a519311 6534
584991dc 6535 i = 0;
2a519311
JB
6536 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
6537 /* user specified, bail out if channel not found */
2a519311 6538 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
6539 struct ieee80211_channel *chan;
6540
6541 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
6542
6543 if (!chan) {
2a519311
JB
6544 err = -EINVAL;
6545 goto out_free;
6546 }
584991dc
JB
6547
6548 /* ignore disabled channels */
6549 if (chan->flags & IEEE80211_CHAN_DISABLED)
6550 continue;
6551
6552 request->channels[i] = chan;
2a519311
JB
6553 i++;
6554 }
6555 } else {
57fbcce3 6556 enum nl80211_band band;
34850ab2 6557
2a519311 6558 /* all channels */
57fbcce3 6559 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 6560 int j;
7a087e74 6561
2a519311
JB
6562 if (!wiphy->bands[band])
6563 continue;
6564 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
6565 struct ieee80211_channel *chan;
6566
6567 chan = &wiphy->bands[band]->channels[j];
6568
6569 if (chan->flags & IEEE80211_CHAN_DISABLED)
6570 continue;
6571
6572 request->channels[i] = chan;
2a519311
JB
6573 i++;
6574 }
6575 }
6576 }
6577
584991dc
JB
6578 if (!i) {
6579 err = -EINVAL;
6580 goto out_free;
6581 }
6582
6583 request->n_channels = i;
6584
2a519311 6585 i = 0;
13874e4b 6586 if (n_ssids) {
2a519311 6587 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 6588 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
6589 err = -EINVAL;
6590 goto out_free;
6591 }
57a27e1d 6592 request->ssids[i].ssid_len = nla_len(attr);
2a519311 6593 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
6594 i++;
6595 }
6596 }
6597
70692ad2
JM
6598 if (info->attrs[NL80211_ATTR_IE]) {
6599 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
6600 memcpy((void *)request->ie,
6601 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
6602 request->ie_len);
6603 }
6604
57fbcce3 6605 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
6606 if (wiphy->bands[i])
6607 request->rates[i] =
6608 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
6609
6610 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
6611 nla_for_each_nested(attr,
6612 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
6613 tmp) {
57fbcce3 6614 enum nl80211_band band = nla_type(attr);
34850ab2 6615
57fbcce3 6616 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
6617 err = -EINVAL;
6618 goto out_free;
6619 }
1b09cd82
FF
6620
6621 if (!wiphy->bands[band])
6622 continue;
6623
34850ab2
JB
6624 err = ieee80211_get_ratemask(wiphy->bands[band],
6625 nla_data(attr),
6626 nla_len(attr),
6627 &request->rates[band]);
6628 if (err)
6629 goto out_free;
6630 }
6631 }
6632
1d76250b
AS
6633 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
6634 if (!wiphy_ext_feature_isset(wiphy,
6635 NL80211_EXT_FEATURE_SET_SCAN_DWELL)) {
6636 err = -EOPNOTSUPP;
6637 goto out_free;
6638 }
6639
6640 request->duration =
6641 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
6642 request->duration_mandatory =
6643 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
6644 }
6645
46856bbf 6646 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
ed473771
SL
6647 request->flags = nla_get_u32(
6648 info->attrs[NL80211_ATTR_SCAN_FLAGS]);
00c3a6ed
JB
6649 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
6650 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
46856bbf
SL
6651 err = -EOPNOTSUPP;
6652 goto out_free;
6653 }
ad2b26ab
JB
6654
6655 if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
6656 if (!(wiphy->features &
6657 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)) {
6658 err = -EOPNOTSUPP;
6659 goto out_free;
6660 }
6661
6662 if (wdev->current_bss) {
6663 err = -EOPNOTSUPP;
6664 goto out_free;
6665 }
6666
6667 err = nl80211_parse_random_mac(info->attrs,
6668 request->mac_addr,
6669 request->mac_addr_mask);
6670 if (err)
6671 goto out_free;
6672 }
46856bbf 6673 }
ed473771 6674
e9f935e3
RM
6675 request->no_cck =
6676 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
6677
818965d3
JM
6678 if (info->attrs[NL80211_ATTR_MAC])
6679 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
6680 ETH_ALEN);
6681 else
6682 eth_broadcast_addr(request->bssid);
6683
fd014284 6684 request->wdev = wdev;
79c97e97 6685 request->wiphy = &rdev->wiphy;
15d6030b 6686 request->scan_start = jiffies;
2a519311 6687
79c97e97 6688 rdev->scan_req = request;
e35e4d28 6689 err = rdev_scan(rdev, request);
2a519311 6690
463d0183 6691 if (!err) {
fd014284
JB
6692 nl80211_send_scan_start(rdev, wdev);
6693 if (wdev->netdev)
6694 dev_hold(wdev->netdev);
4c476991 6695 } else {
2a519311 6696 out_free:
79c97e97 6697 rdev->scan_req = NULL;
2a519311
JB
6698 kfree(request);
6699 }
3b85875a 6700
f9f47529 6701 unlock:
2a519311
JB
6702 return err;
6703}
6704
91d3ab46
VK
6705static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
6706{
6707 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6708 struct wireless_dev *wdev = info->user_ptr[1];
6709
6710 if (!rdev->ops->abort_scan)
6711 return -EOPNOTSUPP;
6712
6713 if (rdev->scan_msg)
6714 return 0;
6715
6716 if (!rdev->scan_req)
6717 return -ENOENT;
6718
6719 rdev_abort_scan(rdev, wdev);
6720 return 0;
6721}
6722
3b06d277
AS
6723static int
6724nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
6725 struct cfg80211_sched_scan_request *request,
6726 struct nlattr **attrs)
6727{
6728 int tmp, err, i = 0;
6729 struct nlattr *attr;
6730
6731 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
6732 u32 interval;
6733
6734 /*
6735 * If scan plans are not specified,
6736 * %NL80211_ATTR_SCHED_SCAN_INTERVAL must be specified. In this
6737 * case one scan plan will be set with the specified scan
6738 * interval and infinite number of iterations.
6739 */
6740 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
6741 return -EINVAL;
6742
6743 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
6744 if (!interval)
6745 return -EINVAL;
6746
6747 request->scan_plans[0].interval =
6748 DIV_ROUND_UP(interval, MSEC_PER_SEC);
6749 if (!request->scan_plans[0].interval)
6750 return -EINVAL;
6751
6752 if (request->scan_plans[0].interval >
6753 wiphy->max_sched_scan_plan_interval)
6754 request->scan_plans[0].interval =
6755 wiphy->max_sched_scan_plan_interval;
6756
6757 return 0;
6758 }
6759
6760 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
6761 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
6762
6763 if (WARN_ON(i >= n_plans))
6764 return -EINVAL;
6765
6766 err = nla_parse(plan, NL80211_SCHED_SCAN_PLAN_MAX,
6767 nla_data(attr), nla_len(attr),
6768 nl80211_plan_policy);
6769 if (err)
6770 return err;
6771
6772 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
6773 return -EINVAL;
6774
6775 request->scan_plans[i].interval =
6776 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
6777 if (!request->scan_plans[i].interval ||
6778 request->scan_plans[i].interval >
6779 wiphy->max_sched_scan_plan_interval)
6780 return -EINVAL;
6781
6782 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
6783 request->scan_plans[i].iterations =
6784 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
6785 if (!request->scan_plans[i].iterations ||
6786 (request->scan_plans[i].iterations >
6787 wiphy->max_sched_scan_plan_iterations))
6788 return -EINVAL;
6789 } else if (i < n_plans - 1) {
6790 /*
6791 * All scan plans but the last one must specify
6792 * a finite number of iterations
6793 */
6794 return -EINVAL;
6795 }
6796
6797 i++;
6798 }
6799
6800 /*
6801 * The last scan plan must not specify the number of
6802 * iterations, it is supposed to run infinitely
6803 */
6804 if (request->scan_plans[n_plans - 1].iterations)
6805 return -EINVAL;
6806
6807 return 0;
6808}
6809
256da02d 6810static struct cfg80211_sched_scan_request *
ad2b26ab 6811nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
256da02d 6812 struct nlattr **attrs)
807f8a8c
LC
6813{
6814 struct cfg80211_sched_scan_request *request;
807f8a8c 6815 struct nlattr *attr;
3b06d277 6816 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 6817 enum nl80211_band band;
807f8a8c 6818 size_t ie_len;
a1f1c21c 6819 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 6820 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 6821
256da02d
LC
6822 if (!is_valid_ie_attr(attrs[NL80211_ATTR_IE]))
6823 return ERR_PTR(-EINVAL);
807f8a8c 6824
256da02d 6825 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 6826 n_channels = validate_scan_freqs(
256da02d 6827 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 6828 if (!n_channels)
256da02d 6829 return ERR_PTR(-EINVAL);
807f8a8c 6830 } else {
bdfbec2d 6831 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
6832 }
6833
256da02d
LC
6834 if (attrs[NL80211_ATTR_SCAN_SSIDS])
6835 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
6836 tmp)
6837 n_ssids++;
6838
93b6aa69 6839 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 6840 return ERR_PTR(-EINVAL);
807f8a8c 6841
ea73cbce
JB
6842 /*
6843 * First, count the number of 'real' matchsets. Due to an issue with
6844 * the old implementation, matchsets containing only the RSSI attribute
6845 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
6846 * RSSI for all matchsets, rather than their own matchset for reporting
6847 * all APs with a strong RSSI. This is needed to be compatible with
6848 * older userspace that treated a matchset with only the RSSI as the
6849 * global RSSI for all other matchsets - if there are other matchsets.
6850 */
256da02d 6851 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 6852 nla_for_each_nested(attr,
256da02d 6853 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
6854 tmp) {
6855 struct nlattr *rssi;
6856
6857 err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
6858 nla_data(attr), nla_len(attr),
6859 nl80211_match_policy);
6860 if (err)
256da02d 6861 return ERR_PTR(err);
ea73cbce
JB
6862 /* add other standalone attributes here */
6863 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
6864 n_match_sets++;
6865 continue;
6866 }
6867 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
6868 if (rssi)
6869 default_match_rssi = nla_get_s32(rssi);
6870 }
6871 }
6872
6873 /* However, if there's no other matchset, add the RSSI one */
6874 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
6875 n_match_sets = 1;
a1f1c21c
LC
6876
6877 if (n_match_sets > wiphy->max_match_sets)
256da02d 6878 return ERR_PTR(-EINVAL);
a1f1c21c 6879
256da02d
LC
6880 if (attrs[NL80211_ATTR_IE])
6881 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
6882 else
6883 ie_len = 0;
6884
5a865bad 6885 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 6886 return ERR_PTR(-EINVAL);
c10841ca 6887
3b06d277
AS
6888 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
6889 /*
6890 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
6891 * each scan plan already specifies its own interval
6892 */
6893 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
6894 return ERR_PTR(-EINVAL);
6895
6896 nla_for_each_nested(attr,
6897 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
6898 n_plans++;
6899 } else {
6900 /*
6901 * The scan interval attribute is kept for backward
6902 * compatibility. If no scan plans are specified and sched scan
6903 * interval is specified, one scan plan will be set with this
6904 * scan interval and infinite number of iterations.
6905 */
6906 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
6907 return ERR_PTR(-EINVAL);
6908
6909 n_plans = 1;
6910 }
6911
6912 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
6913 return ERR_PTR(-EINVAL);
6914
807f8a8c 6915 request = kzalloc(sizeof(*request)
a2cd43c5 6916 + sizeof(*request->ssids) * n_ssids
a1f1c21c 6917 + sizeof(*request->match_sets) * n_match_sets
3b06d277 6918 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 6919 + sizeof(*request->channels) * n_channels
807f8a8c 6920 + ie_len, GFP_KERNEL);
256da02d
LC
6921 if (!request)
6922 return ERR_PTR(-ENOMEM);
807f8a8c
LC
6923
6924 if (n_ssids)
6925 request->ssids = (void *)&request->channels[n_channels];
6926 request->n_ssids = n_ssids;
6927 if (ie_len) {
13874e4b 6928 if (n_ssids)
807f8a8c
LC
6929 request->ie = (void *)(request->ssids + n_ssids);
6930 else
6931 request->ie = (void *)(request->channels + n_channels);
6932 }
6933
a1f1c21c
LC
6934 if (n_match_sets) {
6935 if (request->ie)
6936 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 6937 else if (n_ssids)
a1f1c21c
LC
6938 request->match_sets =
6939 (void *)(request->ssids + n_ssids);
6940 else
6941 request->match_sets =
6942 (void *)(request->channels + n_channels);
6943 }
6944 request->n_match_sets = n_match_sets;
6945
3b06d277
AS
6946 if (n_match_sets)
6947 request->scan_plans = (void *)(request->match_sets +
6948 n_match_sets);
6949 else if (request->ie)
6950 request->scan_plans = (void *)(request->ie + ie_len);
6951 else if (n_ssids)
6952 request->scan_plans = (void *)(request->ssids + n_ssids);
6953 else
6954 request->scan_plans = (void *)(request->channels + n_channels);
6955
6956 request->n_scan_plans = n_plans;
6957
807f8a8c 6958 i = 0;
256da02d 6959 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
6960 /* user specified, bail out if channel not found */
6961 nla_for_each_nested(attr,
256da02d 6962 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
6963 tmp) {
6964 struct ieee80211_channel *chan;
6965
6966 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
6967
6968 if (!chan) {
6969 err = -EINVAL;
6970 goto out_free;
6971 }
6972
6973 /* ignore disabled channels */
6974 if (chan->flags & IEEE80211_CHAN_DISABLED)
6975 continue;
6976
6977 request->channels[i] = chan;
6978 i++;
6979 }
6980 } else {
6981 /* all channels */
57fbcce3 6982 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 6983 int j;
7a087e74 6984
807f8a8c
LC
6985 if (!wiphy->bands[band])
6986 continue;
6987 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
6988 struct ieee80211_channel *chan;
6989
6990 chan = &wiphy->bands[band]->channels[j];
6991
6992 if (chan->flags & IEEE80211_CHAN_DISABLED)
6993 continue;
6994
6995 request->channels[i] = chan;
6996 i++;
6997 }
6998 }
6999 }
7000
7001 if (!i) {
7002 err = -EINVAL;
7003 goto out_free;
7004 }
7005
7006 request->n_channels = i;
7007
7008 i = 0;
13874e4b 7009 if (n_ssids) {
256da02d 7010 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 7011 tmp) {
57a27e1d 7012 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
7013 err = -EINVAL;
7014 goto out_free;
7015 }
57a27e1d 7016 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
7017 memcpy(request->ssids[i].ssid, nla_data(attr),
7018 nla_len(attr));
807f8a8c
LC
7019 i++;
7020 }
7021 }
7022
a1f1c21c 7023 i = 0;
256da02d 7024 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 7025 nla_for_each_nested(attr,
256da02d 7026 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 7027 tmp) {
88e920b4 7028 struct nlattr *ssid, *rssi;
a1f1c21c 7029
ae811e21
JB
7030 err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
7031 nla_data(attr), nla_len(attr),
7032 nl80211_match_policy);
7033 if (err)
7034 goto out_free;
4a4ab0d7 7035 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
a1f1c21c 7036 if (ssid) {
ea73cbce
JB
7037 if (WARN_ON(i >= n_match_sets)) {
7038 /* this indicates a programming error,
7039 * the loop above should have verified
7040 * things properly
7041 */
7042 err = -EINVAL;
7043 goto out_free;
7044 }
7045
a1f1c21c
LC
7046 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
7047 err = -EINVAL;
7048 goto out_free;
7049 }
7050 memcpy(request->match_sets[i].ssid.ssid,
7051 nla_data(ssid), nla_len(ssid));
7052 request->match_sets[i].ssid.ssid_len =
7053 nla_len(ssid);
56ab364f 7054 /* special attribute - old implementation w/a */
ea73cbce
JB
7055 request->match_sets[i].rssi_thold =
7056 default_match_rssi;
7057 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
7058 if (rssi)
7059 request->match_sets[i].rssi_thold =
7060 nla_get_s32(rssi);
a1f1c21c
LC
7061 }
7062 i++;
7063 }
ea73cbce
JB
7064
7065 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 7066 if (i == 0 && n_match_sets)
ea73cbce
JB
7067 request->match_sets[0].rssi_thold = default_match_rssi;
7068
7069 request->min_rssi_thold = INT_MAX;
7070 for (i = 0; i < n_match_sets; i++)
7071 request->min_rssi_thold =
7072 min(request->match_sets[i].rssi_thold,
7073 request->min_rssi_thold);
7074 } else {
7075 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
7076 }
7077
9900e484
JB
7078 if (ie_len) {
7079 request->ie_len = ie_len;
807f8a8c 7080 memcpy((void *)request->ie,
256da02d 7081 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
7082 request->ie_len);
7083 }
7084
256da02d 7085 if (attrs[NL80211_ATTR_SCAN_FLAGS]) {
ed473771 7086 request->flags = nla_get_u32(
256da02d 7087 attrs[NL80211_ATTR_SCAN_FLAGS]);
00c3a6ed
JB
7088 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
7089 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
46856bbf
SL
7090 err = -EOPNOTSUPP;
7091 goto out_free;
7092 }
ad2b26ab
JB
7093
7094 if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
7095 u32 flg = NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
7096
7097 if (!wdev) /* must be net-detect */
7098 flg = NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7099
7100 if (!(wiphy->features & flg)) {
7101 err = -EOPNOTSUPP;
7102 goto out_free;
7103 }
7104
7105 if (wdev && wdev->current_bss) {
7106 err = -EOPNOTSUPP;
7107 goto out_free;
7108 }
7109
7110 err = nl80211_parse_random_mac(attrs, request->mac_addr,
7111 request->mac_addr_mask);
7112 if (err)
7113 goto out_free;
7114 }
46856bbf 7115 }
ed473771 7116
9c748934
LC
7117 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
7118 request->delay =
7119 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
7120
3b06d277
AS
7121 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
7122 if (err)
7123 goto out_free;
7124
15d6030b 7125 request->scan_start = jiffies;
807f8a8c 7126
256da02d 7127 return request;
807f8a8c
LC
7128
7129out_free:
7130 kfree(request);
256da02d
LC
7131 return ERR_PTR(err);
7132}
7133
7134static int nl80211_start_sched_scan(struct sk_buff *skb,
7135 struct genl_info *info)
7136{
7137 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7138 struct net_device *dev = info->user_ptr[1];
ad2b26ab 7139 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 7140 struct cfg80211_sched_scan_request *sched_scan_req;
256da02d
LC
7141 int err;
7142
7143 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
7144 !rdev->ops->sched_scan_start)
7145 return -EOPNOTSUPP;
7146
7147 if (rdev->sched_scan_req)
7148 return -EINPROGRESS;
7149
31a60ed1
JR
7150 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
7151 info->attrs);
7152
7153 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
7154 if (err)
7155 goto out_err;
7156
31a60ed1 7157 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
7158 if (err)
7159 goto out_free;
7160
31a60ed1
JR
7161 sched_scan_req->dev = dev;
7162 sched_scan_req->wiphy = &rdev->wiphy;
7163
93a1e86c
JR
7164 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
7165 sched_scan_req->owner_nlportid = info->snd_portid;
7166
31a60ed1 7167 rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req);
256da02d
LC
7168
7169 nl80211_send_sched_scan(rdev, dev,
7170 NL80211_CMD_START_SCHED_SCAN);
7171 return 0;
7172
7173out_free:
31a60ed1 7174 kfree(sched_scan_req);
256da02d 7175out_err:
807f8a8c
LC
7176 return err;
7177}
7178
7179static int nl80211_stop_sched_scan(struct sk_buff *skb,
7180 struct genl_info *info)
7181{
7182 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7183
7184 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
7185 !rdev->ops->sched_scan_stop)
7186 return -EOPNOTSUPP;
7187
5fe231e8 7188 return __cfg80211_stop_sched_scan(rdev, false);
807f8a8c
LC
7189}
7190
04f39047
SW
7191static int nl80211_start_radar_detection(struct sk_buff *skb,
7192 struct genl_info *info)
7193{
7194 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7195 struct net_device *dev = info->user_ptr[1];
7196 struct wireless_dev *wdev = dev->ieee80211_ptr;
7197 struct cfg80211_chan_def chandef;
55f7435c 7198 enum nl80211_dfs_regions dfs_region;
31559f35 7199 unsigned int cac_time_ms;
04f39047
SW
7200 int err;
7201
55f7435c
LR
7202 dfs_region = reg_get_dfs_region(wdev->wiphy);
7203 if (dfs_region == NL80211_DFS_UNSET)
7204 return -EINVAL;
7205
04f39047
SW
7206 err = nl80211_parse_chandef(rdev, info, &chandef);
7207 if (err)
7208 return err;
7209
ff311bc1
SW
7210 if (netif_carrier_ok(dev))
7211 return -EBUSY;
7212
04f39047
SW
7213 if (wdev->cac_started)
7214 return -EBUSY;
7215
2beb6dab 7216 err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef,
00ec75fc 7217 wdev->iftype);
04f39047
SW
7218 if (err < 0)
7219 return err;
7220
7221 if (err == 0)
7222 return -EINVAL;
7223
fe7c3a1f 7224 if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef))
04f39047
SW
7225 return -EINVAL;
7226
7227 if (!rdev->ops->start_radar_detection)
7228 return -EOPNOTSUPP;
7229
31559f35
JD
7230 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
7231 if (WARN_ON(!cac_time_ms))
7232 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
7233
a1056b1b 7234 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 7235 if (!err) {
9e0e2961 7236 wdev->chandef = chandef;
04f39047
SW
7237 wdev->cac_started = true;
7238 wdev->cac_start_time = jiffies;
31559f35 7239 wdev->cac_time_ms = cac_time_ms;
04f39047 7240 }
04f39047
SW
7241 return err;
7242}
7243
16ef1fe2
SW
7244static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
7245{
7246 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7247 struct net_device *dev = info->user_ptr[1];
7248 struct wireless_dev *wdev = dev->ieee80211_ptr;
7249 struct cfg80211_csa_settings params;
7250 /* csa_attrs is defined static to avoid waste of stack size - this
7251 * function is called under RTNL lock, so this should not be a problem.
7252 */
7253 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
16ef1fe2 7254 int err;
ee4bc9e7 7255 bool need_new_beacon = false;
9a774c78 7256 int len, i;
252e07ca 7257 u32 cs_count;
16ef1fe2
SW
7258
7259 if (!rdev->ops->channel_switch ||
7260 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
7261 return -EOPNOTSUPP;
7262
ee4bc9e7
SW
7263 switch (dev->ieee80211_ptr->iftype) {
7264 case NL80211_IFTYPE_AP:
7265 case NL80211_IFTYPE_P2P_GO:
7266 need_new_beacon = true;
7267
7268 /* useless if AP is not running */
7269 if (!wdev->beacon_interval)
1ff79dfa 7270 return -ENOTCONN;
ee4bc9e7
SW
7271 break;
7272 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
7273 if (!wdev->ssid_len)
7274 return -ENOTCONN;
7275 break;
c6da674a 7276 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
7277 if (!wdev->mesh_id_len)
7278 return -ENOTCONN;
ee4bc9e7
SW
7279 break;
7280 default:
16ef1fe2 7281 return -EOPNOTSUPP;
ee4bc9e7 7282 }
16ef1fe2
SW
7283
7284 memset(&params, 0, sizeof(params));
7285
7286 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
7287 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
7288 return -EINVAL;
7289
7290 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 7291 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
7292 return -EINVAL;
7293
252e07ca
LC
7294 /* Even though the attribute is u32, the specification says
7295 * u8, so let's make sure we don't overflow.
7296 */
7297 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
7298 if (cs_count > 255)
7299 return -EINVAL;
7300
7301 params.count = cs_count;
16ef1fe2 7302
ee4bc9e7
SW
7303 if (!need_new_beacon)
7304 goto skip_beacons;
7305
16ef1fe2
SW
7306 err = nl80211_parse_beacon(info->attrs, &params.beacon_after);
7307 if (err)
7308 return err;
7309
7310 err = nla_parse_nested(csa_attrs, NL80211_ATTR_MAX,
7311 info->attrs[NL80211_ATTR_CSA_IES],
7312 nl80211_policy);
7313 if (err)
7314 return err;
7315
7316 err = nl80211_parse_beacon(csa_attrs, &params.beacon_csa);
7317 if (err)
7318 return err;
7319
7320 if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON])
7321 return -EINVAL;
7322
9a774c78
AO
7323 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
7324 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
7325 return -EINVAL;
7326
9a774c78
AO
7327 params.n_counter_offsets_beacon = len / sizeof(u16);
7328 if (rdev->wiphy.max_num_csa_counters &&
7329 (params.n_counter_offsets_beacon >
7330 rdev->wiphy.max_num_csa_counters))
16ef1fe2
SW
7331 return -EINVAL;
7332
9a774c78
AO
7333 params.counter_offsets_beacon =
7334 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
7335
7336 /* sanity checks - counters should fit and be the same */
7337 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
7338 u16 offset = params.counter_offsets_beacon[i];
7339
7340 if (offset >= params.beacon_csa.tail_len)
7341 return -EINVAL;
7342
7343 if (params.beacon_csa.tail[offset] != params.count)
7344 return -EINVAL;
7345 }
7346
16ef1fe2 7347 if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) {
9a774c78
AO
7348 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
7349 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
7350 return -EINVAL;
7351
9a774c78
AO
7352 params.n_counter_offsets_presp = len / sizeof(u16);
7353 if (rdev->wiphy.max_num_csa_counters &&
7354 (params.n_counter_offsets_beacon >
7355 rdev->wiphy.max_num_csa_counters))
16ef1fe2 7356 return -EINVAL;
9a774c78
AO
7357
7358 params.counter_offsets_presp =
7359 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
7360
7361 /* sanity checks - counters should fit and be the same */
7362 for (i = 0; i < params.n_counter_offsets_presp; i++) {
7363 u16 offset = params.counter_offsets_presp[i];
7364
7365 if (offset >= params.beacon_csa.probe_resp_len)
7366 return -EINVAL;
7367
7368 if (params.beacon_csa.probe_resp[offset] !=
7369 params.count)
7370 return -EINVAL;
7371 }
16ef1fe2
SW
7372 }
7373
ee4bc9e7 7374skip_beacons:
16ef1fe2
SW
7375 err = nl80211_parse_chandef(rdev, info, &params.chandef);
7376 if (err)
7377 return err;
7378
923b352f
AN
7379 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
7380 wdev->iftype))
16ef1fe2
SW
7381 return -EINVAL;
7382
2beb6dab
LC
7383 err = cfg80211_chandef_dfs_required(wdev->wiphy,
7384 &params.chandef,
7385 wdev->iftype);
7386 if (err < 0)
7387 return err;
7388
dcc6c2f5 7389 if (err > 0)
2beb6dab 7390 params.radar_required = true;
16ef1fe2 7391
16ef1fe2
SW
7392 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
7393 params.block_tx = true;
7394
c56589ed
SW
7395 wdev_lock(wdev);
7396 err = rdev_channel_switch(rdev, dev, &params);
7397 wdev_unlock(wdev);
7398
7399 return err;
16ef1fe2
SW
7400}
7401
9720bb3a
JB
7402static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
7403 u32 seq, int flags,
2a519311 7404 struct cfg80211_registered_device *rdev,
48ab905d
JB
7405 struct wireless_dev *wdev,
7406 struct cfg80211_internal_bss *intbss)
2a519311 7407{
48ab905d 7408 struct cfg80211_bss *res = &intbss->pub;
9caf0364 7409 const struct cfg80211_bss_ies *ies;
2a519311
JB
7410 void *hdr;
7411 struct nlattr *bss;
48ab905d
JB
7412
7413 ASSERT_WDEV_LOCK(wdev);
2a519311 7414
15e47304 7415 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
7416 NL80211_CMD_NEW_SCAN_RESULTS);
7417 if (!hdr)
7418 return -1;
7419
9720bb3a
JB
7420 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
7421
97990a06
JB
7422 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
7423 goto nla_put_failure;
7424 if (wdev->netdev &&
9360ffd1
DM
7425 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
7426 goto nla_put_failure;
2dad624e
ND
7427 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
7428 NL80211_ATTR_PAD))
97990a06 7429 goto nla_put_failure;
2a519311
JB
7430
7431 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
7432 if (!bss)
7433 goto nla_put_failure;
9360ffd1 7434 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 7435 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 7436 goto nla_put_failure;
9caf0364
JB
7437
7438 rcu_read_lock();
0e227084
JB
7439 /* indicate whether we have probe response data or not */
7440 if (rcu_access_pointer(res->proberesp_ies) &&
7441 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
7442 goto fail_unlock_rcu;
7443
7444 /* this pointer prefers to be pointed to probe response data
7445 * but is always valid
7446 */
9caf0364 7447 ies = rcu_dereference(res->ies);
8cef2c9d 7448 if (ies) {
2dad624e
ND
7449 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
7450 NL80211_BSS_PAD))
8cef2c9d 7451 goto fail_unlock_rcu;
8cef2c9d
JB
7452 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
7453 ies->len, ies->data))
7454 goto fail_unlock_rcu;
9caf0364 7455 }
0e227084
JB
7456
7457 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 7458 ies = rcu_dereference(res->beacon_ies);
0e227084 7459 if (ies && ies->from_beacon) {
2dad624e
ND
7460 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
7461 NL80211_BSS_PAD))
8cef2c9d
JB
7462 goto fail_unlock_rcu;
7463 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
7464 ies->len, ies->data))
7465 goto fail_unlock_rcu;
9caf0364
JB
7466 }
7467 rcu_read_unlock();
7468
9360ffd1
DM
7469 if (res->beacon_interval &&
7470 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
7471 goto nla_put_failure;
7472 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
7473 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
dcd6eac1 7474 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
7475 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
7476 jiffies_to_msecs(jiffies - intbss->ts)))
7477 goto nla_put_failure;
2a519311 7478
1d76250b
AS
7479 if (intbss->parent_tsf &&
7480 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
7481 intbss->parent_tsf, NL80211_BSS_PAD) ||
7482 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
7483 intbss->parent_bssid)))
7484 goto nla_put_failure;
7485
6e19bc4b 7486 if (intbss->ts_boottime &&
2dad624e
ND
7487 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
7488 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
7489 goto nla_put_failure;
7490
77965c97 7491 switch (rdev->wiphy.signal_type) {
2a519311 7492 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
7493 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
7494 goto nla_put_failure;
2a519311
JB
7495 break;
7496 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
7497 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
7498 goto nla_put_failure;
2a519311
JB
7499 break;
7500 default:
7501 break;
7502 }
7503
48ab905d 7504 switch (wdev->iftype) {
074ac8df 7505 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 7506 case NL80211_IFTYPE_STATION:
9360ffd1
DM
7507 if (intbss == wdev->current_bss &&
7508 nla_put_u32(msg, NL80211_BSS_STATUS,
7509 NL80211_BSS_STATUS_ASSOCIATED))
7510 goto nla_put_failure;
48ab905d
JB
7511 break;
7512 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
7513 if (intbss == wdev->current_bss &&
7514 nla_put_u32(msg, NL80211_BSS_STATUS,
7515 NL80211_BSS_STATUS_IBSS_JOINED))
7516 goto nla_put_failure;
48ab905d
JB
7517 break;
7518 default:
7519 break;
7520 }
7521
2a519311
JB
7522 nla_nest_end(msg, bss);
7523
053c095a
JB
7524 genlmsg_end(msg, hdr);
7525 return 0;
2a519311 7526
8cef2c9d
JB
7527 fail_unlock_rcu:
7528 rcu_read_unlock();
2a519311
JB
7529 nla_put_failure:
7530 genlmsg_cancel(msg, hdr);
7531 return -EMSGSIZE;
7532}
7533
97990a06 7534static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 7535{
48ab905d 7536 struct cfg80211_registered_device *rdev;
2a519311 7537 struct cfg80211_internal_bss *scan;
48ab905d 7538 struct wireless_dev *wdev;
97990a06 7539 int start = cb->args[2], idx = 0;
2a519311
JB
7540 int err;
7541
97990a06 7542 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
7543 if (err)
7544 return err;
2a519311 7545
48ab905d
JB
7546 wdev_lock(wdev);
7547 spin_lock_bh(&rdev->bss_lock);
7548 cfg80211_bss_expire(rdev);
7549
9720bb3a
JB
7550 cb->seq = rdev->bss_generation;
7551
48ab905d 7552 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
7553 if (++idx <= start)
7554 continue;
9720bb3a 7555 if (nl80211_send_bss(skb, cb,
2a519311 7556 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 7557 rdev, wdev, scan) < 0) {
2a519311 7558 idx--;
67748893 7559 break;
2a519311
JB
7560 }
7561 }
7562
48ab905d
JB
7563 spin_unlock_bh(&rdev->bss_lock);
7564 wdev_unlock(wdev);
2a519311 7565
97990a06
JB
7566 cb->args[2] = idx;
7567 nl80211_finish_wdev_dump(rdev);
2a519311 7568
67748893 7569 return skb->len;
2a519311
JB
7570}
7571
15e47304 7572static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
7573 int flags, struct net_device *dev,
7574 bool allow_radio_stats,
7575 struct survey_info *survey)
61fa713c
HS
7576{
7577 void *hdr;
7578 struct nlattr *infoattr;
7579
11f78ac3
JB
7580 /* skip radio stats if userspace didn't request them */
7581 if (!survey->channel && !allow_radio_stats)
7582 return 0;
7583
15e47304 7584 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
7585 NL80211_CMD_NEW_SURVEY_RESULTS);
7586 if (!hdr)
7587 return -ENOMEM;
7588
9360ffd1
DM
7589 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
7590 goto nla_put_failure;
61fa713c
HS
7591
7592 infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
7593 if (!infoattr)
7594 goto nla_put_failure;
7595
11f78ac3
JB
7596 if (survey->channel &&
7597 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
7598 survey->channel->center_freq))
7599 goto nla_put_failure;
7600
7601 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
7602 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
7603 goto nla_put_failure;
7604 if ((survey->filled & SURVEY_INFO_IN_USE) &&
7605 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
7606 goto nla_put_failure;
4ed20beb 7607 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
7608 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
7609 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 7610 goto nla_put_failure;
4ed20beb 7611 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
7612 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
7613 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 7614 goto nla_put_failure;
4ed20beb 7615 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
7616 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
7617 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 7618 goto nla_put_failure;
4ed20beb 7619 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
7620 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
7621 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 7622 goto nla_put_failure;
4ed20beb 7623 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
7624 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
7625 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 7626 goto nla_put_failure;
052536ab 7627 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
7628 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
7629 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 7630 goto nla_put_failure;
61fa713c
HS
7631
7632 nla_nest_end(msg, infoattr);
7633
053c095a
JB
7634 genlmsg_end(msg, hdr);
7635 return 0;
61fa713c
HS
7636
7637 nla_put_failure:
7638 genlmsg_cancel(msg, hdr);
7639 return -EMSGSIZE;
7640}
7641
11f78ac3 7642static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c
HS
7643{
7644 struct survey_info survey;
1b8ec87a 7645 struct cfg80211_registered_device *rdev;
97990a06
JB
7646 struct wireless_dev *wdev;
7647 int survey_idx = cb->args[2];
61fa713c 7648 int res;
11f78ac3 7649 bool radio_stats;
61fa713c 7650
1b8ec87a 7651 res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
7652 if (res)
7653 return res;
61fa713c 7654
11f78ac3
JB
7655 /* prepare_wdev_dump parsed the attributes */
7656 radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
7657
97990a06
JB
7658 if (!wdev->netdev) {
7659 res = -EINVAL;
7660 goto out_err;
7661 }
7662
1b8ec87a 7663 if (!rdev->ops->dump_survey) {
61fa713c
HS
7664 res = -EOPNOTSUPP;
7665 goto out_err;
7666 }
7667
7668 while (1) {
1b8ec87a 7669 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
7670 if (res == -ENOENT)
7671 break;
7672 if (res)
7673 goto out_err;
7674
11f78ac3
JB
7675 /* don't send disabled channels, but do send non-channel data */
7676 if (survey.channel &&
7677 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
7678 survey_idx++;
7679 continue;
7680 }
7681
61fa713c 7682 if (nl80211_send_survey(skb,
15e47304 7683 NETLINK_CB(cb->skb).portid,
61fa713c 7684 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 7685 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
7686 goto out;
7687 survey_idx++;
7688 }
7689
7690 out:
97990a06 7691 cb->args[2] = survey_idx;
61fa713c
HS
7692 res = skb->len;
7693 out_err:
1b8ec87a 7694 nl80211_finish_wdev_dump(rdev);
61fa713c
HS
7695 return res;
7696}
7697
b23aa676
SO
7698static bool nl80211_valid_wpa_versions(u32 wpa_versions)
7699{
7700 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
7701 NL80211_WPA_VERSION_2));
7702}
7703
636a5d36
JM
7704static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
7705{
4c476991
JB
7706 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7707 struct net_device *dev = info->user_ptr[1];
19957bb3 7708 struct ieee80211_channel *chan;
e39e5b5e
JM
7709 const u8 *bssid, *ssid, *ie = NULL, *sae_data = NULL;
7710 int err, ssid_len, ie_len = 0, sae_data_len = 0;
19957bb3 7711 enum nl80211_auth_type auth_type;
fffd0934 7712 struct key_parse key;
d5cdfacb 7713 bool local_state_change;
636a5d36 7714
f4a11bb0
JB
7715 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
7716 return -EINVAL;
7717
7718 if (!info->attrs[NL80211_ATTR_MAC])
7719 return -EINVAL;
7720
1778092e
JM
7721 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
7722 return -EINVAL;
7723
19957bb3
JB
7724 if (!info->attrs[NL80211_ATTR_SSID])
7725 return -EINVAL;
7726
7727 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
7728 return -EINVAL;
7729
fffd0934
JB
7730 err = nl80211_parse_key(info, &key);
7731 if (err)
7732 return err;
7733
7734 if (key.idx >= 0) {
e31b8213
JB
7735 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
7736 return -EINVAL;
fffd0934
JB
7737 if (!key.p.key || !key.p.key_len)
7738 return -EINVAL;
7739 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
7740 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
7741 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
7742 key.p.key_len != WLAN_KEY_LEN_WEP104))
7743 return -EINVAL;
b6b5555b 7744 if (key.idx > 3)
fffd0934
JB
7745 return -EINVAL;
7746 } else {
7747 key.p.key_len = 0;
7748 key.p.key = NULL;
7749 }
7750
afea0b7a
JB
7751 if (key.idx >= 0) {
7752 int i;
7753 bool ok = false;
7a087e74 7754
afea0b7a
JB
7755 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
7756 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
7757 ok = true;
7758 break;
7759 }
7760 }
4c476991
JB
7761 if (!ok)
7762 return -EINVAL;
afea0b7a
JB
7763 }
7764
4c476991
JB
7765 if (!rdev->ops->auth)
7766 return -EOPNOTSUPP;
636a5d36 7767
074ac8df 7768 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7769 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
7770 return -EOPNOTSUPP;
eec60b03 7771
19957bb3 7772 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
664834de
JM
7773 chan = nl80211_get_valid_chan(&rdev->wiphy,
7774 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
7775 if (!chan)
4c476991 7776 return -EINVAL;
636a5d36 7777
19957bb3
JB
7778 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
7779 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
7780
7781 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
7782 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
7783 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
7784 }
7785
19957bb3 7786 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 7787 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 7788 return -EINVAL;
636a5d36 7789
e39e5b5e
JM
7790 if (auth_type == NL80211_AUTHTYPE_SAE &&
7791 !info->attrs[NL80211_ATTR_SAE_DATA])
7792 return -EINVAL;
7793
7794 if (info->attrs[NL80211_ATTR_SAE_DATA]) {
7795 if (auth_type != NL80211_AUTHTYPE_SAE)
7796 return -EINVAL;
7797 sae_data = nla_data(info->attrs[NL80211_ATTR_SAE_DATA]);
7798 sae_data_len = nla_len(info->attrs[NL80211_ATTR_SAE_DATA]);
7799 /* need to include at least Auth Transaction and Status Code */
7800 if (sae_data_len < 4)
7801 return -EINVAL;
7802 }
7803
d5cdfacb
JM
7804 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
7805
95de817b
JB
7806 /*
7807 * Since we no longer track auth state, ignore
7808 * requests to only change local state.
7809 */
7810 if (local_state_change)
7811 return 0;
7812
91bf9b26
JB
7813 wdev_lock(dev->ieee80211_ptr);
7814 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
7815 ssid, ssid_len, ie, ie_len,
7816 key.p.key, key.p.key_len, key.idx,
7817 sae_data, sae_data_len);
7818 wdev_unlock(dev->ieee80211_ptr);
7819 return err;
636a5d36
JM
7820}
7821
c0692b8f
JB
7822static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
7823 struct genl_info *info,
3dc27d25
JB
7824 struct cfg80211_crypto_settings *settings,
7825 int cipher_limit)
b23aa676 7826{
c0b2bbd8
JB
7827 memset(settings, 0, sizeof(*settings));
7828
b23aa676
SO
7829 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
7830
c0692b8f
JB
7831 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
7832 u16 proto;
7a087e74 7833
c0692b8f
JB
7834 proto = nla_get_u16(
7835 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
7836 settings->control_port_ethertype = cpu_to_be16(proto);
7837 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
7838 proto != ETH_P_PAE)
7839 return -EINVAL;
7840 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
7841 settings->control_port_no_encrypt = true;
7842 } else
7843 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
7844
b23aa676
SO
7845 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
7846 void *data;
7847 int len, i;
7848
7849 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
7850 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
7851 settings->n_ciphers_pairwise = len / sizeof(u32);
7852
7853 if (len % sizeof(u32))
7854 return -EINVAL;
7855
3dc27d25 7856 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
7857 return -EINVAL;
7858
7859 memcpy(settings->ciphers_pairwise, data, len);
7860
7861 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
7862 if (!cfg80211_supported_cipher_suite(
7863 &rdev->wiphy,
b23aa676
SO
7864 settings->ciphers_pairwise[i]))
7865 return -EINVAL;
7866 }
7867
7868 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
7869 settings->cipher_group =
7870 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
7871 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
7872 settings->cipher_group))
b23aa676
SO
7873 return -EINVAL;
7874 }
7875
7876 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
7877 settings->wpa_versions =
7878 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
7879 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
7880 return -EINVAL;
7881 }
7882
7883 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
7884 void *data;
6d30240e 7885 int len;
b23aa676
SO
7886
7887 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
7888 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
7889 settings->n_akm_suites = len / sizeof(u32);
7890
7891 if (len % sizeof(u32))
7892 return -EINVAL;
7893
1b9ca027
JM
7894 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
7895 return -EINVAL;
7896
b23aa676 7897 memcpy(settings->akm_suites, data, len);
b23aa676
SO
7898 }
7899
7900 return 0;
7901}
7902
636a5d36
JM
7903static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
7904{
4c476991
JB
7905 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7906 struct net_device *dev = info->user_ptr[1];
f444de05 7907 struct ieee80211_channel *chan;
f62fab73
JB
7908 struct cfg80211_assoc_request req = {};
7909 const u8 *bssid, *ssid;
7910 int err, ssid_len = 0;
636a5d36 7911
f4a11bb0
JB
7912 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
7913 return -EINVAL;
7914
7915 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
7916 !info->attrs[NL80211_ATTR_SSID] ||
7917 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
7918 return -EINVAL;
7919
4c476991
JB
7920 if (!rdev->ops->assoc)
7921 return -EOPNOTSUPP;
636a5d36 7922
074ac8df 7923 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7924 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
7925 return -EOPNOTSUPP;
eec60b03 7926
19957bb3 7927 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 7928
664834de
JM
7929 chan = nl80211_get_valid_chan(&rdev->wiphy,
7930 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
7931 if (!chan)
4c476991 7932 return -EINVAL;
636a5d36 7933
19957bb3
JB
7934 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
7935 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
7936
7937 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
7938 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
7939 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
7940 }
7941
dc6382ce 7942 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 7943 enum nl80211_mfp mfp =
dc6382ce 7944 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 7945 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 7946 req.use_mfp = true;
4c476991
JB
7947 else if (mfp != NL80211_MFP_NO)
7948 return -EINVAL;
dc6382ce
JM
7949 }
7950
3e5d7649 7951 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 7952 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 7953
7e7c8926 7954 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 7955 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
7956
7957 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
7958 memcpy(&req.ht_capa_mask,
7959 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
7960 sizeof(req.ht_capa_mask));
7e7c8926
BG
7961
7962 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 7963 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 7964 return -EINVAL;
f62fab73
JB
7965 memcpy(&req.ht_capa,
7966 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
7967 sizeof(req.ht_capa));
7e7c8926
BG
7968 }
7969
ee2aca34 7970 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 7971 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34
JB
7972
7973 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
7974 memcpy(&req.vht_capa_mask,
7975 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
7976 sizeof(req.vht_capa_mask));
ee2aca34
JB
7977
7978 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 7979 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 7980 return -EINVAL;
f62fab73
JB
7981 memcpy(&req.vht_capa,
7982 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
7983 sizeof(req.vht_capa));
ee2aca34
JB
7984 }
7985
bab5ab7d 7986 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
7987 if (!((rdev->wiphy.features &
7988 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
7989 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
7990 !wiphy_ext_feature_isset(&rdev->wiphy,
7991 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
7992 return -EINVAL;
7993 req.flags |= ASSOC_REQ_USE_RRM;
7994 }
7995
f62fab73 7996 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
7997 if (!err) {
7998 wdev_lock(dev->ieee80211_ptr);
f62fab73
JB
7999 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
8000 ssid, ssid_len, &req);
91bf9b26
JB
8001 wdev_unlock(dev->ieee80211_ptr);
8002 }
636a5d36 8003
636a5d36
JM
8004 return err;
8005}
8006
8007static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
8008{
4c476991
JB
8009 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8010 struct net_device *dev = info->user_ptr[1];
19957bb3 8011 const u8 *ie = NULL, *bssid;
91bf9b26 8012 int ie_len = 0, err;
19957bb3 8013 u16 reason_code;
d5cdfacb 8014 bool local_state_change;
636a5d36 8015
f4a11bb0
JB
8016 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8017 return -EINVAL;
8018
8019 if (!info->attrs[NL80211_ATTR_MAC])
8020 return -EINVAL;
8021
8022 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8023 return -EINVAL;
8024
4c476991
JB
8025 if (!rdev->ops->deauth)
8026 return -EOPNOTSUPP;
636a5d36 8027
074ac8df 8028 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8029 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8030 return -EOPNOTSUPP;
eec60b03 8031
19957bb3 8032 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8033
19957bb3
JB
8034 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8035 if (reason_code == 0) {
f4a11bb0 8036 /* Reason Code 0 is reserved */
4c476991 8037 return -EINVAL;
255e737e 8038 }
636a5d36
JM
8039
8040 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8041 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8042 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8043 }
8044
d5cdfacb
JM
8045 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8046
91bf9b26
JB
8047 wdev_lock(dev->ieee80211_ptr);
8048 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
8049 local_state_change);
8050 wdev_unlock(dev->ieee80211_ptr);
8051 return err;
636a5d36
JM
8052}
8053
8054static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
8055{
4c476991
JB
8056 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8057 struct net_device *dev = info->user_ptr[1];
19957bb3 8058 const u8 *ie = NULL, *bssid;
91bf9b26 8059 int ie_len = 0, err;
19957bb3 8060 u16 reason_code;
d5cdfacb 8061 bool local_state_change;
636a5d36 8062
f4a11bb0
JB
8063 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8064 return -EINVAL;
8065
8066 if (!info->attrs[NL80211_ATTR_MAC])
8067 return -EINVAL;
8068
8069 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8070 return -EINVAL;
8071
4c476991
JB
8072 if (!rdev->ops->disassoc)
8073 return -EOPNOTSUPP;
636a5d36 8074
074ac8df 8075 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8076 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8077 return -EOPNOTSUPP;
eec60b03 8078
19957bb3 8079 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8080
19957bb3
JB
8081 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8082 if (reason_code == 0) {
f4a11bb0 8083 /* Reason Code 0 is reserved */
4c476991 8084 return -EINVAL;
255e737e 8085 }
636a5d36
JM
8086
8087 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8088 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8089 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8090 }
8091
d5cdfacb
JM
8092 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8093
91bf9b26
JB
8094 wdev_lock(dev->ieee80211_ptr);
8095 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
8096 local_state_change);
8097 wdev_unlock(dev->ieee80211_ptr);
8098 return err;
636a5d36
JM
8099}
8100
dd5b4cc7
FF
8101static bool
8102nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 8103 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
8104 int rateval)
8105{
8106 struct wiphy *wiphy = &rdev->wiphy;
8107 bool found = false;
8108 int band, i;
8109
57fbcce3 8110 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
8111 struct ieee80211_supported_band *sband;
8112
8113 sband = wiphy->bands[band];
8114 if (!sband)
8115 continue;
8116
8117 for (i = 0; i < sband->n_bitrates; i++) {
8118 if (sband->bitrates[i].bitrate == rateval) {
8119 mcast_rate[band] = i + 1;
8120 found = true;
8121 break;
8122 }
8123 }
8124 }
8125
8126 return found;
8127}
8128
04a773ad
JB
8129static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
8130{
4c476991
JB
8131 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8132 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
8133 struct cfg80211_ibss_params ibss;
8134 struct wiphy *wiphy;
fffd0934 8135 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
8136 int err;
8137
8e30bc55
JB
8138 memset(&ibss, 0, sizeof(ibss));
8139
04a773ad
JB
8140 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8141 return -EINVAL;
8142
683b6d3b 8143 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
8144 !nla_len(info->attrs[NL80211_ATTR_SSID]))
8145 return -EINVAL;
8146
8e30bc55
JB
8147 ibss.beacon_interval = 100;
8148
12d20fc9 8149 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
8150 ibss.beacon_interval =
8151 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9
PK
8152
8153 err = cfg80211_validate_beacon_int(rdev, ibss.beacon_interval);
8154 if (err)
8155 return err;
8e30bc55 8156
4c476991
JB
8157 if (!rdev->ops->join_ibss)
8158 return -EOPNOTSUPP;
04a773ad 8159
4c476991
JB
8160 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
8161 return -EOPNOTSUPP;
04a773ad 8162
79c97e97 8163 wiphy = &rdev->wiphy;
04a773ad 8164
39193498 8165 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 8166 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
8167
8168 if (!is_valid_ether_addr(ibss.bssid))
8169 return -EINVAL;
8170 }
04a773ad
JB
8171 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8172 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
8173
8174 if (info->attrs[NL80211_ATTR_IE]) {
8175 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8176 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8177 }
8178
683b6d3b
JB
8179 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
8180 if (err)
8181 return err;
04a773ad 8182
174e0cd2
IP
8183 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
8184 NL80211_IFTYPE_ADHOC))
54858ee5
AS
8185 return -EINVAL;
8186
2f301ab2 8187 switch (ibss.chandef.width) {
bf372645
SW
8188 case NL80211_CHAN_WIDTH_5:
8189 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
8190 case NL80211_CHAN_WIDTH_20_NOHT:
8191 break;
8192 case NL80211_CHAN_WIDTH_20:
8193 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
8194 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8195 return -EINVAL;
8196 break;
8197 case NL80211_CHAN_WIDTH_80:
8198 case NL80211_CHAN_WIDTH_80P80:
8199 case NL80211_CHAN_WIDTH_160:
8200 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8201 return -EINVAL;
8202 if (!wiphy_ext_feature_isset(&rdev->wiphy,
8203 NL80211_EXT_FEATURE_VHT_IBSS))
8204 return -EINVAL;
8205 break;
2f301ab2 8206 default:
c04d6150 8207 return -EINVAL;
2f301ab2 8208 }
db9c64cf 8209
04a773ad 8210 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
8211 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
8212
fbd2c8dc
TP
8213 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
8214 u8 *rates =
8215 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8216 int n_rates =
8217 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8218 struct ieee80211_supported_band *sband =
683b6d3b 8219 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 8220
34850ab2
JB
8221 err = ieee80211_get_ratemask(sband, rates, n_rates,
8222 &ibss.basic_rates);
8223 if (err)
8224 return err;
fbd2c8dc 8225 }
dd5b4cc7 8226
803768f5
SW
8227 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8228 memcpy(&ibss.ht_capa_mask,
8229 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8230 sizeof(ibss.ht_capa_mask));
8231
8232 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
8233 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8234 return -EINVAL;
8235 memcpy(&ibss.ht_capa,
8236 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8237 sizeof(ibss.ht_capa));
8238 }
8239
dd5b4cc7
FF
8240 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
8241 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
8242 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
8243 return -EINVAL;
fbd2c8dc 8244
4c476991 8245 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
8246 bool no_ht = false;
8247
4c476991 8248 connkeys = nl80211_parse_connkeys(rdev,
de7044ee
SM
8249 info->attrs[NL80211_ATTR_KEYS],
8250 &no_ht);
4c476991
JB
8251 if (IS_ERR(connkeys))
8252 return PTR_ERR(connkeys);
de7044ee 8253
3d9d1d66
JB
8254 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
8255 no_ht) {
5e950a78 8256 kzfree(connkeys);
de7044ee
SM
8257 return -EINVAL;
8258 }
4c476991 8259 }
04a773ad 8260
267335d6
AQ
8261 ibss.control_port =
8262 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
8263
5336fa88
SW
8264 ibss.userspace_handles_dfs =
8265 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
8266
4c476991 8267 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 8268 if (err)
b47f610b 8269 kzfree(connkeys);
04a773ad
JB
8270 return err;
8271}
8272
8273static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
8274{
4c476991
JB
8275 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8276 struct net_device *dev = info->user_ptr[1];
04a773ad 8277
4c476991
JB
8278 if (!rdev->ops->leave_ibss)
8279 return -EOPNOTSUPP;
04a773ad 8280
4c476991
JB
8281 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
8282 return -EOPNOTSUPP;
04a773ad 8283
4c476991 8284 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
8285}
8286
f4e583c8
AQ
8287static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
8288{
8289 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8290 struct net_device *dev = info->user_ptr[1];
57fbcce3 8291 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
8292 u32 nla_rate;
8293 int err;
8294
8295 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
8296 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
8297 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
8298 return -EOPNOTSUPP;
8299
8300 if (!rdev->ops->set_mcast_rate)
8301 return -EOPNOTSUPP;
8302
8303 memset(mcast_rate, 0, sizeof(mcast_rate));
8304
8305 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
8306 return -EINVAL;
8307
8308 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
8309 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
8310 return -EINVAL;
8311
a1056b1b 8312 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
8313
8314 return err;
8315}
8316
ad7e718c
JB
8317static struct sk_buff *
8318__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
8319 struct wireless_dev *wdev, int approxlen,
8320 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
8321 enum nl80211_attrs attr,
8322 const struct nl80211_vendor_cmd_info *info,
8323 gfp_t gfp)
ad7e718c
JB
8324{
8325 struct sk_buff *skb;
8326 void *hdr;
8327 struct nlattr *data;
8328
8329 skb = nlmsg_new(approxlen + 100, gfp);
8330 if (!skb)
8331 return NULL;
8332
8333 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
8334 if (!hdr) {
8335 kfree_skb(skb);
8336 return NULL;
8337 }
8338
8339 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
8340 goto nla_put_failure;
567ffc35
JB
8341
8342 if (info) {
8343 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
8344 info->vendor_id))
8345 goto nla_put_failure;
8346 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
8347 info->subcmd))
8348 goto nla_put_failure;
8349 }
8350
6c09e791 8351 if (wdev) {
2dad624e
ND
8352 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
8353 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
8354 goto nla_put_failure;
8355 if (wdev->netdev &&
8356 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
8357 wdev->netdev->ifindex))
8358 goto nla_put_failure;
8359 }
8360
ad7e718c 8361 data = nla_nest_start(skb, attr);
76e1fb4b
JB
8362 if (!data)
8363 goto nla_put_failure;
ad7e718c
JB
8364
8365 ((void **)skb->cb)[0] = rdev;
8366 ((void **)skb->cb)[1] = hdr;
8367 ((void **)skb->cb)[2] = data;
8368
8369 return skb;
8370
8371 nla_put_failure:
8372 kfree_skb(skb);
8373 return NULL;
8374}
f4e583c8 8375
e03ad6ea 8376struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 8377 struct wireless_dev *wdev,
e03ad6ea
JB
8378 enum nl80211_commands cmd,
8379 enum nl80211_attrs attr,
8380 int vendor_event_idx,
8381 int approxlen, gfp_t gfp)
8382{
f26cbf40 8383 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
8384 const struct nl80211_vendor_cmd_info *info;
8385
8386 switch (cmd) {
8387 case NL80211_CMD_TESTMODE:
8388 if (WARN_ON(vendor_event_idx != -1))
8389 return NULL;
8390 info = NULL;
8391 break;
8392 case NL80211_CMD_VENDOR:
8393 if (WARN_ON(vendor_event_idx < 0 ||
8394 vendor_event_idx >= wiphy->n_vendor_events))
8395 return NULL;
8396 info = &wiphy->vendor_events[vendor_event_idx];
8397 break;
8398 default:
8399 WARN_ON(1);
8400 return NULL;
8401 }
8402
6c09e791 8403 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, 0, 0,
e03ad6ea
JB
8404 cmd, attr, info, gfp);
8405}
8406EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
8407
8408void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
8409{
8410 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
8411 void *hdr = ((void **)skb->cb)[1];
8412 struct nlattr *data = ((void **)skb->cb)[2];
8413 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
8414
bd8c78e7
JB
8415 /* clear CB data for netlink core to own from now on */
8416 memset(skb->cb, 0, sizeof(skb->cb));
8417
e03ad6ea
JB
8418 nla_nest_end(skb, data);
8419 genlmsg_end(skb, hdr);
8420
8421 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
8422 mcgrp = NL80211_MCGRP_VENDOR;
8423
8424 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0,
8425 mcgrp, gfp);
8426}
8427EXPORT_SYMBOL(__cfg80211_send_event_skb);
8428
aff89a9b 8429#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
8430static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
8431{
4c476991 8432 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fc73f11f
DS
8433 struct wireless_dev *wdev =
8434 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
aff89a9b
JB
8435 int err;
8436
fc73f11f
DS
8437 if (!rdev->ops->testmode_cmd)
8438 return -EOPNOTSUPP;
8439
8440 if (IS_ERR(wdev)) {
8441 err = PTR_ERR(wdev);
8442 if (err != -EINVAL)
8443 return err;
8444 wdev = NULL;
8445 } else if (wdev->wiphy != &rdev->wiphy) {
8446 return -EINVAL;
8447 }
8448
aff89a9b
JB
8449 if (!info->attrs[NL80211_ATTR_TESTDATA])
8450 return -EINVAL;
8451
ad7e718c 8452 rdev->cur_cmd_info = info;
fc73f11f 8453 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
8454 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
8455 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 8456 rdev->cur_cmd_info = NULL;
aff89a9b 8457
aff89a9b
JB
8458 return err;
8459}
8460
71063f0e
WYG
8461static int nl80211_testmode_dump(struct sk_buff *skb,
8462 struct netlink_callback *cb)
8463{
00918d33 8464 struct cfg80211_registered_device *rdev;
71063f0e
WYG
8465 int err;
8466 long phy_idx;
8467 void *data = NULL;
8468 int data_len = 0;
8469
5fe231e8
JB
8470 rtnl_lock();
8471
71063f0e
WYG
8472 if (cb->args[0]) {
8473 /*
8474 * 0 is a valid index, but not valid for args[0],
8475 * so we need to offset by 1.
8476 */
8477 phy_idx = cb->args[0] - 1;
8478 } else {
8479 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
8480 nl80211_fam.attrbuf, nl80211_fam.maxattr,
8481 nl80211_policy);
8482 if (err)
5fe231e8 8483 goto out_err;
00918d33 8484
2bd7e35d
JB
8485 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
8486 nl80211_fam.attrbuf);
8487 if (IS_ERR(rdev)) {
5fe231e8
JB
8488 err = PTR_ERR(rdev);
8489 goto out_err;
00918d33 8490 }
2bd7e35d
JB
8491 phy_idx = rdev->wiphy_idx;
8492 rdev = NULL;
2bd7e35d 8493
71063f0e
WYG
8494 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
8495 cb->args[1] =
8496 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
8497 }
8498
8499 if (cb->args[1]) {
8500 data = nla_data((void *)cb->args[1]);
8501 data_len = nla_len((void *)cb->args[1]);
8502 }
8503
00918d33
JB
8504 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
8505 if (!rdev) {
5fe231e8
JB
8506 err = -ENOENT;
8507 goto out_err;
71063f0e 8508 }
71063f0e 8509
00918d33 8510 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
8511 err = -EOPNOTSUPP;
8512 goto out_err;
8513 }
8514
8515 while (1) {
15e47304 8516 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
8517 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8518 NL80211_CMD_TESTMODE);
8519 struct nlattr *tmdata;
8520
cb35fba3
DC
8521 if (!hdr)
8522 break;
8523
9360ffd1 8524 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
8525 genlmsg_cancel(skb, hdr);
8526 break;
8527 }
8528
8529 tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
8530 if (!tmdata) {
8531 genlmsg_cancel(skb, hdr);
8532 break;
8533 }
e35e4d28 8534 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
8535 nla_nest_end(skb, tmdata);
8536
8537 if (err == -ENOBUFS || err == -ENOENT) {
8538 genlmsg_cancel(skb, hdr);
8539 break;
8540 } else if (err) {
8541 genlmsg_cancel(skb, hdr);
8542 goto out_err;
8543 }
8544
8545 genlmsg_end(skb, hdr);
8546 }
8547
8548 err = skb->len;
8549 /* see above */
8550 cb->args[0] = phy_idx + 1;
8551 out_err:
5fe231e8 8552 rtnl_unlock();
71063f0e
WYG
8553 return err;
8554}
aff89a9b
JB
8555#endif
8556
b23aa676
SO
8557static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
8558{
4c476991
JB
8559 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8560 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
8561 struct cfg80211_connect_params connect;
8562 struct wiphy *wiphy;
fffd0934 8563 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
8564 int err;
8565
8566 memset(&connect, 0, sizeof(connect));
8567
8568 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8569 return -EINVAL;
8570
8571 if (!info->attrs[NL80211_ATTR_SSID] ||
8572 !nla_len(info->attrs[NL80211_ATTR_SSID]))
8573 return -EINVAL;
8574
8575 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
8576 connect.auth_type =
8577 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
8578 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
8579 NL80211_CMD_CONNECT))
b23aa676
SO
8580 return -EINVAL;
8581 } else
8582 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
8583
8584 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
8585
c0692b8f 8586 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 8587 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
8588 if (err)
8589 return err;
b23aa676 8590
074ac8df 8591 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8592 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8593 return -EOPNOTSUPP;
b23aa676 8594
79c97e97 8595 wiphy = &rdev->wiphy;
b23aa676 8596
4486ea98
BS
8597 connect.bg_scan_period = -1;
8598 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
8599 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
8600 connect.bg_scan_period =
8601 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
8602 }
8603
b23aa676
SO
8604 if (info->attrs[NL80211_ATTR_MAC])
8605 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
8606 else if (info->attrs[NL80211_ATTR_MAC_HINT])
8607 connect.bssid_hint =
8608 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
8609 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8610 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
8611
8612 if (info->attrs[NL80211_ATTR_IE]) {
8613 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8614 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8615 }
8616
cee00a95
JM
8617 if (info->attrs[NL80211_ATTR_USE_MFP]) {
8618 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
8619 if (connect.mfp != NL80211_MFP_REQUIRED &&
8620 connect.mfp != NL80211_MFP_NO)
8621 return -EINVAL;
8622 } else {
8623 connect.mfp = NL80211_MFP_NO;
8624 }
8625
ba6fbacf
JM
8626 if (info->attrs[NL80211_ATTR_PREV_BSSID])
8627 connect.prev_bssid =
8628 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
8629
b23aa676 8630 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
664834de
JM
8631 connect.channel = nl80211_get_valid_chan(
8632 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8633 if (!connect.channel)
1df4a510
JM
8634 return -EINVAL;
8635 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
664834de
JM
8636 connect.channel_hint = nl80211_get_valid_chan(
8637 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
8638 if (!connect.channel_hint)
4c476991 8639 return -EINVAL;
b23aa676
SO
8640 }
8641
fffd0934
JB
8642 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
8643 connkeys = nl80211_parse_connkeys(rdev,
de7044ee 8644 info->attrs[NL80211_ATTR_KEYS], NULL);
4c476991
JB
8645 if (IS_ERR(connkeys))
8646 return PTR_ERR(connkeys);
fffd0934
JB
8647 }
8648
7e7c8926
BG
8649 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
8650 connect.flags |= ASSOC_REQ_DISABLE_HT;
8651
8652 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8653 memcpy(&connect.ht_capa_mask,
8654 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8655 sizeof(connect.ht_capa_mask));
8656
8657 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 8658 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
b47f610b 8659 kzfree(connkeys);
7e7c8926 8660 return -EINVAL;
b4e4f47e 8661 }
7e7c8926
BG
8662 memcpy(&connect.ht_capa,
8663 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8664 sizeof(connect.ht_capa));
8665 }
8666
ee2aca34
JB
8667 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
8668 connect.flags |= ASSOC_REQ_DISABLE_VHT;
8669
8670 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
8671 memcpy(&connect.vht_capa_mask,
8672 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
8673 sizeof(connect.vht_capa_mask));
8674
8675 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
8676 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
b47f610b 8677 kzfree(connkeys);
ee2aca34
JB
8678 return -EINVAL;
8679 }
8680 memcpy(&connect.vht_capa,
8681 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
8682 sizeof(connect.vht_capa));
8683 }
8684
bab5ab7d 8685 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
8686 if (!((rdev->wiphy.features &
8687 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
8688 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
8689 !wiphy_ext_feature_isset(&rdev->wiphy,
8690 NL80211_EXT_FEATURE_RRM)) {
707554b4 8691 kzfree(connkeys);
bab5ab7d 8692 return -EINVAL;
707554b4 8693 }
bab5ab7d
AK
8694 connect.flags |= ASSOC_REQ_USE_RRM;
8695 }
8696
34d50519 8697 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 8698 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
34d50519
LD
8699 kzfree(connkeys);
8700 return -EOPNOTSUPP;
8701 }
8702
38de03d2
AS
8703 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
8704 /* bss selection makes no sense if bssid is set */
8705 if (connect.bssid) {
8706 kzfree(connkeys);
8707 return -EINVAL;
8708 }
8709
8710 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
8711 wiphy, &connect.bss_select);
8712 if (err) {
8713 kzfree(connkeys);
8714 return err;
8715 }
8716 }
8717
83739b03 8718 wdev_lock(dev->ieee80211_ptr);
4ce2bd9c
JM
8719 err = cfg80211_connect(rdev, dev, &connect, connkeys,
8720 connect.prev_bssid);
83739b03 8721 wdev_unlock(dev->ieee80211_ptr);
fffd0934 8722 if (err)
b47f610b 8723 kzfree(connkeys);
b23aa676
SO
8724 return err;
8725}
8726
8727static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
8728{
4c476991
JB
8729 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8730 struct net_device *dev = info->user_ptr[1];
b23aa676 8731 u16 reason;
83739b03 8732 int ret;
b23aa676
SO
8733
8734 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8735 reason = WLAN_REASON_DEAUTH_LEAVING;
8736 else
8737 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8738
8739 if (reason == 0)
8740 return -EINVAL;
8741
074ac8df 8742 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8743 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8744 return -EOPNOTSUPP;
b23aa676 8745
83739b03
JB
8746 wdev_lock(dev->ieee80211_ptr);
8747 ret = cfg80211_disconnect(rdev, dev, reason, true);
8748 wdev_unlock(dev->ieee80211_ptr);
8749 return ret;
b23aa676
SO
8750}
8751
463d0183
JB
8752static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
8753{
4c476991 8754 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
8755 struct net *net;
8756 int err;
463d0183 8757
4b681c82
VK
8758 if (info->attrs[NL80211_ATTR_PID]) {
8759 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
8760
8761 net = get_net_ns_by_pid(pid);
8762 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
8763 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 8764
4b681c82
VK
8765 net = get_net_ns_by_fd(fd);
8766 } else {
8767 return -EINVAL;
8768 }
463d0183 8769
4c476991
JB
8770 if (IS_ERR(net))
8771 return PTR_ERR(net);
463d0183
JB
8772
8773 err = 0;
8774
8775 /* check if anything to do */
4c476991
JB
8776 if (!net_eq(wiphy_net(&rdev->wiphy), net))
8777 err = cfg80211_switch_netns(rdev, net);
463d0183 8778
463d0183 8779 put_net(net);
463d0183
JB
8780 return err;
8781}
8782
67fbb16b
SO
8783static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
8784{
4c476991 8785 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
8786 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
8787 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 8788 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
8789 struct cfg80211_pmksa pmksa;
8790
8791 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
8792
8793 if (!info->attrs[NL80211_ATTR_MAC])
8794 return -EINVAL;
8795
8796 if (!info->attrs[NL80211_ATTR_PMKID])
8797 return -EINVAL;
8798
67fbb16b
SO
8799 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
8800 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
8801
074ac8df 8802 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8803 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8804 return -EOPNOTSUPP;
67fbb16b
SO
8805
8806 switch (info->genlhdr->cmd) {
8807 case NL80211_CMD_SET_PMKSA:
8808 rdev_ops = rdev->ops->set_pmksa;
8809 break;
8810 case NL80211_CMD_DEL_PMKSA:
8811 rdev_ops = rdev->ops->del_pmksa;
8812 break;
8813 default:
8814 WARN_ON(1);
8815 break;
8816 }
8817
4c476991
JB
8818 if (!rdev_ops)
8819 return -EOPNOTSUPP;
67fbb16b 8820
4c476991 8821 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
8822}
8823
8824static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
8825{
4c476991
JB
8826 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8827 struct net_device *dev = info->user_ptr[1];
67fbb16b 8828
074ac8df 8829 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8830 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8831 return -EOPNOTSUPP;
67fbb16b 8832
4c476991
JB
8833 if (!rdev->ops->flush_pmksa)
8834 return -EOPNOTSUPP;
67fbb16b 8835
e35e4d28 8836 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
8837}
8838
109086ce
AN
8839static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
8840{
8841 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8842 struct net_device *dev = info->user_ptr[1];
8843 u8 action_code, dialog_token;
df942e7b 8844 u32 peer_capability = 0;
109086ce
AN
8845 u16 status_code;
8846 u8 *peer;
31fa97c5 8847 bool initiator;
109086ce
AN
8848
8849 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
8850 !rdev->ops->tdls_mgmt)
8851 return -EOPNOTSUPP;
8852
8853 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
8854 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
8855 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
8856 !info->attrs[NL80211_ATTR_IE] ||
8857 !info->attrs[NL80211_ATTR_MAC])
8858 return -EINVAL;
8859
8860 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
8861 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
8862 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
8863 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 8864 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
8865 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
8866 peer_capability =
8867 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 8868
e35e4d28 8869 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 8870 dialog_token, status_code, peer_capability,
31fa97c5 8871 initiator,
e35e4d28
HG
8872 nla_data(info->attrs[NL80211_ATTR_IE]),
8873 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
8874}
8875
8876static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
8877{
8878 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8879 struct net_device *dev = info->user_ptr[1];
8880 enum nl80211_tdls_operation operation;
8881 u8 *peer;
8882
8883 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
8884 !rdev->ops->tdls_oper)
8885 return -EOPNOTSUPP;
8886
8887 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
8888 !info->attrs[NL80211_ATTR_MAC])
8889 return -EINVAL;
8890
8891 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
8892 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
8893
e35e4d28 8894 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
8895}
8896
9588bbd5
JM
8897static int nl80211_remain_on_channel(struct sk_buff *skb,
8898 struct genl_info *info)
8899{
4c476991 8900 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 8901 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 8902 struct cfg80211_chan_def chandef;
9588bbd5
JM
8903 struct sk_buff *msg;
8904 void *hdr;
8905 u64 cookie;
683b6d3b 8906 u32 duration;
9588bbd5
JM
8907 int err;
8908
8909 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
8910 !info->attrs[NL80211_ATTR_DURATION])
8911 return -EINVAL;
8912
8913 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
8914
ebf348fc
JB
8915 if (!rdev->ops->remain_on_channel ||
8916 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
8917 return -EOPNOTSUPP;
8918
9588bbd5 8919 /*
ebf348fc
JB
8920 * We should be on that channel for at least a minimum amount of
8921 * time (10ms) but no longer than the driver supports.
9588bbd5 8922 */
ebf348fc 8923 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 8924 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
8925 return -EINVAL;
8926
683b6d3b
JB
8927 err = nl80211_parse_chandef(rdev, info, &chandef);
8928 if (err)
8929 return err;
9588bbd5
JM
8930
8931 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
8932 if (!msg)
8933 return -ENOMEM;
9588bbd5 8934
15e47304 8935 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 8936 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
8937 if (!hdr) {
8938 err = -ENOBUFS;
9588bbd5
JM
8939 goto free_msg;
8940 }
8941
683b6d3b
JB
8942 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
8943 duration, &cookie);
9588bbd5
JM
8944
8945 if (err)
8946 goto free_msg;
8947
2dad624e
ND
8948 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
8949 NL80211_ATTR_PAD))
9360ffd1 8950 goto nla_put_failure;
9588bbd5
JM
8951
8952 genlmsg_end(msg, hdr);
4c476991
JB
8953
8954 return genlmsg_reply(msg, info);
9588bbd5
JM
8955
8956 nla_put_failure:
8957 err = -ENOBUFS;
8958 free_msg:
8959 nlmsg_free(msg);
9588bbd5
JM
8960 return err;
8961}
8962
8963static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
8964 struct genl_info *info)
8965{
4c476991 8966 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 8967 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 8968 u64 cookie;
9588bbd5
JM
8969
8970 if (!info->attrs[NL80211_ATTR_COOKIE])
8971 return -EINVAL;
8972
4c476991
JB
8973 if (!rdev->ops->cancel_remain_on_channel)
8974 return -EOPNOTSUPP;
9588bbd5 8975
9588bbd5
JM
8976 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
8977
e35e4d28 8978 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
8979}
8980
13ae75b1
JM
8981static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
8982 struct genl_info *info)
8983{
13ae75b1 8984 struct cfg80211_bitrate_mask mask;
a7c7fbff 8985 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 8986 struct net_device *dev = info->user_ptr[1];
a7c7fbff 8987 int err;
13ae75b1 8988
4c476991
JB
8989 if (!rdev->ops->set_bitrate_mask)
8990 return -EOPNOTSUPP;
13ae75b1 8991
a7c7fbff
PK
8992 err = nl80211_parse_tx_bitrate_mask(info, &mask);
8993 if (err)
8994 return err;
13ae75b1 8995
e35e4d28 8996 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
8997}
8998
2e161f78 8999static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 9000{
4c476991 9001 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9002 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 9003 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
9004
9005 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
9006 return -EINVAL;
9007
2e161f78
JB
9008 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
9009 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 9010
71bbc994
JB
9011 switch (wdev->iftype) {
9012 case NL80211_IFTYPE_STATION:
9013 case NL80211_IFTYPE_ADHOC:
9014 case NL80211_IFTYPE_P2P_CLIENT:
9015 case NL80211_IFTYPE_AP:
9016 case NL80211_IFTYPE_AP_VLAN:
9017 case NL80211_IFTYPE_MESH_POINT:
9018 case NL80211_IFTYPE_P2P_GO:
98104fde 9019 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 9020 break;
cb3b7d87 9021 case NL80211_IFTYPE_NAN:
71bbc994 9022 default:
4c476991 9023 return -EOPNOTSUPP;
71bbc994 9024 }
026331c4
JM
9025
9026 /* not much point in registering if we can't reply */
4c476991
JB
9027 if (!rdev->ops->mgmt_tx)
9028 return -EOPNOTSUPP;
026331c4 9029
15e47304 9030 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
026331c4
JM
9031 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
9032 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
026331c4
JM
9033}
9034
2e161f78 9035static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 9036{
4c476991 9037 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9038 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 9039 struct cfg80211_chan_def chandef;
026331c4 9040 int err;
d64d373f 9041 void *hdr = NULL;
026331c4 9042 u64 cookie;
e247bd90 9043 struct sk_buff *msg = NULL;
b176e629
AO
9044 struct cfg80211_mgmt_tx_params params = {
9045 .dont_wait_for_ack =
9046 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
9047 };
026331c4 9048
683b6d3b 9049 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
9050 return -EINVAL;
9051
4c476991
JB
9052 if (!rdev->ops->mgmt_tx)
9053 return -EOPNOTSUPP;
026331c4 9054
71bbc994 9055 switch (wdev->iftype) {
ea141b75
AQ
9056 case NL80211_IFTYPE_P2P_DEVICE:
9057 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
9058 return -EINVAL;
71bbc994
JB
9059 case NL80211_IFTYPE_STATION:
9060 case NL80211_IFTYPE_ADHOC:
9061 case NL80211_IFTYPE_P2P_CLIENT:
9062 case NL80211_IFTYPE_AP:
9063 case NL80211_IFTYPE_AP_VLAN:
9064 case NL80211_IFTYPE_MESH_POINT:
9065 case NL80211_IFTYPE_P2P_GO:
9066 break;
cb3b7d87 9067 case NL80211_IFTYPE_NAN:
71bbc994 9068 default:
4c476991 9069 return -EOPNOTSUPP;
71bbc994 9070 }
026331c4 9071
f7ca38df 9072 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 9073 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 9074 return -EINVAL;
b176e629 9075 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
9076
9077 /*
9078 * We should wait on the channel for at least a minimum amount
9079 * of time (10ms) but no longer than the driver supports.
9080 */
b176e629
AO
9081 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
9082 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 9083 return -EINVAL;
f7ca38df
JB
9084 }
9085
b176e629 9086 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 9087
b176e629 9088 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
9089 return -EINVAL;
9090
b176e629 9091 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 9092
ea141b75
AQ
9093 /* get the channel if any has been specified, otherwise pass NULL to
9094 * the driver. The latter will use the current one
9095 */
9096 chandef.chan = NULL;
9097 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
9098 err = nl80211_parse_chandef(rdev, info, &chandef);
9099 if (err)
9100 return err;
9101 }
9102
b176e629 9103 if (!chandef.chan && params.offchan)
ea141b75 9104 return -EINVAL;
026331c4 9105
34d22ce2
AO
9106 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
9107 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
9108
9109 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
9110 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
9111 int i;
9112
9113 if (len % sizeof(u16))
9114 return -EINVAL;
9115
9116 params.n_csa_offsets = len / sizeof(u16);
9117 params.csa_offsets =
9118 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
9119
9120 /* check that all the offsets fit the frame */
9121 for (i = 0; i < params.n_csa_offsets; i++) {
9122 if (params.csa_offsets[i] >= params.len)
9123 return -EINVAL;
9124 }
9125 }
9126
b176e629 9127 if (!params.dont_wait_for_ack) {
e247bd90
JB
9128 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9129 if (!msg)
9130 return -ENOMEM;
026331c4 9131
15e47304 9132 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 9133 NL80211_CMD_FRAME);
cb35fba3
DC
9134 if (!hdr) {
9135 err = -ENOBUFS;
e247bd90
JB
9136 goto free_msg;
9137 }
026331c4 9138 }
e247bd90 9139
b176e629
AO
9140 params.chan = chandef.chan;
9141 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
9142 if (err)
9143 goto free_msg;
9144
e247bd90 9145 if (msg) {
2dad624e
ND
9146 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
9147 NL80211_ATTR_PAD))
9360ffd1 9148 goto nla_put_failure;
026331c4 9149
e247bd90
JB
9150 genlmsg_end(msg, hdr);
9151 return genlmsg_reply(msg, info);
9152 }
9153
9154 return 0;
026331c4
JM
9155
9156 nla_put_failure:
9157 err = -ENOBUFS;
9158 free_msg:
9159 nlmsg_free(msg);
026331c4
JM
9160 return err;
9161}
9162
f7ca38df
JB
9163static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
9164{
9165 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9166 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
9167 u64 cookie;
9168
9169 if (!info->attrs[NL80211_ATTR_COOKIE])
9170 return -EINVAL;
9171
9172 if (!rdev->ops->mgmt_tx_cancel_wait)
9173 return -EOPNOTSUPP;
9174
71bbc994
JB
9175 switch (wdev->iftype) {
9176 case NL80211_IFTYPE_STATION:
9177 case NL80211_IFTYPE_ADHOC:
9178 case NL80211_IFTYPE_P2P_CLIENT:
9179 case NL80211_IFTYPE_AP:
9180 case NL80211_IFTYPE_AP_VLAN:
9181 case NL80211_IFTYPE_P2P_GO:
98104fde 9182 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 9183 break;
cb3b7d87 9184 case NL80211_IFTYPE_NAN:
71bbc994 9185 default:
f7ca38df 9186 return -EOPNOTSUPP;
71bbc994 9187 }
f7ca38df
JB
9188
9189 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9190
e35e4d28 9191 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
9192}
9193
ffb9eb3d
KV
9194static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
9195{
4c476991 9196 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 9197 struct wireless_dev *wdev;
4c476991 9198 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
9199 u8 ps_state;
9200 bool state;
9201 int err;
9202
4c476991
JB
9203 if (!info->attrs[NL80211_ATTR_PS_STATE])
9204 return -EINVAL;
ffb9eb3d
KV
9205
9206 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
9207
4c476991
JB
9208 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
9209 return -EINVAL;
ffb9eb3d
KV
9210
9211 wdev = dev->ieee80211_ptr;
9212
4c476991
JB
9213 if (!rdev->ops->set_power_mgmt)
9214 return -EOPNOTSUPP;
ffb9eb3d
KV
9215
9216 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
9217
9218 if (state == wdev->ps)
4c476991 9219 return 0;
ffb9eb3d 9220
e35e4d28 9221 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
9222 if (!err)
9223 wdev->ps = state;
ffb9eb3d
KV
9224 return err;
9225}
9226
9227static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
9228{
4c476991 9229 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
9230 enum nl80211_ps_state ps_state;
9231 struct wireless_dev *wdev;
4c476991 9232 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
9233 struct sk_buff *msg;
9234 void *hdr;
9235 int err;
9236
ffb9eb3d
KV
9237 wdev = dev->ieee80211_ptr;
9238
4c476991
JB
9239 if (!rdev->ops->set_power_mgmt)
9240 return -EOPNOTSUPP;
ffb9eb3d
KV
9241
9242 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
9243 if (!msg)
9244 return -ENOMEM;
ffb9eb3d 9245
15e47304 9246 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
9247 NL80211_CMD_GET_POWER_SAVE);
9248 if (!hdr) {
4c476991 9249 err = -ENOBUFS;
ffb9eb3d
KV
9250 goto free_msg;
9251 }
9252
9253 if (wdev->ps)
9254 ps_state = NL80211_PS_ENABLED;
9255 else
9256 ps_state = NL80211_PS_DISABLED;
9257
9360ffd1
DM
9258 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
9259 goto nla_put_failure;
ffb9eb3d
KV
9260
9261 genlmsg_end(msg, hdr);
4c476991 9262 return genlmsg_reply(msg, info);
ffb9eb3d 9263
4c476991 9264 nla_put_failure:
ffb9eb3d 9265 err = -ENOBUFS;
4c476991 9266 free_msg:
ffb9eb3d 9267 nlmsg_free(msg);
ffb9eb3d
KV
9268 return err;
9269}
9270
94e860f1
JB
9271static const struct nla_policy
9272nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
d6dc1a38
JO
9273 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
9274 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
9275 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
9276 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
9277 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
9278 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
d6dc1a38
JO
9279};
9280
84f10708 9281static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 9282 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
9283{
9284 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 9285 struct net_device *dev = info->user_ptr[1];
1da5fcc8 9286 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 9287
d9d8b019 9288 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
9289 return -EINVAL;
9290
84f10708
TP
9291 if (!rdev->ops->set_cqm_txe_config)
9292 return -EOPNOTSUPP;
9293
9294 if (wdev->iftype != NL80211_IFTYPE_STATION &&
9295 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
9296 return -EOPNOTSUPP;
9297
e35e4d28 9298 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
9299}
9300
d6dc1a38
JO
9301static int nl80211_set_cqm_rssi(struct genl_info *info,
9302 s32 threshold, u32 hysteresis)
9303{
4c476991 9304 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 9305 struct net_device *dev = info->user_ptr[1];
1da5fcc8 9306 struct wireless_dev *wdev = dev->ieee80211_ptr;
d6dc1a38
JO
9307
9308 if (threshold > 0)
9309 return -EINVAL;
9310
1da5fcc8
JB
9311 /* disabling - hysteresis should also be zero then */
9312 if (threshold == 0)
9313 hysteresis = 0;
d6dc1a38 9314
4c476991
JB
9315 if (!rdev->ops->set_cqm_rssi_config)
9316 return -EOPNOTSUPP;
d6dc1a38 9317
074ac8df 9318 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9319 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
9320 return -EOPNOTSUPP;
d6dc1a38 9321
e35e4d28 9322 return rdev_set_cqm_rssi_config(rdev, dev, threshold, hysteresis);
d6dc1a38
JO
9323}
9324
9325static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
9326{
9327 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
9328 struct nlattr *cqm;
9329 int err;
9330
9331 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
9332 if (!cqm)
9333 return -EINVAL;
d6dc1a38
JO
9334
9335 err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
9336 nl80211_attr_cqm_policy);
9337 if (err)
1da5fcc8 9338 return err;
d6dc1a38
JO
9339
9340 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
9341 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
1da5fcc8
JB
9342 s32 threshold = nla_get_s32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
9343 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 9344
1da5fcc8
JB
9345 return nl80211_set_cqm_rssi(info, threshold, hysteresis);
9346 }
9347
9348 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
9349 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
9350 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
9351 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
9352 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
9353 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
9354
9355 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
9356 }
9357
9358 return -EINVAL;
d6dc1a38
JO
9359}
9360
6e0bd6c3
RL
9361static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
9362{
9363 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9364 struct net_device *dev = info->user_ptr[1];
9365 struct ocb_setup setup = {};
9366 int err;
9367
9368 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
9369 if (err)
9370 return err;
9371
9372 return cfg80211_join_ocb(rdev, dev, &setup);
9373}
9374
9375static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
9376{
9377 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9378 struct net_device *dev = info->user_ptr[1];
9379
9380 return cfg80211_leave_ocb(rdev, dev);
9381}
9382
29cbe68c
JB
9383static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
9384{
9385 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9386 struct net_device *dev = info->user_ptr[1];
9387 struct mesh_config cfg;
c80d545d 9388 struct mesh_setup setup;
29cbe68c
JB
9389 int err;
9390
9391 /* start with default */
9392 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 9393 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 9394
24bdd9f4 9395 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 9396 /* and parse parameters if given */
24bdd9f4 9397 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
9398 if (err)
9399 return err;
9400 }
9401
9402 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
9403 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
9404 return -EINVAL;
9405
c80d545d
JC
9406 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
9407 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
9408
4bb62344
CYY
9409 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
9410 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
9411 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
9412 return -EINVAL;
9413
9bdbf04d
MP
9414 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
9415 setup.beacon_interval =
9416 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9
PK
9417
9418 err = cfg80211_validate_beacon_int(rdev, setup.beacon_interval);
9419 if (err)
9420 return err;
9bdbf04d
MP
9421 }
9422
9423 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
9424 setup.dtim_period =
9425 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
9426 if (setup.dtim_period < 1 || setup.dtim_period > 100)
9427 return -EINVAL;
9428 }
9429
c80d545d
JC
9430 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
9431 /* parse additional setup parameters if given */
9432 err = nl80211_parse_mesh_setup(info, &setup);
9433 if (err)
9434 return err;
9435 }
9436
d37bb18a
TP
9437 if (setup.user_mpm)
9438 cfg.auto_open_plinks = false;
9439
cc1d2806 9440 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
9441 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
9442 if (err)
9443 return err;
cc1d2806
JB
9444 } else {
9445 /* cfg80211_join_mesh() will sort it out */
683b6d3b 9446 setup.chandef.chan = NULL;
cc1d2806
JB
9447 }
9448
ffb3cf30
AN
9449 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
9450 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9451 int n_rates =
9452 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9453 struct ieee80211_supported_band *sband;
9454
9455 if (!setup.chandef.chan)
9456 return -EINVAL;
9457
9458 sband = rdev->wiphy.bands[setup.chandef.chan->band];
9459
9460 err = ieee80211_get_ratemask(sband, rates, n_rates,
9461 &setup.basic_rates);
9462 if (err)
9463 return err;
9464 }
9465
8564e382
JB
9466 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9467 err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate);
9468 if (err)
9469 return err;
9470
9471 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
9472 &setup.beacon_rate);
9473 if (err)
9474 return err;
9475 }
9476
c80d545d 9477 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
29cbe68c
JB
9478}
9479
9480static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
9481{
9482 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9483 struct net_device *dev = info->user_ptr[1];
9484
9485 return cfg80211_leave_mesh(rdev, dev);
9486}
9487
dfb89c56 9488#ifdef CONFIG_PM
bb92d199
AK
9489static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
9490 struct cfg80211_registered_device *rdev)
9491{
6abb9cb9 9492 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
9493 struct nlattr *nl_pats, *nl_pat;
9494 int i, pat_len;
9495
6abb9cb9 9496 if (!wowlan->n_patterns)
bb92d199
AK
9497 return 0;
9498
9499 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
9500 if (!nl_pats)
9501 return -ENOBUFS;
9502
6abb9cb9 9503 for (i = 0; i < wowlan->n_patterns; i++) {
bb92d199
AK
9504 nl_pat = nla_nest_start(msg, i + 1);
9505 if (!nl_pat)
9506 return -ENOBUFS;
6abb9cb9 9507 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 9508 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 9509 wowlan->patterns[i].mask) ||
50ac6607
AK
9510 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
9511 wowlan->patterns[i].pattern) ||
9512 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 9513 wowlan->patterns[i].pkt_offset))
bb92d199
AK
9514 return -ENOBUFS;
9515 nla_nest_end(msg, nl_pat);
9516 }
9517 nla_nest_end(msg, nl_pats);
9518
9519 return 0;
9520}
9521
2a0e047e
JB
9522static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
9523 struct cfg80211_wowlan_tcp *tcp)
9524{
9525 struct nlattr *nl_tcp;
9526
9527 if (!tcp)
9528 return 0;
9529
9530 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
9531 if (!nl_tcp)
9532 return -ENOBUFS;
9533
930345ea
JB
9534 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
9535 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
9536 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
9537 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
9538 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
9539 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
9540 tcp->payload_len, tcp->payload) ||
9541 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
9542 tcp->data_interval) ||
9543 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
9544 tcp->wake_len, tcp->wake_data) ||
9545 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
9546 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
9547 return -ENOBUFS;
9548
9549 if (tcp->payload_seq.len &&
9550 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
9551 sizeof(tcp->payload_seq), &tcp->payload_seq))
9552 return -ENOBUFS;
9553
9554 if (tcp->payload_tok.len &&
9555 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
9556 sizeof(tcp->payload_tok) + tcp->tokens_size,
9557 &tcp->payload_tok))
9558 return -ENOBUFS;
9559
e248ad30
JB
9560 nla_nest_end(msg, nl_tcp);
9561
2a0e047e
JB
9562 return 0;
9563}
9564
75453ccb
LC
9565static int nl80211_send_wowlan_nd(struct sk_buff *msg,
9566 struct cfg80211_sched_scan_request *req)
9567{
3b06d277 9568 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
9569 int i;
9570
9571 if (!req)
9572 return 0;
9573
9574 nd = nla_nest_start(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
9575 if (!nd)
9576 return -ENOBUFS;
9577
3b06d277
AS
9578 if (req->n_scan_plans == 1 &&
9579 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
9580 req->scan_plans[0].interval * 1000))
75453ccb
LC
9581 return -ENOBUFS;
9582
21fea567
LC
9583 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
9584 return -ENOBUFS;
9585
75453ccb
LC
9586 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
9587 if (!freqs)
9588 return -ENOBUFS;
9589
53b18980
JB
9590 for (i = 0; i < req->n_channels; i++) {
9591 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
9592 return -ENOBUFS;
9593 }
75453ccb
LC
9594
9595 nla_nest_end(msg, freqs);
9596
9597 if (req->n_match_sets) {
9598 matches = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
9599 if (!matches)
9600 return -ENOBUFS;
9601
75453ccb
LC
9602 for (i = 0; i < req->n_match_sets; i++) {
9603 match = nla_nest_start(msg, i);
76e1fb4b
JB
9604 if (!match)
9605 return -ENOBUFS;
9606
53b18980
JB
9607 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
9608 req->match_sets[i].ssid.ssid_len,
9609 req->match_sets[i].ssid.ssid))
9610 return -ENOBUFS;
75453ccb
LC
9611 nla_nest_end(msg, match);
9612 }
9613 nla_nest_end(msg, matches);
9614 }
9615
3b06d277
AS
9616 scan_plans = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
9617 if (!scan_plans)
9618 return -ENOBUFS;
9619
9620 for (i = 0; i < req->n_scan_plans; i++) {
9621 scan_plan = nla_nest_start(msg, i + 1);
76e1fb4b
JB
9622 if (!scan_plan)
9623 return -ENOBUFS;
9624
3b06d277
AS
9625 if (!scan_plan ||
9626 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
9627 req->scan_plans[i].interval) ||
9628 (req->scan_plans[i].iterations &&
9629 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
9630 req->scan_plans[i].iterations)))
9631 return -ENOBUFS;
9632 nla_nest_end(msg, scan_plan);
9633 }
9634 nla_nest_end(msg, scan_plans);
9635
75453ccb
LC
9636 nla_nest_end(msg, nd);
9637
9638 return 0;
9639}
9640
ff1b6e69
JB
9641static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
9642{
9643 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9644 struct sk_buff *msg;
9645 void *hdr;
2a0e047e 9646 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 9647
964dc9e2 9648 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
9649 return -EOPNOTSUPP;
9650
6abb9cb9 9651 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 9652 /* adjust size to have room for all the data */
6abb9cb9
JB
9653 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
9654 rdev->wiphy.wowlan_config->tcp->payload_len +
9655 rdev->wiphy.wowlan_config->tcp->wake_len +
9656 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
9657 }
9658
9659 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
9660 if (!msg)
9661 return -ENOMEM;
9662
15e47304 9663 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
9664 NL80211_CMD_GET_WOWLAN);
9665 if (!hdr)
9666 goto nla_put_failure;
9667
6abb9cb9 9668 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
9669 struct nlattr *nl_wowlan;
9670
9671 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
9672 if (!nl_wowlan)
9673 goto nla_put_failure;
9674
6abb9cb9 9675 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 9676 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 9677 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 9678 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 9679 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 9680 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 9681 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 9682 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 9683 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 9684 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 9685 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 9686 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 9687 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
9688 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
9689 goto nla_put_failure;
2a0e047e 9690
bb92d199
AK
9691 if (nl80211_send_wowlan_patterns(msg, rdev))
9692 goto nla_put_failure;
2a0e047e 9693
6abb9cb9
JB
9694 if (nl80211_send_wowlan_tcp(msg,
9695 rdev->wiphy.wowlan_config->tcp))
2a0e047e 9696 goto nla_put_failure;
75453ccb
LC
9697
9698 if (nl80211_send_wowlan_nd(
9699 msg,
9700 rdev->wiphy.wowlan_config->nd_config))
9701 goto nla_put_failure;
2a0e047e 9702
ff1b6e69
JB
9703 nla_nest_end(msg, nl_wowlan);
9704 }
9705
9706 genlmsg_end(msg, hdr);
9707 return genlmsg_reply(msg, info);
9708
9709nla_put_failure:
9710 nlmsg_free(msg);
9711 return -ENOBUFS;
9712}
9713
2a0e047e
JB
9714static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
9715 struct nlattr *attr,
9716 struct cfg80211_wowlan *trig)
9717{
9718 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
9719 struct cfg80211_wowlan_tcp *cfg;
9720 struct nl80211_wowlan_tcp_data_token *tok = NULL;
9721 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
9722 u32 size;
9723 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
9724 int err, port;
9725
964dc9e2 9726 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
9727 return -EINVAL;
9728
9729 err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP,
9730 nla_data(attr), nla_len(attr),
9731 nl80211_wowlan_tcp_policy);
9732 if (err)
9733 return err;
9734
9735 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
9736 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
9737 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
9738 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
9739 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
9740 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
9741 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
9742 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
9743 return -EINVAL;
9744
9745 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 9746 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
9747 return -EINVAL;
9748
9749 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 9750 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 9751 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
9752 return -EINVAL;
9753
9754 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 9755 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
9756 return -EINVAL;
9757
9758 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
9759 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
9760 return -EINVAL;
9761
9762 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
9763 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
9764
9765 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
9766 tokens_size = tokln - sizeof(*tok);
9767
9768 if (!tok->len || tokens_size % tok->len)
9769 return -EINVAL;
964dc9e2 9770 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 9771 return -EINVAL;
964dc9e2 9772 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 9773 return -EINVAL;
964dc9e2 9774 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 9775 return -EINVAL;
964dc9e2 9776 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
9777 return -EINVAL;
9778 if (tok->offset + tok->len > data_size)
9779 return -EINVAL;
9780 }
9781
9782 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
9783 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 9784 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
9785 return -EINVAL;
9786 if (seq->len == 0 || seq->len > 4)
9787 return -EINVAL;
9788 if (seq->len + seq->offset > data_size)
9789 return -EINVAL;
9790 }
9791
9792 size = sizeof(*cfg);
9793 size += data_size;
9794 size += wake_size + wake_mask_size;
9795 size += tokens_size;
9796
9797 cfg = kzalloc(size, GFP_KERNEL);
9798 if (!cfg)
9799 return -ENOMEM;
67b61f6c
JB
9800 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
9801 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
9802 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
9803 ETH_ALEN);
9804 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
9805 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
9806 else
9807 port = 0;
9808#ifdef CONFIG_INET
9809 /* allocate a socket and port for it and use it */
9810 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
9811 IPPROTO_TCP, &cfg->sock, 1);
9812 if (err) {
9813 kfree(cfg);
9814 return err;
9815 }
9816 if (inet_csk_get_port(cfg->sock->sk, port)) {
9817 sock_release(cfg->sock);
9818 kfree(cfg);
9819 return -EADDRINUSE;
9820 }
9821 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
9822#else
9823 if (!port) {
9824 kfree(cfg);
9825 return -EINVAL;
9826 }
9827 cfg->src_port = port;
9828#endif
9829
9830 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
9831 cfg->payload_len = data_size;
9832 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
9833 memcpy((void *)cfg->payload,
9834 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
9835 data_size);
9836 if (seq)
9837 cfg->payload_seq = *seq;
9838 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
9839 cfg->wake_len = wake_size;
9840 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
9841 memcpy((void *)cfg->wake_data,
9842 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
9843 wake_size);
9844 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
9845 data_size + wake_size;
9846 memcpy((void *)cfg->wake_mask,
9847 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
9848 wake_mask_size);
9849 if (tok) {
9850 cfg->tokens_size = tokens_size;
9851 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
9852 }
9853
9854 trig->tcp = cfg;
9855
9856 return 0;
9857}
9858
8cd4d456
LC
9859static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
9860 const struct wiphy_wowlan_support *wowlan,
9861 struct nlattr *attr,
9862 struct cfg80211_wowlan *trig)
9863{
9864 struct nlattr **tb;
9865 int err;
9866
9867 tb = kzalloc(NUM_NL80211_ATTR * sizeof(*tb), GFP_KERNEL);
9868 if (!tb)
9869 return -ENOMEM;
9870
9871 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
9872 err = -EOPNOTSUPP;
9873 goto out;
9874 }
9875
9876 err = nla_parse(tb, NL80211_ATTR_MAX,
9877 nla_data(attr), nla_len(attr),
9878 nl80211_policy);
9879 if (err)
9880 goto out;
9881
ad2b26ab 9882 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb);
8cd4d456
LC
9883 err = PTR_ERR_OR_ZERO(trig->nd_config);
9884 if (err)
9885 trig->nd_config = NULL;
9886
9887out:
9888 kfree(tb);
9889 return err;
9890}
9891
ff1b6e69
JB
9892static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
9893{
9894 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9895 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 9896 struct cfg80211_wowlan new_triggers = {};
ae33bd81 9897 struct cfg80211_wowlan *ntrig;
964dc9e2 9898 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 9899 int err, i;
6abb9cb9 9900 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 9901 bool regular = false;
ff1b6e69 9902
964dc9e2 9903 if (!wowlan)
ff1b6e69
JB
9904 return -EOPNOTSUPP;
9905
ae33bd81
JB
9906 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
9907 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 9908 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
9909 goto set_wakeup;
9910 }
ff1b6e69
JB
9911
9912 err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG,
9913 nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
9914 nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
9915 nl80211_wowlan_policy);
9916 if (err)
9917 return err;
9918
9919 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
9920 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
9921 return -EINVAL;
9922 new_triggers.any = true;
9923 }
9924
9925 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
9926 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
9927 return -EINVAL;
9928 new_triggers.disconnect = true;
98fc4386 9929 regular = true;
ff1b6e69
JB
9930 }
9931
9932 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
9933 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
9934 return -EINVAL;
9935 new_triggers.magic_pkt = true;
98fc4386 9936 regular = true;
ff1b6e69
JB
9937 }
9938
77dbbb13
JB
9939 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
9940 return -EINVAL;
9941
9942 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
9943 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
9944 return -EINVAL;
9945 new_triggers.gtk_rekey_failure = true;
98fc4386 9946 regular = true;
77dbbb13
JB
9947 }
9948
9949 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
9950 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
9951 return -EINVAL;
9952 new_triggers.eap_identity_req = true;
98fc4386 9953 regular = true;
77dbbb13
JB
9954 }
9955
9956 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
9957 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
9958 return -EINVAL;
9959 new_triggers.four_way_handshake = true;
98fc4386 9960 regular = true;
77dbbb13
JB
9961 }
9962
9963 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
9964 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
9965 return -EINVAL;
9966 new_triggers.rfkill_release = true;
98fc4386 9967 regular = true;
77dbbb13
JB
9968 }
9969
ff1b6e69
JB
9970 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
9971 struct nlattr *pat;
9972 int n_patterns = 0;
bb92d199 9973 int rem, pat_len, mask_len, pkt_offset;
50ac6607 9974 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 9975
98fc4386
JB
9976 regular = true;
9977
ff1b6e69
JB
9978 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
9979 rem)
9980 n_patterns++;
9981 if (n_patterns > wowlan->n_patterns)
9982 return -EINVAL;
9983
9984 new_triggers.patterns = kcalloc(n_patterns,
9985 sizeof(new_triggers.patterns[0]),
9986 GFP_KERNEL);
9987 if (!new_triggers.patterns)
9988 return -ENOMEM;
9989
9990 new_triggers.n_patterns = n_patterns;
9991 i = 0;
9992
9993 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
9994 rem) {
922bd80f
JB
9995 u8 *mask_pat;
9996
50ac6607
AK
9997 nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
9998 nla_len(pat), NULL);
ff1b6e69 9999 err = -EINVAL;
50ac6607
AK
10000 if (!pat_tb[NL80211_PKTPAT_MASK] ||
10001 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 10002 goto error;
50ac6607 10003 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 10004 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 10005 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
10006 goto error;
10007 if (pat_len > wowlan->pattern_max_len ||
10008 pat_len < wowlan->pattern_min_len)
10009 goto error;
10010
50ac6607 10011 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
10012 pkt_offset = 0;
10013 else
10014 pkt_offset = nla_get_u32(
50ac6607 10015 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
10016 if (pkt_offset > wowlan->max_pkt_offset)
10017 goto error;
10018 new_triggers.patterns[i].pkt_offset = pkt_offset;
10019
922bd80f
JB
10020 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
10021 if (!mask_pat) {
ff1b6e69
JB
10022 err = -ENOMEM;
10023 goto error;
10024 }
922bd80f
JB
10025 new_triggers.patterns[i].mask = mask_pat;
10026 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 10027 mask_len);
922bd80f
JB
10028 mask_pat += mask_len;
10029 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 10030 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 10031 memcpy(mask_pat,
50ac6607 10032 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
10033 pat_len);
10034 i++;
10035 }
10036 }
10037
2a0e047e 10038 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 10039 regular = true;
2a0e047e
JB
10040 err = nl80211_parse_wowlan_tcp(
10041 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
10042 &new_triggers);
10043 if (err)
10044 goto error;
10045 }
10046
8cd4d456 10047 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 10048 regular = true;
8cd4d456
LC
10049 err = nl80211_parse_wowlan_nd(
10050 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
10051 &new_triggers);
10052 if (err)
10053 goto error;
10054 }
10055
98fc4386
JB
10056 /* The 'any' trigger means the device continues operating more or less
10057 * as in its normal operation mode and wakes up the host on most of the
10058 * normal interrupts (like packet RX, ...)
10059 * It therefore makes little sense to combine with the more constrained
10060 * wakeup trigger modes.
10061 */
10062 if (new_triggers.any && regular) {
10063 err = -EINVAL;
10064 goto error;
10065 }
10066
ae33bd81
JB
10067 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
10068 if (!ntrig) {
10069 err = -ENOMEM;
10070 goto error;
ff1b6e69 10071 }
ae33bd81 10072 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 10073 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 10074
ae33bd81 10075 set_wakeup:
6abb9cb9
JB
10076 if (rdev->ops->set_wakeup &&
10077 prev_enabled != !!rdev->wiphy.wowlan_config)
10078 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 10079
ff1b6e69
JB
10080 return 0;
10081 error:
10082 for (i = 0; i < new_triggers.n_patterns; i++)
10083 kfree(new_triggers.patterns[i].mask);
10084 kfree(new_triggers.patterns);
2a0e047e
JB
10085 if (new_triggers.tcp && new_triggers.tcp->sock)
10086 sock_release(new_triggers.tcp->sock);
10087 kfree(new_triggers.tcp);
e5dbe070 10088 kfree(new_triggers.nd_config);
ff1b6e69
JB
10089 return err;
10090}
dfb89c56 10091#endif
ff1b6e69 10092
be29b99a
AK
10093static int nl80211_send_coalesce_rules(struct sk_buff *msg,
10094 struct cfg80211_registered_device *rdev)
10095{
10096 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
10097 int i, j, pat_len;
10098 struct cfg80211_coalesce_rules *rule;
10099
10100 if (!rdev->coalesce->n_rules)
10101 return 0;
10102
10103 nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
10104 if (!nl_rules)
10105 return -ENOBUFS;
10106
10107 for (i = 0; i < rdev->coalesce->n_rules; i++) {
10108 nl_rule = nla_nest_start(msg, i + 1);
10109 if (!nl_rule)
10110 return -ENOBUFS;
10111
10112 rule = &rdev->coalesce->rules[i];
10113 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
10114 rule->delay))
10115 return -ENOBUFS;
10116
10117 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
10118 rule->condition))
10119 return -ENOBUFS;
10120
10121 nl_pats = nla_nest_start(msg,
10122 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
10123 if (!nl_pats)
10124 return -ENOBUFS;
10125
10126 for (j = 0; j < rule->n_patterns; j++) {
10127 nl_pat = nla_nest_start(msg, j + 1);
10128 if (!nl_pat)
10129 return -ENOBUFS;
10130 pat_len = rule->patterns[j].pattern_len;
10131 if (nla_put(msg, NL80211_PKTPAT_MASK,
10132 DIV_ROUND_UP(pat_len, 8),
10133 rule->patterns[j].mask) ||
10134 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
10135 rule->patterns[j].pattern) ||
10136 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
10137 rule->patterns[j].pkt_offset))
10138 return -ENOBUFS;
10139 nla_nest_end(msg, nl_pat);
10140 }
10141 nla_nest_end(msg, nl_pats);
10142 nla_nest_end(msg, nl_rule);
10143 }
10144 nla_nest_end(msg, nl_rules);
10145
10146 return 0;
10147}
10148
10149static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
10150{
10151 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10152 struct sk_buff *msg;
10153 void *hdr;
10154
10155 if (!rdev->wiphy.coalesce)
10156 return -EOPNOTSUPP;
10157
10158 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10159 if (!msg)
10160 return -ENOMEM;
10161
10162 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
10163 NL80211_CMD_GET_COALESCE);
10164 if (!hdr)
10165 goto nla_put_failure;
10166
10167 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
10168 goto nla_put_failure;
10169
10170 genlmsg_end(msg, hdr);
10171 return genlmsg_reply(msg, info);
10172
10173nla_put_failure:
10174 nlmsg_free(msg);
10175 return -ENOBUFS;
10176}
10177
10178void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
10179{
10180 struct cfg80211_coalesce *coalesce = rdev->coalesce;
10181 int i, j;
10182 struct cfg80211_coalesce_rules *rule;
10183
10184 if (!coalesce)
10185 return;
10186
10187 for (i = 0; i < coalesce->n_rules; i++) {
10188 rule = &coalesce->rules[i];
10189 for (j = 0; j < rule->n_patterns; j++)
10190 kfree(rule->patterns[j].mask);
10191 kfree(rule->patterns);
10192 }
10193 kfree(coalesce->rules);
10194 kfree(coalesce);
10195 rdev->coalesce = NULL;
10196}
10197
10198static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
10199 struct nlattr *rule,
10200 struct cfg80211_coalesce_rules *new_rule)
10201{
10202 int err, i;
10203 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
10204 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
10205 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
10206 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
10207
10208 err = nla_parse(tb, NL80211_ATTR_COALESCE_RULE_MAX, nla_data(rule),
10209 nla_len(rule), nl80211_coalesce_policy);
10210 if (err)
10211 return err;
10212
10213 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
10214 new_rule->delay =
10215 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
10216 if (new_rule->delay > coalesce->max_delay)
10217 return -EINVAL;
10218
10219 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
10220 new_rule->condition =
10221 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
10222 if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH &&
10223 new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH)
10224 return -EINVAL;
10225
10226 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
10227 return -EINVAL;
10228
10229 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
10230 rem)
10231 n_patterns++;
10232 if (n_patterns > coalesce->n_patterns)
10233 return -EINVAL;
10234
10235 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
10236 GFP_KERNEL);
10237 if (!new_rule->patterns)
10238 return -ENOMEM;
10239
10240 new_rule->n_patterns = n_patterns;
10241 i = 0;
10242
10243 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
10244 rem) {
922bd80f
JB
10245 u8 *mask_pat;
10246
be29b99a
AK
10247 nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
10248 nla_len(pat), NULL);
10249 if (!pat_tb[NL80211_PKTPAT_MASK] ||
10250 !pat_tb[NL80211_PKTPAT_PATTERN])
10251 return -EINVAL;
10252 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
10253 mask_len = DIV_ROUND_UP(pat_len, 8);
10254 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
10255 return -EINVAL;
10256 if (pat_len > coalesce->pattern_max_len ||
10257 pat_len < coalesce->pattern_min_len)
10258 return -EINVAL;
10259
10260 if (!pat_tb[NL80211_PKTPAT_OFFSET])
10261 pkt_offset = 0;
10262 else
10263 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
10264 if (pkt_offset > coalesce->max_pkt_offset)
10265 return -EINVAL;
10266 new_rule->patterns[i].pkt_offset = pkt_offset;
10267
922bd80f
JB
10268 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
10269 if (!mask_pat)
be29b99a 10270 return -ENOMEM;
922bd80f
JB
10271
10272 new_rule->patterns[i].mask = mask_pat;
10273 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
10274 mask_len);
10275
10276 mask_pat += mask_len;
10277 new_rule->patterns[i].pattern = mask_pat;
be29b99a 10278 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
10279 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
10280 pat_len);
be29b99a
AK
10281 i++;
10282 }
10283
10284 return 0;
10285}
10286
10287static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
10288{
10289 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10290 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
10291 struct cfg80211_coalesce new_coalesce = {};
10292 struct cfg80211_coalesce *n_coalesce;
10293 int err, rem_rule, n_rules = 0, i, j;
10294 struct nlattr *rule;
10295 struct cfg80211_coalesce_rules *tmp_rule;
10296
10297 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
10298 return -EOPNOTSUPP;
10299
10300 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
10301 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 10302 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
10303 return 0;
10304 }
10305
10306 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
10307 rem_rule)
10308 n_rules++;
10309 if (n_rules > coalesce->n_rules)
10310 return -EINVAL;
10311
10312 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
10313 GFP_KERNEL);
10314 if (!new_coalesce.rules)
10315 return -ENOMEM;
10316
10317 new_coalesce.n_rules = n_rules;
10318 i = 0;
10319
10320 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
10321 rem_rule) {
10322 err = nl80211_parse_coalesce_rule(rdev, rule,
10323 &new_coalesce.rules[i]);
10324 if (err)
10325 goto error;
10326
10327 i++;
10328 }
10329
a1056b1b 10330 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
10331 if (err)
10332 goto error;
10333
10334 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
10335 if (!n_coalesce) {
10336 err = -ENOMEM;
10337 goto error;
10338 }
10339 cfg80211_rdev_free_coalesce(rdev);
10340 rdev->coalesce = n_coalesce;
10341
10342 return 0;
10343error:
10344 for (i = 0; i < new_coalesce.n_rules; i++) {
10345 tmp_rule = &new_coalesce.rules[i];
10346 for (j = 0; j < tmp_rule->n_patterns; j++)
10347 kfree(tmp_rule->patterns[j].mask);
10348 kfree(tmp_rule->patterns);
10349 }
10350 kfree(new_coalesce.rules);
10351
10352 return err;
10353}
10354
e5497d76
JB
10355static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
10356{
10357 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10358 struct net_device *dev = info->user_ptr[1];
10359 struct wireless_dev *wdev = dev->ieee80211_ptr;
10360 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
10361 struct cfg80211_gtk_rekey_data rekey_data;
10362 int err;
10363
10364 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
10365 return -EINVAL;
10366
10367 err = nla_parse(tb, MAX_NL80211_REKEY_DATA,
10368 nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]),
10369 nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]),
10370 nl80211_rekey_policy);
10371 if (err)
10372 return err;
10373
10374 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
10375 return -ERANGE;
10376 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
10377 return -ERANGE;
10378 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
10379 return -ERANGE;
10380
78f686ca
JB
10381 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
10382 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
10383 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
e5497d76
JB
10384
10385 wdev_lock(wdev);
10386 if (!wdev->current_bss) {
10387 err = -ENOTCONN;
10388 goto out;
10389 }
10390
10391 if (!rdev->ops->set_rekey_data) {
10392 err = -EOPNOTSUPP;
10393 goto out;
10394 }
10395
e35e4d28 10396 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
10397 out:
10398 wdev_unlock(wdev);
10399 return err;
10400}
10401
28946da7
JB
10402static int nl80211_register_unexpected_frame(struct sk_buff *skb,
10403 struct genl_info *info)
10404{
10405 struct net_device *dev = info->user_ptr[1];
10406 struct wireless_dev *wdev = dev->ieee80211_ptr;
10407
10408 if (wdev->iftype != NL80211_IFTYPE_AP &&
10409 wdev->iftype != NL80211_IFTYPE_P2P_GO)
10410 return -EINVAL;
10411
15e47304 10412 if (wdev->ap_unexpected_nlportid)
28946da7
JB
10413 return -EBUSY;
10414
15e47304 10415 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
10416 return 0;
10417}
10418
7f6cf311
JB
10419static int nl80211_probe_client(struct sk_buff *skb,
10420 struct genl_info *info)
10421{
10422 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10423 struct net_device *dev = info->user_ptr[1];
10424 struct wireless_dev *wdev = dev->ieee80211_ptr;
10425 struct sk_buff *msg;
10426 void *hdr;
10427 const u8 *addr;
10428 u64 cookie;
10429 int err;
10430
10431 if (wdev->iftype != NL80211_IFTYPE_AP &&
10432 wdev->iftype != NL80211_IFTYPE_P2P_GO)
10433 return -EOPNOTSUPP;
10434
10435 if (!info->attrs[NL80211_ATTR_MAC])
10436 return -EINVAL;
10437
10438 if (!rdev->ops->probe_client)
10439 return -EOPNOTSUPP;
10440
10441 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10442 if (!msg)
10443 return -ENOMEM;
10444
15e47304 10445 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 10446 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
10447 if (!hdr) {
10448 err = -ENOBUFS;
7f6cf311
JB
10449 goto free_msg;
10450 }
10451
10452 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
10453
e35e4d28 10454 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
10455 if (err)
10456 goto free_msg;
10457
2dad624e
ND
10458 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
10459 NL80211_ATTR_PAD))
9360ffd1 10460 goto nla_put_failure;
7f6cf311
JB
10461
10462 genlmsg_end(msg, hdr);
10463
10464 return genlmsg_reply(msg, info);
10465
10466 nla_put_failure:
10467 err = -ENOBUFS;
10468 free_msg:
10469 nlmsg_free(msg);
10470 return err;
10471}
10472
5e760230
JB
10473static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
10474{
10475 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
10476 struct cfg80211_beacon_registration *reg, *nreg;
10477 int rv;
5e760230
JB
10478
10479 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
10480 return -EOPNOTSUPP;
10481
37c73b5f
BG
10482 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
10483 if (!nreg)
10484 return -ENOMEM;
10485
10486 /* First, check if already registered. */
10487 spin_lock_bh(&rdev->beacon_registrations_lock);
10488 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
10489 if (reg->nlportid == info->snd_portid) {
10490 rv = -EALREADY;
10491 goto out_err;
10492 }
10493 }
10494 /* Add it to the list */
10495 nreg->nlportid = info->snd_portid;
10496 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 10497
37c73b5f 10498 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
10499
10500 return 0;
37c73b5f
BG
10501out_err:
10502 spin_unlock_bh(&rdev->beacon_registrations_lock);
10503 kfree(nreg);
10504 return rv;
5e760230
JB
10505}
10506
98104fde
JB
10507static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
10508{
10509 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10510 struct wireless_dev *wdev = info->user_ptr[1];
10511 int err;
10512
10513 if (!rdev->ops->start_p2p_device)
10514 return -EOPNOTSUPP;
10515
10516 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
10517 return -EOPNOTSUPP;
10518
10519 if (wdev->p2p_started)
10520 return 0;
10521
b6a55015
LC
10522 if (rfkill_blocked(rdev->rfkill))
10523 return -ERFKILL;
98104fde 10524
eeb126e9 10525 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
10526 if (err)
10527 return err;
10528
10529 wdev->p2p_started = true;
98104fde 10530 rdev->opencount++;
98104fde
JB
10531
10532 return 0;
10533}
10534
10535static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
10536{
10537 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10538 struct wireless_dev *wdev = info->user_ptr[1];
10539
10540 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
10541 return -EOPNOTSUPP;
10542
10543 if (!rdev->ops->stop_p2p_device)
10544 return -EOPNOTSUPP;
10545
f9f47529 10546 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
10547
10548 return 0;
10549}
10550
cb3b7d87
AB
10551static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
10552{
10553 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10554 struct wireless_dev *wdev = info->user_ptr[1];
10555 struct cfg80211_nan_conf conf = {};
10556 int err;
10557
10558 if (wdev->iftype != NL80211_IFTYPE_NAN)
10559 return -EOPNOTSUPP;
10560
10561 if (wdev->nan_started)
10562 return -EEXIST;
10563
10564 if (rfkill_blocked(rdev->rfkill))
10565 return -ERFKILL;
10566
10567 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
10568 return -EINVAL;
10569
10570 if (!info->attrs[NL80211_ATTR_NAN_DUAL])
10571 return -EINVAL;
10572
10573 conf.master_pref =
10574 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
10575 if (!conf.master_pref)
10576 return -EINVAL;
10577
10578 conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]);
10579
10580 err = rdev_start_nan(rdev, wdev, &conf);
10581 if (err)
10582 return err;
10583
10584 wdev->nan_started = true;
10585 rdev->opencount++;
10586
10587 return 0;
10588}
10589
10590static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
10591{
10592 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10593 struct wireless_dev *wdev = info->user_ptr[1];
10594
10595 if (wdev->iftype != NL80211_IFTYPE_NAN)
10596 return -EOPNOTSUPP;
10597
10598 cfg80211_stop_nan(rdev, wdev);
10599
10600 return 0;
10601}
10602
a442b761
AB
10603static int validate_nan_filter(struct nlattr *filter_attr)
10604{
10605 struct nlattr *attr;
10606 int len = 0, n_entries = 0, rem;
10607
10608 nla_for_each_nested(attr, filter_attr, rem) {
10609 len += nla_len(attr);
10610 n_entries++;
10611 }
10612
10613 if (len >= U8_MAX)
10614 return -EINVAL;
10615
10616 return n_entries;
10617}
10618
10619static int handle_nan_filter(struct nlattr *attr_filter,
10620 struct cfg80211_nan_func *func,
10621 bool tx)
10622{
10623 struct nlattr *attr;
10624 int n_entries, rem, i;
10625 struct cfg80211_nan_func_filter *filter;
10626
10627 n_entries = validate_nan_filter(attr_filter);
10628 if (n_entries < 0)
10629 return n_entries;
10630
10631 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
10632
10633 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
10634 if (!filter)
10635 return -ENOMEM;
10636
10637 i = 0;
10638 nla_for_each_nested(attr, attr_filter, rem) {
10639 filter[i].filter = kmemdup(nla_data(attr), nla_len(attr),
10640 GFP_KERNEL);
10641 filter[i].len = nla_len(attr);
10642 i++;
10643 }
10644 if (tx) {
10645 func->num_tx_filters = n_entries;
10646 func->tx_filters = filter;
10647 } else {
10648 func->num_rx_filters = n_entries;
10649 func->rx_filters = filter;
10650 }
10651
10652 return 0;
10653}
10654
10655static int nl80211_nan_add_func(struct sk_buff *skb,
10656 struct genl_info *info)
10657{
10658 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10659 struct wireless_dev *wdev = info->user_ptr[1];
10660 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
10661 struct cfg80211_nan_func *func;
10662 struct sk_buff *msg = NULL;
10663 void *hdr = NULL;
10664 int err = 0;
10665
10666 if (wdev->iftype != NL80211_IFTYPE_NAN)
10667 return -EOPNOTSUPP;
10668
10669 if (!wdev->nan_started)
10670 return -ENOTCONN;
10671
10672 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
10673 return -EINVAL;
10674
10675 if (wdev->owner_nlportid &&
10676 wdev->owner_nlportid != info->snd_portid)
10677 return -ENOTCONN;
10678
10679 err = nla_parse(tb, NL80211_NAN_FUNC_ATTR_MAX,
10680 nla_data(info->attrs[NL80211_ATTR_NAN_FUNC]),
10681 nla_len(info->attrs[NL80211_ATTR_NAN_FUNC]),
10682 nl80211_nan_func_policy);
10683 if (err)
10684 return err;
10685
10686 func = kzalloc(sizeof(*func), GFP_KERNEL);
10687 if (!func)
10688 return -ENOMEM;
10689
10690 func->cookie = wdev->wiphy->cookie_counter++;
10691
10692 if (!tb[NL80211_NAN_FUNC_TYPE] ||
10693 nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
10694 err = -EINVAL;
10695 goto out;
10696 }
10697
10698
10699 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
10700
10701 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
10702 err = -EINVAL;
10703 goto out;
10704 }
10705
10706 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
10707 sizeof(func->service_id));
10708
10709 func->close_range =
10710 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
10711
10712 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
10713 func->serv_spec_info_len =
10714 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
10715 func->serv_spec_info =
10716 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
10717 func->serv_spec_info_len,
10718 GFP_KERNEL);
10719 if (!func->serv_spec_info) {
10720 err = -ENOMEM;
10721 goto out;
10722 }
10723 }
10724
10725 if (tb[NL80211_NAN_FUNC_TTL])
10726 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
10727
10728 switch (func->type) {
10729 case NL80211_NAN_FUNC_PUBLISH:
10730 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
10731 err = -EINVAL;
10732 goto out;
10733 }
10734
10735 func->publish_type =
10736 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
10737 func->publish_bcast =
10738 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
10739
10740 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
10741 func->publish_bcast) {
10742 err = -EINVAL;
10743 goto out;
10744 }
10745 break;
10746 case NL80211_NAN_FUNC_SUBSCRIBE:
10747 func->subscribe_active =
10748 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
10749 break;
10750 case NL80211_NAN_FUNC_FOLLOW_UP:
10751 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
10752 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]) {
10753 err = -EINVAL;
10754 goto out;
10755 }
10756
10757 func->followup_id =
10758 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
10759 func->followup_reqid =
10760 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
10761 memcpy(func->followup_dest.addr,
10762 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
10763 sizeof(func->followup_dest.addr));
10764 if (func->ttl) {
10765 err = -EINVAL;
10766 goto out;
10767 }
10768 break;
10769 default:
10770 err = -EINVAL;
10771 goto out;
10772 }
10773
10774 if (tb[NL80211_NAN_FUNC_SRF]) {
10775 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
10776
10777 err = nla_parse(srf_tb, NL80211_NAN_SRF_ATTR_MAX,
10778 nla_data(tb[NL80211_NAN_FUNC_SRF]),
10779 nla_len(tb[NL80211_NAN_FUNC_SRF]), NULL);
10780 if (err)
10781 goto out;
10782
10783 func->srf_include =
10784 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
10785
10786 if (srf_tb[NL80211_NAN_SRF_BF]) {
10787 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
10788 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
10789 err = -EINVAL;
10790 goto out;
10791 }
10792
10793 func->srf_bf_len =
10794 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
10795 func->srf_bf =
10796 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
10797 func->srf_bf_len, GFP_KERNEL);
10798 if (!func->srf_bf) {
10799 err = -ENOMEM;
10800 goto out;
10801 }
10802
10803 func->srf_bf_idx =
10804 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
10805 } else {
10806 struct nlattr *attr, *mac_attr =
10807 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
10808 int n_entries, rem, i = 0;
10809
10810 if (!mac_attr) {
10811 err = -EINVAL;
10812 goto out;
10813 }
10814
10815 n_entries = validate_acl_mac_addrs(mac_attr);
10816 if (n_entries <= 0) {
10817 err = -EINVAL;
10818 goto out;
10819 }
10820
10821 func->srf_num_macs = n_entries;
10822 func->srf_macs =
10823 kzalloc(sizeof(*func->srf_macs) * n_entries,
10824 GFP_KERNEL);
10825 if (!func->srf_macs) {
10826 err = -ENOMEM;
10827 goto out;
10828 }
10829
10830 nla_for_each_nested(attr, mac_attr, rem)
10831 memcpy(func->srf_macs[i++].addr, nla_data(attr),
10832 sizeof(*func->srf_macs));
10833 }
10834 }
10835
10836 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
10837 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
10838 func, true);
10839 if (err)
10840 goto out;
10841 }
10842
10843 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
10844 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
10845 func, false);
10846 if (err)
10847 goto out;
10848 }
10849
10850 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10851 if (!msg) {
10852 err = -ENOMEM;
10853 goto out;
10854 }
10855
10856 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
10857 NL80211_CMD_ADD_NAN_FUNCTION);
10858 /* This can't really happen - we just allocated 4KB */
10859 if (WARN_ON(!hdr)) {
10860 err = -ENOMEM;
10861 goto out;
10862 }
10863
10864 err = rdev_add_nan_func(rdev, wdev, func);
10865out:
10866 if (err < 0) {
10867 cfg80211_free_nan_func(func);
10868 nlmsg_free(msg);
10869 return err;
10870 }
10871
10872 /* propagate the instance id and cookie to userspace */
10873 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
10874 NL80211_ATTR_PAD))
10875 goto nla_put_failure;
10876
10877 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
10878 if (!func_attr)
10879 goto nla_put_failure;
10880
10881 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
10882 func->instance_id))
10883 goto nla_put_failure;
10884
10885 nla_nest_end(msg, func_attr);
10886
10887 genlmsg_end(msg, hdr);
10888 return genlmsg_reply(msg, info);
10889
10890nla_put_failure:
10891 nlmsg_free(msg);
10892 return -ENOBUFS;
10893}
10894
10895static int nl80211_nan_del_func(struct sk_buff *skb,
10896 struct genl_info *info)
10897{
10898 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10899 struct wireless_dev *wdev = info->user_ptr[1];
10900 u64 cookie;
10901
10902 if (wdev->iftype != NL80211_IFTYPE_NAN)
10903 return -EOPNOTSUPP;
10904
10905 if (!wdev->nan_started)
10906 return -ENOTCONN;
10907
10908 if (!info->attrs[NL80211_ATTR_COOKIE])
10909 return -EINVAL;
10910
10911 if (wdev->owner_nlportid &&
10912 wdev->owner_nlportid != info->snd_portid)
10913 return -ENOTCONN;
10914
10915 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
10916
10917 rdev_del_nan_func(rdev, wdev, cookie);
10918
10919 return 0;
10920}
10921
a5a9dcf2
AB
10922static int nl80211_nan_change_config(struct sk_buff *skb,
10923 struct genl_info *info)
10924{
10925 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10926 struct wireless_dev *wdev = info->user_ptr[1];
10927 struct cfg80211_nan_conf conf = {};
10928 u32 changed = 0;
10929
10930 if (wdev->iftype != NL80211_IFTYPE_NAN)
10931 return -EOPNOTSUPP;
10932
10933 if (!wdev->nan_started)
10934 return -ENOTCONN;
10935
10936 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
10937 conf.master_pref =
10938 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
10939 if (conf.master_pref <= 1 || conf.master_pref == 255)
10940 return -EINVAL;
10941
10942 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
10943 }
10944
10945 if (info->attrs[NL80211_ATTR_NAN_DUAL]) {
10946 conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]);
10947 changed |= CFG80211_NAN_CONF_CHANGED_DUAL;
10948 }
10949
10950 if (!changed)
10951 return -EINVAL;
10952
10953 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
10954}
10955
3713b4e3
JB
10956static int nl80211_get_protocol_features(struct sk_buff *skb,
10957 struct genl_info *info)
10958{
10959 void *hdr;
10960 struct sk_buff *msg;
10961
10962 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10963 if (!msg)
10964 return -ENOMEM;
10965
10966 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
10967 NL80211_CMD_GET_PROTOCOL_FEATURES);
10968 if (!hdr)
10969 goto nla_put_failure;
10970
10971 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
10972 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
10973 goto nla_put_failure;
10974
10975 genlmsg_end(msg, hdr);
10976 return genlmsg_reply(msg, info);
10977
10978 nla_put_failure:
10979 kfree_skb(msg);
10980 return -ENOBUFS;
10981}
10982
355199e0
JM
10983static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
10984{
10985 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10986 struct cfg80211_update_ft_ies_params ft_params;
10987 struct net_device *dev = info->user_ptr[1];
10988
10989 if (!rdev->ops->update_ft_ies)
10990 return -EOPNOTSUPP;
10991
10992 if (!info->attrs[NL80211_ATTR_MDID] ||
10993 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
10994 return -EINVAL;
10995
10996 memset(&ft_params, 0, sizeof(ft_params));
10997 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
10998 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10999 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11000
11001 return rdev_update_ft_ies(rdev, dev, &ft_params);
11002}
11003
5de17984
AS
11004static int nl80211_crit_protocol_start(struct sk_buff *skb,
11005 struct genl_info *info)
11006{
11007 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11008 struct wireless_dev *wdev = info->user_ptr[1];
11009 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
11010 u16 duration;
11011 int ret;
11012
11013 if (!rdev->ops->crit_proto_start)
11014 return -EOPNOTSUPP;
11015
11016 if (WARN_ON(!rdev->ops->crit_proto_stop))
11017 return -EINVAL;
11018
11019 if (rdev->crit_proto_nlportid)
11020 return -EBUSY;
11021
11022 /* determine protocol if provided */
11023 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
11024 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
11025
11026 if (proto >= NUM_NL80211_CRIT_PROTO)
11027 return -EINVAL;
11028
11029 /* timeout must be provided */
11030 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
11031 return -EINVAL;
11032
11033 duration =
11034 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
11035
11036 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
11037 return -ERANGE;
11038
11039 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
11040 if (!ret)
11041 rdev->crit_proto_nlportid = info->snd_portid;
11042
11043 return ret;
11044}
11045
11046static int nl80211_crit_protocol_stop(struct sk_buff *skb,
11047 struct genl_info *info)
11048{
11049 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11050 struct wireless_dev *wdev = info->user_ptr[1];
11051
11052 if (!rdev->ops->crit_proto_stop)
11053 return -EOPNOTSUPP;
11054
11055 if (rdev->crit_proto_nlportid) {
11056 rdev->crit_proto_nlportid = 0;
11057 rdev_crit_proto_stop(rdev, wdev);
11058 }
11059 return 0;
11060}
11061
ad7e718c
JB
11062static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
11063{
11064 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11065 struct wireless_dev *wdev =
11066 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
11067 int i, err;
11068 u32 vid, subcmd;
11069
11070 if (!rdev->wiphy.vendor_commands)
11071 return -EOPNOTSUPP;
11072
11073 if (IS_ERR(wdev)) {
11074 err = PTR_ERR(wdev);
11075 if (err != -EINVAL)
11076 return err;
11077 wdev = NULL;
11078 } else if (wdev->wiphy != &rdev->wiphy) {
11079 return -EINVAL;
11080 }
11081
11082 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
11083 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
11084 return -EINVAL;
11085
11086 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
11087 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
11088 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
11089 const struct wiphy_vendor_command *vcmd;
11090 void *data = NULL;
11091 int len = 0;
11092
11093 vcmd = &rdev->wiphy.vendor_commands[i];
11094
11095 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11096 continue;
11097
11098 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11099 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11100 if (!wdev)
11101 return -EINVAL;
11102 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11103 !wdev->netdev)
11104 return -EINVAL;
11105
11106 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
11107 if (wdev->netdev &&
11108 !netif_running(wdev->netdev))
11109 return -ENETDOWN;
11110 if (!wdev->netdev && !wdev->p2p_started)
11111 return -ENETDOWN;
11112 }
7bdbe400
JB
11113
11114 if (!vcmd->doit)
11115 return -EOPNOTSUPP;
ad7e718c
JB
11116 } else {
11117 wdev = NULL;
11118 }
11119
11120 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
11121 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11122 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11123 }
11124
11125 rdev->cur_cmd_info = info;
11126 err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
11127 data, len);
11128 rdev->cur_cmd_info = NULL;
11129 return err;
11130 }
11131
11132 return -EOPNOTSUPP;
11133}
11134
7bdbe400
JB
11135static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
11136 struct netlink_callback *cb,
11137 struct cfg80211_registered_device **rdev,
11138 struct wireless_dev **wdev)
11139{
11140 u32 vid, subcmd;
11141 unsigned int i;
11142 int vcmd_idx = -1;
11143 int err;
11144 void *data = NULL;
11145 unsigned int data_len = 0;
11146
11147 rtnl_lock();
11148
11149 if (cb->args[0]) {
11150 /* subtract the 1 again here */
11151 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
11152 struct wireless_dev *tmp;
11153
11154 if (!wiphy) {
11155 err = -ENODEV;
11156 goto out_unlock;
11157 }
11158 *rdev = wiphy_to_rdev(wiphy);
11159 *wdev = NULL;
11160
11161 if (cb->args[1]) {
53873f13 11162 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
11163 if (tmp->identifier == cb->args[1] - 1) {
11164 *wdev = tmp;
11165 break;
11166 }
11167 }
11168 }
11169
11170 /* keep rtnl locked in successful case */
11171 return 0;
11172 }
11173
11174 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
11175 nl80211_fam.attrbuf, nl80211_fam.maxattr,
11176 nl80211_policy);
11177 if (err)
11178 goto out_unlock;
11179
11180 if (!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID] ||
11181 !nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
11182 err = -EINVAL;
11183 goto out_unlock;
11184 }
11185
11186 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
11187 nl80211_fam.attrbuf);
11188 if (IS_ERR(*wdev))
11189 *wdev = NULL;
11190
11191 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
11192 nl80211_fam.attrbuf);
11193 if (IS_ERR(*rdev)) {
11194 err = PTR_ERR(*rdev);
11195 goto out_unlock;
11196 }
11197
11198 vid = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID]);
11199 subcmd = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
11200
11201 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
11202 const struct wiphy_vendor_command *vcmd;
11203
11204 vcmd = &(*rdev)->wiphy.vendor_commands[i];
11205
11206 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11207 continue;
11208
11209 if (!vcmd->dumpit) {
11210 err = -EOPNOTSUPP;
11211 goto out_unlock;
11212 }
11213
11214 vcmd_idx = i;
11215 break;
11216 }
11217
11218 if (vcmd_idx < 0) {
11219 err = -EOPNOTSUPP;
11220 goto out_unlock;
11221 }
11222
11223 if (nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]) {
11224 data = nla_data(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
11225 data_len = nla_len(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
11226 }
11227
11228 /* 0 is the first index - add 1 to parse only once */
11229 cb->args[0] = (*rdev)->wiphy_idx + 1;
11230 /* add 1 to know if it was NULL */
11231 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
11232 cb->args[2] = vcmd_idx;
11233 cb->args[3] = (unsigned long)data;
11234 cb->args[4] = data_len;
11235
11236 /* keep rtnl locked in successful case */
11237 return 0;
11238 out_unlock:
11239 rtnl_unlock();
11240 return err;
11241}
11242
11243static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
11244 struct netlink_callback *cb)
11245{
11246 struct cfg80211_registered_device *rdev;
11247 struct wireless_dev *wdev;
11248 unsigned int vcmd_idx;
11249 const struct wiphy_vendor_command *vcmd;
11250 void *data;
11251 int data_len;
11252 int err;
11253 struct nlattr *vendor_data;
11254
11255 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
11256 if (err)
11257 return err;
11258
11259 vcmd_idx = cb->args[2];
11260 data = (void *)cb->args[3];
11261 data_len = cb->args[4];
11262 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
11263
11264 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11265 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11266 if (!wdev)
11267 return -EINVAL;
11268 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11269 !wdev->netdev)
11270 return -EINVAL;
11271
11272 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
11273 if (wdev->netdev &&
11274 !netif_running(wdev->netdev))
11275 return -ENETDOWN;
11276 if (!wdev->netdev && !wdev->p2p_started)
11277 return -ENETDOWN;
11278 }
11279 }
11280
11281 while (1) {
11282 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
11283 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11284 NL80211_CMD_VENDOR);
11285 if (!hdr)
11286 break;
11287
11288 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
11289 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
11290 wdev_id(wdev),
11291 NL80211_ATTR_PAD))) {
7bdbe400
JB
11292 genlmsg_cancel(skb, hdr);
11293 break;
11294 }
11295
11296 vendor_data = nla_nest_start(skb, NL80211_ATTR_VENDOR_DATA);
11297 if (!vendor_data) {
11298 genlmsg_cancel(skb, hdr);
11299 break;
11300 }
11301
11302 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
11303 (unsigned long *)&cb->args[5]);
11304 nla_nest_end(skb, vendor_data);
11305
11306 if (err == -ENOBUFS || err == -ENOENT) {
11307 genlmsg_cancel(skb, hdr);
11308 break;
11309 } else if (err) {
11310 genlmsg_cancel(skb, hdr);
11311 goto out;
11312 }
11313
11314 genlmsg_end(skb, hdr);
11315 }
11316
11317 err = skb->len;
11318 out:
11319 rtnl_unlock();
11320 return err;
11321}
11322
ad7e718c
JB
11323struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
11324 enum nl80211_commands cmd,
11325 enum nl80211_attrs attr,
11326 int approxlen)
11327{
f26cbf40 11328 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
11329
11330 if (WARN_ON(!rdev->cur_cmd_info))
11331 return NULL;
11332
6c09e791 11333 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
11334 rdev->cur_cmd_info->snd_portid,
11335 rdev->cur_cmd_info->snd_seq,
567ffc35 11336 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
11337}
11338EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
11339
11340int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
11341{
11342 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
11343 void *hdr = ((void **)skb->cb)[1];
11344 struct nlattr *data = ((void **)skb->cb)[2];
11345
bd8c78e7
JB
11346 /* clear CB data for netlink core to own from now on */
11347 memset(skb->cb, 0, sizeof(skb->cb));
11348
ad7e718c
JB
11349 if (WARN_ON(!rdev->cur_cmd_info)) {
11350 kfree_skb(skb);
11351 return -EINVAL;
11352 }
11353
11354 nla_nest_end(skb, data);
11355 genlmsg_end(skb, hdr);
11356 return genlmsg_reply(skb, rdev->cur_cmd_info);
11357}
11358EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
11359
fa9ffc74
KP
11360static int nl80211_set_qos_map(struct sk_buff *skb,
11361 struct genl_info *info)
11362{
11363 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11364 struct cfg80211_qos_map *qos_map = NULL;
11365 struct net_device *dev = info->user_ptr[1];
11366 u8 *pos, len, num_des, des_len, des;
11367 int ret;
11368
11369 if (!rdev->ops->set_qos_map)
11370 return -EOPNOTSUPP;
11371
11372 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
11373 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
11374 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
11375
11376 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
11377 len > IEEE80211_QOS_MAP_LEN_MAX)
11378 return -EINVAL;
11379
11380 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
11381 if (!qos_map)
11382 return -ENOMEM;
11383
11384 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
11385 if (num_des) {
11386 des_len = num_des *
11387 sizeof(struct cfg80211_dscp_exception);
11388 memcpy(qos_map->dscp_exception, pos, des_len);
11389 qos_map->num_des = num_des;
11390 for (des = 0; des < num_des; des++) {
11391 if (qos_map->dscp_exception[des].up > 7) {
11392 kfree(qos_map);
11393 return -EINVAL;
11394 }
11395 }
11396 pos += des_len;
11397 }
11398 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
11399 }
11400
11401 wdev_lock(dev->ieee80211_ptr);
11402 ret = nl80211_key_allowed(dev->ieee80211_ptr);
11403 if (!ret)
11404 ret = rdev_set_qos_map(rdev, dev, qos_map);
11405 wdev_unlock(dev->ieee80211_ptr);
11406
11407 kfree(qos_map);
11408 return ret;
11409}
11410
960d01ac
JB
11411static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
11412{
11413 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11414 struct net_device *dev = info->user_ptr[1];
11415 struct wireless_dev *wdev = dev->ieee80211_ptr;
11416 const u8 *peer;
11417 u8 tsid, up;
11418 u16 admitted_time = 0;
11419 int err;
11420
723e73ac 11421 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
11422 return -EOPNOTSUPP;
11423
11424 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
11425 !info->attrs[NL80211_ATTR_USER_PRIO])
11426 return -EINVAL;
11427
11428 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
11429 if (tsid >= IEEE80211_NUM_TIDS)
11430 return -EINVAL;
11431
11432 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
11433 if (up >= IEEE80211_NUM_UPS)
11434 return -EINVAL;
11435
11436 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 11437 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 11438 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
11439 * need more attributes for that (e.g. BA session requirement);
11440 * change the WMM adminssion test above to allow both then
960d01ac
JB
11441 */
11442 return -EINVAL;
11443 }
11444
11445 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11446
11447 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
11448 admitted_time =
11449 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
11450 if (!admitted_time)
11451 return -EINVAL;
11452 }
11453
11454 wdev_lock(wdev);
11455 switch (wdev->iftype) {
11456 case NL80211_IFTYPE_STATION:
11457 case NL80211_IFTYPE_P2P_CLIENT:
11458 if (wdev->current_bss)
11459 break;
11460 err = -ENOTCONN;
11461 goto out;
11462 default:
11463 err = -EOPNOTSUPP;
11464 goto out;
11465 }
11466
11467 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
11468
11469 out:
11470 wdev_unlock(wdev);
11471 return err;
11472}
11473
11474static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
11475{
11476 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11477 struct net_device *dev = info->user_ptr[1];
11478 struct wireless_dev *wdev = dev->ieee80211_ptr;
11479 const u8 *peer;
11480 u8 tsid;
11481 int err;
11482
11483 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
11484 return -EINVAL;
11485
11486 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
11487 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11488
11489 wdev_lock(wdev);
11490 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
11491 wdev_unlock(wdev);
11492
11493 return err;
11494}
11495
1057d35e
AN
11496static int nl80211_tdls_channel_switch(struct sk_buff *skb,
11497 struct genl_info *info)
11498{
11499 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11500 struct net_device *dev = info->user_ptr[1];
11501 struct wireless_dev *wdev = dev->ieee80211_ptr;
11502 struct cfg80211_chan_def chandef = {};
11503 const u8 *addr;
11504 u8 oper_class;
11505 int err;
11506
11507 if (!rdev->ops->tdls_channel_switch ||
11508 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
11509 return -EOPNOTSUPP;
11510
11511 switch (dev->ieee80211_ptr->iftype) {
11512 case NL80211_IFTYPE_STATION:
11513 case NL80211_IFTYPE_P2P_CLIENT:
11514 break;
11515 default:
11516 return -EOPNOTSUPP;
11517 }
11518
11519 if (!info->attrs[NL80211_ATTR_MAC] ||
11520 !info->attrs[NL80211_ATTR_OPER_CLASS])
11521 return -EINVAL;
11522
11523 err = nl80211_parse_chandef(rdev, info, &chandef);
11524 if (err)
11525 return err;
11526
11527 /*
11528 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
11529 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
11530 * specification is not defined for them.
11531 */
57fbcce3 11532 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
11533 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
11534 chandef.width != NL80211_CHAN_WIDTH_20)
11535 return -EINVAL;
11536
11537 /* we will be active on the TDLS link */
923b352f
AN
11538 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
11539 wdev->iftype))
1057d35e
AN
11540 return -EINVAL;
11541
11542 /* don't allow switching to DFS channels */
11543 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
11544 return -EINVAL;
11545
11546 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11547 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
11548
11549 wdev_lock(wdev);
11550 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
11551 wdev_unlock(wdev);
11552
11553 return err;
11554}
11555
11556static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
11557 struct genl_info *info)
11558{
11559 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11560 struct net_device *dev = info->user_ptr[1];
11561 struct wireless_dev *wdev = dev->ieee80211_ptr;
11562 const u8 *addr;
11563
11564 if (!rdev->ops->tdls_channel_switch ||
11565 !rdev->ops->tdls_cancel_channel_switch ||
11566 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
11567 return -EOPNOTSUPP;
11568
11569 switch (dev->ieee80211_ptr->iftype) {
11570 case NL80211_IFTYPE_STATION:
11571 case NL80211_IFTYPE_P2P_CLIENT:
11572 break;
11573 default:
11574 return -EOPNOTSUPP;
11575 }
11576
11577 if (!info->attrs[NL80211_ATTR_MAC])
11578 return -EINVAL;
11579
11580 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11581
11582 wdev_lock(wdev);
11583 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
11584 wdev_unlock(wdev);
11585
11586 return 0;
11587}
11588
4c476991
JB
11589#define NL80211_FLAG_NEED_WIPHY 0x01
11590#define NL80211_FLAG_NEED_NETDEV 0x02
11591#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
11592#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
11593#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
11594 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 11595#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 11596/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
11597#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
11598 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 11599#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 11600
f84f771d 11601static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
11602 struct genl_info *info)
11603{
11604 struct cfg80211_registered_device *rdev;
89a54e48 11605 struct wireless_dev *wdev;
4c476991 11606 struct net_device *dev;
4c476991
JB
11607 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
11608
11609 if (rtnl)
11610 rtnl_lock();
11611
11612 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 11613 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
11614 if (IS_ERR(rdev)) {
11615 if (rtnl)
11616 rtnl_unlock();
11617 return PTR_ERR(rdev);
11618 }
11619 info->user_ptr[0] = rdev;
1bf614ef
JB
11620 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
11621 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
11622 ASSERT_RTNL();
11623
89a54e48
JB
11624 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
11625 info->attrs);
11626 if (IS_ERR(wdev)) {
4c476991
JB
11627 if (rtnl)
11628 rtnl_unlock();
89a54e48 11629 return PTR_ERR(wdev);
4c476991 11630 }
89a54e48 11631
89a54e48 11632 dev = wdev->netdev;
f26cbf40 11633 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 11634
1bf614ef
JB
11635 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
11636 if (!dev) {
1bf614ef
JB
11637 if (rtnl)
11638 rtnl_unlock();
11639 return -EINVAL;
11640 }
11641
11642 info->user_ptr[1] = dev;
11643 } else {
11644 info->user_ptr[1] = wdev;
41265714 11645 }
1bf614ef
JB
11646
11647 if (dev) {
11648 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
11649 !netif_running(dev)) {
1bf614ef
JB
11650 if (rtnl)
11651 rtnl_unlock();
11652 return -ENETDOWN;
11653 }
11654
11655 dev_hold(dev);
98104fde 11656 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) {
cb3b7d87
AB
11657 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
11658 !wdev->p2p_started) {
11659 if (rtnl)
11660 rtnl_unlock();
11661 return -ENETDOWN;
11662 }
11663 if (wdev->iftype == NL80211_IFTYPE_NAN &&
11664 !wdev->nan_started) {
98104fde
JB
11665 if (rtnl)
11666 rtnl_unlock();
11667 return -ENETDOWN;
11668 }
41265714 11669 }
89a54e48 11670
4c476991 11671 info->user_ptr[0] = rdev;
4c476991
JB
11672 }
11673
11674 return 0;
11675}
11676
f84f771d 11677static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
11678 struct genl_info *info)
11679{
1bf614ef
JB
11680 if (info->user_ptr[1]) {
11681 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
11682 struct wireless_dev *wdev = info->user_ptr[1];
11683
11684 if (wdev->netdev)
11685 dev_put(wdev->netdev);
11686 } else {
11687 dev_put(info->user_ptr[1]);
11688 }
11689 }
5393b917 11690
4c476991
JB
11691 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
11692 rtnl_unlock();
5393b917
JB
11693
11694 /* If needed, clear the netlink message payload from the SKB
11695 * as it might contain key data that shouldn't stick around on
11696 * the heap after the SKB is freed. The netlink message header
11697 * is still needed for further processing, so leave it intact.
11698 */
11699 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
11700 struct nlmsghdr *nlh = nlmsg_hdr(skb);
11701
11702 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
11703 }
4c476991
JB
11704}
11705
4534de83 11706static const struct genl_ops nl80211_ops[] = {
55682965
JB
11707 {
11708 .cmd = NL80211_CMD_GET_WIPHY,
11709 .doit = nl80211_get_wiphy,
11710 .dumpit = nl80211_dump_wiphy,
86e8cf98 11711 .done = nl80211_dump_wiphy_done,
55682965
JB
11712 .policy = nl80211_policy,
11713 /* can be retrieved by unprivileged users */
5fe231e8
JB
11714 .internal_flags = NL80211_FLAG_NEED_WIPHY |
11715 NL80211_FLAG_NEED_RTNL,
55682965
JB
11716 },
11717 {
11718 .cmd = NL80211_CMD_SET_WIPHY,
11719 .doit = nl80211_set_wiphy,
11720 .policy = nl80211_policy,
5617c6cd 11721 .flags = GENL_UNS_ADMIN_PERM,
4c476991 11722 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
11723 },
11724 {
11725 .cmd = NL80211_CMD_GET_INTERFACE,
11726 .doit = nl80211_get_interface,
11727 .dumpit = nl80211_dump_interface,
11728 .policy = nl80211_policy,
11729 /* can be retrieved by unprivileged users */
5fe231e8
JB
11730 .internal_flags = NL80211_FLAG_NEED_WDEV |
11731 NL80211_FLAG_NEED_RTNL,
55682965
JB
11732 },
11733 {
11734 .cmd = NL80211_CMD_SET_INTERFACE,
11735 .doit = nl80211_set_interface,
11736 .policy = nl80211_policy,
5617c6cd 11737 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
11738 .internal_flags = NL80211_FLAG_NEED_NETDEV |
11739 NL80211_FLAG_NEED_RTNL,
55682965
JB
11740 },
11741 {
11742 .cmd = NL80211_CMD_NEW_INTERFACE,
11743 .doit = nl80211_new_interface,
11744 .policy = nl80211_policy,
5617c6cd 11745 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
11746 .internal_flags = NL80211_FLAG_NEED_WIPHY |
11747 NL80211_FLAG_NEED_RTNL,
55682965
JB
11748 },
11749 {
11750 .cmd = NL80211_CMD_DEL_INTERFACE,
11751 .doit = nl80211_del_interface,
11752 .policy = nl80211_policy,
5617c6cd 11753 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 11754 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 11755 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
11756 },
11757 {
11758 .cmd = NL80211_CMD_GET_KEY,
11759 .doit = nl80211_get_key,
11760 .policy = nl80211_policy,
5617c6cd 11761 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11762 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11763 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
11764 },
11765 {
11766 .cmd = NL80211_CMD_SET_KEY,
11767 .doit = nl80211_set_key,
11768 .policy = nl80211_policy,
5617c6cd 11769 .flags = GENL_UNS_ADMIN_PERM,
41265714 11770 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
11771 NL80211_FLAG_NEED_RTNL |
11772 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
11773 },
11774 {
11775 .cmd = NL80211_CMD_NEW_KEY,
11776 .doit = nl80211_new_key,
11777 .policy = nl80211_policy,
5617c6cd 11778 .flags = GENL_UNS_ADMIN_PERM,
41265714 11779 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
11780 NL80211_FLAG_NEED_RTNL |
11781 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
11782 },
11783 {
11784 .cmd = NL80211_CMD_DEL_KEY,
11785 .doit = nl80211_del_key,
11786 .policy = nl80211_policy,
5617c6cd 11787 .flags = GENL_UNS_ADMIN_PERM,
41265714 11788 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11789 NL80211_FLAG_NEED_RTNL,
55682965 11790 },
ed1b6cc7
JB
11791 {
11792 .cmd = NL80211_CMD_SET_BEACON,
11793 .policy = nl80211_policy,
5617c6cd 11794 .flags = GENL_UNS_ADMIN_PERM,
8860020e 11795 .doit = nl80211_set_beacon,
2b5f8b0b 11796 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11797 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
11798 },
11799 {
8860020e 11800 .cmd = NL80211_CMD_START_AP,
ed1b6cc7 11801 .policy = nl80211_policy,
5617c6cd 11802 .flags = GENL_UNS_ADMIN_PERM,
8860020e 11803 .doit = nl80211_start_ap,
2b5f8b0b 11804 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11805 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
11806 },
11807 {
8860020e 11808 .cmd = NL80211_CMD_STOP_AP,
ed1b6cc7 11809 .policy = nl80211_policy,
5617c6cd 11810 .flags = GENL_UNS_ADMIN_PERM,
8860020e 11811 .doit = nl80211_stop_ap,
2b5f8b0b 11812 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11813 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 11814 },
5727ef1b
JB
11815 {
11816 .cmd = NL80211_CMD_GET_STATION,
11817 .doit = nl80211_get_station,
2ec600d6 11818 .dumpit = nl80211_dump_station,
5727ef1b 11819 .policy = nl80211_policy,
4c476991
JB
11820 .internal_flags = NL80211_FLAG_NEED_NETDEV |
11821 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
11822 },
11823 {
11824 .cmd = NL80211_CMD_SET_STATION,
11825 .doit = nl80211_set_station,
11826 .policy = nl80211_policy,
5617c6cd 11827 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11828 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11829 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
11830 },
11831 {
11832 .cmd = NL80211_CMD_NEW_STATION,
11833 .doit = nl80211_new_station,
11834 .policy = nl80211_policy,
5617c6cd 11835 .flags = GENL_UNS_ADMIN_PERM,
41265714 11836 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11837 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
11838 },
11839 {
11840 .cmd = NL80211_CMD_DEL_STATION,
11841 .doit = nl80211_del_station,
11842 .policy = nl80211_policy,
5617c6cd 11843 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11844 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11845 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
11846 },
11847 {
11848 .cmd = NL80211_CMD_GET_MPATH,
11849 .doit = nl80211_get_mpath,
11850 .dumpit = nl80211_dump_mpath,
11851 .policy = nl80211_policy,
5617c6cd 11852 .flags = GENL_UNS_ADMIN_PERM,
41265714 11853 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11854 NL80211_FLAG_NEED_RTNL,
2ec600d6 11855 },
66be7d2b
HR
11856 {
11857 .cmd = NL80211_CMD_GET_MPP,
11858 .doit = nl80211_get_mpp,
11859 .dumpit = nl80211_dump_mpp,
11860 .policy = nl80211_policy,
5617c6cd 11861 .flags = GENL_UNS_ADMIN_PERM,
66be7d2b
HR
11862 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
11863 NL80211_FLAG_NEED_RTNL,
11864 },
2ec600d6
LCC
11865 {
11866 .cmd = NL80211_CMD_SET_MPATH,
11867 .doit = nl80211_set_mpath,
11868 .policy = nl80211_policy,
5617c6cd 11869 .flags = GENL_UNS_ADMIN_PERM,
41265714 11870 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11871 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
11872 },
11873 {
11874 .cmd = NL80211_CMD_NEW_MPATH,
11875 .doit = nl80211_new_mpath,
11876 .policy = nl80211_policy,
5617c6cd 11877 .flags = GENL_UNS_ADMIN_PERM,
41265714 11878 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11879 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
11880 },
11881 {
11882 .cmd = NL80211_CMD_DEL_MPATH,
11883 .doit = nl80211_del_mpath,
11884 .policy = nl80211_policy,
5617c6cd 11885 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11886 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11887 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
11888 },
11889 {
11890 .cmd = NL80211_CMD_SET_BSS,
11891 .doit = nl80211_set_bss,
11892 .policy = nl80211_policy,
5617c6cd 11893 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11894 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11895 NL80211_FLAG_NEED_RTNL,
b2e1b302 11896 },
f130347c
LR
11897 {
11898 .cmd = NL80211_CMD_GET_REG,
ad30ca2c
AN
11899 .doit = nl80211_get_reg_do,
11900 .dumpit = nl80211_get_reg_dump,
f130347c 11901 .policy = nl80211_policy,
5fe231e8 11902 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
11903 /* can be retrieved by unprivileged users */
11904 },
b6863036 11905#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
11906 {
11907 .cmd = NL80211_CMD_SET_REG,
11908 .doit = nl80211_set_reg,
11909 .policy = nl80211_policy,
11910 .flags = GENL_ADMIN_PERM,
5fe231e8 11911 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302 11912 },
b6863036 11913#endif
b2e1b302
LR
11914 {
11915 .cmd = NL80211_CMD_REQ_SET_REG,
11916 .doit = nl80211_req_set_reg,
11917 .policy = nl80211_policy,
93da9cc1 11918 .flags = GENL_ADMIN_PERM,
11919 },
11920 {
24bdd9f4
JC
11921 .cmd = NL80211_CMD_GET_MESH_CONFIG,
11922 .doit = nl80211_get_mesh_config,
93da9cc1 11923 .policy = nl80211_policy,
11924 /* can be retrieved by unprivileged users */
2b5f8b0b 11925 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11926 NL80211_FLAG_NEED_RTNL,
93da9cc1 11927 },
11928 {
24bdd9f4
JC
11929 .cmd = NL80211_CMD_SET_MESH_CONFIG,
11930 .doit = nl80211_update_mesh_config,
93da9cc1 11931 .policy = nl80211_policy,
5617c6cd 11932 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c 11933 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11934 NL80211_FLAG_NEED_RTNL,
9aed3cc1 11935 },
2a519311
JB
11936 {
11937 .cmd = NL80211_CMD_TRIGGER_SCAN,
11938 .doit = nl80211_trigger_scan,
11939 .policy = nl80211_policy,
5617c6cd 11940 .flags = GENL_UNS_ADMIN_PERM,
fd014284 11941 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 11942 NL80211_FLAG_NEED_RTNL,
2a519311 11943 },
91d3ab46
VK
11944 {
11945 .cmd = NL80211_CMD_ABORT_SCAN,
11946 .doit = nl80211_abort_scan,
11947 .policy = nl80211_policy,
5617c6cd 11948 .flags = GENL_UNS_ADMIN_PERM,
91d3ab46
VK
11949 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
11950 NL80211_FLAG_NEED_RTNL,
11951 },
2a519311
JB
11952 {
11953 .cmd = NL80211_CMD_GET_SCAN,
11954 .policy = nl80211_policy,
11955 .dumpit = nl80211_dump_scan,
11956 },
807f8a8c
LC
11957 {
11958 .cmd = NL80211_CMD_START_SCHED_SCAN,
11959 .doit = nl80211_start_sched_scan,
11960 .policy = nl80211_policy,
5617c6cd 11961 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
11962 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
11963 NL80211_FLAG_NEED_RTNL,
11964 },
11965 {
11966 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
11967 .doit = nl80211_stop_sched_scan,
11968 .policy = nl80211_policy,
5617c6cd 11969 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
11970 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
11971 NL80211_FLAG_NEED_RTNL,
11972 },
636a5d36
JM
11973 {
11974 .cmd = NL80211_CMD_AUTHENTICATE,
11975 .doit = nl80211_authenticate,
11976 .policy = nl80211_policy,
5617c6cd 11977 .flags = GENL_UNS_ADMIN_PERM,
41265714 11978 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
11979 NL80211_FLAG_NEED_RTNL |
11980 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
11981 },
11982 {
11983 .cmd = NL80211_CMD_ASSOCIATE,
11984 .doit = nl80211_associate,
11985 .policy = nl80211_policy,
5617c6cd 11986 .flags = GENL_UNS_ADMIN_PERM,
41265714 11987 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11988 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
11989 },
11990 {
11991 .cmd = NL80211_CMD_DEAUTHENTICATE,
11992 .doit = nl80211_deauthenticate,
11993 .policy = nl80211_policy,
5617c6cd 11994 .flags = GENL_UNS_ADMIN_PERM,
41265714 11995 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11996 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
11997 },
11998 {
11999 .cmd = NL80211_CMD_DISASSOCIATE,
12000 .doit = nl80211_disassociate,
12001 .policy = nl80211_policy,
5617c6cd 12002 .flags = GENL_UNS_ADMIN_PERM,
41265714 12003 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12004 NL80211_FLAG_NEED_RTNL,
636a5d36 12005 },
04a773ad
JB
12006 {
12007 .cmd = NL80211_CMD_JOIN_IBSS,
12008 .doit = nl80211_join_ibss,
12009 .policy = nl80211_policy,
5617c6cd 12010 .flags = GENL_UNS_ADMIN_PERM,
41265714 12011 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12012 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
12013 },
12014 {
12015 .cmd = NL80211_CMD_LEAVE_IBSS,
12016 .doit = nl80211_leave_ibss,
12017 .policy = nl80211_policy,
5617c6cd 12018 .flags = GENL_UNS_ADMIN_PERM,
41265714 12019 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12020 NL80211_FLAG_NEED_RTNL,
04a773ad 12021 },
aff89a9b
JB
12022#ifdef CONFIG_NL80211_TESTMODE
12023 {
12024 .cmd = NL80211_CMD_TESTMODE,
12025 .doit = nl80211_testmode_do,
71063f0e 12026 .dumpit = nl80211_testmode_dump,
aff89a9b 12027 .policy = nl80211_policy,
5617c6cd 12028 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12029 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12030 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
12031 },
12032#endif
b23aa676
SO
12033 {
12034 .cmd = NL80211_CMD_CONNECT,
12035 .doit = nl80211_connect,
12036 .policy = nl80211_policy,
5617c6cd 12037 .flags = GENL_UNS_ADMIN_PERM,
41265714 12038 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12039 NL80211_FLAG_NEED_RTNL,
b23aa676
SO
12040 },
12041 {
12042 .cmd = NL80211_CMD_DISCONNECT,
12043 .doit = nl80211_disconnect,
12044 .policy = nl80211_policy,
5617c6cd 12045 .flags = GENL_UNS_ADMIN_PERM,
41265714 12046 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12047 NL80211_FLAG_NEED_RTNL,
b23aa676 12048 },
463d0183
JB
12049 {
12050 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
12051 .doit = nl80211_wiphy_netns,
12052 .policy = nl80211_policy,
5617c6cd 12053 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12054 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12055 NL80211_FLAG_NEED_RTNL,
463d0183 12056 },
61fa713c
HS
12057 {
12058 .cmd = NL80211_CMD_GET_SURVEY,
12059 .policy = nl80211_policy,
12060 .dumpit = nl80211_dump_survey,
12061 },
67fbb16b
SO
12062 {
12063 .cmd = NL80211_CMD_SET_PMKSA,
12064 .doit = nl80211_setdel_pmksa,
12065 .policy = nl80211_policy,
5617c6cd 12066 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12067 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12068 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12069 },
12070 {
12071 .cmd = NL80211_CMD_DEL_PMKSA,
12072 .doit = nl80211_setdel_pmksa,
12073 .policy = nl80211_policy,
5617c6cd 12074 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12075 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12076 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12077 },
12078 {
12079 .cmd = NL80211_CMD_FLUSH_PMKSA,
12080 .doit = nl80211_flush_pmksa,
12081 .policy = nl80211_policy,
5617c6cd 12082 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12083 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12084 NL80211_FLAG_NEED_RTNL,
67fbb16b 12085 },
9588bbd5
JM
12086 {
12087 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
12088 .doit = nl80211_remain_on_channel,
12089 .policy = nl80211_policy,
5617c6cd 12090 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12091 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12092 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
12093 },
12094 {
12095 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
12096 .doit = nl80211_cancel_remain_on_channel,
12097 .policy = nl80211_policy,
5617c6cd 12098 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12099 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12100 NL80211_FLAG_NEED_RTNL,
9588bbd5 12101 },
13ae75b1
JM
12102 {
12103 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
12104 .doit = nl80211_set_tx_bitrate_mask,
12105 .policy = nl80211_policy,
5617c6cd 12106 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12107 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12108 NL80211_FLAG_NEED_RTNL,
13ae75b1 12109 },
026331c4 12110 {
2e161f78
JB
12111 .cmd = NL80211_CMD_REGISTER_FRAME,
12112 .doit = nl80211_register_mgmt,
026331c4 12113 .policy = nl80211_policy,
5617c6cd 12114 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12115 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 12116 NL80211_FLAG_NEED_RTNL,
026331c4
JM
12117 },
12118 {
2e161f78
JB
12119 .cmd = NL80211_CMD_FRAME,
12120 .doit = nl80211_tx_mgmt,
026331c4 12121 .policy = nl80211_policy,
5617c6cd 12122 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12123 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
12124 NL80211_FLAG_NEED_RTNL,
12125 },
12126 {
12127 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
12128 .doit = nl80211_tx_mgmt_cancel_wait,
12129 .policy = nl80211_policy,
5617c6cd 12130 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12131 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12132 NL80211_FLAG_NEED_RTNL,
026331c4 12133 },
ffb9eb3d
KV
12134 {
12135 .cmd = NL80211_CMD_SET_POWER_SAVE,
12136 .doit = nl80211_set_power_save,
12137 .policy = nl80211_policy,
5617c6cd 12138 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12139 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12140 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
12141 },
12142 {
12143 .cmd = NL80211_CMD_GET_POWER_SAVE,
12144 .doit = nl80211_get_power_save,
12145 .policy = nl80211_policy,
12146 /* can be retrieved by unprivileged users */
4c476991
JB
12147 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12148 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 12149 },
d6dc1a38
JO
12150 {
12151 .cmd = NL80211_CMD_SET_CQM,
12152 .doit = nl80211_set_cqm,
12153 .policy = nl80211_policy,
5617c6cd 12154 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12155 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12156 NL80211_FLAG_NEED_RTNL,
d6dc1a38 12157 },
f444de05
JB
12158 {
12159 .cmd = NL80211_CMD_SET_CHANNEL,
12160 .doit = nl80211_set_channel,
12161 .policy = nl80211_policy,
5617c6cd 12162 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12163 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12164 NL80211_FLAG_NEED_RTNL,
f444de05 12165 },
e8347eba
BJ
12166 {
12167 .cmd = NL80211_CMD_SET_WDS_PEER,
12168 .doit = nl80211_set_wds_peer,
12169 .policy = nl80211_policy,
5617c6cd 12170 .flags = GENL_UNS_ADMIN_PERM,
43b19952
JB
12171 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12172 NL80211_FLAG_NEED_RTNL,
e8347eba 12173 },
29cbe68c
JB
12174 {
12175 .cmd = NL80211_CMD_JOIN_MESH,
12176 .doit = nl80211_join_mesh,
12177 .policy = nl80211_policy,
5617c6cd 12178 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
12179 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12180 NL80211_FLAG_NEED_RTNL,
12181 },
12182 {
12183 .cmd = NL80211_CMD_LEAVE_MESH,
12184 .doit = nl80211_leave_mesh,
12185 .policy = nl80211_policy,
5617c6cd 12186 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
12187 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12188 NL80211_FLAG_NEED_RTNL,
12189 },
6e0bd6c3
RL
12190 {
12191 .cmd = NL80211_CMD_JOIN_OCB,
12192 .doit = nl80211_join_ocb,
12193 .policy = nl80211_policy,
5617c6cd 12194 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
12195 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12196 NL80211_FLAG_NEED_RTNL,
12197 },
12198 {
12199 .cmd = NL80211_CMD_LEAVE_OCB,
12200 .doit = nl80211_leave_ocb,
12201 .policy = nl80211_policy,
5617c6cd 12202 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
12203 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12204 NL80211_FLAG_NEED_RTNL,
12205 },
dfb89c56 12206#ifdef CONFIG_PM
ff1b6e69
JB
12207 {
12208 .cmd = NL80211_CMD_GET_WOWLAN,
12209 .doit = nl80211_get_wowlan,
12210 .policy = nl80211_policy,
12211 /* can be retrieved by unprivileged users */
12212 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12213 NL80211_FLAG_NEED_RTNL,
12214 },
12215 {
12216 .cmd = NL80211_CMD_SET_WOWLAN,
12217 .doit = nl80211_set_wowlan,
12218 .policy = nl80211_policy,
5617c6cd 12219 .flags = GENL_UNS_ADMIN_PERM,
ff1b6e69
JB
12220 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12221 NL80211_FLAG_NEED_RTNL,
12222 },
dfb89c56 12223#endif
e5497d76
JB
12224 {
12225 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
12226 .doit = nl80211_set_rekey_data,
12227 .policy = nl80211_policy,
5617c6cd 12228 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 12229 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12230 NL80211_FLAG_NEED_RTNL |
12231 NL80211_FLAG_CLEAR_SKB,
e5497d76 12232 },
109086ce
AN
12233 {
12234 .cmd = NL80211_CMD_TDLS_MGMT,
12235 .doit = nl80211_tdls_mgmt,
12236 .policy = nl80211_policy,
5617c6cd 12237 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
12238 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12239 NL80211_FLAG_NEED_RTNL,
12240 },
12241 {
12242 .cmd = NL80211_CMD_TDLS_OPER,
12243 .doit = nl80211_tdls_oper,
12244 .policy = nl80211_policy,
5617c6cd 12245 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
12246 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12247 NL80211_FLAG_NEED_RTNL,
12248 },
28946da7
JB
12249 {
12250 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
12251 .doit = nl80211_register_unexpected_frame,
12252 .policy = nl80211_policy,
5617c6cd 12253 .flags = GENL_UNS_ADMIN_PERM,
28946da7
JB
12254 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12255 NL80211_FLAG_NEED_RTNL,
12256 },
7f6cf311
JB
12257 {
12258 .cmd = NL80211_CMD_PROBE_CLIENT,
12259 .doit = nl80211_probe_client,
12260 .policy = nl80211_policy,
5617c6cd 12261 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12262 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
12263 NL80211_FLAG_NEED_RTNL,
12264 },
5e760230
JB
12265 {
12266 .cmd = NL80211_CMD_REGISTER_BEACONS,
12267 .doit = nl80211_register_beacons,
12268 .policy = nl80211_policy,
5617c6cd 12269 .flags = GENL_UNS_ADMIN_PERM,
5e760230
JB
12270 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12271 NL80211_FLAG_NEED_RTNL,
12272 },
1d9d9213
SW
12273 {
12274 .cmd = NL80211_CMD_SET_NOACK_MAP,
12275 .doit = nl80211_set_noack_map,
12276 .policy = nl80211_policy,
5617c6cd 12277 .flags = GENL_UNS_ADMIN_PERM,
1d9d9213
SW
12278 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12279 NL80211_FLAG_NEED_RTNL,
12280 },
98104fde
JB
12281 {
12282 .cmd = NL80211_CMD_START_P2P_DEVICE,
12283 .doit = nl80211_start_p2p_device,
12284 .policy = nl80211_policy,
5617c6cd 12285 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
12286 .internal_flags = NL80211_FLAG_NEED_WDEV |
12287 NL80211_FLAG_NEED_RTNL,
12288 },
12289 {
12290 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
12291 .doit = nl80211_stop_p2p_device,
12292 .policy = nl80211_policy,
5617c6cd 12293 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
12294 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12295 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
12296 },
12297 {
12298 .cmd = NL80211_CMD_START_NAN,
12299 .doit = nl80211_start_nan,
12300 .policy = nl80211_policy,
12301 .flags = GENL_ADMIN_PERM,
12302 .internal_flags = NL80211_FLAG_NEED_WDEV |
12303 NL80211_FLAG_NEED_RTNL,
12304 },
12305 {
12306 .cmd = NL80211_CMD_STOP_NAN,
12307 .doit = nl80211_stop_nan,
12308 .policy = nl80211_policy,
12309 .flags = GENL_ADMIN_PERM,
12310 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12311 NL80211_FLAG_NEED_RTNL,
a442b761
AB
12312 },
12313 {
12314 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
12315 .doit = nl80211_nan_add_func,
12316 .policy = nl80211_policy,
12317 .flags = GENL_ADMIN_PERM,
12318 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12319 NL80211_FLAG_NEED_RTNL,
12320 },
12321 {
12322 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
12323 .doit = nl80211_nan_del_func,
12324 .policy = nl80211_policy,
12325 .flags = GENL_ADMIN_PERM,
12326 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12327 NL80211_FLAG_NEED_RTNL,
a5a9dcf2
AB
12328 },
12329 {
12330 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
12331 .doit = nl80211_nan_change_config,
12332 .policy = nl80211_policy,
12333 .flags = GENL_ADMIN_PERM,
12334 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12335 NL80211_FLAG_NEED_RTNL,
98104fde 12336 },
f4e583c8
AQ
12337 {
12338 .cmd = NL80211_CMD_SET_MCAST_RATE,
12339 .doit = nl80211_set_mcast_rate,
77765eaf 12340 .policy = nl80211_policy,
5617c6cd 12341 .flags = GENL_UNS_ADMIN_PERM,
77765eaf
VT
12342 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12343 NL80211_FLAG_NEED_RTNL,
12344 },
12345 {
12346 .cmd = NL80211_CMD_SET_MAC_ACL,
12347 .doit = nl80211_set_mac_acl,
f4e583c8 12348 .policy = nl80211_policy,
5617c6cd 12349 .flags = GENL_UNS_ADMIN_PERM,
f4e583c8
AQ
12350 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12351 NL80211_FLAG_NEED_RTNL,
12352 },
04f39047
SW
12353 {
12354 .cmd = NL80211_CMD_RADAR_DETECT,
12355 .doit = nl80211_start_radar_detection,
12356 .policy = nl80211_policy,
5617c6cd 12357 .flags = GENL_UNS_ADMIN_PERM,
04f39047
SW
12358 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12359 NL80211_FLAG_NEED_RTNL,
12360 },
3713b4e3
JB
12361 {
12362 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
12363 .doit = nl80211_get_protocol_features,
12364 .policy = nl80211_policy,
12365 },
355199e0
JM
12366 {
12367 .cmd = NL80211_CMD_UPDATE_FT_IES,
12368 .doit = nl80211_update_ft_ies,
12369 .policy = nl80211_policy,
5617c6cd 12370 .flags = GENL_UNS_ADMIN_PERM,
355199e0
JM
12371 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12372 NL80211_FLAG_NEED_RTNL,
12373 },
5de17984
AS
12374 {
12375 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
12376 .doit = nl80211_crit_protocol_start,
12377 .policy = nl80211_policy,
5617c6cd 12378 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
12379 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12380 NL80211_FLAG_NEED_RTNL,
12381 },
12382 {
12383 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
12384 .doit = nl80211_crit_protocol_stop,
12385 .policy = nl80211_policy,
5617c6cd 12386 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
12387 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12388 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
12389 },
12390 {
12391 .cmd = NL80211_CMD_GET_COALESCE,
12392 .doit = nl80211_get_coalesce,
12393 .policy = nl80211_policy,
12394 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12395 NL80211_FLAG_NEED_RTNL,
12396 },
12397 {
12398 .cmd = NL80211_CMD_SET_COALESCE,
12399 .doit = nl80211_set_coalesce,
12400 .policy = nl80211_policy,
5617c6cd 12401 .flags = GENL_UNS_ADMIN_PERM,
be29b99a
AK
12402 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12403 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
12404 },
12405 {
12406 .cmd = NL80211_CMD_CHANNEL_SWITCH,
12407 .doit = nl80211_channel_switch,
12408 .policy = nl80211_policy,
5617c6cd 12409 .flags = GENL_UNS_ADMIN_PERM,
16ef1fe2
SW
12410 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12411 NL80211_FLAG_NEED_RTNL,
12412 },
ad7e718c
JB
12413 {
12414 .cmd = NL80211_CMD_VENDOR,
12415 .doit = nl80211_vendor_cmd,
7bdbe400 12416 .dumpit = nl80211_vendor_cmd_dump,
ad7e718c 12417 .policy = nl80211_policy,
5617c6cd 12418 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c
JB
12419 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12420 NL80211_FLAG_NEED_RTNL,
12421 },
fa9ffc74
KP
12422 {
12423 .cmd = NL80211_CMD_SET_QOS_MAP,
12424 .doit = nl80211_set_qos_map,
12425 .policy = nl80211_policy,
5617c6cd 12426 .flags = GENL_UNS_ADMIN_PERM,
fa9ffc74
KP
12427 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12428 NL80211_FLAG_NEED_RTNL,
12429 },
960d01ac
JB
12430 {
12431 .cmd = NL80211_CMD_ADD_TX_TS,
12432 .doit = nl80211_add_tx_ts,
12433 .policy = nl80211_policy,
5617c6cd 12434 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
12435 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12436 NL80211_FLAG_NEED_RTNL,
12437 },
12438 {
12439 .cmd = NL80211_CMD_DEL_TX_TS,
12440 .doit = nl80211_del_tx_ts,
12441 .policy = nl80211_policy,
5617c6cd 12442 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
12443 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12444 NL80211_FLAG_NEED_RTNL,
12445 },
1057d35e
AN
12446 {
12447 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
12448 .doit = nl80211_tdls_channel_switch,
12449 .policy = nl80211_policy,
5617c6cd 12450 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
12451 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12452 NL80211_FLAG_NEED_RTNL,
12453 },
12454 {
12455 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
12456 .doit = nl80211_tdls_cancel_channel_switch,
12457 .policy = nl80211_policy,
5617c6cd 12458 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
12459 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12460 NL80211_FLAG_NEED_RTNL,
12461 },
55682965 12462};
9588bbd5 12463
55682965
JB
12464/* notification functions */
12465
3bb20556
JB
12466void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
12467 enum nl80211_commands cmd)
55682965
JB
12468{
12469 struct sk_buff *msg;
86e8cf98 12470 struct nl80211_dump_wiphy_state state = {};
55682965 12471
3bb20556
JB
12472 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
12473 cmd != NL80211_CMD_DEL_WIPHY);
12474
fd2120ca 12475 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
12476 if (!msg)
12477 return;
12478
3bb20556 12479 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
12480 nlmsg_free(msg);
12481 return;
12482 }
12483
68eb5503 12484 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12485 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
12486}
12487
896ff063
DK
12488void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
12489 struct wireless_dev *wdev,
12490 enum nl80211_commands cmd)
12491{
12492 struct sk_buff *msg;
12493
12494 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
12495 cmd != NL80211_CMD_DEL_INTERFACE);
12496
12497 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12498 if (!msg)
12499 return;
12500
12501 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev,
12502 cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
12503 nlmsg_free(msg);
12504 return;
12505 }
12506
12507 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
12508 NL80211_MCGRP_CONFIG, GFP_KERNEL);
12509}
12510
362a415d
JB
12511static int nl80211_add_scan_req(struct sk_buff *msg,
12512 struct cfg80211_registered_device *rdev)
12513{
12514 struct cfg80211_scan_request *req = rdev->scan_req;
12515 struct nlattr *nest;
12516 int i;
12517
12518 if (WARN_ON(!req))
12519 return 0;
12520
12521 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
12522 if (!nest)
12523 goto nla_put_failure;
9360ffd1
DM
12524 for (i = 0; i < req->n_ssids; i++) {
12525 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
12526 goto nla_put_failure;
12527 }
362a415d
JB
12528 nla_nest_end(msg, nest);
12529
12530 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
12531 if (!nest)
12532 goto nla_put_failure;
9360ffd1
DM
12533 for (i = 0; i < req->n_channels; i++) {
12534 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
12535 goto nla_put_failure;
12536 }
362a415d
JB
12537 nla_nest_end(msg, nest);
12538
9360ffd1
DM
12539 if (req->ie &&
12540 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
12541 goto nla_put_failure;
362a415d 12542
ae917c9f
JB
12543 if (req->flags &&
12544 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
12545 goto nla_put_failure;
ed473771 12546
1d76250b
AS
12547 if (req->info.scan_start_tsf &&
12548 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
12549 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
12550 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
12551 req->info.tsf_bssid)))
12552 goto nla_put_failure;
12553
362a415d
JB
12554 return 0;
12555 nla_put_failure:
12556 return -ENOBUFS;
12557}
12558
a538e2d5
JB
12559static int nl80211_send_scan_msg(struct sk_buff *msg,
12560 struct cfg80211_registered_device *rdev,
fd014284 12561 struct wireless_dev *wdev,
15e47304 12562 u32 portid, u32 seq, int flags,
a538e2d5 12563 u32 cmd)
2a519311
JB
12564{
12565 void *hdr;
12566
15e47304 12567 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
12568 if (!hdr)
12569 return -1;
12570
9360ffd1 12571 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
12572 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12573 wdev->netdev->ifindex)) ||
2dad624e
ND
12574 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12575 NL80211_ATTR_PAD))
9360ffd1 12576 goto nla_put_failure;
2a519311 12577
362a415d
JB
12578 /* ignore errors and send incomplete event anyway */
12579 nl80211_add_scan_req(msg, rdev);
2a519311 12580
053c095a
JB
12581 genlmsg_end(msg, hdr);
12582 return 0;
2a519311
JB
12583
12584 nla_put_failure:
12585 genlmsg_cancel(msg, hdr);
12586 return -EMSGSIZE;
12587}
12588
807f8a8c
LC
12589static int
12590nl80211_send_sched_scan_msg(struct sk_buff *msg,
12591 struct cfg80211_registered_device *rdev,
12592 struct net_device *netdev,
15e47304 12593 u32 portid, u32 seq, int flags, u32 cmd)
807f8a8c
LC
12594{
12595 void *hdr;
12596
15e47304 12597 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
807f8a8c
LC
12598 if (!hdr)
12599 return -1;
12600
9360ffd1
DM
12601 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12602 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
12603 goto nla_put_failure;
807f8a8c 12604
053c095a
JB
12605 genlmsg_end(msg, hdr);
12606 return 0;
807f8a8c
LC
12607
12608 nla_put_failure:
12609 genlmsg_cancel(msg, hdr);
12610 return -EMSGSIZE;
12611}
12612
a538e2d5 12613void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 12614 struct wireless_dev *wdev)
a538e2d5
JB
12615{
12616 struct sk_buff *msg;
12617
58050fce 12618 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
12619 if (!msg)
12620 return;
12621
fd014284 12622 if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
12623 NL80211_CMD_TRIGGER_SCAN) < 0) {
12624 nlmsg_free(msg);
12625 return;
12626 }
12627
68eb5503 12628 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12629 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
12630}
12631
f9d15d16
JB
12632struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
12633 struct wireless_dev *wdev, bool aborted)
2a519311
JB
12634{
12635 struct sk_buff *msg;
12636
fd2120ca 12637 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 12638 if (!msg)
f9d15d16 12639 return NULL;
2a519311 12640
fd014284 12641 if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
12642 aborted ? NL80211_CMD_SCAN_ABORTED :
12643 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 12644 nlmsg_free(msg);
f9d15d16 12645 return NULL;
2a519311
JB
12646 }
12647
f9d15d16 12648 return msg;
2a519311
JB
12649}
12650
f9d15d16
JB
12651void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
12652 struct sk_buff *msg)
2a519311 12653{
2a519311
JB
12654 if (!msg)
12655 return;
12656
68eb5503 12657 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12658 NL80211_MCGRP_SCAN, GFP_KERNEL);
2a519311
JB
12659}
12660
807f8a8c
LC
12661void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
12662 struct net_device *netdev)
12663{
12664 struct sk_buff *msg;
12665
12666 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12667 if (!msg)
12668 return;
12669
12670 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0,
12671 NL80211_CMD_SCHED_SCAN_RESULTS) < 0) {
12672 nlmsg_free(msg);
12673 return;
12674 }
12675
68eb5503 12676 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12677 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
12678}
12679
12680void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
12681 struct net_device *netdev, u32 cmd)
12682{
12683 struct sk_buff *msg;
12684
58050fce 12685 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
12686 if (!msg)
12687 return;
12688
12689 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
12690 nlmsg_free(msg);
12691 return;
12692 }
12693
68eb5503 12694 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12695 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
12696}
12697
b0d7aa59
JD
12698static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
12699 struct regulatory_request *request)
73d54c9e 12700{
73d54c9e 12701 /* Userspace can always count this one always being set */
9360ffd1
DM
12702 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
12703 goto nla_put_failure;
12704
12705 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
12706 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12707 NL80211_REGDOM_TYPE_WORLD))
12708 goto nla_put_failure;
12709 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
12710 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12711 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
12712 goto nla_put_failure;
12713 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
12714 request->intersect) {
12715 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12716 NL80211_REGDOM_TYPE_INTERSECTION))
12717 goto nla_put_failure;
12718 } else {
12719 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12720 NL80211_REGDOM_TYPE_COUNTRY) ||
12721 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
12722 request->alpha2))
12723 goto nla_put_failure;
12724 }
12725
ad30ca2c
AN
12726 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
12727 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
12728
12729 if (wiphy &&
12730 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
12731 goto nla_put_failure;
1bdd716c
AN
12732
12733 if (wiphy &&
12734 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
12735 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
12736 goto nla_put_failure;
ad30ca2c 12737 }
73d54c9e 12738
b0d7aa59
JD
12739 return true;
12740
12741nla_put_failure:
12742 return false;
12743}
12744
12745/*
12746 * This can happen on global regulatory changes or device specific settings
12747 * based on custom regulatory domains.
12748 */
12749void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
12750 struct regulatory_request *request)
12751{
12752 struct sk_buff *msg;
12753 void *hdr;
12754
12755 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12756 if (!msg)
12757 return;
12758
12759 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
12760 if (!hdr) {
12761 nlmsg_free(msg);
12762 return;
12763 }
12764
12765 if (nl80211_reg_change_event_fill(msg, request) == false)
12766 goto nla_put_failure;
12767
3b7b72ee 12768 genlmsg_end(msg, hdr);
73d54c9e 12769
bc43b28c 12770 rcu_read_lock();
68eb5503 12771 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 12772 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 12773 rcu_read_unlock();
73d54c9e
LR
12774
12775 return;
12776
12777nla_put_failure:
12778 genlmsg_cancel(msg, hdr);
12779 nlmsg_free(msg);
12780}
12781
6039f6d2
JM
12782static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
12783 struct net_device *netdev,
12784 const u8 *buf, size_t len,
b0b6aa2c
EP
12785 enum nl80211_commands cmd, gfp_t gfp,
12786 int uapsd_queues)
6039f6d2
JM
12787{
12788 struct sk_buff *msg;
12789 void *hdr;
12790
e6d6e342 12791 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
6039f6d2
JM
12792 if (!msg)
12793 return;
12794
12795 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
12796 if (!hdr) {
12797 nlmsg_free(msg);
12798 return;
12799 }
12800
9360ffd1
DM
12801 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12802 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
12803 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
12804 goto nla_put_failure;
6039f6d2 12805
b0b6aa2c
EP
12806 if (uapsd_queues >= 0) {
12807 struct nlattr *nla_wmm =
12808 nla_nest_start(msg, NL80211_ATTR_STA_WME);
12809 if (!nla_wmm)
12810 goto nla_put_failure;
12811
12812 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
12813 uapsd_queues))
12814 goto nla_put_failure;
12815
12816 nla_nest_end(msg, nla_wmm);
12817 }
12818
3b7b72ee 12819 genlmsg_end(msg, hdr);
6039f6d2 12820
68eb5503 12821 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12822 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
12823 return;
12824
12825 nla_put_failure:
12826 genlmsg_cancel(msg, hdr);
12827 nlmsg_free(msg);
12828}
12829
12830void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12831 struct net_device *netdev, const u8 *buf,
12832 size_t len, gfp_t gfp)
6039f6d2
JM
12833{
12834 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12835 NL80211_CMD_AUTHENTICATE, gfp, -1);
6039f6d2
JM
12836}
12837
12838void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
12839 struct net_device *netdev, const u8 *buf,
b0b6aa2c 12840 size_t len, gfp_t gfp, int uapsd_queues)
6039f6d2 12841{
e6d6e342 12842 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12843 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues);
6039f6d2
JM
12844}
12845
53b46b84 12846void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12847 struct net_device *netdev, const u8 *buf,
12848 size_t len, gfp_t gfp)
6039f6d2
JM
12849{
12850 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12851 NL80211_CMD_DEAUTHENTICATE, gfp, -1);
6039f6d2
JM
12852}
12853
53b46b84
JM
12854void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
12855 struct net_device *netdev, const u8 *buf,
e6d6e342 12856 size_t len, gfp_t gfp)
6039f6d2
JM
12857{
12858 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12859 NL80211_CMD_DISASSOCIATE, gfp, -1);
6039f6d2
JM
12860}
12861
6ff57cf8
JB
12862void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
12863 size_t len)
cf4e594e 12864{
947add36
JB
12865 struct wireless_dev *wdev = dev->ieee80211_ptr;
12866 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 12867 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
12868 const struct ieee80211_mgmt *mgmt = (void *)buf;
12869 u32 cmd;
947add36 12870
6ff57cf8
JB
12871 if (WARN_ON(len < 2))
12872 return;
cf4e594e 12873
6ff57cf8
JB
12874 if (ieee80211_is_deauth(mgmt->frame_control))
12875 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
12876 else
12877 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 12878
6ff57cf8 12879 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
b0b6aa2c 12880 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1);
cf4e594e 12881}
6ff57cf8 12882EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 12883
1b06bb40
LR
12884static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
12885 struct net_device *netdev, int cmd,
e6d6e342 12886 const u8 *addr, gfp_t gfp)
1965c853
JM
12887{
12888 struct sk_buff *msg;
12889 void *hdr;
12890
e6d6e342 12891 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
12892 if (!msg)
12893 return;
12894
12895 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
12896 if (!hdr) {
12897 nlmsg_free(msg);
12898 return;
12899 }
12900
9360ffd1
DM
12901 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12902 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
12903 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
12904 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
12905 goto nla_put_failure;
1965c853 12906
3b7b72ee 12907 genlmsg_end(msg, hdr);
1965c853 12908
68eb5503 12909 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12910 NL80211_MCGRP_MLME, gfp);
1965c853
JM
12911 return;
12912
12913 nla_put_failure:
12914 genlmsg_cancel(msg, hdr);
12915 nlmsg_free(msg);
12916}
12917
12918void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12919 struct net_device *netdev, const u8 *addr,
12920 gfp_t gfp)
1965c853
JM
12921{
12922 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 12923 addr, gfp);
1965c853
JM
12924}
12925
12926void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12927 struct net_device *netdev, const u8 *addr,
12928 gfp_t gfp)
1965c853 12929{
e6d6e342
JB
12930 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
12931 addr, gfp);
1965c853
JM
12932}
12933
b23aa676
SO
12934void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
12935 struct net_device *netdev, const u8 *bssid,
12936 const u8 *req_ie, size_t req_ie_len,
12937 const u8 *resp_ie, size_t resp_ie_len,
bf1ecd21 12938 int status, gfp_t gfp)
b23aa676
SO
12939{
12940 struct sk_buff *msg;
12941 void *hdr;
12942
58050fce 12943 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
b23aa676
SO
12944 if (!msg)
12945 return;
12946
12947 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
12948 if (!hdr) {
12949 nlmsg_free(msg);
12950 return;
12951 }
12952
9360ffd1
DM
12953 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12954 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
12955 (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) ||
bf1ecd21
JM
12956 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
12957 status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
12958 status) ||
12959 (status < 0 && nla_put_flag(msg, NL80211_ATTR_TIMED_OUT)) ||
9360ffd1
DM
12960 (req_ie &&
12961 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
12962 (resp_ie &&
12963 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
12964 goto nla_put_failure;
b23aa676 12965
3b7b72ee 12966 genlmsg_end(msg, hdr);
b23aa676 12967
68eb5503 12968 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12969 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
12970 return;
12971
12972 nla_put_failure:
12973 genlmsg_cancel(msg, hdr);
12974 nlmsg_free(msg);
b23aa676
SO
12975}
12976
12977void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
12978 struct net_device *netdev, const u8 *bssid,
12979 const u8 *req_ie, size_t req_ie_len,
12980 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
12981{
12982 struct sk_buff *msg;
12983 void *hdr;
12984
58050fce 12985 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
b23aa676
SO
12986 if (!msg)
12987 return;
12988
12989 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
12990 if (!hdr) {
12991 nlmsg_free(msg);
12992 return;
12993 }
12994
9360ffd1
DM
12995 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12996 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
12997 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
12998 (req_ie &&
12999 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
13000 (resp_ie &&
13001 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
13002 goto nla_put_failure;
b23aa676 13003
3b7b72ee 13004 genlmsg_end(msg, hdr);
b23aa676 13005
68eb5503 13006 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13007 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
13008 return;
13009
13010 nla_put_failure:
13011 genlmsg_cancel(msg, hdr);
13012 nlmsg_free(msg);
b23aa676
SO
13013}
13014
13015void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
13016 struct net_device *netdev, u16 reason,
667503dd 13017 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
13018{
13019 struct sk_buff *msg;
13020 void *hdr;
13021
58050fce 13022 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
b23aa676
SO
13023 if (!msg)
13024 return;
13025
13026 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
13027 if (!hdr) {
13028 nlmsg_free(msg);
13029 return;
13030 }
13031
9360ffd1
DM
13032 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13033 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13034 (from_ap && reason &&
13035 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
13036 (from_ap &&
13037 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
13038 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
13039 goto nla_put_failure;
b23aa676 13040
3b7b72ee 13041 genlmsg_end(msg, hdr);
b23aa676 13042
68eb5503 13043 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13044 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
13045 return;
13046
13047 nla_put_failure:
13048 genlmsg_cancel(msg, hdr);
13049 nlmsg_free(msg);
b23aa676
SO
13050}
13051
04a773ad
JB
13052void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
13053 struct net_device *netdev, const u8 *bssid,
13054 gfp_t gfp)
13055{
13056 struct sk_buff *msg;
13057 void *hdr;
13058
fd2120ca 13059 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
13060 if (!msg)
13061 return;
13062
13063 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
13064 if (!hdr) {
13065 nlmsg_free(msg);
13066 return;
13067 }
13068
9360ffd1
DM
13069 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13070 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13071 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13072 goto nla_put_failure;
04a773ad 13073
3b7b72ee 13074 genlmsg_end(msg, hdr);
04a773ad 13075
68eb5503 13076 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13077 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
13078 return;
13079
13080 nla_put_failure:
13081 genlmsg_cancel(msg, hdr);
13082 nlmsg_free(msg);
13083}
13084
947add36
JB
13085void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
13086 const u8* ie, u8 ie_len, gfp_t gfp)
c93b5e71 13087{
947add36 13088 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13089 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
13090 struct sk_buff *msg;
13091 void *hdr;
13092
947add36
JB
13093 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
13094 return;
13095
13096 trace_cfg80211_notify_new_peer_candidate(dev, addr);
13097
c93b5e71
JC
13098 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13099 if (!msg)
13100 return;
13101
13102 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
13103 if (!hdr) {
13104 nlmsg_free(msg);
13105 return;
13106 }
13107
9360ffd1 13108 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
13109 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13110 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1
DM
13111 (ie_len && ie &&
13112 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
13113 goto nla_put_failure;
c93b5e71 13114
3b7b72ee 13115 genlmsg_end(msg, hdr);
c93b5e71 13116
68eb5503 13117 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13118 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
13119 return;
13120
13121 nla_put_failure:
13122 genlmsg_cancel(msg, hdr);
13123 nlmsg_free(msg);
13124}
947add36 13125EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 13126
a3b8b056
JM
13127void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
13128 struct net_device *netdev, const u8 *addr,
13129 enum nl80211_key_type key_type, int key_id,
e6d6e342 13130 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
13131{
13132 struct sk_buff *msg;
13133 void *hdr;
13134
e6d6e342 13135 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
13136 if (!msg)
13137 return;
13138
13139 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
13140 if (!hdr) {
13141 nlmsg_free(msg);
13142 return;
13143 }
13144
9360ffd1
DM
13145 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13146 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13147 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
13148 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
13149 (key_id != -1 &&
13150 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
13151 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
13152 goto nla_put_failure;
a3b8b056 13153
3b7b72ee 13154 genlmsg_end(msg, hdr);
a3b8b056 13155
68eb5503 13156 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13157 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
13158 return;
13159
13160 nla_put_failure:
13161 genlmsg_cancel(msg, hdr);
13162 nlmsg_free(msg);
13163}
13164
6bad8766
LR
13165void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
13166 struct ieee80211_channel *channel_before,
13167 struct ieee80211_channel *channel_after)
13168{
13169 struct sk_buff *msg;
13170 void *hdr;
13171 struct nlattr *nl_freq;
13172
fd2120ca 13173 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
13174 if (!msg)
13175 return;
13176
13177 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
13178 if (!hdr) {
13179 nlmsg_free(msg);
13180 return;
13181 }
13182
13183 /*
13184 * Since we are applying the beacon hint to a wiphy we know its
13185 * wiphy_idx is valid
13186 */
9360ffd1
DM
13187 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
13188 goto nla_put_failure;
6bad8766
LR
13189
13190 /* Before */
13191 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
13192 if (!nl_freq)
13193 goto nla_put_failure;
cdc89b97 13194 if (nl80211_msg_put_channel(msg, channel_before, false))
6bad8766
LR
13195 goto nla_put_failure;
13196 nla_nest_end(msg, nl_freq);
13197
13198 /* After */
13199 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
13200 if (!nl_freq)
13201 goto nla_put_failure;
cdc89b97 13202 if (nl80211_msg_put_channel(msg, channel_after, false))
6bad8766
LR
13203 goto nla_put_failure;
13204 nla_nest_end(msg, nl_freq);
13205
3b7b72ee 13206 genlmsg_end(msg, hdr);
6bad8766 13207
463d0183 13208 rcu_read_lock();
68eb5503 13209 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 13210 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 13211 rcu_read_unlock();
6bad8766
LR
13212
13213 return;
13214
13215nla_put_failure:
13216 genlmsg_cancel(msg, hdr);
13217 nlmsg_free(msg);
13218}
13219
9588bbd5
JM
13220static void nl80211_send_remain_on_chan_event(
13221 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 13222 struct wireless_dev *wdev, u64 cookie,
9588bbd5 13223 struct ieee80211_channel *chan,
9588bbd5
JM
13224 unsigned int duration, gfp_t gfp)
13225{
13226 struct sk_buff *msg;
13227 void *hdr;
13228
13229 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13230 if (!msg)
13231 return;
13232
13233 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13234 if (!hdr) {
13235 nlmsg_free(msg);
13236 return;
13237 }
13238
9360ffd1 13239 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13240 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13241 wdev->netdev->ifindex)) ||
2dad624e
ND
13242 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13243 NL80211_ATTR_PAD) ||
9360ffd1 13244 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
13245 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
13246 NL80211_CHAN_NO_HT) ||
2dad624e
ND
13247 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13248 NL80211_ATTR_PAD))
9360ffd1 13249 goto nla_put_failure;
9588bbd5 13250
9360ffd1
DM
13251 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
13252 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
13253 goto nla_put_failure;
9588bbd5 13254
3b7b72ee 13255 genlmsg_end(msg, hdr);
9588bbd5 13256
68eb5503 13257 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13258 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
13259 return;
13260
13261 nla_put_failure:
13262 genlmsg_cancel(msg, hdr);
13263 nlmsg_free(msg);
13264}
13265
947add36
JB
13266void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
13267 struct ieee80211_channel *chan,
13268 unsigned int duration, gfp_t gfp)
9588bbd5 13269{
947add36 13270 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13271 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13272
13273 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 13274 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 13275 rdev, wdev, cookie, chan,
42d97a59 13276 duration, gfp);
9588bbd5 13277}
947add36 13278EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 13279
947add36
JB
13280void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
13281 struct ieee80211_channel *chan,
13282 gfp_t gfp)
9588bbd5 13283{
947add36 13284 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13285 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13286
13287 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 13288 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 13289 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 13290}
947add36 13291EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 13292
947add36
JB
13293void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
13294 struct station_info *sinfo, gfp_t gfp)
98b62183 13295{
947add36 13296 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13297 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
13298 struct sk_buff *msg;
13299
947add36
JB
13300 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
13301
58050fce 13302 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
13303 if (!msg)
13304 return;
13305
cf5ead82 13306 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 13307 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
13308 nlmsg_free(msg);
13309 return;
13310 }
13311
68eb5503 13312 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13313 NL80211_MCGRP_MLME, gfp);
98b62183 13314}
947add36 13315EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 13316
cf5ead82
JB
13317void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
13318 struct station_info *sinfo, gfp_t gfp)
ec15e68b 13319{
947add36 13320 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13321 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 13322 struct sk_buff *msg;
cf5ead82
JB
13323 struct station_info empty_sinfo = {};
13324
13325 if (!sinfo)
13326 sinfo = &empty_sinfo;
ec15e68b 13327
947add36
JB
13328 trace_cfg80211_del_sta(dev, mac_addr);
13329
58050fce 13330 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
ec15e68b
JM
13331 if (!msg)
13332 return;
13333
cf5ead82 13334 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 13335 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b
JM
13336 nlmsg_free(msg);
13337 return;
13338 }
13339
68eb5503 13340 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13341 NL80211_MCGRP_MLME, gfp);
ec15e68b 13342}
cf5ead82 13343EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 13344
947add36
JB
13345void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
13346 enum nl80211_connect_failed_reason reason,
13347 gfp_t gfp)
ed44a951 13348{
947add36 13349 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13350 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
13351 struct sk_buff *msg;
13352 void *hdr;
13353
13354 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
13355 if (!msg)
13356 return;
13357
13358 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
13359 if (!hdr) {
13360 nlmsg_free(msg);
13361 return;
13362 }
13363
13364 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13365 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
13366 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
13367 goto nla_put_failure;
13368
13369 genlmsg_end(msg, hdr);
13370
68eb5503 13371 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13372 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
13373 return;
13374
13375 nla_put_failure:
13376 genlmsg_cancel(msg, hdr);
13377 nlmsg_free(msg);
13378}
947add36 13379EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 13380
b92ab5d8
JB
13381static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
13382 const u8 *addr, gfp_t gfp)
28946da7
JB
13383{
13384 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13385 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
13386 struct sk_buff *msg;
13387 void *hdr;
15e47304 13388 u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid);
28946da7 13389
15e47304 13390 if (!nlportid)
28946da7
JB
13391 return false;
13392
13393 msg = nlmsg_new(100, gfp);
13394 if (!msg)
13395 return true;
13396
b92ab5d8 13397 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
13398 if (!hdr) {
13399 nlmsg_free(msg);
13400 return true;
13401 }
13402
9360ffd1
DM
13403 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13404 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13405 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
13406 goto nla_put_failure;
28946da7 13407
9c90a9f6 13408 genlmsg_end(msg, hdr);
15e47304 13409 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
13410 return true;
13411
13412 nla_put_failure:
13413 genlmsg_cancel(msg, hdr);
13414 nlmsg_free(msg);
13415 return true;
13416}
13417
947add36
JB
13418bool cfg80211_rx_spurious_frame(struct net_device *dev,
13419 const u8 *addr, gfp_t gfp)
b92ab5d8 13420{
947add36
JB
13421 struct wireless_dev *wdev = dev->ieee80211_ptr;
13422 bool ret;
13423
13424 trace_cfg80211_rx_spurious_frame(dev, addr);
13425
13426 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
13427 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
13428 trace_cfg80211_return_bool(false);
13429 return false;
13430 }
13431 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
13432 addr, gfp);
13433 trace_cfg80211_return_bool(ret);
13434 return ret;
b92ab5d8 13435}
947add36 13436EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 13437
947add36
JB
13438bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
13439 const u8 *addr, gfp_t gfp)
b92ab5d8 13440{
947add36
JB
13441 struct wireless_dev *wdev = dev->ieee80211_ptr;
13442 bool ret;
13443
13444 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
13445
13446 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
13447 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
13448 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
13449 trace_cfg80211_return_bool(false);
13450 return false;
13451 }
13452 ret = __nl80211_unexpected_frame(dev,
13453 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
13454 addr, gfp);
13455 trace_cfg80211_return_bool(ret);
13456 return ret;
b92ab5d8 13457}
947add36 13458EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 13459
2e161f78 13460int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 13461 struct wireless_dev *wdev, u32 nlportid,
804483e9 13462 int freq, int sig_dbm,
19504cf5 13463 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 13464{
71bbc994 13465 struct net_device *netdev = wdev->netdev;
026331c4
JM
13466 struct sk_buff *msg;
13467 void *hdr;
026331c4
JM
13468
13469 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13470 if (!msg)
13471 return -ENOMEM;
13472
2e161f78 13473 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
13474 if (!hdr) {
13475 nlmsg_free(msg);
13476 return -ENOMEM;
13477 }
13478
9360ffd1 13479 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13480 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13481 netdev->ifindex)) ||
2dad624e
ND
13482 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13483 NL80211_ATTR_PAD) ||
9360ffd1
DM
13484 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
13485 (sig_dbm &&
13486 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
13487 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
13488 (flags &&
13489 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 13490 goto nla_put_failure;
026331c4 13491
3b7b72ee 13492 genlmsg_end(msg, hdr);
026331c4 13493
15e47304 13494 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
13495
13496 nla_put_failure:
13497 genlmsg_cancel(msg, hdr);
13498 nlmsg_free(msg);
13499 return -ENOBUFS;
13500}
13501
947add36
JB
13502void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
13503 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 13504{
947add36 13505 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13506 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 13507 struct net_device *netdev = wdev->netdev;
026331c4
JM
13508 struct sk_buff *msg;
13509 void *hdr;
13510
947add36
JB
13511 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
13512
026331c4
JM
13513 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13514 if (!msg)
13515 return;
13516
2e161f78 13517 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
13518 if (!hdr) {
13519 nlmsg_free(msg);
13520 return;
13521 }
13522
9360ffd1 13523 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13524 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13525 netdev->ifindex)) ||
2dad624e
ND
13526 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13527 NL80211_ATTR_PAD) ||
9360ffd1 13528 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
13529 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13530 NL80211_ATTR_PAD) ||
9360ffd1
DM
13531 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
13532 goto nla_put_failure;
026331c4 13533
3b7b72ee 13534 genlmsg_end(msg, hdr);
026331c4 13535
68eb5503 13536 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13537 NL80211_MCGRP_MLME, gfp);
026331c4
JM
13538 return;
13539
13540 nla_put_failure:
13541 genlmsg_cancel(msg, hdr);
13542 nlmsg_free(msg);
13543}
947add36 13544EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 13545
5b97f49d
JB
13546static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
13547 const char *mac, gfp_t gfp)
d6dc1a38 13548{
947add36 13549 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
13550 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
13551 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13552 void **cb;
947add36 13553
d6dc1a38 13554 if (!msg)
5b97f49d 13555 return NULL;
d6dc1a38 13556
5b97f49d
JB
13557 cb = (void **)msg->cb;
13558
13559 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
13560 if (!cb[0]) {
d6dc1a38 13561 nlmsg_free(msg);
5b97f49d 13562 return NULL;
d6dc1a38
JO
13563 }
13564
9360ffd1 13565 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 13566 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 13567 goto nla_put_failure;
d6dc1a38 13568
5b97f49d 13569 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
13570 goto nla_put_failure;
13571
5b97f49d
JB
13572 cb[1] = nla_nest_start(msg, NL80211_ATTR_CQM);
13573 if (!cb[1])
9360ffd1 13574 goto nla_put_failure;
d6dc1a38 13575
5b97f49d 13576 cb[2] = rdev;
d6dc1a38 13577
5b97f49d
JB
13578 return msg;
13579 nla_put_failure:
13580 nlmsg_free(msg);
13581 return NULL;
13582}
13583
13584static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
13585{
13586 void **cb = (void **)msg->cb;
13587 struct cfg80211_registered_device *rdev = cb[2];
13588
13589 nla_nest_end(msg, cb[1]);
13590 genlmsg_end(msg, cb[0]);
13591
13592 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 13593
68eb5503 13594 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13595 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
13596}
13597
13598void cfg80211_cqm_rssi_notify(struct net_device *dev,
13599 enum nl80211_cqm_rssi_threshold_event rssi_event,
13600 gfp_t gfp)
13601{
13602 struct sk_buff *msg;
13603
13604 trace_cfg80211_cqm_rssi_notify(dev, rssi_event);
13605
98f03342
JB
13606 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
13607 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
13608 return;
13609
5b97f49d
JB
13610 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
13611 if (!msg)
13612 return;
13613
13614 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
13615 rssi_event))
13616 goto nla_put_failure;
13617
13618 cfg80211_send_cqm(msg, gfp);
13619
d6dc1a38
JO
13620 return;
13621
13622 nla_put_failure:
d6dc1a38
JO
13623 nlmsg_free(msg);
13624}
947add36 13625EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 13626
5b97f49d
JB
13627void cfg80211_cqm_txe_notify(struct net_device *dev,
13628 const u8 *peer, u32 num_packets,
13629 u32 rate, u32 intvl, gfp_t gfp)
13630{
13631 struct sk_buff *msg;
13632
13633 msg = cfg80211_prepare_cqm(dev, peer, gfp);
13634 if (!msg)
13635 return;
13636
13637 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
13638 goto nla_put_failure;
13639
13640 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
13641 goto nla_put_failure;
13642
13643 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
13644 goto nla_put_failure;
13645
13646 cfg80211_send_cqm(msg, gfp);
13647 return;
13648
13649 nla_put_failure:
13650 nlmsg_free(msg);
13651}
13652EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
13653
13654void cfg80211_cqm_pktloss_notify(struct net_device *dev,
13655 const u8 *peer, u32 num_packets, gfp_t gfp)
13656{
13657 struct sk_buff *msg;
13658
13659 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
13660
13661 msg = cfg80211_prepare_cqm(dev, peer, gfp);
13662 if (!msg)
13663 return;
13664
13665 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
13666 goto nla_put_failure;
13667
13668 cfg80211_send_cqm(msg, gfp);
13669 return;
13670
13671 nla_put_failure:
13672 nlmsg_free(msg);
13673}
13674EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
13675
98f03342
JB
13676void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
13677{
13678 struct sk_buff *msg;
13679
13680 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
13681 if (!msg)
13682 return;
13683
13684 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
13685 goto nla_put_failure;
13686
13687 cfg80211_send_cqm(msg, gfp);
13688 return;
13689
13690 nla_put_failure:
13691 nlmsg_free(msg);
13692}
13693EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
13694
947add36
JB
13695static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
13696 struct net_device *netdev, const u8 *bssid,
13697 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
13698{
13699 struct sk_buff *msg;
13700 struct nlattr *rekey_attr;
13701 void *hdr;
13702
58050fce 13703 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
13704 if (!msg)
13705 return;
13706
13707 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
13708 if (!hdr) {
13709 nlmsg_free(msg);
13710 return;
13711 }
13712
9360ffd1
DM
13713 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13714 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13715 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13716 goto nla_put_failure;
e5497d76
JB
13717
13718 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
13719 if (!rekey_attr)
13720 goto nla_put_failure;
13721
9360ffd1
DM
13722 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
13723 NL80211_REPLAY_CTR_LEN, replay_ctr))
13724 goto nla_put_failure;
e5497d76
JB
13725
13726 nla_nest_end(msg, rekey_attr);
13727
3b7b72ee 13728 genlmsg_end(msg, hdr);
e5497d76 13729
68eb5503 13730 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13731 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
13732 return;
13733
13734 nla_put_failure:
13735 genlmsg_cancel(msg, hdr);
13736 nlmsg_free(msg);
13737}
13738
947add36
JB
13739void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
13740 const u8 *replay_ctr, gfp_t gfp)
13741{
13742 struct wireless_dev *wdev = dev->ieee80211_ptr;
13743 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13744 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13745
13746 trace_cfg80211_gtk_rekey_notify(dev, bssid);
13747 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
13748}
13749EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
13750
13751static void
13752nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
13753 struct net_device *netdev, int index,
13754 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
13755{
13756 struct sk_buff *msg;
13757 struct nlattr *attr;
13758 void *hdr;
13759
58050fce 13760 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
13761 if (!msg)
13762 return;
13763
13764 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
13765 if (!hdr) {
13766 nlmsg_free(msg);
13767 return;
13768 }
13769
9360ffd1
DM
13770 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13771 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
13772 goto nla_put_failure;
c9df56b4
JM
13773
13774 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
13775 if (!attr)
13776 goto nla_put_failure;
13777
9360ffd1
DM
13778 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
13779 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
13780 (preauth &&
13781 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
13782 goto nla_put_failure;
c9df56b4
JM
13783
13784 nla_nest_end(msg, attr);
13785
3b7b72ee 13786 genlmsg_end(msg, hdr);
c9df56b4 13787
68eb5503 13788 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13789 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
13790 return;
13791
13792 nla_put_failure:
13793 genlmsg_cancel(msg, hdr);
13794 nlmsg_free(msg);
13795}
13796
947add36
JB
13797void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
13798 const u8 *bssid, bool preauth, gfp_t gfp)
13799{
13800 struct wireless_dev *wdev = dev->ieee80211_ptr;
13801 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13802 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13803
13804 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
13805 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
13806}
13807EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
13808
13809static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
13810 struct net_device *netdev,
13811 struct cfg80211_chan_def *chandef,
f8d7552e
LC
13812 gfp_t gfp,
13813 enum nl80211_commands notif,
13814 u8 count)
5314526b
TP
13815{
13816 struct sk_buff *msg;
13817 void *hdr;
13818
58050fce 13819 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
13820 if (!msg)
13821 return;
13822
f8d7552e 13823 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
13824 if (!hdr) {
13825 nlmsg_free(msg);
13826 return;
13827 }
13828
683b6d3b
JB
13829 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
13830 goto nla_put_failure;
13831
13832 if (nl80211_send_chandef(msg, chandef))
7eab0f64 13833 goto nla_put_failure;
5314526b 13834
f8d7552e
LC
13835 if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
13836 (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
13837 goto nla_put_failure;
13838
5314526b
TP
13839 genlmsg_end(msg, hdr);
13840
68eb5503 13841 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13842 NL80211_MCGRP_MLME, gfp);
5314526b
TP
13843 return;
13844
13845 nla_put_failure:
13846 genlmsg_cancel(msg, hdr);
13847 nlmsg_free(msg);
13848}
13849
947add36
JB
13850void cfg80211_ch_switch_notify(struct net_device *dev,
13851 struct cfg80211_chan_def *chandef)
84f10708 13852{
947add36
JB
13853 struct wireless_dev *wdev = dev->ieee80211_ptr;
13854 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13855 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 13856
e487eaeb 13857 ASSERT_WDEV_LOCK(wdev);
947add36 13858
e487eaeb 13859 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 13860
9e0e2961 13861 wdev->chandef = *chandef;
96f55f12 13862 wdev->preset_chandef = *chandef;
f8d7552e
LC
13863 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
13864 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
947add36
JB
13865}
13866EXPORT_SYMBOL(cfg80211_ch_switch_notify);
13867
f8d7552e
LC
13868void cfg80211_ch_switch_started_notify(struct net_device *dev,
13869 struct cfg80211_chan_def *chandef,
13870 u8 count)
13871{
13872 struct wireless_dev *wdev = dev->ieee80211_ptr;
13873 struct wiphy *wiphy = wdev->wiphy;
13874 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
13875
13876 trace_cfg80211_ch_switch_started_notify(dev, chandef);
13877
13878 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
13879 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
13880}
13881EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
13882
04f39047
SW
13883void
13884nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 13885 const struct cfg80211_chan_def *chandef,
04f39047
SW
13886 enum nl80211_radar_event event,
13887 struct net_device *netdev, gfp_t gfp)
13888{
13889 struct sk_buff *msg;
13890 void *hdr;
13891
13892 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13893 if (!msg)
13894 return;
13895
13896 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
13897 if (!hdr) {
13898 nlmsg_free(msg);
13899 return;
13900 }
13901
13902 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
13903 goto nla_put_failure;
13904
13905 /* NOP and radar events don't need a netdev parameter */
13906 if (netdev) {
13907 struct wireless_dev *wdev = netdev->ieee80211_ptr;
13908
13909 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
13910 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13911 NL80211_ATTR_PAD))
04f39047
SW
13912 goto nla_put_failure;
13913 }
13914
13915 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
13916 goto nla_put_failure;
13917
13918 if (nl80211_send_chandef(msg, chandef))
13919 goto nla_put_failure;
13920
9c90a9f6 13921 genlmsg_end(msg, hdr);
04f39047 13922
68eb5503 13923 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13924 NL80211_MCGRP_MLME, gfp);
04f39047
SW
13925 return;
13926
13927 nla_put_failure:
13928 genlmsg_cancel(msg, hdr);
13929 nlmsg_free(msg);
13930}
13931
7f6cf311
JB
13932void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
13933 u64 cookie, bool acked, gfp_t gfp)
13934{
13935 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13936 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
13937 struct sk_buff *msg;
13938 void *hdr;
7f6cf311 13939
4ee3e063
BL
13940 trace_cfg80211_probe_status(dev, addr, cookie, acked);
13941
58050fce 13942 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 13943
7f6cf311
JB
13944 if (!msg)
13945 return;
13946
13947 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
13948 if (!hdr) {
13949 nlmsg_free(msg);
13950 return;
13951 }
13952
9360ffd1
DM
13953 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13954 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13955 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
13956 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13957 NL80211_ATTR_PAD) ||
9360ffd1
DM
13958 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
13959 goto nla_put_failure;
7f6cf311 13960
9c90a9f6 13961 genlmsg_end(msg, hdr);
7f6cf311 13962
68eb5503 13963 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13964 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
13965 return;
13966
13967 nla_put_failure:
13968 genlmsg_cancel(msg, hdr);
13969 nlmsg_free(msg);
13970}
13971EXPORT_SYMBOL(cfg80211_probe_status);
13972
5e760230
JB
13973void cfg80211_report_obss_beacon(struct wiphy *wiphy,
13974 const u8 *frame, size_t len,
37c73b5f 13975 int freq, int sig_dbm)
5e760230 13976{
f26cbf40 13977 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
13978 struct sk_buff *msg;
13979 void *hdr;
37c73b5f 13980 struct cfg80211_beacon_registration *reg;
5e760230 13981
4ee3e063
BL
13982 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
13983
37c73b5f
BG
13984 spin_lock_bh(&rdev->beacon_registrations_lock);
13985 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
13986 msg = nlmsg_new(len + 100, GFP_ATOMIC);
13987 if (!msg) {
13988 spin_unlock_bh(&rdev->beacon_registrations_lock);
13989 return;
13990 }
5e760230 13991
37c73b5f
BG
13992 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
13993 if (!hdr)
13994 goto nla_put_failure;
5e760230 13995
37c73b5f
BG
13996 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13997 (freq &&
13998 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
13999 (sig_dbm &&
14000 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
14001 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
14002 goto nla_put_failure;
5e760230 14003
37c73b5f 14004 genlmsg_end(msg, hdr);
5e760230 14005
37c73b5f
BG
14006 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
14007 }
14008 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
14009 return;
14010
14011 nla_put_failure:
37c73b5f
BG
14012 spin_unlock_bh(&rdev->beacon_registrations_lock);
14013 if (hdr)
14014 genlmsg_cancel(msg, hdr);
5e760230
JB
14015 nlmsg_free(msg);
14016}
14017EXPORT_SYMBOL(cfg80211_report_obss_beacon);
14018
cd8f7cb4 14019#ifdef CONFIG_PM
8cd4d456
LC
14020static int cfg80211_net_detect_results(struct sk_buff *msg,
14021 struct cfg80211_wowlan_wakeup *wakeup)
14022{
14023 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
14024 struct nlattr *nl_results, *nl_match, *nl_freqs;
14025 int i, j;
14026
14027 nl_results = nla_nest_start(
14028 msg, NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
14029 if (!nl_results)
14030 return -EMSGSIZE;
14031
14032 for (i = 0; i < nd->n_matches; i++) {
14033 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
14034
14035 nl_match = nla_nest_start(msg, i);
14036 if (!nl_match)
14037 break;
14038
14039 /* The SSID attribute is optional in nl80211, but for
14040 * simplicity reasons it's always present in the
14041 * cfg80211 structure. If a driver can't pass the
14042 * SSID, that needs to be changed. A zero length SSID
14043 * is still a valid SSID (wildcard), so it cannot be
14044 * used for this purpose.
14045 */
14046 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
14047 match->ssid.ssid)) {
14048 nla_nest_cancel(msg, nl_match);
14049 goto out;
14050 }
14051
14052 if (match->n_channels) {
14053 nl_freqs = nla_nest_start(
14054 msg, NL80211_ATTR_SCAN_FREQUENCIES);
14055 if (!nl_freqs) {
14056 nla_nest_cancel(msg, nl_match);
14057 goto out;
14058 }
14059
14060 for (j = 0; j < match->n_channels; j++) {
5528fae8 14061 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
14062 nla_nest_cancel(msg, nl_freqs);
14063 nla_nest_cancel(msg, nl_match);
14064 goto out;
14065 }
14066 }
14067
14068 nla_nest_end(msg, nl_freqs);
14069 }
14070
14071 nla_nest_end(msg, nl_match);
14072 }
14073
14074out:
14075 nla_nest_end(msg, nl_results);
14076 return 0;
14077}
14078
cd8f7cb4
JB
14079void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
14080 struct cfg80211_wowlan_wakeup *wakeup,
14081 gfp_t gfp)
14082{
f26cbf40 14083 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
14084 struct sk_buff *msg;
14085 void *hdr;
9c90a9f6 14086 int size = 200;
cd8f7cb4
JB
14087
14088 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
14089
14090 if (wakeup)
14091 size += wakeup->packet_present_len;
14092
14093 msg = nlmsg_new(size, gfp);
14094 if (!msg)
14095 return;
14096
14097 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
14098 if (!hdr)
14099 goto free_msg;
14100
14101 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
14102 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14103 NL80211_ATTR_PAD))
cd8f7cb4
JB
14104 goto free_msg;
14105
14106 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14107 wdev->netdev->ifindex))
14108 goto free_msg;
14109
14110 if (wakeup) {
14111 struct nlattr *reasons;
14112
14113 reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
14114 if (!reasons)
14115 goto free_msg;
cd8f7cb4
JB
14116
14117 if (wakeup->disconnect &&
14118 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
14119 goto free_msg;
14120 if (wakeup->magic_pkt &&
14121 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
14122 goto free_msg;
14123 if (wakeup->gtk_rekey_failure &&
14124 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
14125 goto free_msg;
14126 if (wakeup->eap_identity_req &&
14127 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
14128 goto free_msg;
14129 if (wakeup->four_way_handshake &&
14130 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
14131 goto free_msg;
14132 if (wakeup->rfkill_release &&
14133 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
14134 goto free_msg;
14135
14136 if (wakeup->pattern_idx >= 0 &&
14137 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
14138 wakeup->pattern_idx))
14139 goto free_msg;
14140
ae917c9f
JB
14141 if (wakeup->tcp_match &&
14142 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
14143 goto free_msg;
2a0e047e 14144
ae917c9f
JB
14145 if (wakeup->tcp_connlost &&
14146 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
14147 goto free_msg;
2a0e047e 14148
ae917c9f
JB
14149 if (wakeup->tcp_nomoretokens &&
14150 nla_put_flag(msg,
14151 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
14152 goto free_msg;
2a0e047e 14153
cd8f7cb4
JB
14154 if (wakeup->packet) {
14155 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
14156 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
14157
14158 if (!wakeup->packet_80211) {
14159 pkt_attr =
14160 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
14161 len_attr =
14162 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
14163 }
14164
14165 if (wakeup->packet_len &&
14166 nla_put_u32(msg, len_attr, wakeup->packet_len))
14167 goto free_msg;
14168
14169 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
14170 wakeup->packet))
14171 goto free_msg;
14172 }
14173
8cd4d456
LC
14174 if (wakeup->net_detect &&
14175 cfg80211_net_detect_results(msg, wakeup))
14176 goto free_msg;
14177
cd8f7cb4
JB
14178 nla_nest_end(msg, reasons);
14179 }
14180
9c90a9f6 14181 genlmsg_end(msg, hdr);
cd8f7cb4 14182
68eb5503 14183 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14184 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
14185 return;
14186
14187 free_msg:
14188 nlmsg_free(msg);
14189}
14190EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
14191#endif
14192
3475b094
JM
14193void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
14194 enum nl80211_tdls_operation oper,
14195 u16 reason_code, gfp_t gfp)
14196{
14197 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14198 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
14199 struct sk_buff *msg;
14200 void *hdr;
3475b094
JM
14201
14202 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
14203 reason_code);
14204
14205 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14206 if (!msg)
14207 return;
14208
14209 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
14210 if (!hdr) {
14211 nlmsg_free(msg);
14212 return;
14213 }
14214
14215 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14216 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14217 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
14218 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
14219 (reason_code > 0 &&
14220 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
14221 goto nla_put_failure;
14222
9c90a9f6 14223 genlmsg_end(msg, hdr);
3475b094 14224
68eb5503 14225 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14226 NL80211_MCGRP_MLME, gfp);
3475b094
JM
14227 return;
14228
14229 nla_put_failure:
14230 genlmsg_cancel(msg, hdr);
14231 nlmsg_free(msg);
14232}
14233EXPORT_SYMBOL(cfg80211_tdls_oper_request);
14234
026331c4
JM
14235static int nl80211_netlink_notify(struct notifier_block * nb,
14236 unsigned long state,
14237 void *_notify)
14238{
14239 struct netlink_notify *notify = _notify;
14240 struct cfg80211_registered_device *rdev;
14241 struct wireless_dev *wdev;
37c73b5f 14242 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 14243
8f815cdd 14244 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
14245 return NOTIFY_DONE;
14246
14247 rcu_read_lock();
14248
5e760230 14249 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
78f22b6a 14250 bool schedule_destroy_work = false;
93a1e86c
JR
14251 bool schedule_scan_stop = false;
14252 struct cfg80211_sched_scan_request *sched_scan_req =
14253 rcu_dereference(rdev->sched_scan_req);
14254
14255 if (sched_scan_req && notify->portid &&
14256 sched_scan_req->owner_nlportid == notify->portid)
14257 schedule_scan_stop = true;
78f22b6a 14258
53873f13 14259 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 14260 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 14261
78f22b6a
JB
14262 if (wdev->owner_nlportid == notify->portid)
14263 schedule_destroy_work = true;
14264 }
14265
37c73b5f
BG
14266 spin_lock_bh(&rdev->beacon_registrations_lock);
14267 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
14268 list) {
14269 if (reg->nlportid == notify->portid) {
14270 list_del(&reg->list);
14271 kfree(reg);
14272 break;
14273 }
14274 }
14275 spin_unlock_bh(&rdev->beacon_registrations_lock);
78f22b6a
JB
14276
14277 if (schedule_destroy_work) {
14278 struct cfg80211_iface_destroy *destroy;
14279
14280 destroy = kzalloc(sizeof(*destroy), GFP_ATOMIC);
14281 if (destroy) {
14282 destroy->nlportid = notify->portid;
14283 spin_lock(&rdev->destroy_list_lock);
14284 list_add(&destroy->list, &rdev->destroy_list);
14285 spin_unlock(&rdev->destroy_list_lock);
14286 schedule_work(&rdev->destroy_work);
14287 }
93a1e86c
JR
14288 } else if (schedule_scan_stop) {
14289 sched_scan_req->owner_nlportid = 0;
14290
14291 if (rdev->ops->sched_scan_stop &&
14292 rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
14293 schedule_work(&rdev->sched_scan_stop_wk);
78f22b6a 14294 }
5e760230 14295 }
026331c4
JM
14296
14297 rcu_read_unlock();
14298
05050753
I
14299 /*
14300 * It is possible that the user space process that is controlling the
14301 * indoor setting disappeared, so notify the regulatory core.
14302 */
14303 regulatory_netlink_notify(notify->portid);
6784c7db 14304 return NOTIFY_OK;
026331c4
JM
14305}
14306
14307static struct notifier_block nl80211_netlink_notifier = {
14308 .notifier_call = nl80211_netlink_notify,
14309};
14310
355199e0
JM
14311void cfg80211_ft_event(struct net_device *netdev,
14312 struct cfg80211_ft_event_params *ft_event)
14313{
14314 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 14315 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
14316 struct sk_buff *msg;
14317 void *hdr;
355199e0
JM
14318
14319 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
14320
14321 if (!ft_event->target_ap)
14322 return;
14323
14324 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14325 if (!msg)
14326 return;
14327
14328 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
14329 if (!hdr)
14330 goto out;
355199e0 14331
ae917c9f
JB
14332 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14333 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14334 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
14335 goto out;
355199e0 14336
ae917c9f
JB
14337 if (ft_event->ies &&
14338 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
14339 goto out;
14340 if (ft_event->ric_ies &&
14341 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
14342 ft_event->ric_ies))
14343 goto out;
355199e0 14344
9c90a9f6 14345 genlmsg_end(msg, hdr);
355199e0 14346
68eb5503 14347 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14348 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
14349 return;
14350 out:
14351 nlmsg_free(msg);
355199e0
JM
14352}
14353EXPORT_SYMBOL(cfg80211_ft_event);
14354
5de17984
AS
14355void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
14356{
14357 struct cfg80211_registered_device *rdev;
14358 struct sk_buff *msg;
14359 void *hdr;
14360 u32 nlportid;
14361
f26cbf40 14362 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
14363 if (!rdev->crit_proto_nlportid)
14364 return;
14365
14366 nlportid = rdev->crit_proto_nlportid;
14367 rdev->crit_proto_nlportid = 0;
14368
14369 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14370 if (!msg)
14371 return;
14372
14373 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
14374 if (!hdr)
14375 goto nla_put_failure;
14376
14377 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
14378 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14379 NL80211_ATTR_PAD))
5de17984
AS
14380 goto nla_put_failure;
14381
14382 genlmsg_end(msg, hdr);
14383
14384 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
14385 return;
14386
14387 nla_put_failure:
14388 if (hdr)
14389 genlmsg_cancel(msg, hdr);
14390 nlmsg_free(msg);
5de17984
AS
14391}
14392EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
14393
348baf0e
JB
14394void nl80211_send_ap_stopped(struct wireless_dev *wdev)
14395{
14396 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14397 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
14398 struct sk_buff *msg;
14399 void *hdr;
14400
14401 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14402 if (!msg)
14403 return;
14404
14405 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
14406 if (!hdr)
14407 goto out;
14408
14409 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14410 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
14411 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14412 NL80211_ATTR_PAD))
348baf0e
JB
14413 goto out;
14414
14415 genlmsg_end(msg, hdr);
14416
14417 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
14418 NL80211_MCGRP_MLME, GFP_KERNEL);
14419 return;
14420 out:
14421 nlmsg_free(msg);
14422}
14423
55682965
JB
14424/* initialisation/exit functions */
14425
14426int nl80211_init(void)
14427{
0d63cbb5 14428 int err;
55682965 14429
2a94fe48
JB
14430 err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops,
14431 nl80211_mcgrps);
55682965
JB
14432 if (err)
14433 return err;
14434
026331c4
JM
14435 err = netlink_register_notifier(&nl80211_netlink_notifier);
14436 if (err)
14437 goto err_out;
14438
55682965
JB
14439 return 0;
14440 err_out:
14441 genl_unregister_family(&nl80211_fam);
14442 return err;
14443}
14444
14445void nl80211_exit(void)
14446{
026331c4 14447 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
14448 genl_unregister_family(&nl80211_fam);
14449}