]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - net/wireless/nl80211.c
cfg80211: add add_nan_func / del_nan_func
[mirror_ubuntu-bionic-kernel.git] / net / wireless / nl80211.c
CommitLineData
55682965
JB
1/*
2 * This is the new netlink-based wireless configuration interface.
3 *
026331c4 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
2740f0cf 5 * Copyright 2013-2014 Intel Mobile Communications GmbH
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
3713b4e3
JB
10922static int nl80211_get_protocol_features(struct sk_buff *skb,
10923 struct genl_info *info)
10924{
10925 void *hdr;
10926 struct sk_buff *msg;
10927
10928 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10929 if (!msg)
10930 return -ENOMEM;
10931
10932 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
10933 NL80211_CMD_GET_PROTOCOL_FEATURES);
10934 if (!hdr)
10935 goto nla_put_failure;
10936
10937 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
10938 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
10939 goto nla_put_failure;
10940
10941 genlmsg_end(msg, hdr);
10942 return genlmsg_reply(msg, info);
10943
10944 nla_put_failure:
10945 kfree_skb(msg);
10946 return -ENOBUFS;
10947}
10948
355199e0
JM
10949static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
10950{
10951 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10952 struct cfg80211_update_ft_ies_params ft_params;
10953 struct net_device *dev = info->user_ptr[1];
10954
10955 if (!rdev->ops->update_ft_ies)
10956 return -EOPNOTSUPP;
10957
10958 if (!info->attrs[NL80211_ATTR_MDID] ||
10959 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
10960 return -EINVAL;
10961
10962 memset(&ft_params, 0, sizeof(ft_params));
10963 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
10964 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10965 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10966
10967 return rdev_update_ft_ies(rdev, dev, &ft_params);
10968}
10969
5de17984
AS
10970static int nl80211_crit_protocol_start(struct sk_buff *skb,
10971 struct genl_info *info)
10972{
10973 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10974 struct wireless_dev *wdev = info->user_ptr[1];
10975 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
10976 u16 duration;
10977 int ret;
10978
10979 if (!rdev->ops->crit_proto_start)
10980 return -EOPNOTSUPP;
10981
10982 if (WARN_ON(!rdev->ops->crit_proto_stop))
10983 return -EINVAL;
10984
10985 if (rdev->crit_proto_nlportid)
10986 return -EBUSY;
10987
10988 /* determine protocol if provided */
10989 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
10990 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
10991
10992 if (proto >= NUM_NL80211_CRIT_PROTO)
10993 return -EINVAL;
10994
10995 /* timeout must be provided */
10996 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
10997 return -EINVAL;
10998
10999 duration =
11000 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
11001
11002 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
11003 return -ERANGE;
11004
11005 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
11006 if (!ret)
11007 rdev->crit_proto_nlportid = info->snd_portid;
11008
11009 return ret;
11010}
11011
11012static int nl80211_crit_protocol_stop(struct sk_buff *skb,
11013 struct genl_info *info)
11014{
11015 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11016 struct wireless_dev *wdev = info->user_ptr[1];
11017
11018 if (!rdev->ops->crit_proto_stop)
11019 return -EOPNOTSUPP;
11020
11021 if (rdev->crit_proto_nlportid) {
11022 rdev->crit_proto_nlportid = 0;
11023 rdev_crit_proto_stop(rdev, wdev);
11024 }
11025 return 0;
11026}
11027
ad7e718c
JB
11028static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
11029{
11030 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11031 struct wireless_dev *wdev =
11032 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
11033 int i, err;
11034 u32 vid, subcmd;
11035
11036 if (!rdev->wiphy.vendor_commands)
11037 return -EOPNOTSUPP;
11038
11039 if (IS_ERR(wdev)) {
11040 err = PTR_ERR(wdev);
11041 if (err != -EINVAL)
11042 return err;
11043 wdev = NULL;
11044 } else if (wdev->wiphy != &rdev->wiphy) {
11045 return -EINVAL;
11046 }
11047
11048 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
11049 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
11050 return -EINVAL;
11051
11052 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
11053 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
11054 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
11055 const struct wiphy_vendor_command *vcmd;
11056 void *data = NULL;
11057 int len = 0;
11058
11059 vcmd = &rdev->wiphy.vendor_commands[i];
11060
11061 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11062 continue;
11063
11064 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11065 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11066 if (!wdev)
11067 return -EINVAL;
11068 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11069 !wdev->netdev)
11070 return -EINVAL;
11071
11072 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
11073 if (wdev->netdev &&
11074 !netif_running(wdev->netdev))
11075 return -ENETDOWN;
11076 if (!wdev->netdev && !wdev->p2p_started)
11077 return -ENETDOWN;
11078 }
7bdbe400
JB
11079
11080 if (!vcmd->doit)
11081 return -EOPNOTSUPP;
ad7e718c
JB
11082 } else {
11083 wdev = NULL;
11084 }
11085
11086 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
11087 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11088 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11089 }
11090
11091 rdev->cur_cmd_info = info;
11092 err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
11093 data, len);
11094 rdev->cur_cmd_info = NULL;
11095 return err;
11096 }
11097
11098 return -EOPNOTSUPP;
11099}
11100
7bdbe400
JB
11101static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
11102 struct netlink_callback *cb,
11103 struct cfg80211_registered_device **rdev,
11104 struct wireless_dev **wdev)
11105{
11106 u32 vid, subcmd;
11107 unsigned int i;
11108 int vcmd_idx = -1;
11109 int err;
11110 void *data = NULL;
11111 unsigned int data_len = 0;
11112
11113 rtnl_lock();
11114
11115 if (cb->args[0]) {
11116 /* subtract the 1 again here */
11117 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
11118 struct wireless_dev *tmp;
11119
11120 if (!wiphy) {
11121 err = -ENODEV;
11122 goto out_unlock;
11123 }
11124 *rdev = wiphy_to_rdev(wiphy);
11125 *wdev = NULL;
11126
11127 if (cb->args[1]) {
53873f13 11128 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
11129 if (tmp->identifier == cb->args[1] - 1) {
11130 *wdev = tmp;
11131 break;
11132 }
11133 }
11134 }
11135
11136 /* keep rtnl locked in successful case */
11137 return 0;
11138 }
11139
11140 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
11141 nl80211_fam.attrbuf, nl80211_fam.maxattr,
11142 nl80211_policy);
11143 if (err)
11144 goto out_unlock;
11145
11146 if (!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID] ||
11147 !nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
11148 err = -EINVAL;
11149 goto out_unlock;
11150 }
11151
11152 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
11153 nl80211_fam.attrbuf);
11154 if (IS_ERR(*wdev))
11155 *wdev = NULL;
11156
11157 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
11158 nl80211_fam.attrbuf);
11159 if (IS_ERR(*rdev)) {
11160 err = PTR_ERR(*rdev);
11161 goto out_unlock;
11162 }
11163
11164 vid = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID]);
11165 subcmd = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
11166
11167 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
11168 const struct wiphy_vendor_command *vcmd;
11169
11170 vcmd = &(*rdev)->wiphy.vendor_commands[i];
11171
11172 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11173 continue;
11174
11175 if (!vcmd->dumpit) {
11176 err = -EOPNOTSUPP;
11177 goto out_unlock;
11178 }
11179
11180 vcmd_idx = i;
11181 break;
11182 }
11183
11184 if (vcmd_idx < 0) {
11185 err = -EOPNOTSUPP;
11186 goto out_unlock;
11187 }
11188
11189 if (nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]) {
11190 data = nla_data(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
11191 data_len = nla_len(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
11192 }
11193
11194 /* 0 is the first index - add 1 to parse only once */
11195 cb->args[0] = (*rdev)->wiphy_idx + 1;
11196 /* add 1 to know if it was NULL */
11197 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
11198 cb->args[2] = vcmd_idx;
11199 cb->args[3] = (unsigned long)data;
11200 cb->args[4] = data_len;
11201
11202 /* keep rtnl locked in successful case */
11203 return 0;
11204 out_unlock:
11205 rtnl_unlock();
11206 return err;
11207}
11208
11209static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
11210 struct netlink_callback *cb)
11211{
11212 struct cfg80211_registered_device *rdev;
11213 struct wireless_dev *wdev;
11214 unsigned int vcmd_idx;
11215 const struct wiphy_vendor_command *vcmd;
11216 void *data;
11217 int data_len;
11218 int err;
11219 struct nlattr *vendor_data;
11220
11221 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
11222 if (err)
11223 return err;
11224
11225 vcmd_idx = cb->args[2];
11226 data = (void *)cb->args[3];
11227 data_len = cb->args[4];
11228 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
11229
11230 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11231 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11232 if (!wdev)
11233 return -EINVAL;
11234 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11235 !wdev->netdev)
11236 return -EINVAL;
11237
11238 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
11239 if (wdev->netdev &&
11240 !netif_running(wdev->netdev))
11241 return -ENETDOWN;
11242 if (!wdev->netdev && !wdev->p2p_started)
11243 return -ENETDOWN;
11244 }
11245 }
11246
11247 while (1) {
11248 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
11249 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11250 NL80211_CMD_VENDOR);
11251 if (!hdr)
11252 break;
11253
11254 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
11255 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
11256 wdev_id(wdev),
11257 NL80211_ATTR_PAD))) {
7bdbe400
JB
11258 genlmsg_cancel(skb, hdr);
11259 break;
11260 }
11261
11262 vendor_data = nla_nest_start(skb, NL80211_ATTR_VENDOR_DATA);
11263 if (!vendor_data) {
11264 genlmsg_cancel(skb, hdr);
11265 break;
11266 }
11267
11268 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
11269 (unsigned long *)&cb->args[5]);
11270 nla_nest_end(skb, vendor_data);
11271
11272 if (err == -ENOBUFS || err == -ENOENT) {
11273 genlmsg_cancel(skb, hdr);
11274 break;
11275 } else if (err) {
11276 genlmsg_cancel(skb, hdr);
11277 goto out;
11278 }
11279
11280 genlmsg_end(skb, hdr);
11281 }
11282
11283 err = skb->len;
11284 out:
11285 rtnl_unlock();
11286 return err;
11287}
11288
ad7e718c
JB
11289struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
11290 enum nl80211_commands cmd,
11291 enum nl80211_attrs attr,
11292 int approxlen)
11293{
f26cbf40 11294 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
11295
11296 if (WARN_ON(!rdev->cur_cmd_info))
11297 return NULL;
11298
6c09e791 11299 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
11300 rdev->cur_cmd_info->snd_portid,
11301 rdev->cur_cmd_info->snd_seq,
567ffc35 11302 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
11303}
11304EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
11305
11306int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
11307{
11308 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
11309 void *hdr = ((void **)skb->cb)[1];
11310 struct nlattr *data = ((void **)skb->cb)[2];
11311
bd8c78e7
JB
11312 /* clear CB data for netlink core to own from now on */
11313 memset(skb->cb, 0, sizeof(skb->cb));
11314
ad7e718c
JB
11315 if (WARN_ON(!rdev->cur_cmd_info)) {
11316 kfree_skb(skb);
11317 return -EINVAL;
11318 }
11319
11320 nla_nest_end(skb, data);
11321 genlmsg_end(skb, hdr);
11322 return genlmsg_reply(skb, rdev->cur_cmd_info);
11323}
11324EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
11325
fa9ffc74
KP
11326static int nl80211_set_qos_map(struct sk_buff *skb,
11327 struct genl_info *info)
11328{
11329 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11330 struct cfg80211_qos_map *qos_map = NULL;
11331 struct net_device *dev = info->user_ptr[1];
11332 u8 *pos, len, num_des, des_len, des;
11333 int ret;
11334
11335 if (!rdev->ops->set_qos_map)
11336 return -EOPNOTSUPP;
11337
11338 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
11339 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
11340 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
11341
11342 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
11343 len > IEEE80211_QOS_MAP_LEN_MAX)
11344 return -EINVAL;
11345
11346 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
11347 if (!qos_map)
11348 return -ENOMEM;
11349
11350 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
11351 if (num_des) {
11352 des_len = num_des *
11353 sizeof(struct cfg80211_dscp_exception);
11354 memcpy(qos_map->dscp_exception, pos, des_len);
11355 qos_map->num_des = num_des;
11356 for (des = 0; des < num_des; des++) {
11357 if (qos_map->dscp_exception[des].up > 7) {
11358 kfree(qos_map);
11359 return -EINVAL;
11360 }
11361 }
11362 pos += des_len;
11363 }
11364 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
11365 }
11366
11367 wdev_lock(dev->ieee80211_ptr);
11368 ret = nl80211_key_allowed(dev->ieee80211_ptr);
11369 if (!ret)
11370 ret = rdev_set_qos_map(rdev, dev, qos_map);
11371 wdev_unlock(dev->ieee80211_ptr);
11372
11373 kfree(qos_map);
11374 return ret;
11375}
11376
960d01ac
JB
11377static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
11378{
11379 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11380 struct net_device *dev = info->user_ptr[1];
11381 struct wireless_dev *wdev = dev->ieee80211_ptr;
11382 const u8 *peer;
11383 u8 tsid, up;
11384 u16 admitted_time = 0;
11385 int err;
11386
723e73ac 11387 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
11388 return -EOPNOTSUPP;
11389
11390 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
11391 !info->attrs[NL80211_ATTR_USER_PRIO])
11392 return -EINVAL;
11393
11394 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
11395 if (tsid >= IEEE80211_NUM_TIDS)
11396 return -EINVAL;
11397
11398 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
11399 if (up >= IEEE80211_NUM_UPS)
11400 return -EINVAL;
11401
11402 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 11403 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 11404 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
11405 * need more attributes for that (e.g. BA session requirement);
11406 * change the WMM adminssion test above to allow both then
960d01ac
JB
11407 */
11408 return -EINVAL;
11409 }
11410
11411 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11412
11413 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
11414 admitted_time =
11415 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
11416 if (!admitted_time)
11417 return -EINVAL;
11418 }
11419
11420 wdev_lock(wdev);
11421 switch (wdev->iftype) {
11422 case NL80211_IFTYPE_STATION:
11423 case NL80211_IFTYPE_P2P_CLIENT:
11424 if (wdev->current_bss)
11425 break;
11426 err = -ENOTCONN;
11427 goto out;
11428 default:
11429 err = -EOPNOTSUPP;
11430 goto out;
11431 }
11432
11433 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
11434
11435 out:
11436 wdev_unlock(wdev);
11437 return err;
11438}
11439
11440static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
11441{
11442 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11443 struct net_device *dev = info->user_ptr[1];
11444 struct wireless_dev *wdev = dev->ieee80211_ptr;
11445 const u8 *peer;
11446 u8 tsid;
11447 int err;
11448
11449 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
11450 return -EINVAL;
11451
11452 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
11453 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11454
11455 wdev_lock(wdev);
11456 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
11457 wdev_unlock(wdev);
11458
11459 return err;
11460}
11461
1057d35e
AN
11462static int nl80211_tdls_channel_switch(struct sk_buff *skb,
11463 struct genl_info *info)
11464{
11465 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11466 struct net_device *dev = info->user_ptr[1];
11467 struct wireless_dev *wdev = dev->ieee80211_ptr;
11468 struct cfg80211_chan_def chandef = {};
11469 const u8 *addr;
11470 u8 oper_class;
11471 int err;
11472
11473 if (!rdev->ops->tdls_channel_switch ||
11474 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
11475 return -EOPNOTSUPP;
11476
11477 switch (dev->ieee80211_ptr->iftype) {
11478 case NL80211_IFTYPE_STATION:
11479 case NL80211_IFTYPE_P2P_CLIENT:
11480 break;
11481 default:
11482 return -EOPNOTSUPP;
11483 }
11484
11485 if (!info->attrs[NL80211_ATTR_MAC] ||
11486 !info->attrs[NL80211_ATTR_OPER_CLASS])
11487 return -EINVAL;
11488
11489 err = nl80211_parse_chandef(rdev, info, &chandef);
11490 if (err)
11491 return err;
11492
11493 /*
11494 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
11495 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
11496 * specification is not defined for them.
11497 */
57fbcce3 11498 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
11499 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
11500 chandef.width != NL80211_CHAN_WIDTH_20)
11501 return -EINVAL;
11502
11503 /* we will be active on the TDLS link */
923b352f
AN
11504 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
11505 wdev->iftype))
1057d35e
AN
11506 return -EINVAL;
11507
11508 /* don't allow switching to DFS channels */
11509 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
11510 return -EINVAL;
11511
11512 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11513 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
11514
11515 wdev_lock(wdev);
11516 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
11517 wdev_unlock(wdev);
11518
11519 return err;
11520}
11521
11522static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
11523 struct genl_info *info)
11524{
11525 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11526 struct net_device *dev = info->user_ptr[1];
11527 struct wireless_dev *wdev = dev->ieee80211_ptr;
11528 const u8 *addr;
11529
11530 if (!rdev->ops->tdls_channel_switch ||
11531 !rdev->ops->tdls_cancel_channel_switch ||
11532 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
11533 return -EOPNOTSUPP;
11534
11535 switch (dev->ieee80211_ptr->iftype) {
11536 case NL80211_IFTYPE_STATION:
11537 case NL80211_IFTYPE_P2P_CLIENT:
11538 break;
11539 default:
11540 return -EOPNOTSUPP;
11541 }
11542
11543 if (!info->attrs[NL80211_ATTR_MAC])
11544 return -EINVAL;
11545
11546 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11547
11548 wdev_lock(wdev);
11549 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
11550 wdev_unlock(wdev);
11551
11552 return 0;
11553}
11554
4c476991
JB
11555#define NL80211_FLAG_NEED_WIPHY 0x01
11556#define NL80211_FLAG_NEED_NETDEV 0x02
11557#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
11558#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
11559#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
11560 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 11561#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 11562/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
11563#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
11564 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 11565#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 11566
f84f771d 11567static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
11568 struct genl_info *info)
11569{
11570 struct cfg80211_registered_device *rdev;
89a54e48 11571 struct wireless_dev *wdev;
4c476991 11572 struct net_device *dev;
4c476991
JB
11573 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
11574
11575 if (rtnl)
11576 rtnl_lock();
11577
11578 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 11579 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
11580 if (IS_ERR(rdev)) {
11581 if (rtnl)
11582 rtnl_unlock();
11583 return PTR_ERR(rdev);
11584 }
11585 info->user_ptr[0] = rdev;
1bf614ef
JB
11586 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
11587 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
11588 ASSERT_RTNL();
11589
89a54e48
JB
11590 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
11591 info->attrs);
11592 if (IS_ERR(wdev)) {
4c476991
JB
11593 if (rtnl)
11594 rtnl_unlock();
89a54e48 11595 return PTR_ERR(wdev);
4c476991 11596 }
89a54e48 11597
89a54e48 11598 dev = wdev->netdev;
f26cbf40 11599 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 11600
1bf614ef
JB
11601 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
11602 if (!dev) {
1bf614ef
JB
11603 if (rtnl)
11604 rtnl_unlock();
11605 return -EINVAL;
11606 }
11607
11608 info->user_ptr[1] = dev;
11609 } else {
11610 info->user_ptr[1] = wdev;
41265714 11611 }
1bf614ef
JB
11612
11613 if (dev) {
11614 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
11615 !netif_running(dev)) {
1bf614ef
JB
11616 if (rtnl)
11617 rtnl_unlock();
11618 return -ENETDOWN;
11619 }
11620
11621 dev_hold(dev);
98104fde 11622 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) {
cb3b7d87
AB
11623 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
11624 !wdev->p2p_started) {
11625 if (rtnl)
11626 rtnl_unlock();
11627 return -ENETDOWN;
11628 }
11629 if (wdev->iftype == NL80211_IFTYPE_NAN &&
11630 !wdev->nan_started) {
98104fde
JB
11631 if (rtnl)
11632 rtnl_unlock();
11633 return -ENETDOWN;
11634 }
41265714 11635 }
89a54e48 11636
4c476991 11637 info->user_ptr[0] = rdev;
4c476991
JB
11638 }
11639
11640 return 0;
11641}
11642
f84f771d 11643static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
11644 struct genl_info *info)
11645{
1bf614ef
JB
11646 if (info->user_ptr[1]) {
11647 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
11648 struct wireless_dev *wdev = info->user_ptr[1];
11649
11650 if (wdev->netdev)
11651 dev_put(wdev->netdev);
11652 } else {
11653 dev_put(info->user_ptr[1]);
11654 }
11655 }
5393b917 11656
4c476991
JB
11657 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
11658 rtnl_unlock();
5393b917
JB
11659
11660 /* If needed, clear the netlink message payload from the SKB
11661 * as it might contain key data that shouldn't stick around on
11662 * the heap after the SKB is freed. The netlink message header
11663 * is still needed for further processing, so leave it intact.
11664 */
11665 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
11666 struct nlmsghdr *nlh = nlmsg_hdr(skb);
11667
11668 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
11669 }
4c476991
JB
11670}
11671
4534de83 11672static const struct genl_ops nl80211_ops[] = {
55682965
JB
11673 {
11674 .cmd = NL80211_CMD_GET_WIPHY,
11675 .doit = nl80211_get_wiphy,
11676 .dumpit = nl80211_dump_wiphy,
86e8cf98 11677 .done = nl80211_dump_wiphy_done,
55682965
JB
11678 .policy = nl80211_policy,
11679 /* can be retrieved by unprivileged users */
5fe231e8
JB
11680 .internal_flags = NL80211_FLAG_NEED_WIPHY |
11681 NL80211_FLAG_NEED_RTNL,
55682965
JB
11682 },
11683 {
11684 .cmd = NL80211_CMD_SET_WIPHY,
11685 .doit = nl80211_set_wiphy,
11686 .policy = nl80211_policy,
5617c6cd 11687 .flags = GENL_UNS_ADMIN_PERM,
4c476991 11688 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
11689 },
11690 {
11691 .cmd = NL80211_CMD_GET_INTERFACE,
11692 .doit = nl80211_get_interface,
11693 .dumpit = nl80211_dump_interface,
11694 .policy = nl80211_policy,
11695 /* can be retrieved by unprivileged users */
5fe231e8
JB
11696 .internal_flags = NL80211_FLAG_NEED_WDEV |
11697 NL80211_FLAG_NEED_RTNL,
55682965
JB
11698 },
11699 {
11700 .cmd = NL80211_CMD_SET_INTERFACE,
11701 .doit = nl80211_set_interface,
11702 .policy = nl80211_policy,
5617c6cd 11703 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
11704 .internal_flags = NL80211_FLAG_NEED_NETDEV |
11705 NL80211_FLAG_NEED_RTNL,
55682965
JB
11706 },
11707 {
11708 .cmd = NL80211_CMD_NEW_INTERFACE,
11709 .doit = nl80211_new_interface,
11710 .policy = nl80211_policy,
5617c6cd 11711 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
11712 .internal_flags = NL80211_FLAG_NEED_WIPHY |
11713 NL80211_FLAG_NEED_RTNL,
55682965
JB
11714 },
11715 {
11716 .cmd = NL80211_CMD_DEL_INTERFACE,
11717 .doit = nl80211_del_interface,
11718 .policy = nl80211_policy,
5617c6cd 11719 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 11720 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 11721 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
11722 },
11723 {
11724 .cmd = NL80211_CMD_GET_KEY,
11725 .doit = nl80211_get_key,
11726 .policy = nl80211_policy,
5617c6cd 11727 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11728 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11729 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
11730 },
11731 {
11732 .cmd = NL80211_CMD_SET_KEY,
11733 .doit = nl80211_set_key,
11734 .policy = nl80211_policy,
5617c6cd 11735 .flags = GENL_UNS_ADMIN_PERM,
41265714 11736 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
11737 NL80211_FLAG_NEED_RTNL |
11738 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
11739 },
11740 {
11741 .cmd = NL80211_CMD_NEW_KEY,
11742 .doit = nl80211_new_key,
11743 .policy = nl80211_policy,
5617c6cd 11744 .flags = GENL_UNS_ADMIN_PERM,
41265714 11745 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
11746 NL80211_FLAG_NEED_RTNL |
11747 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
11748 },
11749 {
11750 .cmd = NL80211_CMD_DEL_KEY,
11751 .doit = nl80211_del_key,
11752 .policy = nl80211_policy,
5617c6cd 11753 .flags = GENL_UNS_ADMIN_PERM,
41265714 11754 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11755 NL80211_FLAG_NEED_RTNL,
55682965 11756 },
ed1b6cc7
JB
11757 {
11758 .cmd = NL80211_CMD_SET_BEACON,
11759 .policy = nl80211_policy,
5617c6cd 11760 .flags = GENL_UNS_ADMIN_PERM,
8860020e 11761 .doit = nl80211_set_beacon,
2b5f8b0b 11762 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11763 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
11764 },
11765 {
8860020e 11766 .cmd = NL80211_CMD_START_AP,
ed1b6cc7 11767 .policy = nl80211_policy,
5617c6cd 11768 .flags = GENL_UNS_ADMIN_PERM,
8860020e 11769 .doit = nl80211_start_ap,
2b5f8b0b 11770 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11771 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
11772 },
11773 {
8860020e 11774 .cmd = NL80211_CMD_STOP_AP,
ed1b6cc7 11775 .policy = nl80211_policy,
5617c6cd 11776 .flags = GENL_UNS_ADMIN_PERM,
8860020e 11777 .doit = nl80211_stop_ap,
2b5f8b0b 11778 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11779 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 11780 },
5727ef1b
JB
11781 {
11782 .cmd = NL80211_CMD_GET_STATION,
11783 .doit = nl80211_get_station,
2ec600d6 11784 .dumpit = nl80211_dump_station,
5727ef1b 11785 .policy = nl80211_policy,
4c476991
JB
11786 .internal_flags = NL80211_FLAG_NEED_NETDEV |
11787 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
11788 },
11789 {
11790 .cmd = NL80211_CMD_SET_STATION,
11791 .doit = nl80211_set_station,
11792 .policy = nl80211_policy,
5617c6cd 11793 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11794 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11795 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
11796 },
11797 {
11798 .cmd = NL80211_CMD_NEW_STATION,
11799 .doit = nl80211_new_station,
11800 .policy = nl80211_policy,
5617c6cd 11801 .flags = GENL_UNS_ADMIN_PERM,
41265714 11802 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11803 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
11804 },
11805 {
11806 .cmd = NL80211_CMD_DEL_STATION,
11807 .doit = nl80211_del_station,
11808 .policy = nl80211_policy,
5617c6cd 11809 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11810 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11811 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
11812 },
11813 {
11814 .cmd = NL80211_CMD_GET_MPATH,
11815 .doit = nl80211_get_mpath,
11816 .dumpit = nl80211_dump_mpath,
11817 .policy = nl80211_policy,
5617c6cd 11818 .flags = GENL_UNS_ADMIN_PERM,
41265714 11819 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11820 NL80211_FLAG_NEED_RTNL,
2ec600d6 11821 },
66be7d2b
HR
11822 {
11823 .cmd = NL80211_CMD_GET_MPP,
11824 .doit = nl80211_get_mpp,
11825 .dumpit = nl80211_dump_mpp,
11826 .policy = nl80211_policy,
5617c6cd 11827 .flags = GENL_UNS_ADMIN_PERM,
66be7d2b
HR
11828 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
11829 NL80211_FLAG_NEED_RTNL,
11830 },
2ec600d6
LCC
11831 {
11832 .cmd = NL80211_CMD_SET_MPATH,
11833 .doit = nl80211_set_mpath,
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,
2ec600d6
LCC
11838 },
11839 {
11840 .cmd = NL80211_CMD_NEW_MPATH,
11841 .doit = nl80211_new_mpath,
11842 .policy = nl80211_policy,
5617c6cd 11843 .flags = GENL_UNS_ADMIN_PERM,
41265714 11844 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11845 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
11846 },
11847 {
11848 .cmd = NL80211_CMD_DEL_MPATH,
11849 .doit = nl80211_del_mpath,
11850 .policy = nl80211_policy,
5617c6cd 11851 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11852 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11853 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
11854 },
11855 {
11856 .cmd = NL80211_CMD_SET_BSS,
11857 .doit = nl80211_set_bss,
11858 .policy = nl80211_policy,
5617c6cd 11859 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11860 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11861 NL80211_FLAG_NEED_RTNL,
b2e1b302 11862 },
f130347c
LR
11863 {
11864 .cmd = NL80211_CMD_GET_REG,
ad30ca2c
AN
11865 .doit = nl80211_get_reg_do,
11866 .dumpit = nl80211_get_reg_dump,
f130347c 11867 .policy = nl80211_policy,
5fe231e8 11868 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
11869 /* can be retrieved by unprivileged users */
11870 },
b6863036 11871#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
11872 {
11873 .cmd = NL80211_CMD_SET_REG,
11874 .doit = nl80211_set_reg,
11875 .policy = nl80211_policy,
11876 .flags = GENL_ADMIN_PERM,
5fe231e8 11877 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302 11878 },
b6863036 11879#endif
b2e1b302
LR
11880 {
11881 .cmd = NL80211_CMD_REQ_SET_REG,
11882 .doit = nl80211_req_set_reg,
11883 .policy = nl80211_policy,
93da9cc1 11884 .flags = GENL_ADMIN_PERM,
11885 },
11886 {
24bdd9f4
JC
11887 .cmd = NL80211_CMD_GET_MESH_CONFIG,
11888 .doit = nl80211_get_mesh_config,
93da9cc1 11889 .policy = nl80211_policy,
11890 /* can be retrieved by unprivileged users */
2b5f8b0b 11891 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11892 NL80211_FLAG_NEED_RTNL,
93da9cc1 11893 },
11894 {
24bdd9f4
JC
11895 .cmd = NL80211_CMD_SET_MESH_CONFIG,
11896 .doit = nl80211_update_mesh_config,
93da9cc1 11897 .policy = nl80211_policy,
5617c6cd 11898 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c 11899 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11900 NL80211_FLAG_NEED_RTNL,
9aed3cc1 11901 },
2a519311
JB
11902 {
11903 .cmd = NL80211_CMD_TRIGGER_SCAN,
11904 .doit = nl80211_trigger_scan,
11905 .policy = nl80211_policy,
5617c6cd 11906 .flags = GENL_UNS_ADMIN_PERM,
fd014284 11907 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 11908 NL80211_FLAG_NEED_RTNL,
2a519311 11909 },
91d3ab46
VK
11910 {
11911 .cmd = NL80211_CMD_ABORT_SCAN,
11912 .doit = nl80211_abort_scan,
11913 .policy = nl80211_policy,
5617c6cd 11914 .flags = GENL_UNS_ADMIN_PERM,
91d3ab46
VK
11915 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
11916 NL80211_FLAG_NEED_RTNL,
11917 },
2a519311
JB
11918 {
11919 .cmd = NL80211_CMD_GET_SCAN,
11920 .policy = nl80211_policy,
11921 .dumpit = nl80211_dump_scan,
11922 },
807f8a8c
LC
11923 {
11924 .cmd = NL80211_CMD_START_SCHED_SCAN,
11925 .doit = nl80211_start_sched_scan,
11926 .policy = nl80211_policy,
5617c6cd 11927 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
11928 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
11929 NL80211_FLAG_NEED_RTNL,
11930 },
11931 {
11932 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
11933 .doit = nl80211_stop_sched_scan,
11934 .policy = nl80211_policy,
5617c6cd 11935 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
11936 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
11937 NL80211_FLAG_NEED_RTNL,
11938 },
636a5d36
JM
11939 {
11940 .cmd = NL80211_CMD_AUTHENTICATE,
11941 .doit = nl80211_authenticate,
11942 .policy = nl80211_policy,
5617c6cd 11943 .flags = GENL_UNS_ADMIN_PERM,
41265714 11944 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
11945 NL80211_FLAG_NEED_RTNL |
11946 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
11947 },
11948 {
11949 .cmd = NL80211_CMD_ASSOCIATE,
11950 .doit = nl80211_associate,
11951 .policy = nl80211_policy,
5617c6cd 11952 .flags = GENL_UNS_ADMIN_PERM,
41265714 11953 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11954 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
11955 },
11956 {
11957 .cmd = NL80211_CMD_DEAUTHENTICATE,
11958 .doit = nl80211_deauthenticate,
11959 .policy = nl80211_policy,
5617c6cd 11960 .flags = GENL_UNS_ADMIN_PERM,
41265714 11961 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11962 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
11963 },
11964 {
11965 .cmd = NL80211_CMD_DISASSOCIATE,
11966 .doit = nl80211_disassociate,
11967 .policy = nl80211_policy,
5617c6cd 11968 .flags = GENL_UNS_ADMIN_PERM,
41265714 11969 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11970 NL80211_FLAG_NEED_RTNL,
636a5d36 11971 },
04a773ad
JB
11972 {
11973 .cmd = NL80211_CMD_JOIN_IBSS,
11974 .doit = nl80211_join_ibss,
11975 .policy = nl80211_policy,
5617c6cd 11976 .flags = GENL_UNS_ADMIN_PERM,
41265714 11977 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11978 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
11979 },
11980 {
11981 .cmd = NL80211_CMD_LEAVE_IBSS,
11982 .doit = nl80211_leave_ibss,
11983 .policy = nl80211_policy,
5617c6cd 11984 .flags = GENL_UNS_ADMIN_PERM,
41265714 11985 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11986 NL80211_FLAG_NEED_RTNL,
04a773ad 11987 },
aff89a9b
JB
11988#ifdef CONFIG_NL80211_TESTMODE
11989 {
11990 .cmd = NL80211_CMD_TESTMODE,
11991 .doit = nl80211_testmode_do,
71063f0e 11992 .dumpit = nl80211_testmode_dump,
aff89a9b 11993 .policy = nl80211_policy,
5617c6cd 11994 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
11995 .internal_flags = NL80211_FLAG_NEED_WIPHY |
11996 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
11997 },
11998#endif
b23aa676
SO
11999 {
12000 .cmd = NL80211_CMD_CONNECT,
12001 .doit = nl80211_connect,
12002 .policy = nl80211_policy,
5617c6cd 12003 .flags = GENL_UNS_ADMIN_PERM,
41265714 12004 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12005 NL80211_FLAG_NEED_RTNL,
b23aa676
SO
12006 },
12007 {
12008 .cmd = NL80211_CMD_DISCONNECT,
12009 .doit = nl80211_disconnect,
12010 .policy = nl80211_policy,
5617c6cd 12011 .flags = GENL_UNS_ADMIN_PERM,
41265714 12012 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12013 NL80211_FLAG_NEED_RTNL,
b23aa676 12014 },
463d0183
JB
12015 {
12016 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
12017 .doit = nl80211_wiphy_netns,
12018 .policy = nl80211_policy,
5617c6cd 12019 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12020 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12021 NL80211_FLAG_NEED_RTNL,
463d0183 12022 },
61fa713c
HS
12023 {
12024 .cmd = NL80211_CMD_GET_SURVEY,
12025 .policy = nl80211_policy,
12026 .dumpit = nl80211_dump_survey,
12027 },
67fbb16b
SO
12028 {
12029 .cmd = NL80211_CMD_SET_PMKSA,
12030 .doit = nl80211_setdel_pmksa,
12031 .policy = nl80211_policy,
5617c6cd 12032 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12033 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12034 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12035 },
12036 {
12037 .cmd = NL80211_CMD_DEL_PMKSA,
12038 .doit = nl80211_setdel_pmksa,
12039 .policy = nl80211_policy,
5617c6cd 12040 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12041 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12042 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12043 },
12044 {
12045 .cmd = NL80211_CMD_FLUSH_PMKSA,
12046 .doit = nl80211_flush_pmksa,
12047 .policy = nl80211_policy,
5617c6cd 12048 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12049 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12050 NL80211_FLAG_NEED_RTNL,
67fbb16b 12051 },
9588bbd5
JM
12052 {
12053 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
12054 .doit = nl80211_remain_on_channel,
12055 .policy = nl80211_policy,
5617c6cd 12056 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12057 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12058 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
12059 },
12060 {
12061 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
12062 .doit = nl80211_cancel_remain_on_channel,
12063 .policy = nl80211_policy,
5617c6cd 12064 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12065 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12066 NL80211_FLAG_NEED_RTNL,
9588bbd5 12067 },
13ae75b1
JM
12068 {
12069 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
12070 .doit = nl80211_set_tx_bitrate_mask,
12071 .policy = nl80211_policy,
5617c6cd 12072 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12073 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12074 NL80211_FLAG_NEED_RTNL,
13ae75b1 12075 },
026331c4 12076 {
2e161f78
JB
12077 .cmd = NL80211_CMD_REGISTER_FRAME,
12078 .doit = nl80211_register_mgmt,
026331c4 12079 .policy = nl80211_policy,
5617c6cd 12080 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12081 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 12082 NL80211_FLAG_NEED_RTNL,
026331c4
JM
12083 },
12084 {
2e161f78
JB
12085 .cmd = NL80211_CMD_FRAME,
12086 .doit = nl80211_tx_mgmt,
026331c4 12087 .policy = nl80211_policy,
5617c6cd 12088 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12089 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
12090 NL80211_FLAG_NEED_RTNL,
12091 },
12092 {
12093 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
12094 .doit = nl80211_tx_mgmt_cancel_wait,
12095 .policy = nl80211_policy,
5617c6cd 12096 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12097 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12098 NL80211_FLAG_NEED_RTNL,
026331c4 12099 },
ffb9eb3d
KV
12100 {
12101 .cmd = NL80211_CMD_SET_POWER_SAVE,
12102 .doit = nl80211_set_power_save,
12103 .policy = nl80211_policy,
5617c6cd 12104 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12105 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12106 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
12107 },
12108 {
12109 .cmd = NL80211_CMD_GET_POWER_SAVE,
12110 .doit = nl80211_get_power_save,
12111 .policy = nl80211_policy,
12112 /* can be retrieved by unprivileged users */
4c476991
JB
12113 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12114 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 12115 },
d6dc1a38
JO
12116 {
12117 .cmd = NL80211_CMD_SET_CQM,
12118 .doit = nl80211_set_cqm,
12119 .policy = nl80211_policy,
5617c6cd 12120 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12121 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12122 NL80211_FLAG_NEED_RTNL,
d6dc1a38 12123 },
f444de05
JB
12124 {
12125 .cmd = NL80211_CMD_SET_CHANNEL,
12126 .doit = nl80211_set_channel,
12127 .policy = nl80211_policy,
5617c6cd 12128 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12129 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12130 NL80211_FLAG_NEED_RTNL,
f444de05 12131 },
e8347eba
BJ
12132 {
12133 .cmd = NL80211_CMD_SET_WDS_PEER,
12134 .doit = nl80211_set_wds_peer,
12135 .policy = nl80211_policy,
5617c6cd 12136 .flags = GENL_UNS_ADMIN_PERM,
43b19952
JB
12137 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12138 NL80211_FLAG_NEED_RTNL,
e8347eba 12139 },
29cbe68c
JB
12140 {
12141 .cmd = NL80211_CMD_JOIN_MESH,
12142 .doit = nl80211_join_mesh,
12143 .policy = nl80211_policy,
5617c6cd 12144 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
12145 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12146 NL80211_FLAG_NEED_RTNL,
12147 },
12148 {
12149 .cmd = NL80211_CMD_LEAVE_MESH,
12150 .doit = nl80211_leave_mesh,
12151 .policy = nl80211_policy,
5617c6cd 12152 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
12153 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12154 NL80211_FLAG_NEED_RTNL,
12155 },
6e0bd6c3
RL
12156 {
12157 .cmd = NL80211_CMD_JOIN_OCB,
12158 .doit = nl80211_join_ocb,
12159 .policy = nl80211_policy,
5617c6cd 12160 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
12161 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12162 NL80211_FLAG_NEED_RTNL,
12163 },
12164 {
12165 .cmd = NL80211_CMD_LEAVE_OCB,
12166 .doit = nl80211_leave_ocb,
12167 .policy = nl80211_policy,
5617c6cd 12168 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
12169 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12170 NL80211_FLAG_NEED_RTNL,
12171 },
dfb89c56 12172#ifdef CONFIG_PM
ff1b6e69
JB
12173 {
12174 .cmd = NL80211_CMD_GET_WOWLAN,
12175 .doit = nl80211_get_wowlan,
12176 .policy = nl80211_policy,
12177 /* can be retrieved by unprivileged users */
12178 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12179 NL80211_FLAG_NEED_RTNL,
12180 },
12181 {
12182 .cmd = NL80211_CMD_SET_WOWLAN,
12183 .doit = nl80211_set_wowlan,
12184 .policy = nl80211_policy,
5617c6cd 12185 .flags = GENL_UNS_ADMIN_PERM,
ff1b6e69
JB
12186 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12187 NL80211_FLAG_NEED_RTNL,
12188 },
dfb89c56 12189#endif
e5497d76
JB
12190 {
12191 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
12192 .doit = nl80211_set_rekey_data,
12193 .policy = nl80211_policy,
5617c6cd 12194 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 12195 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12196 NL80211_FLAG_NEED_RTNL |
12197 NL80211_FLAG_CLEAR_SKB,
e5497d76 12198 },
109086ce
AN
12199 {
12200 .cmd = NL80211_CMD_TDLS_MGMT,
12201 .doit = nl80211_tdls_mgmt,
12202 .policy = nl80211_policy,
5617c6cd 12203 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
12204 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12205 NL80211_FLAG_NEED_RTNL,
12206 },
12207 {
12208 .cmd = NL80211_CMD_TDLS_OPER,
12209 .doit = nl80211_tdls_oper,
12210 .policy = nl80211_policy,
5617c6cd 12211 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
12212 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12213 NL80211_FLAG_NEED_RTNL,
12214 },
28946da7
JB
12215 {
12216 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
12217 .doit = nl80211_register_unexpected_frame,
12218 .policy = nl80211_policy,
5617c6cd 12219 .flags = GENL_UNS_ADMIN_PERM,
28946da7
JB
12220 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12221 NL80211_FLAG_NEED_RTNL,
12222 },
7f6cf311
JB
12223 {
12224 .cmd = NL80211_CMD_PROBE_CLIENT,
12225 .doit = nl80211_probe_client,
12226 .policy = nl80211_policy,
5617c6cd 12227 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12228 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
12229 NL80211_FLAG_NEED_RTNL,
12230 },
5e760230
JB
12231 {
12232 .cmd = NL80211_CMD_REGISTER_BEACONS,
12233 .doit = nl80211_register_beacons,
12234 .policy = nl80211_policy,
5617c6cd 12235 .flags = GENL_UNS_ADMIN_PERM,
5e760230
JB
12236 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12237 NL80211_FLAG_NEED_RTNL,
12238 },
1d9d9213
SW
12239 {
12240 .cmd = NL80211_CMD_SET_NOACK_MAP,
12241 .doit = nl80211_set_noack_map,
12242 .policy = nl80211_policy,
5617c6cd 12243 .flags = GENL_UNS_ADMIN_PERM,
1d9d9213
SW
12244 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12245 NL80211_FLAG_NEED_RTNL,
12246 },
98104fde
JB
12247 {
12248 .cmd = NL80211_CMD_START_P2P_DEVICE,
12249 .doit = nl80211_start_p2p_device,
12250 .policy = nl80211_policy,
5617c6cd 12251 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
12252 .internal_flags = NL80211_FLAG_NEED_WDEV |
12253 NL80211_FLAG_NEED_RTNL,
12254 },
12255 {
12256 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
12257 .doit = nl80211_stop_p2p_device,
12258 .policy = nl80211_policy,
5617c6cd 12259 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
12260 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12261 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
12262 },
12263 {
12264 .cmd = NL80211_CMD_START_NAN,
12265 .doit = nl80211_start_nan,
12266 .policy = nl80211_policy,
12267 .flags = GENL_ADMIN_PERM,
12268 .internal_flags = NL80211_FLAG_NEED_WDEV |
12269 NL80211_FLAG_NEED_RTNL,
12270 },
12271 {
12272 .cmd = NL80211_CMD_STOP_NAN,
12273 .doit = nl80211_stop_nan,
12274 .policy = nl80211_policy,
12275 .flags = GENL_ADMIN_PERM,
12276 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12277 NL80211_FLAG_NEED_RTNL,
a442b761
AB
12278 },
12279 {
12280 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
12281 .doit = nl80211_nan_add_func,
12282 .policy = nl80211_policy,
12283 .flags = GENL_ADMIN_PERM,
12284 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12285 NL80211_FLAG_NEED_RTNL,
12286 },
12287 {
12288 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
12289 .doit = nl80211_nan_del_func,
12290 .policy = nl80211_policy,
12291 .flags = GENL_ADMIN_PERM,
12292 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12293 NL80211_FLAG_NEED_RTNL,
98104fde 12294 },
f4e583c8
AQ
12295 {
12296 .cmd = NL80211_CMD_SET_MCAST_RATE,
12297 .doit = nl80211_set_mcast_rate,
77765eaf 12298 .policy = nl80211_policy,
5617c6cd 12299 .flags = GENL_UNS_ADMIN_PERM,
77765eaf
VT
12300 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12301 NL80211_FLAG_NEED_RTNL,
12302 },
12303 {
12304 .cmd = NL80211_CMD_SET_MAC_ACL,
12305 .doit = nl80211_set_mac_acl,
f4e583c8 12306 .policy = nl80211_policy,
5617c6cd 12307 .flags = GENL_UNS_ADMIN_PERM,
f4e583c8
AQ
12308 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12309 NL80211_FLAG_NEED_RTNL,
12310 },
04f39047
SW
12311 {
12312 .cmd = NL80211_CMD_RADAR_DETECT,
12313 .doit = nl80211_start_radar_detection,
12314 .policy = nl80211_policy,
5617c6cd 12315 .flags = GENL_UNS_ADMIN_PERM,
04f39047
SW
12316 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12317 NL80211_FLAG_NEED_RTNL,
12318 },
3713b4e3
JB
12319 {
12320 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
12321 .doit = nl80211_get_protocol_features,
12322 .policy = nl80211_policy,
12323 },
355199e0
JM
12324 {
12325 .cmd = NL80211_CMD_UPDATE_FT_IES,
12326 .doit = nl80211_update_ft_ies,
12327 .policy = nl80211_policy,
5617c6cd 12328 .flags = GENL_UNS_ADMIN_PERM,
355199e0
JM
12329 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12330 NL80211_FLAG_NEED_RTNL,
12331 },
5de17984
AS
12332 {
12333 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
12334 .doit = nl80211_crit_protocol_start,
12335 .policy = nl80211_policy,
5617c6cd 12336 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
12337 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12338 NL80211_FLAG_NEED_RTNL,
12339 },
12340 {
12341 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
12342 .doit = nl80211_crit_protocol_stop,
12343 .policy = nl80211_policy,
5617c6cd 12344 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
12345 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12346 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
12347 },
12348 {
12349 .cmd = NL80211_CMD_GET_COALESCE,
12350 .doit = nl80211_get_coalesce,
12351 .policy = nl80211_policy,
12352 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12353 NL80211_FLAG_NEED_RTNL,
12354 },
12355 {
12356 .cmd = NL80211_CMD_SET_COALESCE,
12357 .doit = nl80211_set_coalesce,
12358 .policy = nl80211_policy,
5617c6cd 12359 .flags = GENL_UNS_ADMIN_PERM,
be29b99a
AK
12360 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12361 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
12362 },
12363 {
12364 .cmd = NL80211_CMD_CHANNEL_SWITCH,
12365 .doit = nl80211_channel_switch,
12366 .policy = nl80211_policy,
5617c6cd 12367 .flags = GENL_UNS_ADMIN_PERM,
16ef1fe2
SW
12368 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12369 NL80211_FLAG_NEED_RTNL,
12370 },
ad7e718c
JB
12371 {
12372 .cmd = NL80211_CMD_VENDOR,
12373 .doit = nl80211_vendor_cmd,
7bdbe400 12374 .dumpit = nl80211_vendor_cmd_dump,
ad7e718c 12375 .policy = nl80211_policy,
5617c6cd 12376 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c
JB
12377 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12378 NL80211_FLAG_NEED_RTNL,
12379 },
fa9ffc74
KP
12380 {
12381 .cmd = NL80211_CMD_SET_QOS_MAP,
12382 .doit = nl80211_set_qos_map,
12383 .policy = nl80211_policy,
5617c6cd 12384 .flags = GENL_UNS_ADMIN_PERM,
fa9ffc74
KP
12385 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12386 NL80211_FLAG_NEED_RTNL,
12387 },
960d01ac
JB
12388 {
12389 .cmd = NL80211_CMD_ADD_TX_TS,
12390 .doit = nl80211_add_tx_ts,
12391 .policy = nl80211_policy,
5617c6cd 12392 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
12393 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12394 NL80211_FLAG_NEED_RTNL,
12395 },
12396 {
12397 .cmd = NL80211_CMD_DEL_TX_TS,
12398 .doit = nl80211_del_tx_ts,
12399 .policy = nl80211_policy,
5617c6cd 12400 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
12401 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12402 NL80211_FLAG_NEED_RTNL,
12403 },
1057d35e
AN
12404 {
12405 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
12406 .doit = nl80211_tdls_channel_switch,
12407 .policy = nl80211_policy,
5617c6cd 12408 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
12409 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12410 NL80211_FLAG_NEED_RTNL,
12411 },
12412 {
12413 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
12414 .doit = nl80211_tdls_cancel_channel_switch,
12415 .policy = nl80211_policy,
5617c6cd 12416 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
12417 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12418 NL80211_FLAG_NEED_RTNL,
12419 },
55682965 12420};
9588bbd5 12421
55682965
JB
12422/* notification functions */
12423
3bb20556
JB
12424void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
12425 enum nl80211_commands cmd)
55682965
JB
12426{
12427 struct sk_buff *msg;
86e8cf98 12428 struct nl80211_dump_wiphy_state state = {};
55682965 12429
3bb20556
JB
12430 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
12431 cmd != NL80211_CMD_DEL_WIPHY);
12432
fd2120ca 12433 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
12434 if (!msg)
12435 return;
12436
3bb20556 12437 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
12438 nlmsg_free(msg);
12439 return;
12440 }
12441
68eb5503 12442 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12443 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
12444}
12445
896ff063
DK
12446void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
12447 struct wireless_dev *wdev,
12448 enum nl80211_commands cmd)
12449{
12450 struct sk_buff *msg;
12451
12452 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
12453 cmd != NL80211_CMD_DEL_INTERFACE);
12454
12455 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12456 if (!msg)
12457 return;
12458
12459 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev,
12460 cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
12461 nlmsg_free(msg);
12462 return;
12463 }
12464
12465 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
12466 NL80211_MCGRP_CONFIG, GFP_KERNEL);
12467}
12468
362a415d
JB
12469static int nl80211_add_scan_req(struct sk_buff *msg,
12470 struct cfg80211_registered_device *rdev)
12471{
12472 struct cfg80211_scan_request *req = rdev->scan_req;
12473 struct nlattr *nest;
12474 int i;
12475
12476 if (WARN_ON(!req))
12477 return 0;
12478
12479 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
12480 if (!nest)
12481 goto nla_put_failure;
9360ffd1
DM
12482 for (i = 0; i < req->n_ssids; i++) {
12483 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
12484 goto nla_put_failure;
12485 }
362a415d
JB
12486 nla_nest_end(msg, nest);
12487
12488 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
12489 if (!nest)
12490 goto nla_put_failure;
9360ffd1
DM
12491 for (i = 0; i < req->n_channels; i++) {
12492 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
12493 goto nla_put_failure;
12494 }
362a415d
JB
12495 nla_nest_end(msg, nest);
12496
9360ffd1
DM
12497 if (req->ie &&
12498 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
12499 goto nla_put_failure;
362a415d 12500
ae917c9f
JB
12501 if (req->flags &&
12502 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
12503 goto nla_put_failure;
ed473771 12504
1d76250b
AS
12505 if (req->info.scan_start_tsf &&
12506 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
12507 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
12508 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
12509 req->info.tsf_bssid)))
12510 goto nla_put_failure;
12511
362a415d
JB
12512 return 0;
12513 nla_put_failure:
12514 return -ENOBUFS;
12515}
12516
a538e2d5
JB
12517static int nl80211_send_scan_msg(struct sk_buff *msg,
12518 struct cfg80211_registered_device *rdev,
fd014284 12519 struct wireless_dev *wdev,
15e47304 12520 u32 portid, u32 seq, int flags,
a538e2d5 12521 u32 cmd)
2a519311
JB
12522{
12523 void *hdr;
12524
15e47304 12525 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
12526 if (!hdr)
12527 return -1;
12528
9360ffd1 12529 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
12530 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12531 wdev->netdev->ifindex)) ||
2dad624e
ND
12532 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12533 NL80211_ATTR_PAD))
9360ffd1 12534 goto nla_put_failure;
2a519311 12535
362a415d
JB
12536 /* ignore errors and send incomplete event anyway */
12537 nl80211_add_scan_req(msg, rdev);
2a519311 12538
053c095a
JB
12539 genlmsg_end(msg, hdr);
12540 return 0;
2a519311
JB
12541
12542 nla_put_failure:
12543 genlmsg_cancel(msg, hdr);
12544 return -EMSGSIZE;
12545}
12546
807f8a8c
LC
12547static int
12548nl80211_send_sched_scan_msg(struct sk_buff *msg,
12549 struct cfg80211_registered_device *rdev,
12550 struct net_device *netdev,
15e47304 12551 u32 portid, u32 seq, int flags, u32 cmd)
807f8a8c
LC
12552{
12553 void *hdr;
12554
15e47304 12555 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
807f8a8c
LC
12556 if (!hdr)
12557 return -1;
12558
9360ffd1
DM
12559 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12560 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
12561 goto nla_put_failure;
807f8a8c 12562
053c095a
JB
12563 genlmsg_end(msg, hdr);
12564 return 0;
807f8a8c
LC
12565
12566 nla_put_failure:
12567 genlmsg_cancel(msg, hdr);
12568 return -EMSGSIZE;
12569}
12570
a538e2d5 12571void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 12572 struct wireless_dev *wdev)
a538e2d5
JB
12573{
12574 struct sk_buff *msg;
12575
58050fce 12576 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
12577 if (!msg)
12578 return;
12579
fd014284 12580 if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
12581 NL80211_CMD_TRIGGER_SCAN) < 0) {
12582 nlmsg_free(msg);
12583 return;
12584 }
12585
68eb5503 12586 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12587 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
12588}
12589
f9d15d16
JB
12590struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
12591 struct wireless_dev *wdev, bool aborted)
2a519311
JB
12592{
12593 struct sk_buff *msg;
12594
fd2120ca 12595 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 12596 if (!msg)
f9d15d16 12597 return NULL;
2a519311 12598
fd014284 12599 if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
12600 aborted ? NL80211_CMD_SCAN_ABORTED :
12601 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 12602 nlmsg_free(msg);
f9d15d16 12603 return NULL;
2a519311
JB
12604 }
12605
f9d15d16 12606 return msg;
2a519311
JB
12607}
12608
f9d15d16
JB
12609void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
12610 struct sk_buff *msg)
2a519311 12611{
2a519311
JB
12612 if (!msg)
12613 return;
12614
68eb5503 12615 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12616 NL80211_MCGRP_SCAN, GFP_KERNEL);
2a519311
JB
12617}
12618
807f8a8c
LC
12619void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
12620 struct net_device *netdev)
12621{
12622 struct sk_buff *msg;
12623
12624 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12625 if (!msg)
12626 return;
12627
12628 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0,
12629 NL80211_CMD_SCHED_SCAN_RESULTS) < 0) {
12630 nlmsg_free(msg);
12631 return;
12632 }
12633
68eb5503 12634 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12635 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
12636}
12637
12638void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
12639 struct net_device *netdev, u32 cmd)
12640{
12641 struct sk_buff *msg;
12642
58050fce 12643 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
12644 if (!msg)
12645 return;
12646
12647 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
12648 nlmsg_free(msg);
12649 return;
12650 }
12651
68eb5503 12652 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12653 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
12654}
12655
b0d7aa59
JD
12656static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
12657 struct regulatory_request *request)
73d54c9e 12658{
73d54c9e 12659 /* Userspace can always count this one always being set */
9360ffd1
DM
12660 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
12661 goto nla_put_failure;
12662
12663 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
12664 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12665 NL80211_REGDOM_TYPE_WORLD))
12666 goto nla_put_failure;
12667 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
12668 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12669 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
12670 goto nla_put_failure;
12671 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
12672 request->intersect) {
12673 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12674 NL80211_REGDOM_TYPE_INTERSECTION))
12675 goto nla_put_failure;
12676 } else {
12677 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12678 NL80211_REGDOM_TYPE_COUNTRY) ||
12679 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
12680 request->alpha2))
12681 goto nla_put_failure;
12682 }
12683
ad30ca2c
AN
12684 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
12685 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
12686
12687 if (wiphy &&
12688 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
12689 goto nla_put_failure;
1bdd716c
AN
12690
12691 if (wiphy &&
12692 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
12693 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
12694 goto nla_put_failure;
ad30ca2c 12695 }
73d54c9e 12696
b0d7aa59
JD
12697 return true;
12698
12699nla_put_failure:
12700 return false;
12701}
12702
12703/*
12704 * This can happen on global regulatory changes or device specific settings
12705 * based on custom regulatory domains.
12706 */
12707void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
12708 struct regulatory_request *request)
12709{
12710 struct sk_buff *msg;
12711 void *hdr;
12712
12713 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12714 if (!msg)
12715 return;
12716
12717 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
12718 if (!hdr) {
12719 nlmsg_free(msg);
12720 return;
12721 }
12722
12723 if (nl80211_reg_change_event_fill(msg, request) == false)
12724 goto nla_put_failure;
12725
3b7b72ee 12726 genlmsg_end(msg, hdr);
73d54c9e 12727
bc43b28c 12728 rcu_read_lock();
68eb5503 12729 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 12730 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 12731 rcu_read_unlock();
73d54c9e
LR
12732
12733 return;
12734
12735nla_put_failure:
12736 genlmsg_cancel(msg, hdr);
12737 nlmsg_free(msg);
12738}
12739
6039f6d2
JM
12740static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
12741 struct net_device *netdev,
12742 const u8 *buf, size_t len,
b0b6aa2c
EP
12743 enum nl80211_commands cmd, gfp_t gfp,
12744 int uapsd_queues)
6039f6d2
JM
12745{
12746 struct sk_buff *msg;
12747 void *hdr;
12748
e6d6e342 12749 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
6039f6d2
JM
12750 if (!msg)
12751 return;
12752
12753 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
12754 if (!hdr) {
12755 nlmsg_free(msg);
12756 return;
12757 }
12758
9360ffd1
DM
12759 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12760 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
12761 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
12762 goto nla_put_failure;
6039f6d2 12763
b0b6aa2c
EP
12764 if (uapsd_queues >= 0) {
12765 struct nlattr *nla_wmm =
12766 nla_nest_start(msg, NL80211_ATTR_STA_WME);
12767 if (!nla_wmm)
12768 goto nla_put_failure;
12769
12770 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
12771 uapsd_queues))
12772 goto nla_put_failure;
12773
12774 nla_nest_end(msg, nla_wmm);
12775 }
12776
3b7b72ee 12777 genlmsg_end(msg, hdr);
6039f6d2 12778
68eb5503 12779 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12780 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
12781 return;
12782
12783 nla_put_failure:
12784 genlmsg_cancel(msg, hdr);
12785 nlmsg_free(msg);
12786}
12787
12788void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12789 struct net_device *netdev, const u8 *buf,
12790 size_t len, gfp_t gfp)
6039f6d2
JM
12791{
12792 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12793 NL80211_CMD_AUTHENTICATE, gfp, -1);
6039f6d2
JM
12794}
12795
12796void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
12797 struct net_device *netdev, const u8 *buf,
b0b6aa2c 12798 size_t len, gfp_t gfp, int uapsd_queues)
6039f6d2 12799{
e6d6e342 12800 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12801 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues);
6039f6d2
JM
12802}
12803
53b46b84 12804void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12805 struct net_device *netdev, const u8 *buf,
12806 size_t len, gfp_t gfp)
6039f6d2
JM
12807{
12808 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12809 NL80211_CMD_DEAUTHENTICATE, gfp, -1);
6039f6d2
JM
12810}
12811
53b46b84
JM
12812void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
12813 struct net_device *netdev, const u8 *buf,
e6d6e342 12814 size_t len, gfp_t gfp)
6039f6d2
JM
12815{
12816 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12817 NL80211_CMD_DISASSOCIATE, gfp, -1);
6039f6d2
JM
12818}
12819
6ff57cf8
JB
12820void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
12821 size_t len)
cf4e594e 12822{
947add36
JB
12823 struct wireless_dev *wdev = dev->ieee80211_ptr;
12824 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 12825 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
12826 const struct ieee80211_mgmt *mgmt = (void *)buf;
12827 u32 cmd;
947add36 12828
6ff57cf8
JB
12829 if (WARN_ON(len < 2))
12830 return;
cf4e594e 12831
6ff57cf8
JB
12832 if (ieee80211_is_deauth(mgmt->frame_control))
12833 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
12834 else
12835 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 12836
6ff57cf8 12837 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
b0b6aa2c 12838 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1);
cf4e594e 12839}
6ff57cf8 12840EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 12841
1b06bb40
LR
12842static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
12843 struct net_device *netdev, int cmd,
e6d6e342 12844 const u8 *addr, gfp_t gfp)
1965c853
JM
12845{
12846 struct sk_buff *msg;
12847 void *hdr;
12848
e6d6e342 12849 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
12850 if (!msg)
12851 return;
12852
12853 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
12854 if (!hdr) {
12855 nlmsg_free(msg);
12856 return;
12857 }
12858
9360ffd1
DM
12859 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12860 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
12861 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
12862 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
12863 goto nla_put_failure;
1965c853 12864
3b7b72ee 12865 genlmsg_end(msg, hdr);
1965c853 12866
68eb5503 12867 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12868 NL80211_MCGRP_MLME, gfp);
1965c853
JM
12869 return;
12870
12871 nla_put_failure:
12872 genlmsg_cancel(msg, hdr);
12873 nlmsg_free(msg);
12874}
12875
12876void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12877 struct net_device *netdev, const u8 *addr,
12878 gfp_t gfp)
1965c853
JM
12879{
12880 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 12881 addr, gfp);
1965c853
JM
12882}
12883
12884void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12885 struct net_device *netdev, const u8 *addr,
12886 gfp_t gfp)
1965c853 12887{
e6d6e342
JB
12888 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
12889 addr, gfp);
1965c853
JM
12890}
12891
b23aa676
SO
12892void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
12893 struct net_device *netdev, const u8 *bssid,
12894 const u8 *req_ie, size_t req_ie_len,
12895 const u8 *resp_ie, size_t resp_ie_len,
bf1ecd21 12896 int status, gfp_t gfp)
b23aa676
SO
12897{
12898 struct sk_buff *msg;
12899 void *hdr;
12900
58050fce 12901 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
b23aa676
SO
12902 if (!msg)
12903 return;
12904
12905 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
12906 if (!hdr) {
12907 nlmsg_free(msg);
12908 return;
12909 }
12910
9360ffd1
DM
12911 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12912 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
12913 (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) ||
bf1ecd21
JM
12914 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
12915 status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
12916 status) ||
12917 (status < 0 && nla_put_flag(msg, NL80211_ATTR_TIMED_OUT)) ||
9360ffd1
DM
12918 (req_ie &&
12919 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
12920 (resp_ie &&
12921 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
12922 goto nla_put_failure;
b23aa676 12923
3b7b72ee 12924 genlmsg_end(msg, hdr);
b23aa676 12925
68eb5503 12926 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12927 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
12928 return;
12929
12930 nla_put_failure:
12931 genlmsg_cancel(msg, hdr);
12932 nlmsg_free(msg);
b23aa676
SO
12933}
12934
12935void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
12936 struct net_device *netdev, const u8 *bssid,
12937 const u8 *req_ie, size_t req_ie_len,
12938 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
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_ROAM);
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 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
12956 (req_ie &&
12957 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
12958 (resp_ie &&
12959 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
12960 goto nla_put_failure;
b23aa676 12961
3b7b72ee 12962 genlmsg_end(msg, hdr);
b23aa676 12963
68eb5503 12964 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12965 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
12966 return;
12967
12968 nla_put_failure:
12969 genlmsg_cancel(msg, hdr);
12970 nlmsg_free(msg);
b23aa676
SO
12971}
12972
12973void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
12974 struct net_device *netdev, u16 reason,
667503dd 12975 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
12976{
12977 struct sk_buff *msg;
12978 void *hdr;
12979
58050fce 12980 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
b23aa676
SO
12981 if (!msg)
12982 return;
12983
12984 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
12985 if (!hdr) {
12986 nlmsg_free(msg);
12987 return;
12988 }
12989
9360ffd1
DM
12990 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12991 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
12992 (from_ap && reason &&
12993 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
12994 (from_ap &&
12995 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
12996 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
12997 goto nla_put_failure;
b23aa676 12998
3b7b72ee 12999 genlmsg_end(msg, hdr);
b23aa676 13000
68eb5503 13001 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13002 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
13003 return;
13004
13005 nla_put_failure:
13006 genlmsg_cancel(msg, hdr);
13007 nlmsg_free(msg);
b23aa676
SO
13008}
13009
04a773ad
JB
13010void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
13011 struct net_device *netdev, const u8 *bssid,
13012 gfp_t gfp)
13013{
13014 struct sk_buff *msg;
13015 void *hdr;
13016
fd2120ca 13017 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
13018 if (!msg)
13019 return;
13020
13021 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
13022 if (!hdr) {
13023 nlmsg_free(msg);
13024 return;
13025 }
13026
9360ffd1
DM
13027 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13028 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13029 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13030 goto nla_put_failure;
04a773ad 13031
3b7b72ee 13032 genlmsg_end(msg, hdr);
04a773ad 13033
68eb5503 13034 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13035 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
13036 return;
13037
13038 nla_put_failure:
13039 genlmsg_cancel(msg, hdr);
13040 nlmsg_free(msg);
13041}
13042
947add36
JB
13043void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
13044 const u8* ie, u8 ie_len, gfp_t gfp)
c93b5e71 13045{
947add36 13046 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13047 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
13048 struct sk_buff *msg;
13049 void *hdr;
13050
947add36
JB
13051 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
13052 return;
13053
13054 trace_cfg80211_notify_new_peer_candidate(dev, addr);
13055
c93b5e71
JC
13056 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13057 if (!msg)
13058 return;
13059
13060 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
13061 if (!hdr) {
13062 nlmsg_free(msg);
13063 return;
13064 }
13065
9360ffd1 13066 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
13067 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13068 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1
DM
13069 (ie_len && ie &&
13070 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
13071 goto nla_put_failure;
c93b5e71 13072
3b7b72ee 13073 genlmsg_end(msg, hdr);
c93b5e71 13074
68eb5503 13075 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13076 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
13077 return;
13078
13079 nla_put_failure:
13080 genlmsg_cancel(msg, hdr);
13081 nlmsg_free(msg);
13082}
947add36 13083EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 13084
a3b8b056
JM
13085void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
13086 struct net_device *netdev, const u8 *addr,
13087 enum nl80211_key_type key_type, int key_id,
e6d6e342 13088 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
13089{
13090 struct sk_buff *msg;
13091 void *hdr;
13092
e6d6e342 13093 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
13094 if (!msg)
13095 return;
13096
13097 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
13098 if (!hdr) {
13099 nlmsg_free(msg);
13100 return;
13101 }
13102
9360ffd1
DM
13103 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13104 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13105 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
13106 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
13107 (key_id != -1 &&
13108 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
13109 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
13110 goto nla_put_failure;
a3b8b056 13111
3b7b72ee 13112 genlmsg_end(msg, hdr);
a3b8b056 13113
68eb5503 13114 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13115 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
13116 return;
13117
13118 nla_put_failure:
13119 genlmsg_cancel(msg, hdr);
13120 nlmsg_free(msg);
13121}
13122
6bad8766
LR
13123void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
13124 struct ieee80211_channel *channel_before,
13125 struct ieee80211_channel *channel_after)
13126{
13127 struct sk_buff *msg;
13128 void *hdr;
13129 struct nlattr *nl_freq;
13130
fd2120ca 13131 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
13132 if (!msg)
13133 return;
13134
13135 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
13136 if (!hdr) {
13137 nlmsg_free(msg);
13138 return;
13139 }
13140
13141 /*
13142 * Since we are applying the beacon hint to a wiphy we know its
13143 * wiphy_idx is valid
13144 */
9360ffd1
DM
13145 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
13146 goto nla_put_failure;
6bad8766
LR
13147
13148 /* Before */
13149 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
13150 if (!nl_freq)
13151 goto nla_put_failure;
cdc89b97 13152 if (nl80211_msg_put_channel(msg, channel_before, false))
6bad8766
LR
13153 goto nla_put_failure;
13154 nla_nest_end(msg, nl_freq);
13155
13156 /* After */
13157 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
13158 if (!nl_freq)
13159 goto nla_put_failure;
cdc89b97 13160 if (nl80211_msg_put_channel(msg, channel_after, false))
6bad8766
LR
13161 goto nla_put_failure;
13162 nla_nest_end(msg, nl_freq);
13163
3b7b72ee 13164 genlmsg_end(msg, hdr);
6bad8766 13165
463d0183 13166 rcu_read_lock();
68eb5503 13167 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 13168 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 13169 rcu_read_unlock();
6bad8766
LR
13170
13171 return;
13172
13173nla_put_failure:
13174 genlmsg_cancel(msg, hdr);
13175 nlmsg_free(msg);
13176}
13177
9588bbd5
JM
13178static void nl80211_send_remain_on_chan_event(
13179 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 13180 struct wireless_dev *wdev, u64 cookie,
9588bbd5 13181 struct ieee80211_channel *chan,
9588bbd5
JM
13182 unsigned int duration, gfp_t gfp)
13183{
13184 struct sk_buff *msg;
13185 void *hdr;
13186
13187 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13188 if (!msg)
13189 return;
13190
13191 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13192 if (!hdr) {
13193 nlmsg_free(msg);
13194 return;
13195 }
13196
9360ffd1 13197 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13198 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13199 wdev->netdev->ifindex)) ||
2dad624e
ND
13200 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13201 NL80211_ATTR_PAD) ||
9360ffd1 13202 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
13203 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
13204 NL80211_CHAN_NO_HT) ||
2dad624e
ND
13205 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13206 NL80211_ATTR_PAD))
9360ffd1 13207 goto nla_put_failure;
9588bbd5 13208
9360ffd1
DM
13209 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
13210 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
13211 goto nla_put_failure;
9588bbd5 13212
3b7b72ee 13213 genlmsg_end(msg, hdr);
9588bbd5 13214
68eb5503 13215 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13216 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
13217 return;
13218
13219 nla_put_failure:
13220 genlmsg_cancel(msg, hdr);
13221 nlmsg_free(msg);
13222}
13223
947add36
JB
13224void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
13225 struct ieee80211_channel *chan,
13226 unsigned int duration, gfp_t gfp)
9588bbd5 13227{
947add36 13228 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13229 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13230
13231 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 13232 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 13233 rdev, wdev, cookie, chan,
42d97a59 13234 duration, gfp);
9588bbd5 13235}
947add36 13236EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 13237
947add36
JB
13238void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
13239 struct ieee80211_channel *chan,
13240 gfp_t gfp)
9588bbd5 13241{
947add36 13242 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13243 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13244
13245 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 13246 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 13247 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 13248}
947add36 13249EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 13250
947add36
JB
13251void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
13252 struct station_info *sinfo, gfp_t gfp)
98b62183 13253{
947add36 13254 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13255 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
13256 struct sk_buff *msg;
13257
947add36
JB
13258 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
13259
58050fce 13260 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
13261 if (!msg)
13262 return;
13263
cf5ead82 13264 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 13265 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
13266 nlmsg_free(msg);
13267 return;
13268 }
13269
68eb5503 13270 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13271 NL80211_MCGRP_MLME, gfp);
98b62183 13272}
947add36 13273EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 13274
cf5ead82
JB
13275void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
13276 struct station_info *sinfo, gfp_t gfp)
ec15e68b 13277{
947add36 13278 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13279 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 13280 struct sk_buff *msg;
cf5ead82
JB
13281 struct station_info empty_sinfo = {};
13282
13283 if (!sinfo)
13284 sinfo = &empty_sinfo;
ec15e68b 13285
947add36
JB
13286 trace_cfg80211_del_sta(dev, mac_addr);
13287
58050fce 13288 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
ec15e68b
JM
13289 if (!msg)
13290 return;
13291
cf5ead82 13292 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 13293 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b
JM
13294 nlmsg_free(msg);
13295 return;
13296 }
13297
68eb5503 13298 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13299 NL80211_MCGRP_MLME, gfp);
ec15e68b 13300}
cf5ead82 13301EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 13302
947add36
JB
13303void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
13304 enum nl80211_connect_failed_reason reason,
13305 gfp_t gfp)
ed44a951 13306{
947add36 13307 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13308 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
13309 struct sk_buff *msg;
13310 void *hdr;
13311
13312 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
13313 if (!msg)
13314 return;
13315
13316 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
13317 if (!hdr) {
13318 nlmsg_free(msg);
13319 return;
13320 }
13321
13322 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13323 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
13324 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
13325 goto nla_put_failure;
13326
13327 genlmsg_end(msg, hdr);
13328
68eb5503 13329 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13330 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
13331 return;
13332
13333 nla_put_failure:
13334 genlmsg_cancel(msg, hdr);
13335 nlmsg_free(msg);
13336}
947add36 13337EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 13338
b92ab5d8
JB
13339static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
13340 const u8 *addr, gfp_t gfp)
28946da7
JB
13341{
13342 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13343 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
13344 struct sk_buff *msg;
13345 void *hdr;
15e47304 13346 u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid);
28946da7 13347
15e47304 13348 if (!nlportid)
28946da7
JB
13349 return false;
13350
13351 msg = nlmsg_new(100, gfp);
13352 if (!msg)
13353 return true;
13354
b92ab5d8 13355 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
13356 if (!hdr) {
13357 nlmsg_free(msg);
13358 return true;
13359 }
13360
9360ffd1
DM
13361 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13362 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13363 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
13364 goto nla_put_failure;
28946da7 13365
9c90a9f6 13366 genlmsg_end(msg, hdr);
15e47304 13367 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
13368 return true;
13369
13370 nla_put_failure:
13371 genlmsg_cancel(msg, hdr);
13372 nlmsg_free(msg);
13373 return true;
13374}
13375
947add36
JB
13376bool cfg80211_rx_spurious_frame(struct net_device *dev,
13377 const u8 *addr, gfp_t gfp)
b92ab5d8 13378{
947add36
JB
13379 struct wireless_dev *wdev = dev->ieee80211_ptr;
13380 bool ret;
13381
13382 trace_cfg80211_rx_spurious_frame(dev, addr);
13383
13384 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
13385 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
13386 trace_cfg80211_return_bool(false);
13387 return false;
13388 }
13389 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
13390 addr, gfp);
13391 trace_cfg80211_return_bool(ret);
13392 return ret;
b92ab5d8 13393}
947add36 13394EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 13395
947add36
JB
13396bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
13397 const u8 *addr, gfp_t gfp)
b92ab5d8 13398{
947add36
JB
13399 struct wireless_dev *wdev = dev->ieee80211_ptr;
13400 bool ret;
13401
13402 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
13403
13404 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
13405 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
13406 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
13407 trace_cfg80211_return_bool(false);
13408 return false;
13409 }
13410 ret = __nl80211_unexpected_frame(dev,
13411 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
13412 addr, gfp);
13413 trace_cfg80211_return_bool(ret);
13414 return ret;
b92ab5d8 13415}
947add36 13416EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 13417
2e161f78 13418int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 13419 struct wireless_dev *wdev, u32 nlportid,
804483e9 13420 int freq, int sig_dbm,
19504cf5 13421 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 13422{
71bbc994 13423 struct net_device *netdev = wdev->netdev;
026331c4
JM
13424 struct sk_buff *msg;
13425 void *hdr;
026331c4
JM
13426
13427 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13428 if (!msg)
13429 return -ENOMEM;
13430
2e161f78 13431 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
13432 if (!hdr) {
13433 nlmsg_free(msg);
13434 return -ENOMEM;
13435 }
13436
9360ffd1 13437 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13438 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13439 netdev->ifindex)) ||
2dad624e
ND
13440 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13441 NL80211_ATTR_PAD) ||
9360ffd1
DM
13442 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
13443 (sig_dbm &&
13444 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
13445 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
13446 (flags &&
13447 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 13448 goto nla_put_failure;
026331c4 13449
3b7b72ee 13450 genlmsg_end(msg, hdr);
026331c4 13451
15e47304 13452 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
13453
13454 nla_put_failure:
13455 genlmsg_cancel(msg, hdr);
13456 nlmsg_free(msg);
13457 return -ENOBUFS;
13458}
13459
947add36
JB
13460void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
13461 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 13462{
947add36 13463 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13464 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 13465 struct net_device *netdev = wdev->netdev;
026331c4
JM
13466 struct sk_buff *msg;
13467 void *hdr;
13468
947add36
JB
13469 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
13470
026331c4
JM
13471 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13472 if (!msg)
13473 return;
13474
2e161f78 13475 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
13476 if (!hdr) {
13477 nlmsg_free(msg);
13478 return;
13479 }
13480
9360ffd1 13481 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13482 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13483 netdev->ifindex)) ||
2dad624e
ND
13484 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13485 NL80211_ATTR_PAD) ||
9360ffd1 13486 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
13487 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13488 NL80211_ATTR_PAD) ||
9360ffd1
DM
13489 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
13490 goto nla_put_failure;
026331c4 13491
3b7b72ee 13492 genlmsg_end(msg, hdr);
026331c4 13493
68eb5503 13494 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13495 NL80211_MCGRP_MLME, gfp);
026331c4
JM
13496 return;
13497
13498 nla_put_failure:
13499 genlmsg_cancel(msg, hdr);
13500 nlmsg_free(msg);
13501}
947add36 13502EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 13503
5b97f49d
JB
13504static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
13505 const char *mac, gfp_t gfp)
d6dc1a38 13506{
947add36 13507 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
13508 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
13509 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13510 void **cb;
947add36 13511
d6dc1a38 13512 if (!msg)
5b97f49d 13513 return NULL;
d6dc1a38 13514
5b97f49d
JB
13515 cb = (void **)msg->cb;
13516
13517 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
13518 if (!cb[0]) {
d6dc1a38 13519 nlmsg_free(msg);
5b97f49d 13520 return NULL;
d6dc1a38
JO
13521 }
13522
9360ffd1 13523 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 13524 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 13525 goto nla_put_failure;
d6dc1a38 13526
5b97f49d 13527 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
13528 goto nla_put_failure;
13529
5b97f49d
JB
13530 cb[1] = nla_nest_start(msg, NL80211_ATTR_CQM);
13531 if (!cb[1])
9360ffd1 13532 goto nla_put_failure;
d6dc1a38 13533
5b97f49d 13534 cb[2] = rdev;
d6dc1a38 13535
5b97f49d
JB
13536 return msg;
13537 nla_put_failure:
13538 nlmsg_free(msg);
13539 return NULL;
13540}
13541
13542static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
13543{
13544 void **cb = (void **)msg->cb;
13545 struct cfg80211_registered_device *rdev = cb[2];
13546
13547 nla_nest_end(msg, cb[1]);
13548 genlmsg_end(msg, cb[0]);
13549
13550 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 13551
68eb5503 13552 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13553 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
13554}
13555
13556void cfg80211_cqm_rssi_notify(struct net_device *dev,
13557 enum nl80211_cqm_rssi_threshold_event rssi_event,
13558 gfp_t gfp)
13559{
13560 struct sk_buff *msg;
13561
13562 trace_cfg80211_cqm_rssi_notify(dev, rssi_event);
13563
98f03342
JB
13564 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
13565 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
13566 return;
13567
5b97f49d
JB
13568 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
13569 if (!msg)
13570 return;
13571
13572 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
13573 rssi_event))
13574 goto nla_put_failure;
13575
13576 cfg80211_send_cqm(msg, gfp);
13577
d6dc1a38
JO
13578 return;
13579
13580 nla_put_failure:
d6dc1a38
JO
13581 nlmsg_free(msg);
13582}
947add36 13583EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 13584
5b97f49d
JB
13585void cfg80211_cqm_txe_notify(struct net_device *dev,
13586 const u8 *peer, u32 num_packets,
13587 u32 rate, u32 intvl, gfp_t gfp)
13588{
13589 struct sk_buff *msg;
13590
13591 msg = cfg80211_prepare_cqm(dev, peer, gfp);
13592 if (!msg)
13593 return;
13594
13595 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
13596 goto nla_put_failure;
13597
13598 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
13599 goto nla_put_failure;
13600
13601 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
13602 goto nla_put_failure;
13603
13604 cfg80211_send_cqm(msg, gfp);
13605 return;
13606
13607 nla_put_failure:
13608 nlmsg_free(msg);
13609}
13610EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
13611
13612void cfg80211_cqm_pktloss_notify(struct net_device *dev,
13613 const u8 *peer, u32 num_packets, gfp_t gfp)
13614{
13615 struct sk_buff *msg;
13616
13617 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
13618
13619 msg = cfg80211_prepare_cqm(dev, peer, gfp);
13620 if (!msg)
13621 return;
13622
13623 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
13624 goto nla_put_failure;
13625
13626 cfg80211_send_cqm(msg, gfp);
13627 return;
13628
13629 nla_put_failure:
13630 nlmsg_free(msg);
13631}
13632EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
13633
98f03342
JB
13634void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
13635{
13636 struct sk_buff *msg;
13637
13638 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
13639 if (!msg)
13640 return;
13641
13642 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
13643 goto nla_put_failure;
13644
13645 cfg80211_send_cqm(msg, gfp);
13646 return;
13647
13648 nla_put_failure:
13649 nlmsg_free(msg);
13650}
13651EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
13652
947add36
JB
13653static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
13654 struct net_device *netdev, const u8 *bssid,
13655 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
13656{
13657 struct sk_buff *msg;
13658 struct nlattr *rekey_attr;
13659 void *hdr;
13660
58050fce 13661 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
13662 if (!msg)
13663 return;
13664
13665 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
13666 if (!hdr) {
13667 nlmsg_free(msg);
13668 return;
13669 }
13670
9360ffd1
DM
13671 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13672 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13673 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13674 goto nla_put_failure;
e5497d76
JB
13675
13676 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
13677 if (!rekey_attr)
13678 goto nla_put_failure;
13679
9360ffd1
DM
13680 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
13681 NL80211_REPLAY_CTR_LEN, replay_ctr))
13682 goto nla_put_failure;
e5497d76
JB
13683
13684 nla_nest_end(msg, rekey_attr);
13685
3b7b72ee 13686 genlmsg_end(msg, hdr);
e5497d76 13687
68eb5503 13688 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13689 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
13690 return;
13691
13692 nla_put_failure:
13693 genlmsg_cancel(msg, hdr);
13694 nlmsg_free(msg);
13695}
13696
947add36
JB
13697void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
13698 const u8 *replay_ctr, gfp_t gfp)
13699{
13700 struct wireless_dev *wdev = dev->ieee80211_ptr;
13701 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13702 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13703
13704 trace_cfg80211_gtk_rekey_notify(dev, bssid);
13705 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
13706}
13707EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
13708
13709static void
13710nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
13711 struct net_device *netdev, int index,
13712 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
13713{
13714 struct sk_buff *msg;
13715 struct nlattr *attr;
13716 void *hdr;
13717
58050fce 13718 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
13719 if (!msg)
13720 return;
13721
13722 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
13723 if (!hdr) {
13724 nlmsg_free(msg);
13725 return;
13726 }
13727
9360ffd1
DM
13728 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13729 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
13730 goto nla_put_failure;
c9df56b4
JM
13731
13732 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
13733 if (!attr)
13734 goto nla_put_failure;
13735
9360ffd1
DM
13736 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
13737 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
13738 (preauth &&
13739 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
13740 goto nla_put_failure;
c9df56b4
JM
13741
13742 nla_nest_end(msg, attr);
13743
3b7b72ee 13744 genlmsg_end(msg, hdr);
c9df56b4 13745
68eb5503 13746 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13747 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
13748 return;
13749
13750 nla_put_failure:
13751 genlmsg_cancel(msg, hdr);
13752 nlmsg_free(msg);
13753}
13754
947add36
JB
13755void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
13756 const u8 *bssid, bool preauth, gfp_t gfp)
13757{
13758 struct wireless_dev *wdev = dev->ieee80211_ptr;
13759 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13760 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13761
13762 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
13763 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
13764}
13765EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
13766
13767static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
13768 struct net_device *netdev,
13769 struct cfg80211_chan_def *chandef,
f8d7552e
LC
13770 gfp_t gfp,
13771 enum nl80211_commands notif,
13772 u8 count)
5314526b
TP
13773{
13774 struct sk_buff *msg;
13775 void *hdr;
13776
58050fce 13777 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
13778 if (!msg)
13779 return;
13780
f8d7552e 13781 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
13782 if (!hdr) {
13783 nlmsg_free(msg);
13784 return;
13785 }
13786
683b6d3b
JB
13787 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
13788 goto nla_put_failure;
13789
13790 if (nl80211_send_chandef(msg, chandef))
7eab0f64 13791 goto nla_put_failure;
5314526b 13792
f8d7552e
LC
13793 if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
13794 (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
13795 goto nla_put_failure;
13796
5314526b
TP
13797 genlmsg_end(msg, hdr);
13798
68eb5503 13799 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13800 NL80211_MCGRP_MLME, gfp);
5314526b
TP
13801 return;
13802
13803 nla_put_failure:
13804 genlmsg_cancel(msg, hdr);
13805 nlmsg_free(msg);
13806}
13807
947add36
JB
13808void cfg80211_ch_switch_notify(struct net_device *dev,
13809 struct cfg80211_chan_def *chandef)
84f10708 13810{
947add36
JB
13811 struct wireless_dev *wdev = dev->ieee80211_ptr;
13812 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13813 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 13814
e487eaeb 13815 ASSERT_WDEV_LOCK(wdev);
947add36 13816
e487eaeb 13817 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 13818
9e0e2961 13819 wdev->chandef = *chandef;
96f55f12 13820 wdev->preset_chandef = *chandef;
f8d7552e
LC
13821 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
13822 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
947add36
JB
13823}
13824EXPORT_SYMBOL(cfg80211_ch_switch_notify);
13825
f8d7552e
LC
13826void cfg80211_ch_switch_started_notify(struct net_device *dev,
13827 struct cfg80211_chan_def *chandef,
13828 u8 count)
13829{
13830 struct wireless_dev *wdev = dev->ieee80211_ptr;
13831 struct wiphy *wiphy = wdev->wiphy;
13832 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
13833
13834 trace_cfg80211_ch_switch_started_notify(dev, chandef);
13835
13836 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
13837 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
13838}
13839EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
13840
04f39047
SW
13841void
13842nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 13843 const struct cfg80211_chan_def *chandef,
04f39047
SW
13844 enum nl80211_radar_event event,
13845 struct net_device *netdev, gfp_t gfp)
13846{
13847 struct sk_buff *msg;
13848 void *hdr;
13849
13850 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13851 if (!msg)
13852 return;
13853
13854 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
13855 if (!hdr) {
13856 nlmsg_free(msg);
13857 return;
13858 }
13859
13860 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
13861 goto nla_put_failure;
13862
13863 /* NOP and radar events don't need a netdev parameter */
13864 if (netdev) {
13865 struct wireless_dev *wdev = netdev->ieee80211_ptr;
13866
13867 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
13868 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13869 NL80211_ATTR_PAD))
04f39047
SW
13870 goto nla_put_failure;
13871 }
13872
13873 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
13874 goto nla_put_failure;
13875
13876 if (nl80211_send_chandef(msg, chandef))
13877 goto nla_put_failure;
13878
9c90a9f6 13879 genlmsg_end(msg, hdr);
04f39047 13880
68eb5503 13881 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13882 NL80211_MCGRP_MLME, gfp);
04f39047
SW
13883 return;
13884
13885 nla_put_failure:
13886 genlmsg_cancel(msg, hdr);
13887 nlmsg_free(msg);
13888}
13889
7f6cf311
JB
13890void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
13891 u64 cookie, bool acked, gfp_t gfp)
13892{
13893 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13894 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
13895 struct sk_buff *msg;
13896 void *hdr;
7f6cf311 13897
4ee3e063
BL
13898 trace_cfg80211_probe_status(dev, addr, cookie, acked);
13899
58050fce 13900 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 13901
7f6cf311
JB
13902 if (!msg)
13903 return;
13904
13905 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
13906 if (!hdr) {
13907 nlmsg_free(msg);
13908 return;
13909 }
13910
9360ffd1
DM
13911 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13912 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13913 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
13914 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13915 NL80211_ATTR_PAD) ||
9360ffd1
DM
13916 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
13917 goto nla_put_failure;
7f6cf311 13918
9c90a9f6 13919 genlmsg_end(msg, hdr);
7f6cf311 13920
68eb5503 13921 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13922 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
13923 return;
13924
13925 nla_put_failure:
13926 genlmsg_cancel(msg, hdr);
13927 nlmsg_free(msg);
13928}
13929EXPORT_SYMBOL(cfg80211_probe_status);
13930
5e760230
JB
13931void cfg80211_report_obss_beacon(struct wiphy *wiphy,
13932 const u8 *frame, size_t len,
37c73b5f 13933 int freq, int sig_dbm)
5e760230 13934{
f26cbf40 13935 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
13936 struct sk_buff *msg;
13937 void *hdr;
37c73b5f 13938 struct cfg80211_beacon_registration *reg;
5e760230 13939
4ee3e063
BL
13940 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
13941
37c73b5f
BG
13942 spin_lock_bh(&rdev->beacon_registrations_lock);
13943 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
13944 msg = nlmsg_new(len + 100, GFP_ATOMIC);
13945 if (!msg) {
13946 spin_unlock_bh(&rdev->beacon_registrations_lock);
13947 return;
13948 }
5e760230 13949
37c73b5f
BG
13950 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
13951 if (!hdr)
13952 goto nla_put_failure;
5e760230 13953
37c73b5f
BG
13954 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13955 (freq &&
13956 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
13957 (sig_dbm &&
13958 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
13959 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
13960 goto nla_put_failure;
5e760230 13961
37c73b5f 13962 genlmsg_end(msg, hdr);
5e760230 13963
37c73b5f
BG
13964 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
13965 }
13966 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
13967 return;
13968
13969 nla_put_failure:
37c73b5f
BG
13970 spin_unlock_bh(&rdev->beacon_registrations_lock);
13971 if (hdr)
13972 genlmsg_cancel(msg, hdr);
5e760230
JB
13973 nlmsg_free(msg);
13974}
13975EXPORT_SYMBOL(cfg80211_report_obss_beacon);
13976
cd8f7cb4 13977#ifdef CONFIG_PM
8cd4d456
LC
13978static int cfg80211_net_detect_results(struct sk_buff *msg,
13979 struct cfg80211_wowlan_wakeup *wakeup)
13980{
13981 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
13982 struct nlattr *nl_results, *nl_match, *nl_freqs;
13983 int i, j;
13984
13985 nl_results = nla_nest_start(
13986 msg, NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
13987 if (!nl_results)
13988 return -EMSGSIZE;
13989
13990 for (i = 0; i < nd->n_matches; i++) {
13991 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
13992
13993 nl_match = nla_nest_start(msg, i);
13994 if (!nl_match)
13995 break;
13996
13997 /* The SSID attribute is optional in nl80211, but for
13998 * simplicity reasons it's always present in the
13999 * cfg80211 structure. If a driver can't pass the
14000 * SSID, that needs to be changed. A zero length SSID
14001 * is still a valid SSID (wildcard), so it cannot be
14002 * used for this purpose.
14003 */
14004 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
14005 match->ssid.ssid)) {
14006 nla_nest_cancel(msg, nl_match);
14007 goto out;
14008 }
14009
14010 if (match->n_channels) {
14011 nl_freqs = nla_nest_start(
14012 msg, NL80211_ATTR_SCAN_FREQUENCIES);
14013 if (!nl_freqs) {
14014 nla_nest_cancel(msg, nl_match);
14015 goto out;
14016 }
14017
14018 for (j = 0; j < match->n_channels; j++) {
5528fae8 14019 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
14020 nla_nest_cancel(msg, nl_freqs);
14021 nla_nest_cancel(msg, nl_match);
14022 goto out;
14023 }
14024 }
14025
14026 nla_nest_end(msg, nl_freqs);
14027 }
14028
14029 nla_nest_end(msg, nl_match);
14030 }
14031
14032out:
14033 nla_nest_end(msg, nl_results);
14034 return 0;
14035}
14036
cd8f7cb4
JB
14037void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
14038 struct cfg80211_wowlan_wakeup *wakeup,
14039 gfp_t gfp)
14040{
f26cbf40 14041 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
14042 struct sk_buff *msg;
14043 void *hdr;
9c90a9f6 14044 int size = 200;
cd8f7cb4
JB
14045
14046 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
14047
14048 if (wakeup)
14049 size += wakeup->packet_present_len;
14050
14051 msg = nlmsg_new(size, gfp);
14052 if (!msg)
14053 return;
14054
14055 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
14056 if (!hdr)
14057 goto free_msg;
14058
14059 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
14060 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14061 NL80211_ATTR_PAD))
cd8f7cb4
JB
14062 goto free_msg;
14063
14064 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14065 wdev->netdev->ifindex))
14066 goto free_msg;
14067
14068 if (wakeup) {
14069 struct nlattr *reasons;
14070
14071 reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
14072 if (!reasons)
14073 goto free_msg;
cd8f7cb4
JB
14074
14075 if (wakeup->disconnect &&
14076 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
14077 goto free_msg;
14078 if (wakeup->magic_pkt &&
14079 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
14080 goto free_msg;
14081 if (wakeup->gtk_rekey_failure &&
14082 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
14083 goto free_msg;
14084 if (wakeup->eap_identity_req &&
14085 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
14086 goto free_msg;
14087 if (wakeup->four_way_handshake &&
14088 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
14089 goto free_msg;
14090 if (wakeup->rfkill_release &&
14091 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
14092 goto free_msg;
14093
14094 if (wakeup->pattern_idx >= 0 &&
14095 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
14096 wakeup->pattern_idx))
14097 goto free_msg;
14098
ae917c9f
JB
14099 if (wakeup->tcp_match &&
14100 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
14101 goto free_msg;
2a0e047e 14102
ae917c9f
JB
14103 if (wakeup->tcp_connlost &&
14104 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
14105 goto free_msg;
2a0e047e 14106
ae917c9f
JB
14107 if (wakeup->tcp_nomoretokens &&
14108 nla_put_flag(msg,
14109 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
14110 goto free_msg;
2a0e047e 14111
cd8f7cb4
JB
14112 if (wakeup->packet) {
14113 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
14114 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
14115
14116 if (!wakeup->packet_80211) {
14117 pkt_attr =
14118 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
14119 len_attr =
14120 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
14121 }
14122
14123 if (wakeup->packet_len &&
14124 nla_put_u32(msg, len_attr, wakeup->packet_len))
14125 goto free_msg;
14126
14127 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
14128 wakeup->packet))
14129 goto free_msg;
14130 }
14131
8cd4d456
LC
14132 if (wakeup->net_detect &&
14133 cfg80211_net_detect_results(msg, wakeup))
14134 goto free_msg;
14135
cd8f7cb4
JB
14136 nla_nest_end(msg, reasons);
14137 }
14138
9c90a9f6 14139 genlmsg_end(msg, hdr);
cd8f7cb4 14140
68eb5503 14141 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14142 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
14143 return;
14144
14145 free_msg:
14146 nlmsg_free(msg);
14147}
14148EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
14149#endif
14150
3475b094
JM
14151void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
14152 enum nl80211_tdls_operation oper,
14153 u16 reason_code, gfp_t gfp)
14154{
14155 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14156 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
14157 struct sk_buff *msg;
14158 void *hdr;
3475b094
JM
14159
14160 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
14161 reason_code);
14162
14163 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14164 if (!msg)
14165 return;
14166
14167 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
14168 if (!hdr) {
14169 nlmsg_free(msg);
14170 return;
14171 }
14172
14173 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14174 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14175 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
14176 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
14177 (reason_code > 0 &&
14178 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
14179 goto nla_put_failure;
14180
9c90a9f6 14181 genlmsg_end(msg, hdr);
3475b094 14182
68eb5503 14183 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14184 NL80211_MCGRP_MLME, gfp);
3475b094
JM
14185 return;
14186
14187 nla_put_failure:
14188 genlmsg_cancel(msg, hdr);
14189 nlmsg_free(msg);
14190}
14191EXPORT_SYMBOL(cfg80211_tdls_oper_request);
14192
026331c4
JM
14193static int nl80211_netlink_notify(struct notifier_block * nb,
14194 unsigned long state,
14195 void *_notify)
14196{
14197 struct netlink_notify *notify = _notify;
14198 struct cfg80211_registered_device *rdev;
14199 struct wireless_dev *wdev;
37c73b5f 14200 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 14201
8f815cdd 14202 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
14203 return NOTIFY_DONE;
14204
14205 rcu_read_lock();
14206
5e760230 14207 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
78f22b6a 14208 bool schedule_destroy_work = false;
93a1e86c
JR
14209 bool schedule_scan_stop = false;
14210 struct cfg80211_sched_scan_request *sched_scan_req =
14211 rcu_dereference(rdev->sched_scan_req);
14212
14213 if (sched_scan_req && notify->portid &&
14214 sched_scan_req->owner_nlportid == notify->portid)
14215 schedule_scan_stop = true;
78f22b6a 14216
53873f13 14217 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 14218 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 14219
78f22b6a
JB
14220 if (wdev->owner_nlportid == notify->portid)
14221 schedule_destroy_work = true;
14222 }
14223
37c73b5f
BG
14224 spin_lock_bh(&rdev->beacon_registrations_lock);
14225 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
14226 list) {
14227 if (reg->nlportid == notify->portid) {
14228 list_del(&reg->list);
14229 kfree(reg);
14230 break;
14231 }
14232 }
14233 spin_unlock_bh(&rdev->beacon_registrations_lock);
78f22b6a
JB
14234
14235 if (schedule_destroy_work) {
14236 struct cfg80211_iface_destroy *destroy;
14237
14238 destroy = kzalloc(sizeof(*destroy), GFP_ATOMIC);
14239 if (destroy) {
14240 destroy->nlportid = notify->portid;
14241 spin_lock(&rdev->destroy_list_lock);
14242 list_add(&destroy->list, &rdev->destroy_list);
14243 spin_unlock(&rdev->destroy_list_lock);
14244 schedule_work(&rdev->destroy_work);
14245 }
93a1e86c
JR
14246 } else if (schedule_scan_stop) {
14247 sched_scan_req->owner_nlportid = 0;
14248
14249 if (rdev->ops->sched_scan_stop &&
14250 rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
14251 schedule_work(&rdev->sched_scan_stop_wk);
78f22b6a 14252 }
5e760230 14253 }
026331c4
JM
14254
14255 rcu_read_unlock();
14256
05050753
I
14257 /*
14258 * It is possible that the user space process that is controlling the
14259 * indoor setting disappeared, so notify the regulatory core.
14260 */
14261 regulatory_netlink_notify(notify->portid);
6784c7db 14262 return NOTIFY_OK;
026331c4
JM
14263}
14264
14265static struct notifier_block nl80211_netlink_notifier = {
14266 .notifier_call = nl80211_netlink_notify,
14267};
14268
355199e0
JM
14269void cfg80211_ft_event(struct net_device *netdev,
14270 struct cfg80211_ft_event_params *ft_event)
14271{
14272 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 14273 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
14274 struct sk_buff *msg;
14275 void *hdr;
355199e0
JM
14276
14277 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
14278
14279 if (!ft_event->target_ap)
14280 return;
14281
14282 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14283 if (!msg)
14284 return;
14285
14286 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
14287 if (!hdr)
14288 goto out;
355199e0 14289
ae917c9f
JB
14290 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14291 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14292 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
14293 goto out;
355199e0 14294
ae917c9f
JB
14295 if (ft_event->ies &&
14296 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
14297 goto out;
14298 if (ft_event->ric_ies &&
14299 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
14300 ft_event->ric_ies))
14301 goto out;
355199e0 14302
9c90a9f6 14303 genlmsg_end(msg, hdr);
355199e0 14304
68eb5503 14305 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14306 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
14307 return;
14308 out:
14309 nlmsg_free(msg);
355199e0
JM
14310}
14311EXPORT_SYMBOL(cfg80211_ft_event);
14312
5de17984
AS
14313void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
14314{
14315 struct cfg80211_registered_device *rdev;
14316 struct sk_buff *msg;
14317 void *hdr;
14318 u32 nlportid;
14319
f26cbf40 14320 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
14321 if (!rdev->crit_proto_nlportid)
14322 return;
14323
14324 nlportid = rdev->crit_proto_nlportid;
14325 rdev->crit_proto_nlportid = 0;
14326
14327 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14328 if (!msg)
14329 return;
14330
14331 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
14332 if (!hdr)
14333 goto nla_put_failure;
14334
14335 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
14336 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14337 NL80211_ATTR_PAD))
5de17984
AS
14338 goto nla_put_failure;
14339
14340 genlmsg_end(msg, hdr);
14341
14342 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
14343 return;
14344
14345 nla_put_failure:
14346 if (hdr)
14347 genlmsg_cancel(msg, hdr);
14348 nlmsg_free(msg);
5de17984
AS
14349}
14350EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
14351
348baf0e
JB
14352void nl80211_send_ap_stopped(struct wireless_dev *wdev)
14353{
14354 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14355 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
14356 struct sk_buff *msg;
14357 void *hdr;
14358
14359 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14360 if (!msg)
14361 return;
14362
14363 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
14364 if (!hdr)
14365 goto out;
14366
14367 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14368 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
14369 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14370 NL80211_ATTR_PAD))
348baf0e
JB
14371 goto out;
14372
14373 genlmsg_end(msg, hdr);
14374
14375 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
14376 NL80211_MCGRP_MLME, GFP_KERNEL);
14377 return;
14378 out:
14379 nlmsg_free(msg);
14380}
14381
55682965
JB
14382/* initialisation/exit functions */
14383
14384int nl80211_init(void)
14385{
0d63cbb5 14386 int err;
55682965 14387
2a94fe48
JB
14388 err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops,
14389 nl80211_mcgrps);
55682965
JB
14390 if (err)
14391 return err;
14392
026331c4
JM
14393 err = netlink_register_notifier(&nl80211_netlink_notifier);
14394 if (err)
14395 goto err_out;
14396
55682965
JB
14397 return 0;
14398 err_out:
14399 genl_unregister_family(&nl80211_fam);
14400 return err;
14401}
14402
14403void nl80211_exit(void)
14404{
026331c4 14405 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
14406 genl_unregister_family(&nl80211_fam);
14407}