]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - net/wireless/nl80211.c
cfg80211: remove NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL
[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>
55682965
JB
5 */
6
7#include <linux/if.h>
8#include <linux/module.h>
9#include <linux/err.h>
5a0e3ad6 10#include <linux/slab.h>
55682965
JB
11#include <linux/list.h>
12#include <linux/if_ether.h>
13#include <linux/ieee80211.h>
14#include <linux/nl80211.h>
15#include <linux/rtnetlink.h>
16#include <linux/netlink.h>
2a519311 17#include <linux/etherdevice.h>
463d0183 18#include <net/net_namespace.h>
55682965
JB
19#include <net/genetlink.h>
20#include <net/cfg80211.h>
463d0183 21#include <net/sock.h>
2a0e047e 22#include <net/inet_connection_sock.h>
55682965
JB
23#include "core.h"
24#include "nl80211.h"
b2e1b302 25#include "reg.h"
e35e4d28 26#include "rdev-ops.h"
55682965 27
5fb628e9
JM
28static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
29 struct genl_info *info,
30 struct cfg80211_crypto_settings *settings,
31 int cipher_limit);
32
f84f771d 33static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991 34 struct genl_info *info);
f84f771d 35static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
36 struct genl_info *info);
37
55682965
JB
38/* the netlink family */
39static struct genl_family nl80211_fam = {
fb4e1568
MH
40 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
41 .name = NL80211_GENL_NAME, /* have users key off the name instead */
42 .hdrsize = 0, /* no private header */
43 .version = 1, /* no particular meaning now */
55682965 44 .maxattr = NL80211_ATTR_MAX,
463d0183 45 .netnsok = true,
4c476991
JB
46 .pre_doit = nl80211_pre_doit,
47 .post_doit = nl80211_post_doit,
55682965
JB
48};
49
2a94fe48
JB
50/* multicast groups */
51enum nl80211_multicast_groups {
52 NL80211_MCGRP_CONFIG,
53 NL80211_MCGRP_SCAN,
54 NL80211_MCGRP_REGULATORY,
55 NL80211_MCGRP_MLME,
567ffc35 56 NL80211_MCGRP_VENDOR,
2a94fe48
JB
57 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
58};
59
60static const struct genl_multicast_group nl80211_mcgrps[] = {
61 [NL80211_MCGRP_CONFIG] = { .name = "config", },
62 [NL80211_MCGRP_SCAN] = { .name = "scan", },
63 [NL80211_MCGRP_REGULATORY] = { .name = "regulatory", },
64 [NL80211_MCGRP_MLME] = { .name = "mlme", },
567ffc35 65 [NL80211_MCGRP_VENDOR] = { .name = "vendor", },
2a94fe48
JB
66#ifdef CONFIG_NL80211_TESTMODE
67 [NL80211_MCGRP_TESTMODE] = { .name = "testmode", }
68#endif
69};
70
89a54e48
JB
71/* returns ERR_PTR values */
72static struct wireless_dev *
73__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
55682965 74{
89a54e48
JB
75 struct cfg80211_registered_device *rdev;
76 struct wireless_dev *result = NULL;
77 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
78 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
79 u64 wdev_id;
80 int wiphy_idx = -1;
81 int ifidx = -1;
55682965 82
5fe231e8 83 ASSERT_RTNL();
55682965 84
89a54e48
JB
85 if (!have_ifidx && !have_wdev_id)
86 return ERR_PTR(-EINVAL);
55682965 87
89a54e48
JB
88 if (have_ifidx)
89 ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
90 if (have_wdev_id) {
91 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
92 wiphy_idx = wdev_id >> 32;
55682965
JB
93 }
94
89a54e48
JB
95 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
96 struct wireless_dev *wdev;
97
98 if (wiphy_net(&rdev->wiphy) != netns)
99 continue;
100
101 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
102 continue;
103
89a54e48
JB
104 list_for_each_entry(wdev, &rdev->wdev_list, list) {
105 if (have_ifidx && wdev->netdev &&
106 wdev->netdev->ifindex == ifidx) {
107 result = wdev;
108 break;
109 }
110 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
111 result = wdev;
112 break;
113 }
114 }
89a54e48
JB
115
116 if (result)
117 break;
118 }
119
120 if (result)
121 return result;
122 return ERR_PTR(-ENODEV);
55682965
JB
123}
124
a9455408 125static struct cfg80211_registered_device *
878d9ec7 126__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
a9455408 127{
7fee4778
JB
128 struct cfg80211_registered_device *rdev = NULL, *tmp;
129 struct net_device *netdev;
a9455408 130
5fe231e8 131 ASSERT_RTNL();
a9455408 132
878d9ec7 133 if (!attrs[NL80211_ATTR_WIPHY] &&
89a54e48
JB
134 !attrs[NL80211_ATTR_IFINDEX] &&
135 !attrs[NL80211_ATTR_WDEV])
7fee4778
JB
136 return ERR_PTR(-EINVAL);
137
878d9ec7 138 if (attrs[NL80211_ATTR_WIPHY])
7fee4778 139 rdev = cfg80211_rdev_by_wiphy_idx(
878d9ec7 140 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
a9455408 141
89a54e48
JB
142 if (attrs[NL80211_ATTR_WDEV]) {
143 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
144 struct wireless_dev *wdev;
145 bool found = false;
146
147 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
148 if (tmp) {
149 /* make sure wdev exists */
89a54e48
JB
150 list_for_each_entry(wdev, &tmp->wdev_list, list) {
151 if (wdev->identifier != (u32)wdev_id)
152 continue;
153 found = true;
154 break;
155 }
89a54e48
JB
156
157 if (!found)
158 tmp = NULL;
159
160 if (rdev && tmp != rdev)
161 return ERR_PTR(-EINVAL);
162 rdev = tmp;
163 }
164 }
165
878d9ec7
JB
166 if (attrs[NL80211_ATTR_IFINDEX]) {
167 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
7f2b8562 168 netdev = __dev_get_by_index(netns, ifindex);
7fee4778
JB
169 if (netdev) {
170 if (netdev->ieee80211_ptr)
171 tmp = wiphy_to_dev(
172 netdev->ieee80211_ptr->wiphy);
173 else
174 tmp = NULL;
175
7fee4778
JB
176 /* not wireless device -- return error */
177 if (!tmp)
178 return ERR_PTR(-EINVAL);
179
180 /* mismatch -- return error */
181 if (rdev && tmp != rdev)
182 return ERR_PTR(-EINVAL);
183
184 rdev = tmp;
a9455408 185 }
a9455408 186 }
a9455408 187
4f7eff10
JB
188 if (!rdev)
189 return ERR_PTR(-ENODEV);
a9455408 190
4f7eff10
JB
191 if (netns != wiphy_net(&rdev->wiphy))
192 return ERR_PTR(-ENODEV);
193
194 return rdev;
a9455408
JB
195}
196
197/*
198 * This function returns a pointer to the driver
199 * that the genl_info item that is passed refers to.
a9455408
JB
200 *
201 * The result of this can be a PTR_ERR and hence must
202 * be checked with IS_ERR() for errors.
203 */
204static struct cfg80211_registered_device *
4f7eff10 205cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
a9455408 206{
5fe231e8 207 return __cfg80211_rdev_from_attrs(netns, info->attrs);
a9455408
JB
208}
209
55682965 210/* policy for the attributes */
b54452b0 211static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
55682965
JB
212 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
213 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 214 .len = 20-1 },
31888487 215 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 216
72bdcf34 217 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 218 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
3d9d1d66
JB
219 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
220 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
221 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
222
b9a5f8ca
JM
223 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
224 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
225 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
226 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 227 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
55682965
JB
228
229 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
230 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
231 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 232
e007b857
EP
233 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
234 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
41ade00f 235
b9454e83 236 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
237 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
238 .len = WLAN_MAX_KEY_LEN },
239 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
240 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
241 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 242 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
e31b8213 243 [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
ed1b6cc7
JB
244
245 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
246 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
247 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
248 .len = IEEE80211_MAX_DATA_LEN },
249 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
250 .len = IEEE80211_MAX_DATA_LEN },
5727ef1b
JB
251 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
252 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
253 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
254 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
255 .len = NL80211_MAX_SUPP_RATES },
2ec600d6 256 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
5727ef1b 257 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 258 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 259 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 260 .len = IEEE80211_MAX_MESH_ID_LEN },
2ec600d6 261 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
9f1ba906 262
b2e1b302
LR
263 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
264 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
265
9f1ba906
JM
266 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
267 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
268 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
269 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
270 .len = NL80211_MAX_SUPP_RATES },
50b12f59 271 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 272
24bdd9f4 273 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 274 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 275
6c739419 276 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
9aed3cc1
JM
277
278 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
279 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
280 .len = IEEE80211_MAX_DATA_LEN },
2a519311
JB
281 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
282 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
283
284 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
285 .len = IEEE80211_MAX_SSID_LEN },
286 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
287 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 288 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 289 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
dc6382ce 290 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
eccb8e8f
JB
291 [NL80211_ATTR_STA_FLAGS2] = {
292 .len = sizeof(struct nl80211_sta_flag_update),
293 },
3f77316c 294 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
295 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
296 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
b23aa676
SO
297 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
298 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
299 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 300 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 301 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
67fbb16b
SO
302 [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
303 .len = WLAN_PMKID_LEN },
9588bbd5
JM
304 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
305 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 306 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
307 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
308 .len = IEEE80211_MAX_DATA_LEN },
309 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ffb9eb3d 310 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
d6dc1a38 311 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 312 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 313 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
314 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
315 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 316 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
317 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
318 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 319 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 320 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 321 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 322 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
9c3990aa 323 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
bbe6ad6d 324 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 325 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 326 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
32e9de84 327 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
9946ecfb
JM
328 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
329 .len = IEEE80211_MAX_DATA_LEN },
330 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
331 .len = IEEE80211_MAX_DATA_LEN },
f4b34b55 332 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 333 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 334 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
335 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
336 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
337 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
338 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
339 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
e247bd90 340 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
341 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
342 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 343 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
344 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
345 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
346 .len = NL80211_HT_CAPABILITY_LEN
347 },
1d9d9213 348 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 349 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 350 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 351 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 352 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
e39e5b5e 353 [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, },
f461be3e 354 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
ed473771 355 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
53cabad7
JB
356 [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
357 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
77765eaf
VT
358 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
359 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
360 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
361 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 362 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
363 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
364 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
365 .len = NL80211_VHT_CAPABILITY_LEN,
366 },
355199e0
JM
367 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
368 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
369 .len = IEEE80211_MAX_DATA_LEN },
5e4b6f56 370 [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
16ef1fe2
SW
371 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
372 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
373 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
374 [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 },
375 [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 },
c01fc9ad
SD
376 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
377 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
5336fa88 378 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 379 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
380 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
381 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
382 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
fa9ffc74
KP
383 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
384 .len = IEEE80211_QOS_MAP_LEN_MAX },
1df4a510
JM
385 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
386 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
55682965
JB
387};
388
e31b8213 389/* policy for the key attributes */
b54452b0 390static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 391 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
392 [NL80211_KEY_IDX] = { .type = NLA_U8 },
393 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 394 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
395 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
396 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
e31b8213 397 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
dbd2fd65
JB
398 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
399};
400
401/* policy for the key default flags */
402static const struct nla_policy
403nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
404 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
405 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
406};
407
ff1b6e69
JB
408/* policy for WoWLAN attributes */
409static const struct nla_policy
410nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
411 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
412 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
413 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
414 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
415 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
416 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
417 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
418 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e
JB
419 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
420};
421
422static const struct nla_policy
423nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
424 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
425 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
426 [NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
427 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
428 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
429 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
430 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
431 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
432 },
433 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
434 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
435 },
436 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
437 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
438 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
ff1b6e69
JB
439};
440
be29b99a
AK
441/* policy for coalesce rule attributes */
442static const struct nla_policy
443nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
444 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
445 [NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U32 },
446 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
447};
448
e5497d76
JB
449/* policy for GTK rekey offload attributes */
450static const struct nla_policy
451nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
452 [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
453 [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
454 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
455};
456
a1f1c21c
LC
457static const struct nla_policy
458nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 459 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 460 .len = IEEE80211_MAX_SSID_LEN },
88e920b4 461 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
a1f1c21c
LC
462};
463
97990a06
JB
464static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
465 struct netlink_callback *cb,
466 struct cfg80211_registered_device **rdev,
467 struct wireless_dev **wdev)
a043897a 468{
97990a06 469 int err;
a043897a 470
97990a06 471 rtnl_lock();
a043897a 472
97990a06
JB
473 if (!cb->args[0]) {
474 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
475 nl80211_fam.attrbuf, nl80211_fam.maxattr,
476 nl80211_policy);
477 if (err)
478 goto out_unlock;
67748893 479
97990a06
JB
480 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
481 nl80211_fam.attrbuf);
482 if (IS_ERR(*wdev)) {
483 err = PTR_ERR(*wdev);
484 goto out_unlock;
485 }
486 *rdev = wiphy_to_dev((*wdev)->wiphy);
c319d50b
JB
487 /* 0 is the first index - add 1 to parse only once */
488 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
489 cb->args[1] = (*wdev)->identifier;
490 } else {
c319d50b
JB
491 /* subtract the 1 again here */
492 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
97990a06 493 struct wireless_dev *tmp;
67748893 494
97990a06
JB
495 if (!wiphy) {
496 err = -ENODEV;
497 goto out_unlock;
498 }
499 *rdev = wiphy_to_dev(wiphy);
500 *wdev = NULL;
67748893 501
97990a06
JB
502 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
503 if (tmp->identifier == cb->args[1]) {
504 *wdev = tmp;
505 break;
506 }
507 }
67748893 508
97990a06
JB
509 if (!*wdev) {
510 err = -ENODEV;
511 goto out_unlock;
512 }
67748893
JB
513 }
514
67748893 515 return 0;
97990a06 516 out_unlock:
67748893
JB
517 rtnl_unlock();
518 return err;
519}
520
97990a06 521static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
67748893 522{
67748893
JB
523 rtnl_unlock();
524}
525
f4a11bb0
JB
526/* IE validation */
527static bool is_valid_ie_attr(const struct nlattr *attr)
528{
529 const u8 *pos;
530 int len;
531
532 if (!attr)
533 return true;
534
535 pos = nla_data(attr);
536 len = nla_len(attr);
537
538 while (len) {
539 u8 elemlen;
540
541 if (len < 2)
542 return false;
543 len -= 2;
544
545 elemlen = pos[1];
546 if (elemlen > len)
547 return false;
548
549 len -= elemlen;
550 pos += 2 + elemlen;
551 }
552
553 return true;
554}
555
55682965 556/* message building helper */
15e47304 557static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
55682965
JB
558 int flags, u8 cmd)
559{
560 /* since there is no private header just add the generic one */
15e47304 561 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
562}
563
5dab3b8a 564static int nl80211_msg_put_channel(struct sk_buff *msg,
cdc89b97
JB
565 struct ieee80211_channel *chan,
566 bool large)
5dab3b8a 567{
9360ffd1
DM
568 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
569 chan->center_freq))
570 goto nla_put_failure;
5dab3b8a 571
9360ffd1
DM
572 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
573 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
574 goto nla_put_failure;
8fe02e16
LR
575 if (chan->flags & IEEE80211_CHAN_NO_IR) {
576 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
577 goto nla_put_failure;
578 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
579 goto nla_put_failure;
580 }
cdc89b97
JB
581 if (chan->flags & IEEE80211_CHAN_RADAR) {
582 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
583 goto nla_put_failure;
584 if (large) {
585 u32 time;
586
587 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
588
589 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
590 chan->dfs_state))
591 goto nla_put_failure;
592 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
593 time))
594 goto nla_put_failure;
595 }
596 }
5dab3b8a 597
fe1abafd
JB
598 if (large) {
599 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
600 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
601 goto nla_put_failure;
602 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
603 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
604 goto nla_put_failure;
605 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
606 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
607 goto nla_put_failure;
608 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
609 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
610 goto nla_put_failure;
611 }
612
9360ffd1
DM
613 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
614 DBM_TO_MBM(chan->max_power)))
615 goto nla_put_failure;
5dab3b8a
LR
616
617 return 0;
618
619 nla_put_failure:
620 return -ENOBUFS;
621}
622
55682965
JB
623/* netlink command implementations */
624
b9454e83
JB
625struct key_parse {
626 struct key_params p;
627 int idx;
e31b8213 628 int type;
b9454e83 629 bool def, defmgmt;
dbd2fd65 630 bool def_uni, def_multi;
b9454e83
JB
631};
632
633static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
634{
635 struct nlattr *tb[NL80211_KEY_MAX + 1];
636 int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
637 nl80211_key_policy);
638 if (err)
639 return err;
640
641 k->def = !!tb[NL80211_KEY_DEFAULT];
642 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
643
dbd2fd65
JB
644 if (k->def) {
645 k->def_uni = true;
646 k->def_multi = true;
647 }
648 if (k->defmgmt)
649 k->def_multi = true;
650
b9454e83
JB
651 if (tb[NL80211_KEY_IDX])
652 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
653
654 if (tb[NL80211_KEY_DATA]) {
655 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
656 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
657 }
658
659 if (tb[NL80211_KEY_SEQ]) {
660 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
661 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
662 }
663
664 if (tb[NL80211_KEY_CIPHER])
665 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
666
e31b8213
JB
667 if (tb[NL80211_KEY_TYPE]) {
668 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
669 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
670 return -EINVAL;
671 }
672
dbd2fd65
JB
673 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
674 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
2da8f419
JB
675 err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
676 tb[NL80211_KEY_DEFAULT_TYPES],
677 nl80211_key_default_policy);
dbd2fd65
JB
678 if (err)
679 return err;
680
681 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
682 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
683 }
684
b9454e83
JB
685 return 0;
686}
687
688static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
689{
690 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
691 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
692 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
693 }
694
695 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
696 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
697 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
698 }
699
700 if (info->attrs[NL80211_ATTR_KEY_IDX])
701 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
702
703 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
704 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
705
706 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
707 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
708
dbd2fd65
JB
709 if (k->def) {
710 k->def_uni = true;
711 k->def_multi = true;
712 }
713 if (k->defmgmt)
714 k->def_multi = true;
715
e31b8213
JB
716 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
717 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
718 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
719 return -EINVAL;
720 }
721
dbd2fd65
JB
722 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
723 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
724 int err = nla_parse_nested(
725 kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
726 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
727 nl80211_key_default_policy);
728 if (err)
729 return err;
730
731 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
732 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
733 }
734
b9454e83
JB
735 return 0;
736}
737
738static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
739{
740 int err;
741
742 memset(k, 0, sizeof(*k));
743 k->idx = -1;
e31b8213 744 k->type = -1;
b9454e83
JB
745
746 if (info->attrs[NL80211_ATTR_KEY])
747 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
748 else
749 err = nl80211_parse_key_old(info, k);
750
751 if (err)
752 return err;
753
754 if (k->def && k->defmgmt)
755 return -EINVAL;
756
dbd2fd65
JB
757 if (k->defmgmt) {
758 if (k->def_uni || !k->def_multi)
759 return -EINVAL;
760 }
761
b9454e83
JB
762 if (k->idx != -1) {
763 if (k->defmgmt) {
764 if (k->idx < 4 || k->idx > 5)
765 return -EINVAL;
766 } else if (k->def) {
767 if (k->idx < 0 || k->idx > 3)
768 return -EINVAL;
769 } else {
770 if (k->idx < 0 || k->idx > 5)
771 return -EINVAL;
772 }
773 }
774
775 return 0;
776}
777
fffd0934
JB
778static struct cfg80211_cached_keys *
779nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
de7044ee 780 struct nlattr *keys, bool *no_ht)
fffd0934
JB
781{
782 struct key_parse parse;
783 struct nlattr *key;
784 struct cfg80211_cached_keys *result;
785 int rem, err, def = 0;
786
787 result = kzalloc(sizeof(*result), GFP_KERNEL);
788 if (!result)
789 return ERR_PTR(-ENOMEM);
790
791 result->def = -1;
792 result->defmgmt = -1;
793
794 nla_for_each_nested(key, keys, rem) {
795 memset(&parse, 0, sizeof(parse));
796 parse.idx = -1;
797
798 err = nl80211_parse_key_new(key, &parse);
799 if (err)
800 goto error;
801 err = -EINVAL;
802 if (!parse.p.key)
803 goto error;
804 if (parse.idx < 0 || parse.idx > 4)
805 goto error;
806 if (parse.def) {
807 if (def)
808 goto error;
809 def = 1;
810 result->def = parse.idx;
dbd2fd65
JB
811 if (!parse.def_uni || !parse.def_multi)
812 goto error;
fffd0934
JB
813 } else if (parse.defmgmt)
814 goto error;
815 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 816 parse.idx, false, NULL);
fffd0934
JB
817 if (err)
818 goto error;
819 result->params[parse.idx].cipher = parse.p.cipher;
820 result->params[parse.idx].key_len = parse.p.key_len;
821 result->params[parse.idx].key = result->data[parse.idx];
822 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee
SM
823
824 if (parse.p.cipher == WLAN_CIPHER_SUITE_WEP40 ||
825 parse.p.cipher == WLAN_CIPHER_SUITE_WEP104) {
826 if (no_ht)
827 *no_ht = true;
828 }
fffd0934
JB
829 }
830
831 return result;
832 error:
833 kfree(result);
834 return ERR_PTR(err);
835}
836
837static int nl80211_key_allowed(struct wireless_dev *wdev)
838{
839 ASSERT_WDEV_LOCK(wdev);
840
fffd0934
JB
841 switch (wdev->iftype) {
842 case NL80211_IFTYPE_AP:
843 case NL80211_IFTYPE_AP_VLAN:
074ac8df 844 case NL80211_IFTYPE_P2P_GO:
ff973af7 845 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
846 break;
847 case NL80211_IFTYPE_ADHOC:
fffd0934 848 case NL80211_IFTYPE_STATION:
074ac8df 849 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 850 if (!wdev->current_bss)
fffd0934
JB
851 return -ENOLINK;
852 break;
853 default:
854 return -EINVAL;
855 }
856
857 return 0;
858}
859
664834de
JM
860static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
861 struct nlattr *tb)
862{
863 struct ieee80211_channel *chan;
864
865 if (tb == NULL)
866 return NULL;
867 chan = ieee80211_get_channel(wiphy, nla_get_u32(tb));
868 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
869 return NULL;
870 return chan;
871}
872
7527a782
JB
873static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
874{
875 struct nlattr *nl_modes = nla_nest_start(msg, attr);
876 int i;
877
878 if (!nl_modes)
879 goto nla_put_failure;
880
881 i = 0;
882 while (ifmodes) {
9360ffd1
DM
883 if ((ifmodes & 1) && nla_put_flag(msg, i))
884 goto nla_put_failure;
7527a782
JB
885 ifmodes >>= 1;
886 i++;
887 }
888
889 nla_nest_end(msg, nl_modes);
890 return 0;
891
892nla_put_failure:
893 return -ENOBUFS;
894}
895
896static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
897 struct sk_buff *msg,
898 bool large)
7527a782
JB
899{
900 struct nlattr *nl_combis;
901 int i, j;
902
903 nl_combis = nla_nest_start(msg,
904 NL80211_ATTR_INTERFACE_COMBINATIONS);
905 if (!nl_combis)
906 goto nla_put_failure;
907
908 for (i = 0; i < wiphy->n_iface_combinations; i++) {
909 const struct ieee80211_iface_combination *c;
910 struct nlattr *nl_combi, *nl_limits;
911
912 c = &wiphy->iface_combinations[i];
913
914 nl_combi = nla_nest_start(msg, i + 1);
915 if (!nl_combi)
916 goto nla_put_failure;
917
918 nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
919 if (!nl_limits)
920 goto nla_put_failure;
921
922 for (j = 0; j < c->n_limits; j++) {
923 struct nlattr *nl_limit;
924
925 nl_limit = nla_nest_start(msg, j + 1);
926 if (!nl_limit)
927 goto nla_put_failure;
9360ffd1
DM
928 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
929 c->limits[j].max))
930 goto nla_put_failure;
7527a782
JB
931 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
932 c->limits[j].types))
933 goto nla_put_failure;
934 nla_nest_end(msg, nl_limit);
935 }
936
937 nla_nest_end(msg, nl_limits);
938
9360ffd1
DM
939 if (c->beacon_int_infra_match &&
940 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
941 goto nla_put_failure;
942 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
943 c->num_different_channels) ||
944 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
945 c->max_interfaces))
946 goto nla_put_failure;
cdc89b97
JB
947 if (large &&
948 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
949 c->radar_detect_widths))
950 goto nla_put_failure;
7527a782
JB
951
952 nla_nest_end(msg, nl_combi);
953 }
954
955 nla_nest_end(msg, nl_combis);
956
957 return 0;
958nla_put_failure:
959 return -ENOBUFS;
960}
961
3713b4e3 962#ifdef CONFIG_PM
b56cf720
JB
963static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
964 struct sk_buff *msg)
965{
964dc9e2 966 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
967 struct nlattr *nl_tcp;
968
969 if (!tcp)
970 return 0;
971
972 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
973 if (!nl_tcp)
974 return -ENOBUFS;
975
976 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
977 tcp->data_payload_max))
978 return -ENOBUFS;
979
980 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
981 tcp->data_payload_max))
982 return -ENOBUFS;
983
984 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
985 return -ENOBUFS;
986
987 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
988 sizeof(*tcp->tok), tcp->tok))
989 return -ENOBUFS;
990
991 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
992 tcp->data_interval_max))
993 return -ENOBUFS;
994
995 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
996 tcp->wake_payload_max))
997 return -ENOBUFS;
998
999 nla_nest_end(msg, nl_tcp);
1000 return 0;
1001}
1002
3713b4e3 1003static int nl80211_send_wowlan(struct sk_buff *msg,
b56cf720
JB
1004 struct cfg80211_registered_device *dev,
1005 bool large)
55682965 1006{
3713b4e3 1007 struct nlattr *nl_wowlan;
55682965 1008
964dc9e2 1009 if (!dev->wiphy.wowlan)
3713b4e3 1010 return 0;
55682965 1011
3713b4e3
JB
1012 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
1013 if (!nl_wowlan)
1014 return -ENOBUFS;
9360ffd1 1015
964dc9e2 1016 if (((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1017 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
964dc9e2 1018 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1019 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
964dc9e2 1020 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1021 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
964dc9e2 1022 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1023 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
964dc9e2 1024 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1025 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
964dc9e2 1026 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1027 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
964dc9e2 1028 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1029 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
964dc9e2 1030 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1031 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1032 return -ENOBUFS;
9360ffd1 1033
964dc9e2 1034 if (dev->wiphy.wowlan->n_patterns) {
50ac6607 1035 struct nl80211_pattern_support pat = {
964dc9e2
JB
1036 .max_patterns = dev->wiphy.wowlan->n_patterns,
1037 .min_pattern_len = dev->wiphy.wowlan->pattern_min_len,
1038 .max_pattern_len = dev->wiphy.wowlan->pattern_max_len,
1039 .max_pkt_offset = dev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1040 };
9360ffd1 1041
3713b4e3
JB
1042 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1043 sizeof(pat), &pat))
1044 return -ENOBUFS;
1045 }
9360ffd1 1046
b56cf720
JB
1047 if (large && nl80211_send_wowlan_tcp_caps(dev, msg))
1048 return -ENOBUFS;
1049
3713b4e3 1050 nla_nest_end(msg, nl_wowlan);
9360ffd1 1051
3713b4e3
JB
1052 return 0;
1053}
1054#endif
9360ffd1 1055
be29b99a
AK
1056static int nl80211_send_coalesce(struct sk_buff *msg,
1057 struct cfg80211_registered_device *dev)
1058{
1059 struct nl80211_coalesce_rule_support rule;
1060
1061 if (!dev->wiphy.coalesce)
1062 return 0;
1063
1064 rule.max_rules = dev->wiphy.coalesce->n_rules;
1065 rule.max_delay = dev->wiphy.coalesce->max_delay;
1066 rule.pat.max_patterns = dev->wiphy.coalesce->n_patterns;
1067 rule.pat.min_pattern_len = dev->wiphy.coalesce->pattern_min_len;
1068 rule.pat.max_pattern_len = dev->wiphy.coalesce->pattern_max_len;
1069 rule.pat.max_pkt_offset = dev->wiphy.coalesce->max_pkt_offset;
1070
1071 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1072 return -ENOBUFS;
1073
1074 return 0;
1075}
1076
3713b4e3
JB
1077static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1078 struct ieee80211_supported_band *sband)
1079{
1080 struct nlattr *nl_rates, *nl_rate;
1081 struct ieee80211_rate *rate;
1082 int i;
87bbbe22 1083
3713b4e3
JB
1084 /* add HT info */
1085 if (sband->ht_cap.ht_supported &&
1086 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1087 sizeof(sband->ht_cap.mcs),
1088 &sband->ht_cap.mcs) ||
1089 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1090 sband->ht_cap.cap) ||
1091 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1092 sband->ht_cap.ampdu_factor) ||
1093 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1094 sband->ht_cap.ampdu_density)))
1095 return -ENOBUFS;
afe0cbf8 1096
3713b4e3
JB
1097 /* add VHT info */
1098 if (sband->vht_cap.vht_supported &&
1099 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1100 sizeof(sband->vht_cap.vht_mcs),
1101 &sband->vht_cap.vht_mcs) ||
1102 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1103 sband->vht_cap.cap)))
1104 return -ENOBUFS;
f59ac048 1105
3713b4e3
JB
1106 /* add bitrates */
1107 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
1108 if (!nl_rates)
1109 return -ENOBUFS;
ee688b00 1110
3713b4e3
JB
1111 for (i = 0; i < sband->n_bitrates; i++) {
1112 nl_rate = nla_nest_start(msg, i);
1113 if (!nl_rate)
1114 return -ENOBUFS;
ee688b00 1115
3713b4e3
JB
1116 rate = &sband->bitrates[i];
1117 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1118 rate->bitrate))
1119 return -ENOBUFS;
1120 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1121 nla_put_flag(msg,
1122 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1123 return -ENOBUFS;
ee688b00 1124
3713b4e3
JB
1125 nla_nest_end(msg, nl_rate);
1126 }
d51626df 1127
3713b4e3 1128 nla_nest_end(msg, nl_rates);
bf0c111e 1129
3713b4e3
JB
1130 return 0;
1131}
ee688b00 1132
3713b4e3
JB
1133static int
1134nl80211_send_mgmt_stypes(struct sk_buff *msg,
1135 const struct ieee80211_txrx_stypes *mgmt_stypes)
1136{
1137 u16 stypes;
1138 struct nlattr *nl_ftypes, *nl_ifs;
1139 enum nl80211_iftype ift;
1140 int i;
ee688b00 1141
3713b4e3
JB
1142 if (!mgmt_stypes)
1143 return 0;
5dab3b8a 1144
3713b4e3
JB
1145 nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES);
1146 if (!nl_ifs)
1147 return -ENOBUFS;
e2f367f2 1148
3713b4e3
JB
1149 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1150 nl_ftypes = nla_nest_start(msg, ift);
1151 if (!nl_ftypes)
1152 return -ENOBUFS;
1153 i = 0;
1154 stypes = mgmt_stypes[ift].tx;
1155 while (stypes) {
1156 if ((stypes & 1) &&
1157 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1158 (i << 4) | IEEE80211_FTYPE_MGMT))
1159 return -ENOBUFS;
1160 stypes >>= 1;
1161 i++;
ee688b00 1162 }
3713b4e3
JB
1163 nla_nest_end(msg, nl_ftypes);
1164 }
ee688b00 1165
3713b4e3 1166 nla_nest_end(msg, nl_ifs);
ee688b00 1167
3713b4e3
JB
1168 nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES);
1169 if (!nl_ifs)
1170 return -ENOBUFS;
ee688b00 1171
3713b4e3
JB
1172 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1173 nl_ftypes = nla_nest_start(msg, ift);
1174 if (!nl_ftypes)
1175 return -ENOBUFS;
1176 i = 0;
1177 stypes = mgmt_stypes[ift].rx;
1178 while (stypes) {
1179 if ((stypes & 1) &&
1180 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1181 (i << 4) | IEEE80211_FTYPE_MGMT))
1182 return -ENOBUFS;
1183 stypes >>= 1;
1184 i++;
1185 }
1186 nla_nest_end(msg, nl_ftypes);
1187 }
1188 nla_nest_end(msg, nl_ifs);
ee688b00 1189
3713b4e3
JB
1190 return 0;
1191}
ee688b00 1192
86e8cf98
JB
1193struct nl80211_dump_wiphy_state {
1194 s64 filter_wiphy;
1195 long start;
1196 long split_start, band_start, chan_start;
1197 bool split;
1198};
1199
3713b4e3
JB
1200static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1201 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 1202 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
1203{
1204 void *hdr;
1205 struct nlattr *nl_bands, *nl_band;
1206 struct nlattr *nl_freqs, *nl_freq;
1207 struct nlattr *nl_cmds;
1208 enum ieee80211_band band;
1209 struct ieee80211_channel *chan;
1210 int i;
1211 const struct ieee80211_txrx_stypes *mgmt_stypes =
1212 dev->wiphy.mgmt_stypes;
fe1abafd 1213 u32 features;
ee688b00 1214
3713b4e3
JB
1215 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY);
1216 if (!hdr)
1217 return -ENOBUFS;
ee688b00 1218
86e8cf98
JB
1219 if (WARN_ON(!state))
1220 return -EINVAL;
ee688b00 1221
3713b4e3
JB
1222 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) ||
1223 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1224 wiphy_name(&dev->wiphy)) ||
1225 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1226 cfg80211_rdev_list_generation))
8fdc621d
JB
1227 goto nla_put_failure;
1228
86e8cf98 1229 switch (state->split_start) {
3713b4e3
JB
1230 case 0:
1231 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1232 dev->wiphy.retry_short) ||
1233 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1234 dev->wiphy.retry_long) ||
1235 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1236 dev->wiphy.frag_threshold) ||
1237 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1238 dev->wiphy.rts_threshold) ||
1239 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1240 dev->wiphy.coverage_class) ||
1241 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1242 dev->wiphy.max_scan_ssids) ||
1243 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1244 dev->wiphy.max_sched_scan_ssids) ||
1245 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1246 dev->wiphy.max_scan_ie_len) ||
1247 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1248 dev->wiphy.max_sched_scan_ie_len) ||
1249 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
1250 dev->wiphy.max_match_sets))
9360ffd1 1251 goto nla_put_failure;
3713b4e3
JB
1252
1253 if ((dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
1254 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 1255 goto nla_put_failure;
3713b4e3
JB
1256 if ((dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
1257 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
1258 goto nla_put_failure;
1259 if ((dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
1260 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
1261 goto nla_put_failure;
1262 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
1263 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
1264 goto nla_put_failure;
1265 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
1266 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
1267 goto nla_put_failure;
1268 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
1269 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 1270 goto nla_put_failure;
86e8cf98
JB
1271 state->split_start++;
1272 if (state->split)
3713b4e3
JB
1273 break;
1274 case 1:
1275 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1276 sizeof(u32) * dev->wiphy.n_cipher_suites,
1277 dev->wiphy.cipher_suites))
1278 goto nla_put_failure;
4745fc09 1279
3713b4e3
JB
1280 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1281 dev->wiphy.max_num_pmkids))
1282 goto nla_put_failure;
b23aa676 1283
3713b4e3
JB
1284 if ((dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
1285 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 1286 goto nla_put_failure;
b23aa676 1287
3713b4e3
JB
1288 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1289 dev->wiphy.available_antennas_tx) ||
1290 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1291 dev->wiphy.available_antennas_rx))
9360ffd1 1292 goto nla_put_failure;
b23aa676 1293
3713b4e3
JB
1294 if ((dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
1295 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1296 dev->wiphy.probe_resp_offload))
1297 goto nla_put_failure;
8fdc621d 1298
3713b4e3
JB
1299 if ((dev->wiphy.available_antennas_tx ||
1300 dev->wiphy.available_antennas_rx) &&
1301 dev->ops->get_antenna) {
1302 u32 tx_ant = 0, rx_ant = 0;
1303 int res;
1304 res = rdev_get_antenna(dev, &tx_ant, &rx_ant);
1305 if (!res) {
1306 if (nla_put_u32(msg,
1307 NL80211_ATTR_WIPHY_ANTENNA_TX,
1308 tx_ant) ||
1309 nla_put_u32(msg,
1310 NL80211_ATTR_WIPHY_ANTENNA_RX,
1311 rx_ant))
1312 goto nla_put_failure;
1313 }
1314 }
a293911d 1315
86e8cf98
JB
1316 state->split_start++;
1317 if (state->split)
3713b4e3
JB
1318 break;
1319 case 2:
1320 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1321 dev->wiphy.interface_modes))
1322 goto nla_put_failure;
86e8cf98
JB
1323 state->split_start++;
1324 if (state->split)
3713b4e3
JB
1325 break;
1326 case 3:
1327 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1328 if (!nl_bands)
1329 goto nla_put_failure;
f7ca38df 1330
86e8cf98
JB
1331 for (band = state->band_start;
1332 band < IEEE80211_NUM_BANDS; band++) {
3713b4e3 1333 struct ieee80211_supported_band *sband;
2e161f78 1334
3713b4e3 1335 sband = dev->wiphy.bands[band];
2e161f78 1336
3713b4e3
JB
1337 if (!sband)
1338 continue;
1339
1340 nl_band = nla_nest_start(msg, band);
1341 if (!nl_band)
2e161f78 1342 goto nla_put_failure;
3713b4e3 1343
86e8cf98 1344 switch (state->chan_start) {
3713b4e3
JB
1345 case 0:
1346 if (nl80211_send_band_rateinfo(msg, sband))
9360ffd1 1347 goto nla_put_failure;
86e8cf98
JB
1348 state->chan_start++;
1349 if (state->split)
3713b4e3
JB
1350 break;
1351 default:
1352 /* add frequencies */
1353 nl_freqs = nla_nest_start(
1354 msg, NL80211_BAND_ATTR_FREQS);
1355 if (!nl_freqs)
1356 goto nla_put_failure;
1357
86e8cf98 1358 for (i = state->chan_start - 1;
3713b4e3
JB
1359 i < sband->n_channels;
1360 i++) {
1361 nl_freq = nla_nest_start(msg, i);
1362 if (!nl_freq)
1363 goto nla_put_failure;
1364
1365 chan = &sband->channels[i];
1366
86e8cf98
JB
1367 if (nl80211_msg_put_channel(
1368 msg, chan,
1369 state->split))
3713b4e3
JB
1370 goto nla_put_failure;
1371
1372 nla_nest_end(msg, nl_freq);
86e8cf98 1373 if (state->split)
3713b4e3
JB
1374 break;
1375 }
1376 if (i < sband->n_channels)
86e8cf98 1377 state->chan_start = i + 2;
3713b4e3 1378 else
86e8cf98 1379 state->chan_start = 0;
3713b4e3
JB
1380 nla_nest_end(msg, nl_freqs);
1381 }
1382
1383 nla_nest_end(msg, nl_band);
1384
86e8cf98 1385 if (state->split) {
3713b4e3 1386 /* start again here */
86e8cf98 1387 if (state->chan_start)
3713b4e3
JB
1388 band--;
1389 break;
2e161f78 1390 }
2e161f78 1391 }
3713b4e3 1392 nla_nest_end(msg, nl_bands);
2e161f78 1393
3713b4e3 1394 if (band < IEEE80211_NUM_BANDS)
86e8cf98 1395 state->band_start = band + 1;
3713b4e3 1396 else
86e8cf98 1397 state->band_start = 0;
74b70a4e 1398
3713b4e3 1399 /* if bands & channels are done, continue outside */
86e8cf98
JB
1400 if (state->band_start == 0 && state->chan_start == 0)
1401 state->split_start++;
1402 if (state->split)
3713b4e3
JB
1403 break;
1404 case 4:
1405 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
1406 if (!nl_cmds)
2e161f78
JB
1407 goto nla_put_failure;
1408
3713b4e3
JB
1409 i = 0;
1410#define CMD(op, n) \
1411 do { \
1412 if (dev->ops->op) { \
1413 i++; \
1414 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1415 goto nla_put_failure; \
1416 } \
1417 } while (0)
1418
1419 CMD(add_virtual_intf, NEW_INTERFACE);
1420 CMD(change_virtual_intf, SET_INTERFACE);
1421 CMD(add_key, NEW_KEY);
1422 CMD(start_ap, START_AP);
1423 CMD(add_station, NEW_STATION);
1424 CMD(add_mpath, NEW_MPATH);
1425 CMD(update_mesh_config, SET_MESH_CONFIG);
1426 CMD(change_bss, SET_BSS);
1427 CMD(auth, AUTHENTICATE);
1428 CMD(assoc, ASSOCIATE);
1429 CMD(deauth, DEAUTHENTICATE);
1430 CMD(disassoc, DISASSOCIATE);
1431 CMD(join_ibss, JOIN_IBSS);
1432 CMD(join_mesh, JOIN_MESH);
1433 CMD(set_pmksa, SET_PMKSA);
1434 CMD(del_pmksa, DEL_PMKSA);
1435 CMD(flush_pmksa, FLUSH_PMKSA);
1436 if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1437 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1438 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1439 CMD(mgmt_tx, FRAME);
1440 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1441 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1442 i++;
1443 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
2e161f78 1444 goto nla_put_failure;
2e161f78 1445 }
3713b4e3
JB
1446 if (dev->ops->set_monitor_channel || dev->ops->start_ap ||
1447 dev->ops->join_mesh) {
1448 i++;
1449 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1450 goto nla_put_failure;
1451 }
1452 CMD(set_wds_peer, SET_WDS_PEER);
1453 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1454 CMD(tdls_mgmt, TDLS_MGMT);
1455 CMD(tdls_oper, TDLS_OPER);
1456 }
1457 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
1458 CMD(sched_scan_start, START_SCHED_SCAN);
1459 CMD(probe_client, PROBE_CLIENT);
1460 CMD(set_noack_map, SET_NOACK_MAP);
1461 if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1462 i++;
1463 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1464 goto nla_put_failure;
1465 }
1466 CMD(start_p2p_device, START_P2P_DEVICE);
1467 CMD(set_mcast_rate, SET_MCAST_RATE);
86e8cf98 1468 if (state->split) {
5de17984
AS
1469 CMD(crit_proto_start, CRIT_PROTOCOL_START);
1470 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
16ef1fe2
SW
1471 if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
1472 CMD(channel_switch, CHANNEL_SWITCH);
5de17984 1473 }
fa9ffc74 1474 CMD(set_qos_map, SET_QOS_MAP);
2e161f78 1475
3713b4e3
JB
1476#ifdef CONFIG_NL80211_TESTMODE
1477 CMD(testmode_cmd, TESTMODE);
1478#endif
ff1b6e69 1479
3713b4e3 1480#undef CMD
ff1b6e69 1481
3713b4e3
JB
1482 if (dev->ops->connect || dev->ops->auth) {
1483 i++;
1484 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
9360ffd1 1485 goto nla_put_failure;
ff1b6e69
JB
1486 }
1487
3713b4e3
JB
1488 if (dev->ops->disconnect || dev->ops->deauth) {
1489 i++;
1490 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1491 goto nla_put_failure;
1492 }
1493
1494 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
1495 state->split_start++;
1496 if (state->split)
3713b4e3
JB
1497 break;
1498 case 5:
1499 if (dev->ops->remain_on_channel &&
1500 (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
1501 nla_put_u32(msg,
1502 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1503 dev->wiphy.max_remain_on_channel_duration))
1504 goto nla_put_failure;
1505
1506 if ((dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
1507 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
1508 goto nla_put_failure;
1509
1510 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
1511 goto nla_put_failure;
86e8cf98
JB
1512 state->split_start++;
1513 if (state->split)
3713b4e3
JB
1514 break;
1515 case 6:
1516#ifdef CONFIG_PM
86e8cf98 1517 if (nl80211_send_wowlan(msg, dev, state->split))
3713b4e3 1518 goto nla_put_failure;
86e8cf98
JB
1519 state->split_start++;
1520 if (state->split)
3713b4e3
JB
1521 break;
1522#else
86e8cf98 1523 state->split_start++;
dfb89c56 1524#endif
3713b4e3
JB
1525 case 7:
1526 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1527 dev->wiphy.software_iftypes))
1528 goto nla_put_failure;
ff1b6e69 1529
86e8cf98
JB
1530 if (nl80211_put_iface_combinations(&dev->wiphy, msg,
1531 state->split))
3713b4e3 1532 goto nla_put_failure;
7527a782 1533
86e8cf98
JB
1534 state->split_start++;
1535 if (state->split)
3713b4e3
JB
1536 break;
1537 case 8:
1538 if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
1539 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1540 dev->wiphy.ap_sme_capa))
1541 goto nla_put_failure;
7527a782 1542
fe1abafd
JB
1543 features = dev->wiphy.features;
1544 /*
1545 * We can only add the per-channel limit information if the
1546 * dump is split, otherwise it makes it too big. Therefore
1547 * only advertise it in that case.
1548 */
86e8cf98 1549 if (state->split)
fe1abafd
JB
1550 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
1551 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 1552 goto nla_put_failure;
562a7480 1553
3713b4e3
JB
1554 if (dev->wiphy.ht_capa_mod_mask &&
1555 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1556 sizeof(*dev->wiphy.ht_capa_mod_mask),
1557 dev->wiphy.ht_capa_mod_mask))
1558 goto nla_put_failure;
1f074bd8 1559
3713b4e3
JB
1560 if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
1561 dev->wiphy.max_acl_mac_addrs &&
1562 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1563 dev->wiphy.max_acl_mac_addrs))
1564 goto nla_put_failure;
7e7c8926 1565
3713b4e3
JB
1566 /*
1567 * Any information below this point is only available to
1568 * applications that can deal with it being split. This
1569 * helps ensure that newly added capabilities don't break
1570 * older tools by overrunning their buffers.
1571 *
1572 * We still increment split_start so that in the split
1573 * case we'll continue with more data in the next round,
1574 * but break unconditionally so unsplit data stops here.
1575 */
86e8cf98 1576 state->split_start++;
3713b4e3
JB
1577 break;
1578 case 9:
fe1abafd
JB
1579 if (dev->wiphy.extended_capabilities &&
1580 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1581 dev->wiphy.extended_capabilities_len,
1582 dev->wiphy.extended_capabilities) ||
1583 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1584 dev->wiphy.extended_capabilities_len,
1585 dev->wiphy.extended_capabilities_mask)))
1586 goto nla_put_failure;
a50df0c4 1587
ee2aca34
JB
1588 if (dev->wiphy.vht_capa_mod_mask &&
1589 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1590 sizeof(*dev->wiphy.vht_capa_mod_mask),
1591 dev->wiphy.vht_capa_mod_mask))
1592 goto nla_put_failure;
1593
be29b99a
AK
1594 state->split_start++;
1595 break;
1596 case 10:
1597 if (nl80211_send_coalesce(msg, dev))
1598 goto nla_put_failure;
1599
01e0daa4
FF
1600 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
1601 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
1602 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
1603 goto nla_put_failure;
b43504cf
JM
1604
1605 if (dev->wiphy.max_ap_assoc_sta &&
1606 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1607 dev->wiphy.max_ap_assoc_sta))
1608 goto nla_put_failure;
1609
ad7e718c
JB
1610 state->split_start++;
1611 break;
1612 case 11:
567ffc35
JB
1613 if (dev->wiphy.n_vendor_commands) {
1614 const struct nl80211_vendor_cmd_info *info;
1615 struct nlattr *nested;
1616
1617 nested = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1618 if (!nested)
1619 goto nla_put_failure;
1620
1621 for (i = 0; i < dev->wiphy.n_vendor_commands; i++) {
1622 info = &dev->wiphy.vendor_commands[i].info;
1623 if (nla_put(msg, i + 1, sizeof(*info), info))
1624 goto nla_put_failure;
1625 }
1626 nla_nest_end(msg, nested);
1627 }
1628
1629 if (dev->wiphy.n_vendor_events) {
1630 const struct nl80211_vendor_cmd_info *info;
1631 struct nlattr *nested;
ad7e718c 1632
567ffc35
JB
1633 nested = nla_nest_start(msg,
1634 NL80211_ATTR_VENDOR_EVENTS);
1635 if (!nested)
ad7e718c 1636 goto nla_put_failure;
567ffc35
JB
1637
1638 for (i = 0; i < dev->wiphy.n_vendor_events; i++) {
1639 info = &dev->wiphy.vendor_events[i];
1640 if (nla_put(msg, i + 1, sizeof(*info), info))
1641 goto nla_put_failure;
1642 }
1643 nla_nest_end(msg, nested);
1644 }
01e0daa4 1645
3713b4e3 1646 /* done */
86e8cf98 1647 state->split_start = 0;
3713b4e3
JB
1648 break;
1649 }
55682965
JB
1650 return genlmsg_end(msg, hdr);
1651
1652 nla_put_failure:
bc3ed28c
TG
1653 genlmsg_cancel(msg, hdr);
1654 return -EMSGSIZE;
55682965
JB
1655}
1656
86e8cf98
JB
1657static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
1658 struct netlink_callback *cb,
1659 struct nl80211_dump_wiphy_state *state)
1660{
1661 struct nlattr **tb = nl80211_fam.attrbuf;
1662 int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1663 tb, nl80211_fam.maxattr, nl80211_policy);
1664 /* ignore parse errors for backward compatibility */
1665 if (ret)
1666 return 0;
1667
1668 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
1669 if (tb[NL80211_ATTR_WIPHY])
1670 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1671 if (tb[NL80211_ATTR_WDEV])
1672 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
1673 if (tb[NL80211_ATTR_IFINDEX]) {
1674 struct net_device *netdev;
1675 struct cfg80211_registered_device *rdev;
1676 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1677
7f2b8562 1678 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
86e8cf98
JB
1679 if (!netdev)
1680 return -ENODEV;
1681 if (netdev->ieee80211_ptr) {
1682 rdev = wiphy_to_dev(
1683 netdev->ieee80211_ptr->wiphy);
1684 state->filter_wiphy = rdev->wiphy_idx;
1685 }
86e8cf98
JB
1686 }
1687
1688 return 0;
1689}
1690
55682965
JB
1691static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1692{
645e77de 1693 int idx = 0, ret;
86e8cf98 1694 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
55682965 1695 struct cfg80211_registered_device *dev;
3a5a423b 1696
5fe231e8 1697 rtnl_lock();
86e8cf98
JB
1698 if (!state) {
1699 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
1700 if (!state) {
1701 rtnl_unlock();
86e8cf98 1702 return -ENOMEM;
3713b4e3 1703 }
86e8cf98
JB
1704 state->filter_wiphy = -1;
1705 ret = nl80211_dump_wiphy_parse(skb, cb, state);
1706 if (ret) {
1707 kfree(state);
1708 rtnl_unlock();
1709 return ret;
3713b4e3 1710 }
86e8cf98 1711 cb->args[0] = (long)state;
3713b4e3
JB
1712 }
1713
79c97e97 1714 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
463d0183
JB
1715 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
1716 continue;
86e8cf98 1717 if (++idx <= state->start)
55682965 1718 continue;
86e8cf98
JB
1719 if (state->filter_wiphy != -1 &&
1720 state->filter_wiphy != dev->wiphy_idx)
3713b4e3
JB
1721 continue;
1722 /* attempt to fit multiple wiphy data chunks into the skb */
1723 do {
1724 ret = nl80211_send_wiphy(dev, skb,
1725 NETLINK_CB(cb->skb).portid,
1726 cb->nlh->nlmsg_seq,
86e8cf98 1727 NLM_F_MULTI, state);
3713b4e3
JB
1728 if (ret < 0) {
1729 /*
1730 * If sending the wiphy data didn't fit (ENOBUFS
1731 * or EMSGSIZE returned), this SKB is still
1732 * empty (so it's not too big because another
1733 * wiphy dataset is already in the skb) and
1734 * we've not tried to adjust the dump allocation
1735 * yet ... then adjust the alloc size to be
1736 * bigger, and return 1 but with the empty skb.
1737 * This results in an empty message being RX'ed
1738 * in userspace, but that is ignored.
1739 *
1740 * We can then retry with the larger buffer.
1741 */
1742 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
1743 !skb->len &&
1744 cb->min_dump_alloc < 4096) {
1745 cb->min_dump_alloc = 4096;
d98cae64 1746 rtnl_unlock();
3713b4e3
JB
1747 return 1;
1748 }
1749 idx--;
1750 break;
645e77de 1751 }
86e8cf98 1752 } while (state->split_start > 0);
3713b4e3 1753 break;
55682965 1754 }
5fe231e8 1755 rtnl_unlock();
55682965 1756
86e8cf98 1757 state->start = idx;
55682965
JB
1758
1759 return skb->len;
1760}
1761
86e8cf98
JB
1762static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
1763{
1764 kfree((void *)cb->args[0]);
1765 return 0;
1766}
1767
55682965
JB
1768static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
1769{
1770 struct sk_buff *msg;
4c476991 1771 struct cfg80211_registered_device *dev = info->user_ptr[0];
86e8cf98 1772 struct nl80211_dump_wiphy_state state = {};
55682965 1773
645e77de 1774 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 1775 if (!msg)
4c476991 1776 return -ENOMEM;
55682965 1777
3713b4e3 1778 if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0,
86e8cf98 1779 &state) < 0) {
4c476991
JB
1780 nlmsg_free(msg);
1781 return -ENOBUFS;
1782 }
55682965 1783
134e6375 1784 return genlmsg_reply(msg, info);
55682965
JB
1785}
1786
31888487
JM
1787static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
1788 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
1789 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
1790 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
1791 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
1792 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
1793};
1794
1795static int parse_txq_params(struct nlattr *tb[],
1796 struct ieee80211_txq_params *txq_params)
1797{
a3304b0a 1798 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
1799 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
1800 !tb[NL80211_TXQ_ATTR_AIFS])
1801 return -EINVAL;
1802
a3304b0a 1803 txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
1804 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
1805 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
1806 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
1807 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
1808
a3304b0a
JB
1809 if (txq_params->ac >= NL80211_NUM_ACS)
1810 return -EINVAL;
1811
31888487
JM
1812 return 0;
1813}
1814
f444de05
JB
1815static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
1816{
1817 /*
cc1d2806
JB
1818 * You can only set the channel explicitly for WDS interfaces,
1819 * all others have their channel managed via their respective
1820 * "establish a connection" command (connect, join, ...)
1821 *
1822 * For AP/GO and mesh mode, the channel can be set with the
1823 * channel userspace API, but is only stored and passed to the
1824 * low-level driver when the AP starts or the mesh is joined.
1825 * This is for backward compatibility, userspace can also give
1826 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
1827 *
1828 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
1829 * whatever else is going on, so they have their own special
1830 * operation to set the monitor channel if possible.
f444de05
JB
1831 */
1832 return !wdev ||
1833 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 1834 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
1835 wdev->iftype == NL80211_IFTYPE_MONITOR ||
1836 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
1837}
1838
683b6d3b
JB
1839static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
1840 struct genl_info *info,
1841 struct cfg80211_chan_def *chandef)
1842{
dbeca2ea 1843 u32 control_freq;
683b6d3b
JB
1844
1845 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1846 return -EINVAL;
1847
1848 control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1849
1850 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
3d9d1d66
JB
1851 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
1852 chandef->center_freq1 = control_freq;
1853 chandef->center_freq2 = 0;
683b6d3b
JB
1854
1855 /* Primary channel not allowed */
1856 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
1857 return -EINVAL;
1858
3d9d1d66
JB
1859 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
1860 enum nl80211_channel_type chantype;
1861
1862 chantype = nla_get_u32(
1863 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
1864
1865 switch (chantype) {
1866 case NL80211_CHAN_NO_HT:
1867 case NL80211_CHAN_HT20:
1868 case NL80211_CHAN_HT40PLUS:
1869 case NL80211_CHAN_HT40MINUS:
1870 cfg80211_chandef_create(chandef, chandef->chan,
1871 chantype);
1872 break;
1873 default:
1874 return -EINVAL;
1875 }
1876 } else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
1877 chandef->width =
1878 nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
1879 if (info->attrs[NL80211_ATTR_CENTER_FREQ1])
1880 chandef->center_freq1 =
1881 nla_get_u32(
1882 info->attrs[NL80211_ATTR_CENTER_FREQ1]);
1883 if (info->attrs[NL80211_ATTR_CENTER_FREQ2])
1884 chandef->center_freq2 =
1885 nla_get_u32(
1886 info->attrs[NL80211_ATTR_CENTER_FREQ2]);
1887 }
1888
9f5e8f6e 1889 if (!cfg80211_chandef_valid(chandef))
3d9d1d66
JB
1890 return -EINVAL;
1891
9f5e8f6e
JB
1892 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
1893 IEEE80211_CHAN_DISABLED))
3d9d1d66
JB
1894 return -EINVAL;
1895
2f301ab2
SW
1896 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
1897 chandef->width == NL80211_CHAN_WIDTH_10) &&
1898 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ))
1899 return -EINVAL;
1900
683b6d3b
JB
1901 return 0;
1902}
1903
f444de05
JB
1904static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1905 struct wireless_dev *wdev,
1906 struct genl_info *info)
1907{
683b6d3b 1908 struct cfg80211_chan_def chandef;
f444de05 1909 int result;
e8c9bd5b
JB
1910 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
1911
1912 if (wdev)
1913 iftype = wdev->iftype;
f444de05 1914
f444de05
JB
1915 if (!nl80211_can_set_dev_channel(wdev))
1916 return -EOPNOTSUPP;
1917
683b6d3b
JB
1918 result = nl80211_parse_chandef(rdev, info, &chandef);
1919 if (result)
1920 return result;
f444de05 1921
e8c9bd5b 1922 switch (iftype) {
aa430da4
JB
1923 case NL80211_IFTYPE_AP:
1924 case NL80211_IFTYPE_P2P_GO:
1925 if (wdev->beacon_interval) {
1926 result = -EBUSY;
1927 break;
1928 }
683b6d3b 1929 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) {
aa430da4
JB
1930 result = -EINVAL;
1931 break;
1932 }
683b6d3b 1933 wdev->preset_chandef = chandef;
aa430da4
JB
1934 result = 0;
1935 break;
cc1d2806 1936 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 1937 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 1938 break;
e8c9bd5b 1939 case NL80211_IFTYPE_MONITOR:
683b6d3b 1940 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 1941 break;
aa430da4 1942 default:
e8c9bd5b 1943 result = -EINVAL;
f444de05 1944 }
f444de05
JB
1945
1946 return result;
1947}
1948
1949static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
1950{
4c476991
JB
1951 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1952 struct net_device *netdev = info->user_ptr[1];
f444de05 1953
4c476991 1954 return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info);
f444de05
JB
1955}
1956
e8347eba
BJ
1957static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
1958{
43b19952
JB
1959 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1960 struct net_device *dev = info->user_ptr[1];
1961 struct wireless_dev *wdev = dev->ieee80211_ptr;
388ac775 1962 const u8 *bssid;
e8347eba
BJ
1963
1964 if (!info->attrs[NL80211_ATTR_MAC])
1965 return -EINVAL;
1966
43b19952
JB
1967 if (netif_running(dev))
1968 return -EBUSY;
e8347eba 1969
43b19952
JB
1970 if (!rdev->ops->set_wds_peer)
1971 return -EOPNOTSUPP;
e8347eba 1972
43b19952
JB
1973 if (wdev->iftype != NL80211_IFTYPE_WDS)
1974 return -EOPNOTSUPP;
e8347eba
BJ
1975
1976 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
e35e4d28 1977 return rdev_set_wds_peer(rdev, dev, bssid);
e8347eba
BJ
1978}
1979
1980
55682965
JB
1981static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1982{
1983 struct cfg80211_registered_device *rdev;
f444de05
JB
1984 struct net_device *netdev = NULL;
1985 struct wireless_dev *wdev;
a1e567c8 1986 int result = 0, rem_txq_params = 0;
31888487 1987 struct nlattr *nl_txq_params;
b9a5f8ca
JM
1988 u32 changed;
1989 u8 retry_short = 0, retry_long = 0;
1990 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 1991 u8 coverage_class = 0;
55682965 1992
5fe231e8
JB
1993 ASSERT_RTNL();
1994
f444de05
JB
1995 /*
1996 * Try to find the wiphy and netdev. Normally this
1997 * function shouldn't need the netdev, but this is
1998 * done for backward compatibility -- previously
1999 * setting the channel was done per wiphy, but now
2000 * it is per netdev. Previous userland like hostapd
2001 * also passed a netdev to set_wiphy, so that it is
2002 * possible to let that go to the right netdev!
2003 */
4bbf4d56 2004
f444de05
JB
2005 if (info->attrs[NL80211_ATTR_IFINDEX]) {
2006 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
2007
7f2b8562 2008 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 2009 if (netdev && netdev->ieee80211_ptr)
f444de05 2010 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy);
5fe231e8 2011 else
f444de05 2012 netdev = NULL;
4bbf4d56
JB
2013 }
2014
f444de05 2015 if (!netdev) {
878d9ec7
JB
2016 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
2017 info->attrs);
5fe231e8 2018 if (IS_ERR(rdev))
4c476991 2019 return PTR_ERR(rdev);
f444de05
JB
2020 wdev = NULL;
2021 netdev = NULL;
2022 result = 0;
71fe96bf 2023 } else
f444de05 2024 wdev = netdev->ieee80211_ptr;
f444de05
JB
2025
2026 /*
2027 * end workaround code, by now the rdev is available
2028 * and locked, and wdev may or may not be NULL.
2029 */
4bbf4d56
JB
2030
2031 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
2032 result = cfg80211_dev_rename(
2033 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56 2034
4bbf4d56 2035 if (result)
7f2b8562 2036 return result;
31888487
JM
2037
2038 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
2039 struct ieee80211_txq_params txq_params;
2040 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
2041
7f2b8562
YX
2042 if (!rdev->ops->set_txq_params)
2043 return -EOPNOTSUPP;
31888487 2044
7f2b8562
YX
2045 if (!netdev)
2046 return -EINVAL;
f70f01c2 2047
133a3ff2 2048 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
7f2b8562
YX
2049 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2050 return -EINVAL;
133a3ff2 2051
7f2b8562
YX
2052 if (!netif_running(netdev))
2053 return -ENETDOWN;
2b5f8b0b 2054
31888487
JM
2055 nla_for_each_nested(nl_txq_params,
2056 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
2057 rem_txq_params) {
ae811e21
JB
2058 result = nla_parse(tb, NL80211_TXQ_ATTR_MAX,
2059 nla_data(nl_txq_params),
2060 nla_len(nl_txq_params),
2061 txq_params_policy);
2062 if (result)
2063 return result;
31888487
JM
2064 result = parse_txq_params(tb, &txq_params);
2065 if (result)
7f2b8562 2066 return result;
31888487 2067
e35e4d28
HG
2068 result = rdev_set_txq_params(rdev, netdev,
2069 &txq_params);
31888487 2070 if (result)
7f2b8562 2071 return result;
31888487
JM
2072 }
2073 }
55682965 2074
72bdcf34 2075 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
71fe96bf
JB
2076 result = __nl80211_set_channel(rdev,
2077 nl80211_can_set_dev_channel(wdev) ? wdev : NULL,
2078 info);
72bdcf34 2079 if (result)
7f2b8562 2080 return result;
72bdcf34
JM
2081 }
2082
98d2ff8b 2083 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 2084 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
2085 enum nl80211_tx_power_setting type;
2086 int idx, mbm = 0;
2087
c8442118
JB
2088 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
2089 txp_wdev = NULL;
2090
7f2b8562
YX
2091 if (!rdev->ops->set_tx_power)
2092 return -EOPNOTSUPP;
98d2ff8b
JO
2093
2094 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
2095 type = nla_get_u32(info->attrs[idx]);
2096
2097 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
7f2b8562
YX
2098 (type != NL80211_TX_POWER_AUTOMATIC))
2099 return -EINVAL;
98d2ff8b
JO
2100
2101 if (type != NL80211_TX_POWER_AUTOMATIC) {
2102 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
2103 mbm = nla_get_u32(info->attrs[idx]);
2104 }
2105
c8442118 2106 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 2107 if (result)
7f2b8562 2108 return result;
98d2ff8b
JO
2109 }
2110
afe0cbf8
BR
2111 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
2112 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
2113 u32 tx_ant, rx_ant;
7f531e03
BR
2114 if ((!rdev->wiphy.available_antennas_tx &&
2115 !rdev->wiphy.available_antennas_rx) ||
7f2b8562
YX
2116 !rdev->ops->set_antenna)
2117 return -EOPNOTSUPP;
afe0cbf8
BR
2118
2119 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
2120 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
2121
a7ffac95 2122 /* reject antenna configurations which don't match the
7f531e03
BR
2123 * available antenna masks, except for the "all" mask */
2124 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
7f2b8562
YX
2125 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
2126 return -EINVAL;
a7ffac95 2127
7f531e03
BR
2128 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
2129 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 2130
e35e4d28 2131 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 2132 if (result)
7f2b8562 2133 return result;
afe0cbf8
BR
2134 }
2135
b9a5f8ca
JM
2136 changed = 0;
2137
2138 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
2139 retry_short = nla_get_u8(
2140 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562
YX
2141 if (retry_short == 0)
2142 return -EINVAL;
2143
b9a5f8ca
JM
2144 changed |= WIPHY_PARAM_RETRY_SHORT;
2145 }
2146
2147 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
2148 retry_long = nla_get_u8(
2149 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562
YX
2150 if (retry_long == 0)
2151 return -EINVAL;
2152
b9a5f8ca
JM
2153 changed |= WIPHY_PARAM_RETRY_LONG;
2154 }
2155
2156 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
2157 frag_threshold = nla_get_u32(
2158 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
7f2b8562
YX
2159 if (frag_threshold < 256)
2160 return -EINVAL;
2161
b9a5f8ca
JM
2162 if (frag_threshold != (u32) -1) {
2163 /*
2164 * Fragments (apart from the last one) are required to
2165 * have even length. Make the fragmentation code
2166 * simpler by stripping LSB should someone try to use
2167 * odd threshold value.
2168 */
2169 frag_threshold &= ~0x1;
2170 }
2171 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
2172 }
2173
2174 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
2175 rts_threshold = nla_get_u32(
2176 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
2177 changed |= WIPHY_PARAM_RTS_THRESHOLD;
2178 }
2179
81077e82
LT
2180 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
2181 coverage_class = nla_get_u8(
2182 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
2183 changed |= WIPHY_PARAM_COVERAGE_CLASS;
2184 }
2185
b9a5f8ca
JM
2186 if (changed) {
2187 u8 old_retry_short, old_retry_long;
2188 u32 old_frag_threshold, old_rts_threshold;
81077e82 2189 u8 old_coverage_class;
b9a5f8ca 2190
7f2b8562
YX
2191 if (!rdev->ops->set_wiphy_params)
2192 return -EOPNOTSUPP;
b9a5f8ca
JM
2193
2194 old_retry_short = rdev->wiphy.retry_short;
2195 old_retry_long = rdev->wiphy.retry_long;
2196 old_frag_threshold = rdev->wiphy.frag_threshold;
2197 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 2198 old_coverage_class = rdev->wiphy.coverage_class;
b9a5f8ca
JM
2199
2200 if (changed & WIPHY_PARAM_RETRY_SHORT)
2201 rdev->wiphy.retry_short = retry_short;
2202 if (changed & WIPHY_PARAM_RETRY_LONG)
2203 rdev->wiphy.retry_long = retry_long;
2204 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
2205 rdev->wiphy.frag_threshold = frag_threshold;
2206 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
2207 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
2208 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
2209 rdev->wiphy.coverage_class = coverage_class;
b9a5f8ca 2210
e35e4d28 2211 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
2212 if (result) {
2213 rdev->wiphy.retry_short = old_retry_short;
2214 rdev->wiphy.retry_long = old_retry_long;
2215 rdev->wiphy.frag_threshold = old_frag_threshold;
2216 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 2217 rdev->wiphy.coverage_class = old_coverage_class;
b9a5f8ca
JM
2218 }
2219 }
7f2b8562 2220 return 0;
55682965
JB
2221}
2222
71bbc994
JB
2223static inline u64 wdev_id(struct wireless_dev *wdev)
2224{
2225 return (u64)wdev->identifier |
2226 ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32);
2227}
55682965 2228
683b6d3b 2229static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 2230 const struct cfg80211_chan_def *chandef)
683b6d3b 2231{
9f5e8f6e 2232 WARN_ON(!cfg80211_chandef_valid(chandef));
3d9d1d66 2233
683b6d3b
JB
2234 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
2235 chandef->chan->center_freq))
2236 return -ENOBUFS;
3d9d1d66
JB
2237 switch (chandef->width) {
2238 case NL80211_CHAN_WIDTH_20_NOHT:
2239 case NL80211_CHAN_WIDTH_20:
2240 case NL80211_CHAN_WIDTH_40:
2241 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2242 cfg80211_get_chandef_type(chandef)))
2243 return -ENOBUFS;
2244 break;
2245 default:
2246 break;
2247 }
2248 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
2249 return -ENOBUFS;
2250 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
2251 return -ENOBUFS;
2252 if (chandef->center_freq2 &&
2253 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
2254 return -ENOBUFS;
2255 return 0;
2256}
2257
15e47304 2258static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 2259 struct cfg80211_registered_device *rdev,
72fb2abc 2260 struct wireless_dev *wdev)
55682965 2261{
72fb2abc 2262 struct net_device *dev = wdev->netdev;
55682965
JB
2263 void *hdr;
2264
15e47304 2265 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_INTERFACE);
55682965
JB
2266 if (!hdr)
2267 return -1;
2268
72fb2abc
JB
2269 if (dev &&
2270 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 2271 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
2272 goto nla_put_failure;
2273
2274 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2275 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
71bbc994 2276 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
98104fde 2277 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
2278 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2279 rdev->devlist_generation ^
2280 (cfg80211_rdev_list_generation << 2)))
2281 goto nla_put_failure;
f5ea9120 2282
5b7ccaf3 2283 if (rdev->ops->get_channel) {
683b6d3b
JB
2284 int ret;
2285 struct cfg80211_chan_def chandef;
2286
2287 ret = rdev_get_channel(rdev, wdev, &chandef);
2288 if (ret == 0) {
2289 if (nl80211_send_chandef(msg, &chandef))
2290 goto nla_put_failure;
2291 }
d91df0e3
PF
2292 }
2293
b84e7a05
AQ
2294 if (wdev->ssid_len) {
2295 if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
2296 goto nla_put_failure;
2297 }
2298
55682965
JB
2299 return genlmsg_end(msg, hdr);
2300
2301 nla_put_failure:
bc3ed28c
TG
2302 genlmsg_cancel(msg, hdr);
2303 return -EMSGSIZE;
55682965
JB
2304}
2305
2306static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
2307{
2308 int wp_idx = 0;
2309 int if_idx = 0;
2310 int wp_start = cb->args[0];
2311 int if_start = cb->args[1];
f5ea9120 2312 struct cfg80211_registered_device *rdev;
55682965
JB
2313 struct wireless_dev *wdev;
2314
5fe231e8 2315 rtnl_lock();
f5ea9120
JB
2316 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2317 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2318 continue;
bba95fef
JB
2319 if (wp_idx < wp_start) {
2320 wp_idx++;
55682965 2321 continue;
bba95fef 2322 }
55682965
JB
2323 if_idx = 0;
2324
89a54e48 2325 list_for_each_entry(wdev, &rdev->wdev_list, list) {
bba95fef
JB
2326 if (if_idx < if_start) {
2327 if_idx++;
55682965 2328 continue;
bba95fef 2329 }
15e47304 2330 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 2331 cb->nlh->nlmsg_seq, NLM_F_MULTI,
72fb2abc 2332 rdev, wdev) < 0) {
bba95fef
JB
2333 goto out;
2334 }
2335 if_idx++;
55682965 2336 }
bba95fef
JB
2337
2338 wp_idx++;
55682965 2339 }
bba95fef 2340 out:
5fe231e8 2341 rtnl_unlock();
55682965
JB
2342
2343 cb->args[0] = wp_idx;
2344 cb->args[1] = if_idx;
2345
2346 return skb->len;
2347}
2348
2349static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
2350{
2351 struct sk_buff *msg;
4c476991 2352 struct cfg80211_registered_device *dev = info->user_ptr[0];
72fb2abc 2353 struct wireless_dev *wdev = info->user_ptr[1];
55682965 2354
fd2120ca 2355 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 2356 if (!msg)
4c476991 2357 return -ENOMEM;
55682965 2358
15e47304 2359 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
72fb2abc 2360 dev, wdev) < 0) {
4c476991
JB
2361 nlmsg_free(msg);
2362 return -ENOBUFS;
2363 }
55682965 2364
134e6375 2365 return genlmsg_reply(msg, info);
55682965
JB
2366}
2367
66f7ac50
MW
2368static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
2369 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
2370 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
2371 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
2372 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
2373 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 2374 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
2375};
2376
2377static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
2378{
2379 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
2380 int flag;
2381
2382 *mntrflags = 0;
2383
2384 if (!nla)
2385 return -EINVAL;
2386
2387 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
2388 nla, mntr_flags_policy))
2389 return -EINVAL;
2390
2391 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
2392 if (flags[flag])
2393 *mntrflags |= (1<<flag);
2394
2395 return 0;
2396}
2397
9bc383de 2398static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
2399 struct net_device *netdev, u8 use_4addr,
2400 enum nl80211_iftype iftype)
9bc383de 2401{
ad4bb6f8 2402 if (!use_4addr) {
f350a0a8 2403 if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT))
ad4bb6f8 2404 return -EBUSY;
9bc383de 2405 return 0;
ad4bb6f8 2406 }
9bc383de
JB
2407
2408 switch (iftype) {
2409 case NL80211_IFTYPE_AP_VLAN:
2410 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
2411 return 0;
2412 break;
2413 case NL80211_IFTYPE_STATION:
2414 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
2415 return 0;
2416 break;
2417 default:
2418 break;
2419 }
2420
2421 return -EOPNOTSUPP;
2422}
2423
55682965
JB
2424static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
2425{
4c476991 2426 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2427 struct vif_params params;
e36d56b6 2428 int err;
04a773ad 2429 enum nl80211_iftype otype, ntype;
4c476991 2430 struct net_device *dev = info->user_ptr[1];
92ffe055 2431 u32 _flags, *flags = NULL;
ac7f9cfa 2432 bool change = false;
55682965 2433
2ec600d6
LCC
2434 memset(&params, 0, sizeof(params));
2435
04a773ad 2436 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 2437
723b038d 2438 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 2439 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 2440 if (otype != ntype)
ac7f9cfa 2441 change = true;
4c476991
JB
2442 if (ntype > NL80211_IFTYPE_MAX)
2443 return -EINVAL;
723b038d
JB
2444 }
2445
92ffe055 2446 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
2447 struct wireless_dev *wdev = dev->ieee80211_ptr;
2448
4c476991
JB
2449 if (ntype != NL80211_IFTYPE_MESH_POINT)
2450 return -EINVAL;
29cbe68c
JB
2451 if (netif_running(dev))
2452 return -EBUSY;
2453
2454 wdev_lock(wdev);
2455 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2456 IEEE80211_MAX_MESH_ID_LEN);
2457 wdev->mesh_id_up_len =
2458 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2459 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
2460 wdev->mesh_id_up_len);
2461 wdev_unlock(wdev);
2ec600d6
LCC
2462 }
2463
8b787643
FF
2464 if (info->attrs[NL80211_ATTR_4ADDR]) {
2465 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
2466 change = true;
ad4bb6f8 2467 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 2468 if (err)
4c476991 2469 return err;
8b787643
FF
2470 } else {
2471 params.use_4addr = -1;
2472 }
2473
92ffe055 2474 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
4c476991
JB
2475 if (ntype != NL80211_IFTYPE_MONITOR)
2476 return -EINVAL;
92ffe055
JB
2477 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
2478 &_flags);
ac7f9cfa 2479 if (err)
4c476991 2480 return err;
ac7f9cfa
JB
2481
2482 flags = &_flags;
2483 change = true;
92ffe055 2484 }
3b85875a 2485
18003297 2486 if (flags && (*flags & MONITOR_FLAG_ACTIVE) &&
e057d3c3
FF
2487 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2488 return -EOPNOTSUPP;
2489
ac7f9cfa 2490 if (change)
3d54d255 2491 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
ac7f9cfa
JB
2492 else
2493 err = 0;
60719ffd 2494
9bc383de
JB
2495 if (!err && params.use_4addr != -1)
2496 dev->ieee80211_ptr->use_4addr = params.use_4addr;
2497
55682965
JB
2498 return err;
2499}
2500
2501static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2502{
4c476991 2503 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2504 struct vif_params params;
84efbb84 2505 struct wireless_dev *wdev;
1c90f9d4 2506 struct sk_buff *msg;
55682965
JB
2507 int err;
2508 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
66f7ac50 2509 u32 flags;
55682965 2510
2ec600d6
LCC
2511 memset(&params, 0, sizeof(params));
2512
55682965
JB
2513 if (!info->attrs[NL80211_ATTR_IFNAME])
2514 return -EINVAL;
2515
2516 if (info->attrs[NL80211_ATTR_IFTYPE]) {
2517 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
2518 if (type > NL80211_IFTYPE_MAX)
2519 return -EINVAL;
2520 }
2521
79c97e97 2522 if (!rdev->ops->add_virtual_intf ||
4c476991
JB
2523 !(rdev->wiphy.interface_modes & (1 << type)))
2524 return -EOPNOTSUPP;
55682965 2525
1c18f145
AS
2526 if (type == NL80211_IFTYPE_P2P_DEVICE && info->attrs[NL80211_ATTR_MAC]) {
2527 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
2528 ETH_ALEN);
2529 if (!is_valid_ether_addr(params.macaddr))
2530 return -EADDRNOTAVAIL;
2531 }
2532
9bc383de 2533 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 2534 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 2535 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 2536 if (err)
4c476991 2537 return err;
9bc383de 2538 }
8b787643 2539
1c90f9d4
JB
2540 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2541 if (!msg)
2542 return -ENOMEM;
2543
66f7ac50
MW
2544 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
2545 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
2546 &flags);
e057d3c3 2547
18003297 2548 if (!err && (flags & MONITOR_FLAG_ACTIVE) &&
e057d3c3
FF
2549 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2550 return -EOPNOTSUPP;
2551
e35e4d28
HG
2552 wdev = rdev_add_virtual_intf(rdev,
2553 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
2554 type, err ? NULL : &flags, &params);
1c90f9d4
JB
2555 if (IS_ERR(wdev)) {
2556 nlmsg_free(msg);
84efbb84 2557 return PTR_ERR(wdev);
1c90f9d4 2558 }
2ec600d6 2559
98104fde
JB
2560 switch (type) {
2561 case NL80211_IFTYPE_MESH_POINT:
2562 if (!info->attrs[NL80211_ATTR_MESH_ID])
2563 break;
29cbe68c
JB
2564 wdev_lock(wdev);
2565 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2566 IEEE80211_MAX_MESH_ID_LEN);
2567 wdev->mesh_id_up_len =
2568 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2569 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
2570 wdev->mesh_id_up_len);
2571 wdev_unlock(wdev);
98104fde
JB
2572 break;
2573 case NL80211_IFTYPE_P2P_DEVICE:
2574 /*
2575 * P2P Device doesn't have a netdev, so doesn't go
2576 * through the netdev notifier and must be added here
2577 */
2578 mutex_init(&wdev->mtx);
2579 INIT_LIST_HEAD(&wdev->event_list);
2580 spin_lock_init(&wdev->event_lock);
2581 INIT_LIST_HEAD(&wdev->mgmt_registrations);
2582 spin_lock_init(&wdev->mgmt_registrations_lock);
2583
98104fde
JB
2584 wdev->identifier = ++rdev->wdev_id;
2585 list_add_rcu(&wdev->list, &rdev->wdev_list);
2586 rdev->devlist_generation++;
98104fde
JB
2587 break;
2588 default:
2589 break;
29cbe68c
JB
2590 }
2591
15e47304 2592 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
1c90f9d4
JB
2593 rdev, wdev) < 0) {
2594 nlmsg_free(msg);
2595 return -ENOBUFS;
2596 }
2597
2598 return genlmsg_reply(msg, info);
55682965
JB
2599}
2600
2601static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
2602{
4c476991 2603 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 2604 struct wireless_dev *wdev = info->user_ptr[1];
55682965 2605
4c476991
JB
2606 if (!rdev->ops->del_virtual_intf)
2607 return -EOPNOTSUPP;
55682965 2608
84efbb84
JB
2609 /*
2610 * If we remove a wireless device without a netdev then clear
2611 * user_ptr[1] so that nl80211_post_doit won't dereference it
2612 * to check if it needs to do dev_put(). Otherwise it crashes
2613 * since the wdev has been freed, unlike with a netdev where
2614 * we need the dev_put() for the netdev to really be freed.
2615 */
2616 if (!wdev->netdev)
2617 info->user_ptr[1] = NULL;
2618
e35e4d28 2619 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
2620}
2621
1d9d9213
SW
2622static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
2623{
2624 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2625 struct net_device *dev = info->user_ptr[1];
2626 u16 noack_map;
2627
2628 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
2629 return -EINVAL;
2630
2631 if (!rdev->ops->set_noack_map)
2632 return -EOPNOTSUPP;
2633
2634 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
2635
e35e4d28 2636 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
2637}
2638
41ade00f
JB
2639struct get_key_cookie {
2640 struct sk_buff *msg;
2641 int error;
b9454e83 2642 int idx;
41ade00f
JB
2643};
2644
2645static void get_key_callback(void *c, struct key_params *params)
2646{
b9454e83 2647 struct nlattr *key;
41ade00f
JB
2648 struct get_key_cookie *cookie = c;
2649
9360ffd1
DM
2650 if ((params->key &&
2651 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
2652 params->key_len, params->key)) ||
2653 (params->seq &&
2654 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
2655 params->seq_len, params->seq)) ||
2656 (params->cipher &&
2657 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
2658 params->cipher)))
2659 goto nla_put_failure;
41ade00f 2660
b9454e83
JB
2661 key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
2662 if (!key)
2663 goto nla_put_failure;
2664
9360ffd1
DM
2665 if ((params->key &&
2666 nla_put(cookie->msg, NL80211_KEY_DATA,
2667 params->key_len, params->key)) ||
2668 (params->seq &&
2669 nla_put(cookie->msg, NL80211_KEY_SEQ,
2670 params->seq_len, params->seq)) ||
2671 (params->cipher &&
2672 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
2673 params->cipher)))
2674 goto nla_put_failure;
b9454e83 2675
9360ffd1
DM
2676 if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx))
2677 goto nla_put_failure;
b9454e83
JB
2678
2679 nla_nest_end(cookie->msg, key);
2680
41ade00f
JB
2681 return;
2682 nla_put_failure:
2683 cookie->error = 1;
2684}
2685
2686static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
2687{
4c476991 2688 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 2689 int err;
4c476991 2690 struct net_device *dev = info->user_ptr[1];
41ade00f 2691 u8 key_idx = 0;
e31b8213
JB
2692 const u8 *mac_addr = NULL;
2693 bool pairwise;
41ade00f
JB
2694 struct get_key_cookie cookie = {
2695 .error = 0,
2696 };
2697 void *hdr;
2698 struct sk_buff *msg;
2699
2700 if (info->attrs[NL80211_ATTR_KEY_IDX])
2701 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
2702
3cfcf6ac 2703 if (key_idx > 5)
41ade00f
JB
2704 return -EINVAL;
2705
2706 if (info->attrs[NL80211_ATTR_MAC])
2707 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2708
e31b8213
JB
2709 pairwise = !!mac_addr;
2710 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
2711 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
2712 if (kt >= NUM_NL80211_KEYTYPES)
2713 return -EINVAL;
2714 if (kt != NL80211_KEYTYPE_GROUP &&
2715 kt != NL80211_KEYTYPE_PAIRWISE)
2716 return -EINVAL;
2717 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
2718 }
2719
4c476991
JB
2720 if (!rdev->ops->get_key)
2721 return -EOPNOTSUPP;
41ade00f 2722
fd2120ca 2723 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
2724 if (!msg)
2725 return -ENOMEM;
41ade00f 2726
15e47304 2727 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 2728 NL80211_CMD_NEW_KEY);
cb35fba3 2729 if (!hdr)
9fe271af 2730 goto nla_put_failure;
41ade00f
JB
2731
2732 cookie.msg = msg;
b9454e83 2733 cookie.idx = key_idx;
41ade00f 2734
9360ffd1
DM
2735 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
2736 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
2737 goto nla_put_failure;
2738 if (mac_addr &&
2739 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
2740 goto nla_put_failure;
41ade00f 2741
e31b8213
JB
2742 if (pairwise && mac_addr &&
2743 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
2744 return -ENOENT;
2745
e35e4d28
HG
2746 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
2747 get_key_callback);
41ade00f
JB
2748
2749 if (err)
6c95e2a2 2750 goto free_msg;
41ade00f
JB
2751
2752 if (cookie.error)
2753 goto nla_put_failure;
2754
2755 genlmsg_end(msg, hdr);
4c476991 2756 return genlmsg_reply(msg, info);
41ade00f
JB
2757
2758 nla_put_failure:
2759 err = -ENOBUFS;
6c95e2a2 2760 free_msg:
41ade00f 2761 nlmsg_free(msg);
41ade00f
JB
2762 return err;
2763}
2764
2765static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
2766{
4c476991 2767 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 2768 struct key_parse key;
41ade00f 2769 int err;
4c476991 2770 struct net_device *dev = info->user_ptr[1];
41ade00f 2771
b9454e83
JB
2772 err = nl80211_parse_key(info, &key);
2773 if (err)
2774 return err;
41ade00f 2775
b9454e83 2776 if (key.idx < 0)
41ade00f
JB
2777 return -EINVAL;
2778
b9454e83
JB
2779 /* only support setting default key */
2780 if (!key.def && !key.defmgmt)
41ade00f
JB
2781 return -EINVAL;
2782
dbd2fd65 2783 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 2784
dbd2fd65
JB
2785 if (key.def) {
2786 if (!rdev->ops->set_default_key) {
2787 err = -EOPNOTSUPP;
2788 goto out;
2789 }
41ade00f 2790
dbd2fd65
JB
2791 err = nl80211_key_allowed(dev->ieee80211_ptr);
2792 if (err)
2793 goto out;
2794
e35e4d28 2795 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
2796 key.def_uni, key.def_multi);
2797
2798 if (err)
2799 goto out;
fffd0934 2800
3d23e349 2801#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
2802 dev->ieee80211_ptr->wext.default_key = key.idx;
2803#endif
2804 } else {
2805 if (key.def_uni || !key.def_multi) {
2806 err = -EINVAL;
2807 goto out;
2808 }
2809
2810 if (!rdev->ops->set_default_mgmt_key) {
2811 err = -EOPNOTSUPP;
2812 goto out;
2813 }
2814
2815 err = nl80211_key_allowed(dev->ieee80211_ptr);
2816 if (err)
2817 goto out;
2818
e35e4d28 2819 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
2820 if (err)
2821 goto out;
2822
2823#ifdef CONFIG_CFG80211_WEXT
2824 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 2825#endif
dbd2fd65
JB
2826 }
2827
2828 out:
fffd0934 2829 wdev_unlock(dev->ieee80211_ptr);
41ade00f 2830
41ade00f
JB
2831 return err;
2832}
2833
2834static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
2835{
4c476991 2836 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 2837 int err;
4c476991 2838 struct net_device *dev = info->user_ptr[1];
b9454e83 2839 struct key_parse key;
e31b8213 2840 const u8 *mac_addr = NULL;
41ade00f 2841
b9454e83
JB
2842 err = nl80211_parse_key(info, &key);
2843 if (err)
2844 return err;
41ade00f 2845
b9454e83 2846 if (!key.p.key)
41ade00f
JB
2847 return -EINVAL;
2848
41ade00f
JB
2849 if (info->attrs[NL80211_ATTR_MAC])
2850 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2851
e31b8213
JB
2852 if (key.type == -1) {
2853 if (mac_addr)
2854 key.type = NL80211_KEYTYPE_PAIRWISE;
2855 else
2856 key.type = NL80211_KEYTYPE_GROUP;
2857 }
2858
2859 /* for now */
2860 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
2861 key.type != NL80211_KEYTYPE_GROUP)
2862 return -EINVAL;
2863
4c476991
JB
2864 if (!rdev->ops->add_key)
2865 return -EOPNOTSUPP;
25e47c18 2866
e31b8213
JB
2867 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
2868 key.type == NL80211_KEYTYPE_PAIRWISE,
2869 mac_addr))
4c476991 2870 return -EINVAL;
41ade00f 2871
fffd0934
JB
2872 wdev_lock(dev->ieee80211_ptr);
2873 err = nl80211_key_allowed(dev->ieee80211_ptr);
2874 if (!err)
e35e4d28
HG
2875 err = rdev_add_key(rdev, dev, key.idx,
2876 key.type == NL80211_KEYTYPE_PAIRWISE,
2877 mac_addr, &key.p);
fffd0934 2878 wdev_unlock(dev->ieee80211_ptr);
41ade00f 2879
41ade00f
JB
2880 return err;
2881}
2882
2883static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
2884{
4c476991 2885 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 2886 int err;
4c476991 2887 struct net_device *dev = info->user_ptr[1];
41ade00f 2888 u8 *mac_addr = NULL;
b9454e83 2889 struct key_parse key;
41ade00f 2890
b9454e83
JB
2891 err = nl80211_parse_key(info, &key);
2892 if (err)
2893 return err;
41ade00f
JB
2894
2895 if (info->attrs[NL80211_ATTR_MAC])
2896 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2897
e31b8213
JB
2898 if (key.type == -1) {
2899 if (mac_addr)
2900 key.type = NL80211_KEYTYPE_PAIRWISE;
2901 else
2902 key.type = NL80211_KEYTYPE_GROUP;
2903 }
2904
2905 /* for now */
2906 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
2907 key.type != NL80211_KEYTYPE_GROUP)
2908 return -EINVAL;
2909
4c476991
JB
2910 if (!rdev->ops->del_key)
2911 return -EOPNOTSUPP;
41ade00f 2912
fffd0934
JB
2913 wdev_lock(dev->ieee80211_ptr);
2914 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213
JB
2915
2916 if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr &&
2917 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
2918 err = -ENOENT;
2919
fffd0934 2920 if (!err)
e35e4d28
HG
2921 err = rdev_del_key(rdev, dev, key.idx,
2922 key.type == NL80211_KEYTYPE_PAIRWISE,
2923 mac_addr);
41ade00f 2924
3d23e349 2925#ifdef CONFIG_CFG80211_WEXT
08645126 2926 if (!err) {
b9454e83 2927 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 2928 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 2929 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
2930 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
2931 }
2932#endif
fffd0934 2933 wdev_unlock(dev->ieee80211_ptr);
08645126 2934
41ade00f
JB
2935 return err;
2936}
2937
77765eaf
VT
2938/* This function returns an error or the number of nested attributes */
2939static int validate_acl_mac_addrs(struct nlattr *nl_attr)
2940{
2941 struct nlattr *attr;
2942 int n_entries = 0, tmp;
2943
2944 nla_for_each_nested(attr, nl_attr, tmp) {
2945 if (nla_len(attr) != ETH_ALEN)
2946 return -EINVAL;
2947
2948 n_entries++;
2949 }
2950
2951 return n_entries;
2952}
2953
2954/*
2955 * This function parses ACL information and allocates memory for ACL data.
2956 * On successful return, the calling function is responsible to free the
2957 * ACL buffer returned by this function.
2958 */
2959static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
2960 struct genl_info *info)
2961{
2962 enum nl80211_acl_policy acl_policy;
2963 struct nlattr *attr;
2964 struct cfg80211_acl_data *acl;
2965 int i = 0, n_entries, tmp;
2966
2967 if (!wiphy->max_acl_mac_addrs)
2968 return ERR_PTR(-EOPNOTSUPP);
2969
2970 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
2971 return ERR_PTR(-EINVAL);
2972
2973 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
2974 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
2975 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
2976 return ERR_PTR(-EINVAL);
2977
2978 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
2979 return ERR_PTR(-EINVAL);
2980
2981 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
2982 if (n_entries < 0)
2983 return ERR_PTR(n_entries);
2984
2985 if (n_entries > wiphy->max_acl_mac_addrs)
2986 return ERR_PTR(-ENOTSUPP);
2987
2988 acl = kzalloc(sizeof(*acl) + (sizeof(struct mac_address) * n_entries),
2989 GFP_KERNEL);
2990 if (!acl)
2991 return ERR_PTR(-ENOMEM);
2992
2993 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
2994 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
2995 i++;
2996 }
2997
2998 acl->n_acl_entries = n_entries;
2999 acl->acl_policy = acl_policy;
3000
3001 return acl;
3002}
3003
3004static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
3005{
3006 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3007 struct net_device *dev = info->user_ptr[1];
3008 struct cfg80211_acl_data *acl;
3009 int err;
3010
3011 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3012 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3013 return -EOPNOTSUPP;
3014
3015 if (!dev->ieee80211_ptr->beacon_interval)
3016 return -EINVAL;
3017
3018 acl = parse_acl_data(&rdev->wiphy, info);
3019 if (IS_ERR(acl))
3020 return PTR_ERR(acl);
3021
3022 err = rdev_set_mac_acl(rdev, dev, acl);
3023
3024 kfree(acl);
3025
3026 return err;
3027}
3028
a1193be8 3029static int nl80211_parse_beacon(struct nlattr *attrs[],
8860020e 3030 struct cfg80211_beacon_data *bcn)
ed1b6cc7 3031{
8860020e 3032 bool haveinfo = false;
ed1b6cc7 3033
a1193be8
SW
3034 if (!is_valid_ie_attr(attrs[NL80211_ATTR_BEACON_TAIL]) ||
3035 !is_valid_ie_attr(attrs[NL80211_ATTR_IE]) ||
3036 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
3037 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_ASSOC_RESP]))
f4a11bb0
JB
3038 return -EINVAL;
3039
8860020e 3040 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 3041
a1193be8
SW
3042 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
3043 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
3044 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
3045 if (!bcn->head_len)
3046 return -EINVAL;
3047 haveinfo = true;
ed1b6cc7
JB
3048 }
3049
a1193be8
SW
3050 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
3051 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
3052 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 3053 haveinfo = true;
ed1b6cc7
JB
3054 }
3055
4c476991
JB
3056 if (!haveinfo)
3057 return -EINVAL;
3b85875a 3058
a1193be8
SW
3059 if (attrs[NL80211_ATTR_IE]) {
3060 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
3061 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
3062 }
3063
a1193be8 3064 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 3065 bcn->proberesp_ies =
a1193be8 3066 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 3067 bcn->proberesp_ies_len =
a1193be8 3068 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
3069 }
3070
a1193be8 3071 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 3072 bcn->assocresp_ies =
a1193be8 3073 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 3074 bcn->assocresp_ies_len =
a1193be8 3075 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
3076 }
3077
a1193be8
SW
3078 if (attrs[NL80211_ATTR_PROBE_RESP]) {
3079 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
3080 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
3081 }
3082
8860020e
JB
3083 return 0;
3084}
3085
46c1dd0c
FF
3086static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3087 struct cfg80211_ap_settings *params)
3088{
3089 struct wireless_dev *wdev;
3090 bool ret = false;
3091
89a54e48 3092 list_for_each_entry(wdev, &rdev->wdev_list, list) {
46c1dd0c
FF
3093 if (wdev->iftype != NL80211_IFTYPE_AP &&
3094 wdev->iftype != NL80211_IFTYPE_P2P_GO)
3095 continue;
3096
683b6d3b 3097 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
3098 continue;
3099
683b6d3b 3100 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
3101 ret = true;
3102 break;
3103 }
3104
46c1dd0c
FF
3105 return ret;
3106}
3107
e39e5b5e
JM
3108static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
3109 enum nl80211_auth_type auth_type,
3110 enum nl80211_commands cmd)
3111{
3112 if (auth_type > NL80211_AUTHTYPE_MAX)
3113 return false;
3114
3115 switch (cmd) {
3116 case NL80211_CMD_AUTHENTICATE:
3117 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
3118 auth_type == NL80211_AUTHTYPE_SAE)
3119 return false;
3120 return true;
3121 case NL80211_CMD_CONNECT:
3122 case NL80211_CMD_START_AP:
3123 /* SAE not supported yet */
3124 if (auth_type == NL80211_AUTHTYPE_SAE)
3125 return false;
3126 return true;
3127 default:
3128 return false;
3129 }
3130}
3131
8860020e
JB
3132static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3133{
3134 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3135 struct net_device *dev = info->user_ptr[1];
3136 struct wireless_dev *wdev = dev->ieee80211_ptr;
3137 struct cfg80211_ap_settings params;
3138 int err;
04f39047 3139 u8 radar_detect_width = 0;
8860020e
JB
3140
3141 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3142 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3143 return -EOPNOTSUPP;
3144
3145 if (!rdev->ops->start_ap)
3146 return -EOPNOTSUPP;
3147
3148 if (wdev->beacon_interval)
3149 return -EALREADY;
3150
3151 memset(&params, 0, sizeof(params));
3152
3153 /* these are required for START_AP */
3154 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
3155 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
3156 !info->attrs[NL80211_ATTR_BEACON_HEAD])
3157 return -EINVAL;
3158
a1193be8 3159 err = nl80211_parse_beacon(info->attrs, &params.beacon);
8860020e
JB
3160 if (err)
3161 return err;
3162
3163 params.beacon_interval =
3164 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3165 params.dtim_period =
3166 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
3167
3168 err = cfg80211_validate_beacon_int(rdev, params.beacon_interval);
3169 if (err)
3170 return err;
3171
3172 /*
3173 * In theory, some of these attributes should be required here
3174 * but since they were not used when the command was originally
3175 * added, keep them optional for old user space programs to let
3176 * them continue to work with drivers that do not need the
3177 * additional information -- drivers must check!
3178 */
3179 if (info->attrs[NL80211_ATTR_SSID]) {
3180 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3181 params.ssid_len =
3182 nla_len(info->attrs[NL80211_ATTR_SSID]);
3183 if (params.ssid_len == 0 ||
3184 params.ssid_len > IEEE80211_MAX_SSID_LEN)
3185 return -EINVAL;
3186 }
3187
3188 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
3189 params.hidden_ssid = nla_get_u32(
3190 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
3191 if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
3192 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
3193 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
3194 return -EINVAL;
3195 }
3196
3197 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
3198
3199 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
3200 params.auth_type = nla_get_u32(
3201 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
3202 if (!nl80211_valid_auth_type(rdev, params.auth_type,
3203 NL80211_CMD_START_AP))
8860020e
JB
3204 return -EINVAL;
3205 } else
3206 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
3207
3208 err = nl80211_crypto_settings(rdev, info, &params.crypto,
3209 NL80211_MAX_NR_CIPHER_SUITES);
3210 if (err)
3211 return err;
3212
1b658f11
VT
3213 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
3214 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
3215 return -EOPNOTSUPP;
3216 params.inactivity_timeout = nla_get_u16(
3217 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
3218 }
3219
53cabad7
JB
3220 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
3221 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3222 return -EINVAL;
3223 params.p2p_ctwindow =
3224 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
3225 if (params.p2p_ctwindow > 127)
3226 return -EINVAL;
3227 if (params.p2p_ctwindow != 0 &&
3228 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
3229 return -EINVAL;
3230 }
3231
3232 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
3233 u8 tmp;
3234
3235 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3236 return -EINVAL;
3237 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
3238 if (tmp > 1)
3239 return -EINVAL;
3240 params.p2p_opp_ps = tmp;
3241 if (params.p2p_opp_ps != 0 &&
3242 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
3243 return -EINVAL;
3244 }
3245
aa430da4 3246 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
3247 err = nl80211_parse_chandef(rdev, info, &params.chandef);
3248 if (err)
3249 return err;
3250 } else if (wdev->preset_chandef.chan) {
3251 params.chandef = wdev->preset_chandef;
46c1dd0c 3252 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
3253 return -EINVAL;
3254
683b6d3b 3255 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
aa430da4
JB
3256 return -EINVAL;
3257
04f39047
SW
3258 err = cfg80211_chandef_dfs_required(wdev->wiphy, &params.chandef);
3259 if (err < 0)
3260 return err;
3261 if (err) {
3262 radar_detect_width = BIT(params.chandef.width);
3263 params.radar_required = true;
3264 }
3265
04f39047
SW
3266 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
3267 params.chandef.chan,
3268 CHAN_MODE_SHARED,
3269 radar_detect_width);
e4e32459
MK
3270 if (err)
3271 return err;
3272
77765eaf
VT
3273 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
3274 params.acl = parse_acl_data(&rdev->wiphy, info);
3275 if (IS_ERR(params.acl))
3276 return PTR_ERR(params.acl);
3277 }
3278
c56589ed 3279 wdev_lock(wdev);
e35e4d28 3280 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 3281 if (!err) {
683b6d3b 3282 wdev->preset_chandef = params.chandef;
8860020e 3283 wdev->beacon_interval = params.beacon_interval;
9e0e2961 3284 wdev->chandef = params.chandef;
06e191e2
AQ
3285 wdev->ssid_len = params.ssid_len;
3286 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
46c1dd0c 3287 }
c56589ed 3288 wdev_unlock(wdev);
77765eaf
VT
3289
3290 kfree(params.acl);
3291
56d1893d 3292 return err;
ed1b6cc7
JB
3293}
3294
8860020e
JB
3295static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
3296{
3297 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3298 struct net_device *dev = info->user_ptr[1];
3299 struct wireless_dev *wdev = dev->ieee80211_ptr;
3300 struct cfg80211_beacon_data params;
3301 int err;
3302
3303 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3304 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3305 return -EOPNOTSUPP;
3306
3307 if (!rdev->ops->change_beacon)
3308 return -EOPNOTSUPP;
3309
3310 if (!wdev->beacon_interval)
3311 return -EINVAL;
3312
a1193be8 3313 err = nl80211_parse_beacon(info->attrs, &params);
8860020e
JB
3314 if (err)
3315 return err;
3316
c56589ed
SW
3317 wdev_lock(wdev);
3318 err = rdev_change_beacon(rdev, dev, &params);
3319 wdev_unlock(wdev);
3320
3321 return err;
8860020e
JB
3322}
3323
3324static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 3325{
4c476991
JB
3326 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3327 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 3328
60771780 3329 return cfg80211_stop_ap(rdev, dev);
ed1b6cc7
JB
3330}
3331
5727ef1b
JB
3332static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
3333 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
3334 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
3335 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 3336 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 3337 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 3338 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
3339};
3340
eccb8e8f 3341static int parse_station_flags(struct genl_info *info,
bdd3ae3d 3342 enum nl80211_iftype iftype,
eccb8e8f 3343 struct station_parameters *params)
5727ef1b
JB
3344{
3345 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 3346 struct nlattr *nla;
5727ef1b
JB
3347 int flag;
3348
eccb8e8f
JB
3349 /*
3350 * Try parsing the new attribute first so userspace
3351 * can specify both for older kernels.
3352 */
3353 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
3354 if (nla) {
3355 struct nl80211_sta_flag_update *sta_flags;
3356
3357 sta_flags = nla_data(nla);
3358 params->sta_flags_mask = sta_flags->mask;
3359 params->sta_flags_set = sta_flags->set;
77ee7c89 3360 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
3361 if ((params->sta_flags_mask |
3362 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
3363 return -EINVAL;
3364 return 0;
3365 }
3366
3367 /* if present, parse the old attribute */
5727ef1b 3368
eccb8e8f 3369 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
3370 if (!nla)
3371 return 0;
3372
3373 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
3374 nla, sta_flags_policy))
3375 return -EINVAL;
3376
bdd3ae3d
JB
3377 /*
3378 * Only allow certain flags for interface types so that
3379 * other attributes are silently ignored. Remember that
3380 * this is backward compatibility code with old userspace
3381 * and shouldn't be hit in other cases anyway.
3382 */
3383 switch (iftype) {
3384 case NL80211_IFTYPE_AP:
3385 case NL80211_IFTYPE_AP_VLAN:
3386 case NL80211_IFTYPE_P2P_GO:
3387 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
3388 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
3389 BIT(NL80211_STA_FLAG_WME) |
3390 BIT(NL80211_STA_FLAG_MFP);
3391 break;
3392 case NL80211_IFTYPE_P2P_CLIENT:
3393 case NL80211_IFTYPE_STATION:
3394 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
3395 BIT(NL80211_STA_FLAG_TDLS_PEER);
3396 break;
3397 case NL80211_IFTYPE_MESH_POINT:
3398 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3399 BIT(NL80211_STA_FLAG_MFP) |
3400 BIT(NL80211_STA_FLAG_AUTHORIZED);
3401 default:
3402 return -EINVAL;
3403 }
5727ef1b 3404
3383b5a6
JB
3405 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
3406 if (flags[flag]) {
eccb8e8f 3407 params->sta_flags_set |= (1<<flag);
5727ef1b 3408
3383b5a6
JB
3409 /* no longer support new API additions in old API */
3410 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
3411 return -EINVAL;
3412 }
3413 }
3414
5727ef1b
JB
3415 return 0;
3416}
3417
c8dcfd8a
FF
3418static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
3419 int attr)
3420{
3421 struct nlattr *rate;
8eb41c8d
VK
3422 u32 bitrate;
3423 u16 bitrate_compat;
c8dcfd8a
FF
3424
3425 rate = nla_nest_start(msg, attr);
3426 if (!rate)
db9c64cf 3427 return false;
c8dcfd8a
FF
3428
3429 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
3430 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
3431 /* report 16-bit bitrate only if we can */
3432 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
3433 if (bitrate > 0 &&
3434 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
3435 return false;
3436 if (bitrate_compat > 0 &&
3437 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
3438 return false;
3439
3440 if (info->flags & RATE_INFO_FLAGS_MCS) {
3441 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
3442 return false;
3443 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
3444 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
3445 return false;
3446 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
3447 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
3448 return false;
3449 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
3450 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
3451 return false;
3452 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
3453 return false;
3454 if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
3455 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
3456 return false;
3457 if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH &&
3458 nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH))
3459 return false;
3460 if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH &&
3461 nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH))
3462 return false;
3463 if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH &&
3464 nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH))
3465 return false;
3466 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
3467 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
3468 return false;
3469 }
c8dcfd8a
FF
3470
3471 nla_nest_end(msg, rate);
3472 return true;
c8dcfd8a
FF
3473}
3474
119363c7
FF
3475static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
3476 int id)
3477{
3478 void *attr;
3479 int i = 0;
3480
3481 if (!mask)
3482 return true;
3483
3484 attr = nla_nest_start(msg, id);
3485 if (!attr)
3486 return false;
3487
3488 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
3489 if (!(mask & BIT(i)))
3490 continue;
3491
3492 if (nla_put_u8(msg, i, signal[i]))
3493 return false;
3494 }
3495
3496 nla_nest_end(msg, attr);
3497
3498 return true;
3499}
3500
15e47304 3501static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
66266b3a
JL
3502 int flags,
3503 struct cfg80211_registered_device *rdev,
3504 struct net_device *dev,
98b62183 3505 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
3506{
3507 void *hdr;
f4263c98 3508 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 3509
15e47304 3510 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION);
fd5b74dc
JB
3511 if (!hdr)
3512 return -1;
3513
9360ffd1
DM
3514 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3515 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
3516 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
3517 goto nla_put_failure;
f5ea9120 3518
2ec600d6
LCC
3519 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
3520 if (!sinfoattr)
fd5b74dc 3521 goto nla_put_failure;
9360ffd1
DM
3522 if ((sinfo->filled & STATION_INFO_CONNECTED_TIME) &&
3523 nla_put_u32(msg, NL80211_STA_INFO_CONNECTED_TIME,
3524 sinfo->connected_time))
3525 goto nla_put_failure;
3526 if ((sinfo->filled & STATION_INFO_INACTIVE_TIME) &&
3527 nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME,
3528 sinfo->inactive_time))
3529 goto nla_put_failure;
42745e03
VK
3530 if ((sinfo->filled & (STATION_INFO_RX_BYTES |
3531 STATION_INFO_RX_BYTES64)) &&
9360ffd1 3532 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 3533 (u32)sinfo->rx_bytes))
9360ffd1 3534 goto nla_put_failure;
42745e03 3535 if ((sinfo->filled & (STATION_INFO_TX_BYTES |
4325d724 3536 STATION_INFO_TX_BYTES64)) &&
9360ffd1 3537 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
3538 (u32)sinfo->tx_bytes))
3539 goto nla_put_failure;
3540 if ((sinfo->filled & STATION_INFO_RX_BYTES64) &&
3541 nla_put_u64(msg, NL80211_STA_INFO_RX_BYTES64,
3542 sinfo->rx_bytes))
3543 goto nla_put_failure;
3544 if ((sinfo->filled & STATION_INFO_TX_BYTES64) &&
3545 nla_put_u64(msg, NL80211_STA_INFO_TX_BYTES64,
9360ffd1
DM
3546 sinfo->tx_bytes))
3547 goto nla_put_failure;
3548 if ((sinfo->filled & STATION_INFO_LLID) &&
3549 nla_put_u16(msg, NL80211_STA_INFO_LLID, sinfo->llid))
3550 goto nla_put_failure;
3551 if ((sinfo->filled & STATION_INFO_PLID) &&
3552 nla_put_u16(msg, NL80211_STA_INFO_PLID, sinfo->plid))
3553 goto nla_put_failure;
3554 if ((sinfo->filled & STATION_INFO_PLINK_STATE) &&
3555 nla_put_u8(msg, NL80211_STA_INFO_PLINK_STATE,
3556 sinfo->plink_state))
3557 goto nla_put_failure;
66266b3a
JL
3558 switch (rdev->wiphy.signal_type) {
3559 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
3560 if ((sinfo->filled & STATION_INFO_SIGNAL) &&
3561 nla_put_u8(msg, NL80211_STA_INFO_SIGNAL,
3562 sinfo->signal))
3563 goto nla_put_failure;
3564 if ((sinfo->filled & STATION_INFO_SIGNAL_AVG) &&
3565 nla_put_u8(msg, NL80211_STA_INFO_SIGNAL_AVG,
3566 sinfo->signal_avg))
3567 goto nla_put_failure;
66266b3a
JL
3568 break;
3569 default:
3570 break;
3571 }
119363c7
FF
3572 if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
3573 if (!nl80211_put_signal(msg, sinfo->chains,
3574 sinfo->chain_signal,
3575 NL80211_STA_INFO_CHAIN_SIGNAL))
3576 goto nla_put_failure;
3577 }
3578 if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
3579 if (!nl80211_put_signal(msg, sinfo->chains,
3580 sinfo->chain_signal_avg,
3581 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
3582 goto nla_put_failure;
3583 }
420e7fab 3584 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
c8dcfd8a
FF
3585 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
3586 NL80211_STA_INFO_TX_BITRATE))
3587 goto nla_put_failure;
3588 }
3589 if (sinfo->filled & STATION_INFO_RX_BITRATE) {
3590 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
3591 NL80211_STA_INFO_RX_BITRATE))
420e7fab 3592 goto nla_put_failure;
420e7fab 3593 }
9360ffd1
DM
3594 if ((sinfo->filled & STATION_INFO_RX_PACKETS) &&
3595 nla_put_u32(msg, NL80211_STA_INFO_RX_PACKETS,
3596 sinfo->rx_packets))
3597 goto nla_put_failure;
3598 if ((sinfo->filled & STATION_INFO_TX_PACKETS) &&
3599 nla_put_u32(msg, NL80211_STA_INFO_TX_PACKETS,
3600 sinfo->tx_packets))
3601 goto nla_put_failure;
3602 if ((sinfo->filled & STATION_INFO_TX_RETRIES) &&
3603 nla_put_u32(msg, NL80211_STA_INFO_TX_RETRIES,
3604 sinfo->tx_retries))
3605 goto nla_put_failure;
3606 if ((sinfo->filled & STATION_INFO_TX_FAILED) &&
3607 nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED,
3608 sinfo->tx_failed))
3609 goto nla_put_failure;
3610 if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) &&
3611 nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS,
3612 sinfo->beacon_loss_count))
3613 goto nla_put_failure;
3b1c5a53
MP
3614 if ((sinfo->filled & STATION_INFO_LOCAL_PM) &&
3615 nla_put_u32(msg, NL80211_STA_INFO_LOCAL_PM,
3616 sinfo->local_pm))
3617 goto nla_put_failure;
3618 if ((sinfo->filled & STATION_INFO_PEER_PM) &&
3619 nla_put_u32(msg, NL80211_STA_INFO_PEER_PM,
3620 sinfo->peer_pm))
3621 goto nla_put_failure;
3622 if ((sinfo->filled & STATION_INFO_NONPEER_PM) &&
3623 nla_put_u32(msg, NL80211_STA_INFO_NONPEER_PM,
3624 sinfo->nonpeer_pm))
3625 goto nla_put_failure;
f4263c98
PS
3626 if (sinfo->filled & STATION_INFO_BSS_PARAM) {
3627 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
3628 if (!bss_param)
3629 goto nla_put_failure;
3630
9360ffd1
DM
3631 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
3632 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
3633 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
3634 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
3635 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
3636 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
3637 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
3638 sinfo->bss_param.dtim_period) ||
3639 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
3640 sinfo->bss_param.beacon_interval))
3641 goto nla_put_failure;
f4263c98
PS
3642
3643 nla_nest_end(msg, bss_param);
3644 }
9360ffd1
DM
3645 if ((sinfo->filled & STATION_INFO_STA_FLAGS) &&
3646 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
3647 sizeof(struct nl80211_sta_flag_update),
3648 &sinfo->sta_flags))
3649 goto nla_put_failure;
7eab0f64
JL
3650 if ((sinfo->filled & STATION_INFO_T_OFFSET) &&
3651 nla_put_u64(msg, NL80211_STA_INFO_T_OFFSET,
3652 sinfo->t_offset))
3653 goto nla_put_failure;
2ec600d6 3654 nla_nest_end(msg, sinfoattr);
fd5b74dc 3655
9360ffd1
DM
3656 if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) &&
3657 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
3658 sinfo->assoc_req_ies))
3659 goto nla_put_failure;
50d3dfb7 3660
fd5b74dc
JB
3661 return genlmsg_end(msg, hdr);
3662
3663 nla_put_failure:
bc3ed28c
TG
3664 genlmsg_cancel(msg, hdr);
3665 return -EMSGSIZE;
fd5b74dc
JB
3666}
3667
2ec600d6 3668static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 3669 struct netlink_callback *cb)
2ec600d6 3670{
2ec600d6
LCC
3671 struct station_info sinfo;
3672 struct cfg80211_registered_device *dev;
97990a06 3673 struct wireless_dev *wdev;
2ec600d6 3674 u8 mac_addr[ETH_ALEN];
97990a06 3675 int sta_idx = cb->args[2];
2ec600d6 3676 int err;
2ec600d6 3677
97990a06 3678 err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev);
67748893
JB
3679 if (err)
3680 return err;
bba95fef 3681
97990a06
JB
3682 if (!wdev->netdev) {
3683 err = -EINVAL;
3684 goto out_err;
3685 }
3686
bba95fef 3687 if (!dev->ops->dump_station) {
eec60b03 3688 err = -EOPNOTSUPP;
bba95fef
JB
3689 goto out_err;
3690 }
3691
bba95fef 3692 while (1) {
f612cedf 3693 memset(&sinfo, 0, sizeof(sinfo));
97990a06 3694 err = rdev_dump_station(dev, wdev->netdev, sta_idx,
e35e4d28 3695 mac_addr, &sinfo);
bba95fef
JB
3696 if (err == -ENOENT)
3697 break;
3698 if (err)
3b85875a 3699 goto out_err;
bba95fef
JB
3700
3701 if (nl80211_send_station(skb,
15e47304 3702 NETLINK_CB(cb->skb).portid,
bba95fef 3703 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 3704 dev, wdev->netdev, mac_addr,
bba95fef
JB
3705 &sinfo) < 0)
3706 goto out;
3707
3708 sta_idx++;
3709 }
3710
3711
3712 out:
97990a06 3713 cb->args[2] = sta_idx;
bba95fef 3714 err = skb->len;
bba95fef 3715 out_err:
97990a06 3716 nl80211_finish_wdev_dump(dev);
bba95fef
JB
3717
3718 return err;
2ec600d6 3719}
fd5b74dc 3720
5727ef1b
JB
3721static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
3722{
4c476991
JB
3723 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3724 struct net_device *dev = info->user_ptr[1];
2ec600d6 3725 struct station_info sinfo;
fd5b74dc
JB
3726 struct sk_buff *msg;
3727 u8 *mac_addr = NULL;
4c476991 3728 int err;
fd5b74dc 3729
2ec600d6 3730 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc
JB
3731
3732 if (!info->attrs[NL80211_ATTR_MAC])
3733 return -EINVAL;
3734
3735 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3736
4c476991
JB
3737 if (!rdev->ops->get_station)
3738 return -EOPNOTSUPP;
3b85875a 3739
e35e4d28 3740 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 3741 if (err)
4c476991 3742 return err;
2ec600d6 3743
fd2120ca 3744 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
fd5b74dc 3745 if (!msg)
4c476991 3746 return -ENOMEM;
fd5b74dc 3747
15e47304 3748 if (nl80211_send_station(msg, info->snd_portid, info->snd_seq, 0,
66266b3a 3749 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991
JB
3750 nlmsg_free(msg);
3751 return -ENOBUFS;
3752 }
3b85875a 3753
4c476991 3754 return genlmsg_reply(msg, info);
5727ef1b
JB
3755}
3756
77ee7c89
JB
3757int cfg80211_check_station_change(struct wiphy *wiphy,
3758 struct station_parameters *params,
3759 enum cfg80211_station_type statype)
3760{
3761 if (params->listen_interval != -1)
3762 return -EINVAL;
3763 if (params->aid)
3764 return -EINVAL;
3765
3766 /* When you run into this, adjust the code below for the new flag */
3767 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
3768
3769 switch (statype) {
eef941e6
TP
3770 case CFG80211_STA_MESH_PEER_KERNEL:
3771 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
3772 /*
3773 * No ignoring the TDLS flag here -- the userspace mesh
3774 * code doesn't have the bug of including TDLS in the
3775 * mask everywhere.
3776 */
3777 if (params->sta_flags_mask &
3778 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3779 BIT(NL80211_STA_FLAG_MFP) |
3780 BIT(NL80211_STA_FLAG_AUTHORIZED)))
3781 return -EINVAL;
3782 break;
3783 case CFG80211_STA_TDLS_PEER_SETUP:
3784 case CFG80211_STA_TDLS_PEER_ACTIVE:
3785 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
3786 return -EINVAL;
3787 /* ignore since it can't change */
3788 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3789 break;
3790 default:
3791 /* disallow mesh-specific things */
3792 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
3793 return -EINVAL;
3794 if (params->local_pm)
3795 return -EINVAL;
3796 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
3797 return -EINVAL;
3798 }
3799
3800 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
3801 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
3802 /* TDLS can't be set, ... */
3803 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
3804 return -EINVAL;
3805 /*
3806 * ... but don't bother the driver with it. This works around
3807 * a hostapd/wpa_supplicant issue -- it always includes the
3808 * TLDS_PEER flag in the mask even for AP mode.
3809 */
3810 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3811 }
3812
3813 if (statype != CFG80211_STA_TDLS_PEER_SETUP) {
3814 /* reject other things that can't change */
3815 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
3816 return -EINVAL;
3817 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
3818 return -EINVAL;
3819 if (params->supported_rates)
3820 return -EINVAL;
3821 if (params->ext_capab || params->ht_capa || params->vht_capa)
3822 return -EINVAL;
3823 }
3824
3825 if (statype != CFG80211_STA_AP_CLIENT) {
3826 if (params->vlan)
3827 return -EINVAL;
3828 }
3829
3830 switch (statype) {
3831 case CFG80211_STA_AP_MLME_CLIENT:
3832 /* Use this only for authorizing/unauthorizing a station */
3833 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
3834 return -EOPNOTSUPP;
3835 break;
3836 case CFG80211_STA_AP_CLIENT:
3837 /* accept only the listed bits */
3838 if (params->sta_flags_mask &
3839 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
3840 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3841 BIT(NL80211_STA_FLAG_ASSOCIATED) |
3842 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
3843 BIT(NL80211_STA_FLAG_WME) |
3844 BIT(NL80211_STA_FLAG_MFP)))
3845 return -EINVAL;
3846
3847 /* but authenticated/associated only if driver handles it */
3848 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
3849 params->sta_flags_mask &
3850 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3851 BIT(NL80211_STA_FLAG_ASSOCIATED)))
3852 return -EINVAL;
3853 break;
3854 case CFG80211_STA_IBSS:
3855 case CFG80211_STA_AP_STA:
3856 /* reject any changes other than AUTHORIZED */
3857 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
3858 return -EINVAL;
3859 break;
3860 case CFG80211_STA_TDLS_PEER_SETUP:
3861 /* reject any changes other than AUTHORIZED or WME */
3862 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
3863 BIT(NL80211_STA_FLAG_WME)))
3864 return -EINVAL;
3865 /* force (at least) rates when authorizing */
3866 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
3867 !params->supported_rates)
3868 return -EINVAL;
3869 break;
3870 case CFG80211_STA_TDLS_PEER_ACTIVE:
3871 /* reject any changes */
3872 return -EINVAL;
eef941e6 3873 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
3874 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
3875 return -EINVAL;
3876 break;
eef941e6 3877 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
3878 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
3879 return -EINVAL;
3880 break;
3881 }
3882
3883 return 0;
3884}
3885EXPORT_SYMBOL(cfg80211_check_station_change);
3886
5727ef1b 3887/*
c258d2de 3888 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 3889 */
80b99899
JB
3890static struct net_device *get_vlan(struct genl_info *info,
3891 struct cfg80211_registered_device *rdev)
5727ef1b 3892{
463d0183 3893 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
3894 struct net_device *v;
3895 int ret;
3896
3897 if (!vlanattr)
3898 return NULL;
3899
3900 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
3901 if (!v)
3902 return ERR_PTR(-ENODEV);
3903
3904 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
3905 ret = -EINVAL;
3906 goto error;
5727ef1b 3907 }
80b99899 3908
77ee7c89
JB
3909 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
3910 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3911 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
3912 ret = -EINVAL;
3913 goto error;
3914 }
3915
80b99899
JB
3916 if (!netif_running(v)) {
3917 ret = -ENETDOWN;
3918 goto error;
3919 }
3920
3921 return v;
3922 error:
3923 dev_put(v);
3924 return ERR_PTR(ret);
5727ef1b
JB
3925}
3926
94e860f1
JB
3927static const struct nla_policy
3928nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
3929 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
3930 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
3931};
3932
ff276691
JB
3933static int nl80211_parse_sta_wme(struct genl_info *info,
3934 struct station_parameters *params)
df881293 3935{
df881293
JM
3936 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
3937 struct nlattr *nla;
3938 int err;
3939
df881293
JM
3940 /* parse WME attributes if present */
3941 if (!info->attrs[NL80211_ATTR_STA_WME])
3942 return 0;
3943
3944 nla = info->attrs[NL80211_ATTR_STA_WME];
3945 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
3946 nl80211_sta_wme_policy);
3947 if (err)
3948 return err;
3949
3950 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
3951 params->uapsd_queues = nla_get_u8(
3952 tb[NL80211_STA_WME_UAPSD_QUEUES]);
3953 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
3954 return -EINVAL;
3955
3956 if (tb[NL80211_STA_WME_MAX_SP])
3957 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
3958
3959 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
3960 return -EINVAL;
3961
3962 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
3963
3964 return 0;
3965}
3966
c01fc9ad
SD
3967static int nl80211_parse_sta_channel_info(struct genl_info *info,
3968 struct station_parameters *params)
3969{
3970 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
3971 params->supported_channels =
3972 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
3973 params->supported_channels_len =
3974 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
3975 /*
3976 * Need to include at least one (first channel, number of
3977 * channels) tuple for each subband, and must have proper
3978 * tuples for the rest of the data as well.
3979 */
3980 if (params->supported_channels_len < 2)
3981 return -EINVAL;
3982 if (params->supported_channels_len % 2)
3983 return -EINVAL;
3984 }
3985
3986 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
3987 params->supported_oper_classes =
3988 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
3989 params->supported_oper_classes_len =
3990 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
3991 /*
3992 * The value of the Length field of the Supported Operating
3993 * Classes element is between 2 and 253.
3994 */
3995 if (params->supported_oper_classes_len < 2 ||
3996 params->supported_oper_classes_len > 253)
3997 return -EINVAL;
3998 }
3999 return 0;
4000}
4001
ff276691
JB
4002static int nl80211_set_station_tdls(struct genl_info *info,
4003 struct station_parameters *params)
4004{
c01fc9ad 4005 int err;
ff276691 4006 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
4007 if (info->attrs[NL80211_ATTR_PEER_AID])
4008 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
4009 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
4010 params->ht_capa =
4011 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
4012 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
4013 params->vht_capa =
4014 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
4015
c01fc9ad
SD
4016 err = nl80211_parse_sta_channel_info(info, params);
4017 if (err)
4018 return err;
4019
ff276691
JB
4020 return nl80211_parse_sta_wme(info, params);
4021}
4022
5727ef1b
JB
4023static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
4024{
4c476991 4025 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 4026 struct net_device *dev = info->user_ptr[1];
5727ef1b 4027 struct station_parameters params;
77ee7c89
JB
4028 u8 *mac_addr;
4029 int err;
5727ef1b
JB
4030
4031 memset(&params, 0, sizeof(params));
4032
4033 params.listen_interval = -1;
4034
77ee7c89
JB
4035 if (!rdev->ops->change_station)
4036 return -EOPNOTSUPP;
4037
5727ef1b
JB
4038 if (info->attrs[NL80211_ATTR_STA_AID])
4039 return -EINVAL;
4040
4041 if (!info->attrs[NL80211_ATTR_MAC])
4042 return -EINVAL;
4043
4044 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4045
4046 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
4047 params.supported_rates =
4048 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4049 params.supported_rates_len =
4050 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4051 }
4052
9d62a986
JM
4053 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
4054 params.capability =
4055 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
4056 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
4057 }
4058
4059 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
4060 params.ext_capab =
4061 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4062 params.ext_capab_len =
4063 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4064 }
4065
df881293 4066 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
ba23d206 4067 return -EINVAL;
36aedc90 4068
bdd3ae3d 4069 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
4070 return -EINVAL;
4071
f8bacc21 4072 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
2ec600d6 4073 params.plink_action =
f8bacc21
JB
4074 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
4075 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
4076 return -EINVAL;
4077 }
2ec600d6 4078
f8bacc21 4079 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 4080 params.plink_state =
f8bacc21
JB
4081 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
4082 if (params.plink_state >= NUM_NL80211_PLINK_STATES)
4083 return -EINVAL;
4084 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
4085 }
9c3990aa 4086
3b1c5a53
MP
4087 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) {
4088 enum nl80211_mesh_power_mode pm = nla_get_u32(
4089 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
4090
4091 if (pm <= NL80211_MESH_POWER_UNKNOWN ||
4092 pm > NL80211_MESH_POWER_MAX)
4093 return -EINVAL;
4094
4095 params.local_pm = pm;
4096 }
4097
77ee7c89
JB
4098 /* Include parameters for TDLS peer (will check later) */
4099 err = nl80211_set_station_tdls(info, &params);
4100 if (err)
4101 return err;
4102
4103 params.vlan = get_vlan(info, rdev);
4104 if (IS_ERR(params.vlan))
4105 return PTR_ERR(params.vlan);
4106
a97f4424
JB
4107 switch (dev->ieee80211_ptr->iftype) {
4108 case NL80211_IFTYPE_AP:
4109 case NL80211_IFTYPE_AP_VLAN:
074ac8df 4110 case NL80211_IFTYPE_P2P_GO:
074ac8df 4111 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 4112 case NL80211_IFTYPE_STATION:
267335d6 4113 case NL80211_IFTYPE_ADHOC:
a97f4424 4114 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
4115 break;
4116 default:
77ee7c89
JB
4117 err = -EOPNOTSUPP;
4118 goto out_put_vlan;
034d655e
JB
4119 }
4120
77ee7c89 4121 /* driver will call cfg80211_check_station_change() */
e35e4d28 4122 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 4123
77ee7c89 4124 out_put_vlan:
5727ef1b
JB
4125 if (params.vlan)
4126 dev_put(params.vlan);
3b85875a 4127
5727ef1b
JB
4128 return err;
4129}
4130
4131static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
4132{
4c476991 4133 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 4134 int err;
4c476991 4135 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
4136 struct station_parameters params;
4137 u8 *mac_addr = NULL;
4138
4139 memset(&params, 0, sizeof(params));
4140
984c311b
JB
4141 if (!rdev->ops->add_station)
4142 return -EOPNOTSUPP;
4143
5727ef1b
JB
4144 if (!info->attrs[NL80211_ATTR_MAC])
4145 return -EINVAL;
4146
5727ef1b
JB
4147 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
4148 return -EINVAL;
4149
4150 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
4151 return -EINVAL;
4152
5e4b6f56
JM
4153 if (!info->attrs[NL80211_ATTR_STA_AID] &&
4154 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
4155 return -EINVAL;
4156
5727ef1b
JB
4157 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4158 params.supported_rates =
4159 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4160 params.supported_rates_len =
4161 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4162 params.listen_interval =
4163 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 4164
3d124ea2 4165 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 4166 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
4167 else
4168 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
0e956c13
TLSC
4169 if (!params.aid || params.aid > IEEE80211_MAX_AID)
4170 return -EINVAL;
51b50fbe 4171
9d62a986
JM
4172 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
4173 params.capability =
4174 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
4175 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
4176 }
4177
4178 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
4179 params.ext_capab =
4180 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4181 params.ext_capab_len =
4182 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4183 }
4184
36aedc90
JM
4185 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
4186 params.ht_capa =
4187 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 4188
f461be3e
MP
4189 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
4190 params.vht_capa =
4191 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
4192
60f4a7b1
MK
4193 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
4194 params.opmode_notif_used = true;
4195 params.opmode_notif =
4196 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
4197 }
4198
f8bacc21 4199 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
96b78dff 4200 params.plink_action =
f8bacc21
JB
4201 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
4202 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
4203 return -EINVAL;
4204 }
96b78dff 4205
c01fc9ad
SD
4206 err = nl80211_parse_sta_channel_info(info, &params);
4207 if (err)
4208 return err;
4209
ff276691
JB
4210 err = nl80211_parse_sta_wme(info, &params);
4211 if (err)
4212 return err;
bdd90d5e 4213
bdd3ae3d 4214 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
4215 return -EINVAL;
4216
77ee7c89
JB
4217 /* When you run into this, adjust the code below for the new flag */
4218 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
4219
bdd90d5e
JB
4220 switch (dev->ieee80211_ptr->iftype) {
4221 case NL80211_IFTYPE_AP:
4222 case NL80211_IFTYPE_AP_VLAN:
4223 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
4224 /* ignore WME attributes if iface/sta is not capable */
4225 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
4226 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
4227 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 4228
bdd90d5e 4229 /* TDLS peers cannot be added */
3d124ea2
JM
4230 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
4231 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 4232 return -EINVAL;
bdd90d5e
JB
4233 /* but don't bother the driver with it */
4234 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 4235
d582cffb
JB
4236 /* allow authenticated/associated only if driver handles it */
4237 if (!(rdev->wiphy.features &
4238 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
4239 params.sta_flags_mask &
4240 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4241 BIT(NL80211_STA_FLAG_ASSOCIATED)))
4242 return -EINVAL;
4243
bdd90d5e
JB
4244 /* must be last in here for error handling */
4245 params.vlan = get_vlan(info, rdev);
4246 if (IS_ERR(params.vlan))
4247 return PTR_ERR(params.vlan);
4248 break;
4249 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
4250 /* ignore uAPSD data */
4251 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
4252
d582cffb
JB
4253 /* associated is disallowed */
4254 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
4255 return -EINVAL;
bdd90d5e 4256 /* TDLS peers cannot be added */
3d124ea2
JM
4257 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
4258 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
4259 return -EINVAL;
4260 break;
4261 case NL80211_IFTYPE_STATION:
93d08f0b 4262 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
4263 /* ignore uAPSD data */
4264 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
4265
77ee7c89
JB
4266 /* these are disallowed */
4267 if (params.sta_flags_mask &
4268 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
4269 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 4270 return -EINVAL;
bdd90d5e
JB
4271 /* Only TDLS peers can be added */
4272 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
4273 return -EINVAL;
4274 /* Can only add if TDLS ... */
4275 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
4276 return -EOPNOTSUPP;
4277 /* ... with external setup is supported */
4278 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
4279 return -EOPNOTSUPP;
77ee7c89
JB
4280 /*
4281 * Older wpa_supplicant versions always mark the TDLS peer
4282 * as authorized, but it shouldn't yet be.
4283 */
4284 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
4285 break;
4286 default:
4287 return -EOPNOTSUPP;
c75786c9
EP
4288 }
4289
bdd90d5e 4290 /* be aware of params.vlan when changing code here */
5727ef1b 4291
e35e4d28 4292 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 4293
5727ef1b
JB
4294 if (params.vlan)
4295 dev_put(params.vlan);
5727ef1b
JB
4296 return err;
4297}
4298
4299static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
4300{
4c476991
JB
4301 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4302 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
4303 u8 *mac_addr = NULL;
4304
4305 if (info->attrs[NL80211_ATTR_MAC])
4306 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4307
e80cf853 4308 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
d5d9de02 4309 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
074ac8df 4310 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
4311 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4312 return -EINVAL;
5727ef1b 4313
4c476991
JB
4314 if (!rdev->ops->del_station)
4315 return -EOPNOTSUPP;
3b85875a 4316
e35e4d28 4317 return rdev_del_station(rdev, dev, mac_addr);
5727ef1b
JB
4318}
4319
15e47304 4320static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
4321 int flags, struct net_device *dev,
4322 u8 *dst, u8 *next_hop,
4323 struct mpath_info *pinfo)
4324{
4325 void *hdr;
4326 struct nlattr *pinfoattr;
4327
15e47304 4328 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION);
2ec600d6
LCC
4329 if (!hdr)
4330 return -1;
4331
9360ffd1
DM
4332 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4333 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
4334 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
4335 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
4336 goto nla_put_failure;
f5ea9120 4337
2ec600d6
LCC
4338 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
4339 if (!pinfoattr)
4340 goto nla_put_failure;
9360ffd1
DM
4341 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
4342 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
4343 pinfo->frame_qlen))
4344 goto nla_put_failure;
4345 if (((pinfo->filled & MPATH_INFO_SN) &&
4346 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
4347 ((pinfo->filled & MPATH_INFO_METRIC) &&
4348 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
4349 pinfo->metric)) ||
4350 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
4351 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
4352 pinfo->exptime)) ||
4353 ((pinfo->filled & MPATH_INFO_FLAGS) &&
4354 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
4355 pinfo->flags)) ||
4356 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
4357 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
4358 pinfo->discovery_timeout)) ||
4359 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
4360 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
4361 pinfo->discovery_retries)))
4362 goto nla_put_failure;
2ec600d6
LCC
4363
4364 nla_nest_end(msg, pinfoattr);
4365
4366 return genlmsg_end(msg, hdr);
4367
4368 nla_put_failure:
bc3ed28c
TG
4369 genlmsg_cancel(msg, hdr);
4370 return -EMSGSIZE;
2ec600d6
LCC
4371}
4372
4373static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 4374 struct netlink_callback *cb)
2ec600d6 4375{
2ec600d6
LCC
4376 struct mpath_info pinfo;
4377 struct cfg80211_registered_device *dev;
97990a06 4378 struct wireless_dev *wdev;
2ec600d6
LCC
4379 u8 dst[ETH_ALEN];
4380 u8 next_hop[ETH_ALEN];
97990a06 4381 int path_idx = cb->args[2];
2ec600d6 4382 int err;
2ec600d6 4383
97990a06 4384 err = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev);
67748893
JB
4385 if (err)
4386 return err;
bba95fef
JB
4387
4388 if (!dev->ops->dump_mpath) {
eec60b03 4389 err = -EOPNOTSUPP;
bba95fef
JB
4390 goto out_err;
4391 }
4392
97990a06 4393 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 4394 err = -EOPNOTSUPP;
0448b5fc 4395 goto out_err;
eec60b03
JM
4396 }
4397
bba95fef 4398 while (1) {
97990a06
JB
4399 err = rdev_dump_mpath(dev, wdev->netdev, path_idx, dst,
4400 next_hop, &pinfo);
bba95fef 4401 if (err == -ENOENT)
2ec600d6 4402 break;
bba95fef 4403 if (err)
3b85875a 4404 goto out_err;
2ec600d6 4405
15e47304 4406 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 4407 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 4408 wdev->netdev, dst, next_hop,
bba95fef
JB
4409 &pinfo) < 0)
4410 goto out;
2ec600d6 4411
bba95fef 4412 path_idx++;
2ec600d6 4413 }
2ec600d6 4414
2ec600d6 4415
bba95fef 4416 out:
97990a06 4417 cb->args[2] = path_idx;
bba95fef 4418 err = skb->len;
bba95fef 4419 out_err:
97990a06 4420 nl80211_finish_wdev_dump(dev);
bba95fef 4421 return err;
2ec600d6
LCC
4422}
4423
4424static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
4425{
4c476991 4426 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 4427 int err;
4c476991 4428 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
4429 struct mpath_info pinfo;
4430 struct sk_buff *msg;
4431 u8 *dst = NULL;
4432 u8 next_hop[ETH_ALEN];
4433
4434 memset(&pinfo, 0, sizeof(pinfo));
4435
4436 if (!info->attrs[NL80211_ATTR_MAC])
4437 return -EINVAL;
4438
4439 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
4440
4c476991
JB
4441 if (!rdev->ops->get_mpath)
4442 return -EOPNOTSUPP;
2ec600d6 4443
4c476991
JB
4444 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
4445 return -EOPNOTSUPP;
eec60b03 4446
e35e4d28 4447 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 4448 if (err)
4c476991 4449 return err;
2ec600d6 4450
fd2120ca 4451 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 4452 if (!msg)
4c476991 4453 return -ENOMEM;
2ec600d6 4454
15e47304 4455 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
4456 dev, dst, next_hop, &pinfo) < 0) {
4457 nlmsg_free(msg);
4458 return -ENOBUFS;
4459 }
3b85875a 4460
4c476991 4461 return genlmsg_reply(msg, info);
2ec600d6
LCC
4462}
4463
4464static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
4465{
4c476991
JB
4466 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4467 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
4468 u8 *dst = NULL;
4469 u8 *next_hop = NULL;
4470
4471 if (!info->attrs[NL80211_ATTR_MAC])
4472 return -EINVAL;
4473
4474 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
4475 return -EINVAL;
4476
4477 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
4478 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
4479
4c476991
JB
4480 if (!rdev->ops->change_mpath)
4481 return -EOPNOTSUPP;
35a8efe1 4482
4c476991
JB
4483 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
4484 return -EOPNOTSUPP;
2ec600d6 4485
e35e4d28 4486 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 4487}
4c476991 4488
2ec600d6
LCC
4489static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
4490{
4c476991
JB
4491 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4492 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
4493 u8 *dst = NULL;
4494 u8 *next_hop = NULL;
4495
4496 if (!info->attrs[NL80211_ATTR_MAC])
4497 return -EINVAL;
4498
4499 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
4500 return -EINVAL;
4501
4502 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
4503 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
4504
4c476991
JB
4505 if (!rdev->ops->add_mpath)
4506 return -EOPNOTSUPP;
35a8efe1 4507
4c476991
JB
4508 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
4509 return -EOPNOTSUPP;
2ec600d6 4510
e35e4d28 4511 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
4512}
4513
4514static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
4515{
4c476991
JB
4516 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4517 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
4518 u8 *dst = NULL;
4519
4520 if (info->attrs[NL80211_ATTR_MAC])
4521 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
4522
4c476991
JB
4523 if (!rdev->ops->del_mpath)
4524 return -EOPNOTSUPP;
3b85875a 4525
e35e4d28 4526 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
4527}
4528
9f1ba906
JM
4529static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
4530{
4c476991
JB
4531 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4532 struct net_device *dev = info->user_ptr[1];
c56589ed 4533 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 4534 struct bss_parameters params;
c56589ed 4535 int err;
9f1ba906
JM
4536
4537 memset(&params, 0, sizeof(params));
4538 /* default to not changing parameters */
4539 params.use_cts_prot = -1;
4540 params.use_short_preamble = -1;
4541 params.use_short_slot_time = -1;
fd8aaaf3 4542 params.ap_isolate = -1;
50b12f59 4543 params.ht_opmode = -1;
53cabad7
JB
4544 params.p2p_ctwindow = -1;
4545 params.p2p_opp_ps = -1;
9f1ba906
JM
4546
4547 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
4548 params.use_cts_prot =
4549 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
4550 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
4551 params.use_short_preamble =
4552 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
4553 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
4554 params.use_short_slot_time =
4555 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
4556 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
4557 params.basic_rates =
4558 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
4559 params.basic_rates_len =
4560 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
4561 }
fd8aaaf3
FF
4562 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
4563 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
4564 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
4565 params.ht_opmode =
4566 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 4567
53cabad7
JB
4568 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
4569 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4570 return -EINVAL;
4571 params.p2p_ctwindow =
4572 nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
4573 if (params.p2p_ctwindow < 0)
4574 return -EINVAL;
4575 if (params.p2p_ctwindow != 0 &&
4576 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
4577 return -EINVAL;
4578 }
4579
4580 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
4581 u8 tmp;
4582
4583 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4584 return -EINVAL;
4585 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
4586 if (tmp > 1)
4587 return -EINVAL;
4588 params.p2p_opp_ps = tmp;
4589 if (params.p2p_opp_ps &&
4590 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
4591 return -EINVAL;
4592 }
4593
4c476991
JB
4594 if (!rdev->ops->change_bss)
4595 return -EOPNOTSUPP;
9f1ba906 4596
074ac8df 4597 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
4598 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4599 return -EOPNOTSUPP;
3b85875a 4600
c56589ed
SW
4601 wdev_lock(wdev);
4602 err = rdev_change_bss(rdev, dev, &params);
4603 wdev_unlock(wdev);
4604
4605 return err;
9f1ba906
JM
4606}
4607
b54452b0 4608static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
b2e1b302
LR
4609 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
4610 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
4611 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
4612 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
4613 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
4614 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
4615};
4616
4617static int parse_reg_rule(struct nlattr *tb[],
4618 struct ieee80211_reg_rule *reg_rule)
4619{
4620 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
4621 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
4622
4623 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
4624 return -EINVAL;
4625 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
4626 return -EINVAL;
4627 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
4628 return -EINVAL;
b2e1b302
LR
4629 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
4630 return -EINVAL;
4631
4632 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
4633
4634 freq_range->start_freq_khz =
4635 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
4636 freq_range->end_freq_khz =
4637 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
97524820
JD
4638 if (tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
4639 freq_range->max_bandwidth_khz =
4640 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
b2e1b302
LR
4641
4642 power_rule->max_eirp =
4643 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
4644
4645 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
4646 power_rule->max_antenna_gain =
4647 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
4648
4649 return 0;
4650}
4651
4652static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
4653{
4654 int r;
4655 char *data = NULL;
57b5ce07 4656 enum nl80211_user_reg_hint_type user_reg_hint_type;
b2e1b302 4657
80778f18
LR
4658 /*
4659 * You should only get this when cfg80211 hasn't yet initialized
4660 * completely when built-in to the kernel right between the time
4661 * window between nl80211_init() and regulatory_init(), if that is
4662 * even possible.
4663 */
458f4f9e 4664 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 4665 return -EINPROGRESS;
80778f18 4666
fe33eb39
LR
4667 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
4668 return -EINVAL;
b2e1b302
LR
4669
4670 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
4671
57b5ce07
LR
4672 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
4673 user_reg_hint_type =
4674 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
4675 else
4676 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
4677
4678 switch (user_reg_hint_type) {
4679 case NL80211_USER_REG_HINT_USER:
4680 case NL80211_USER_REG_HINT_CELL_BASE:
4681 break;
4682 default:
4683 return -EINVAL;
4684 }
4685
4686 r = regulatory_hint_user(data, user_reg_hint_type);
fe33eb39 4687
b2e1b302
LR
4688 return r;
4689}
4690
24bdd9f4 4691static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 4692 struct genl_info *info)
93da9cc1 4693{
4c476991 4694 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 4695 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
4696 struct wireless_dev *wdev = dev->ieee80211_ptr;
4697 struct mesh_config cur_params;
4698 int err = 0;
93da9cc1 4699 void *hdr;
4700 struct nlattr *pinfoattr;
4701 struct sk_buff *msg;
4702
29cbe68c
JB
4703 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
4704 return -EOPNOTSUPP;
4705
24bdd9f4 4706 if (!rdev->ops->get_mesh_config)
4c476991 4707 return -EOPNOTSUPP;
f3f92586 4708
29cbe68c
JB
4709 wdev_lock(wdev);
4710 /* If not connected, get default parameters */
4711 if (!wdev->mesh_id_len)
4712 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
4713 else
e35e4d28 4714 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
4715 wdev_unlock(wdev);
4716
93da9cc1 4717 if (err)
4c476991 4718 return err;
93da9cc1 4719
4720 /* Draw up a netlink message to send back */
fd2120ca 4721 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
4722 if (!msg)
4723 return -ENOMEM;
15e47304 4724 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 4725 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 4726 if (!hdr)
efe1cf0c 4727 goto out;
24bdd9f4 4728 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 4729 if (!pinfoattr)
4730 goto nla_put_failure;
9360ffd1
DM
4731 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4732 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
4733 cur_params.dot11MeshRetryTimeout) ||
4734 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
4735 cur_params.dot11MeshConfirmTimeout) ||
4736 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
4737 cur_params.dot11MeshHoldingTimeout) ||
4738 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
4739 cur_params.dot11MeshMaxPeerLinks) ||
4740 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
4741 cur_params.dot11MeshMaxRetries) ||
4742 nla_put_u8(msg, NL80211_MESHCONF_TTL,
4743 cur_params.dot11MeshTTL) ||
4744 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
4745 cur_params.element_ttl) ||
4746 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
4747 cur_params.auto_open_plinks) ||
7eab0f64
JL
4748 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
4749 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
4750 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
4751 cur_params.dot11MeshHWMPmaxPREQretries) ||
4752 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
4753 cur_params.path_refresh_time) ||
4754 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
4755 cur_params.min_discovery_timeout) ||
4756 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
4757 cur_params.dot11MeshHWMPactivePathTimeout) ||
4758 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
4759 cur_params.dot11MeshHWMPpreqMinInterval) ||
4760 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
4761 cur_params.dot11MeshHWMPperrMinInterval) ||
4762 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
4763 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
4764 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
4765 cur_params.dot11MeshHWMPRootMode) ||
4766 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
4767 cur_params.dot11MeshHWMPRannInterval) ||
4768 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
4769 cur_params.dot11MeshGateAnnouncementProtocol) ||
4770 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
4771 cur_params.dot11MeshForwarding) ||
4772 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
4773 cur_params.rssi_threshold) ||
4774 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
4775 cur_params.ht_opmode) ||
4776 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
4777 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
4778 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
4779 cur_params.dot11MeshHWMProotInterval) ||
4780 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
4781 cur_params.dot11MeshHWMPconfirmationInterval) ||
4782 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
4783 cur_params.power_mode) ||
4784 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
4785 cur_params.dot11MeshAwakeWindowDuration) ||
4786 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
4787 cur_params.plink_timeout))
9360ffd1 4788 goto nla_put_failure;
93da9cc1 4789 nla_nest_end(msg, pinfoattr);
4790 genlmsg_end(msg, hdr);
4c476991 4791 return genlmsg_reply(msg, info);
93da9cc1 4792
3b85875a 4793 nla_put_failure:
93da9cc1 4794 genlmsg_cancel(msg, hdr);
efe1cf0c 4795 out:
d080e275 4796 nlmsg_free(msg);
4c476991 4797 return -ENOBUFS;
93da9cc1 4798}
4799
b54452b0 4800static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
93da9cc1 4801 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
4802 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
4803 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
4804 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
4805 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
4806 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
45904f21 4807 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
93da9cc1 4808 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
d299a1f2 4809 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
93da9cc1 4810 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
4811 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
4812 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
4813 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
4814 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
dca7e943 4815 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 },
93da9cc1 4816 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
699403db 4817 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
0507e159 4818 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
16dd7267 4819 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
94f90656 4820 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
a4f606ea
CYY
4821 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
4822 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6
CYY
4823 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
4824 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
728b19e5 4825 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
3b1c5a53
MP
4826 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 },
4827 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 4828 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
93da9cc1 4829};
4830
c80d545d
JC
4831static const struct nla_policy
4832 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 4833 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
4834 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
4835 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 4836 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 4837 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 4838 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
581a8b0f 4839 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
a4f606ea 4840 .len = IEEE80211_MAX_DATA_LEN },
b130e5ce 4841 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
4842};
4843
24bdd9f4 4844static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
4845 struct mesh_config *cfg,
4846 u32 *mask_out)
93da9cc1 4847{
93da9cc1 4848 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 4849 u32 mask = 0;
93da9cc1 4850
ea54fba2
MP
4851#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \
4852do { \
4853 if (tb[attr]) { \
4854 if (fn(tb[attr]) < min || fn(tb[attr]) > max) \
4855 return -EINVAL; \
4856 cfg->param = fn(tb[attr]); \
4857 mask |= (1 << (attr - 1)); \
4858 } \
4859} while (0)
bd90fdcc
JB
4860
4861
24bdd9f4 4862 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 4863 return -EINVAL;
4864 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
24bdd9f4 4865 info->attrs[NL80211_ATTR_MESH_CONFIG],
bd90fdcc 4866 nl80211_meshconf_params_policy))
93da9cc1 4867 return -EINVAL;
4868
93da9cc1 4869 /* This makes sure that there aren't more than 32 mesh config
4870 * parameters (otherwise our bitfield scheme would not work.) */
4871 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
4872
4873 /* Fill in the params struct */
ea54fba2 4874 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255,
a4f606ea
CYY
4875 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
4876 nla_get_u16);
ea54fba2 4877 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255,
a4f606ea
CYY
4878 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
4879 nla_get_u16);
ea54fba2 4880 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255,
a4f606ea
CYY
4881 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
4882 nla_get_u16);
ea54fba2 4883 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255,
a4f606ea
CYY
4884 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
4885 nla_get_u16);
ea54fba2 4886 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16,
a4f606ea
CYY
4887 mask, NL80211_MESHCONF_MAX_RETRIES,
4888 nla_get_u8);
ea54fba2 4889 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255,
a4f606ea 4890 mask, NL80211_MESHCONF_TTL, nla_get_u8);
ea54fba2 4891 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255,
a4f606ea
CYY
4892 mask, NL80211_MESHCONF_ELEMENT_TTL,
4893 nla_get_u8);
ea54fba2 4894 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1,
a4f606ea
CYY
4895 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
4896 nla_get_u8);
ea54fba2
MP
4897 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
4898 1, 255, mask,
a4f606ea
CYY
4899 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
4900 nla_get_u32);
ea54fba2 4901 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255,
a4f606ea
CYY
4902 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
4903 nla_get_u8);
ea54fba2 4904 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535,
a4f606ea
CYY
4905 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
4906 nla_get_u32);
ea54fba2 4907 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535,
a4f606ea
CYY
4908 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
4909 nla_get_u16);
ea54fba2
MP
4910 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
4911 1, 65535, mask,
a4f606ea
CYY
4912 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
4913 nla_get_u32);
93da9cc1 4914 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
ea54fba2
MP
4915 1, 65535, mask,
4916 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
a4f606ea 4917 nla_get_u16);
dca7e943 4918 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
ea54fba2
MP
4919 1, 65535, mask,
4920 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
a4f606ea 4921 nla_get_u16);
93da9cc1 4922 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
4923 dot11MeshHWMPnetDiameterTraversalTime,
4924 1, 65535, mask,
a4f606ea
CYY
4925 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
4926 nla_get_u16);
ea54fba2
MP
4927 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4,
4928 mask, NL80211_MESHCONF_HWMP_ROOTMODE,
4929 nla_get_u8);
4930 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535,
4931 mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
a4f606ea 4932 nla_get_u16);
63c5723b 4933 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
4934 dot11MeshGateAnnouncementProtocol, 0, 1,
4935 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
a4f606ea 4936 nla_get_u8);
ea54fba2 4937 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1,
a4f606ea
CYY
4938 mask, NL80211_MESHCONF_FORWARDING,
4939 nla_get_u8);
83374fe9 4940 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
a4f606ea 4941 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
83374fe9 4942 nla_get_s32);
ea54fba2 4943 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 0, 16,
a4f606ea 4944 mask, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
4945 nla_get_u16);
4946 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
ea54fba2 4947 1, 65535, mask,
ac1073a6
CYY
4948 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
4949 nla_get_u32);
ea54fba2 4950 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535,
ac1073a6 4951 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
4952 nla_get_u16);
4953 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
4954 dot11MeshHWMPconfirmationInterval,
4955 1, 65535, mask,
728b19e5 4956 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
a4f606ea 4957 nla_get_u16);
3b1c5a53
MP
4958 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode,
4959 NL80211_MESH_POWER_ACTIVE,
4960 NL80211_MESH_POWER_MAX,
4961 mask, NL80211_MESHCONF_POWER_MODE,
4962 nla_get_u32);
4963 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration,
4964 0, 65535, mask,
4965 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
8e7c0538
CT
4966 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 1, 0xffffffff,
4967 mask, NL80211_MESHCONF_PLINK_TIMEOUT,
4968 nla_get_u32);
bd90fdcc
JB
4969 if (mask_out)
4970 *mask_out = mask;
c80d545d 4971
bd90fdcc
JB
4972 return 0;
4973
4974#undef FILL_IN_MESH_PARAM_IF_SET
4975}
4976
c80d545d
JC
4977static int nl80211_parse_mesh_setup(struct genl_info *info,
4978 struct mesh_setup *setup)
4979{
bb2798d4 4980 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
4981 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
4982
4983 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
4984 return -EINVAL;
4985 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
4986 info->attrs[NL80211_ATTR_MESH_SETUP],
4987 nl80211_mesh_setup_params_policy))
4988 return -EINVAL;
4989
d299a1f2
JC
4990 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
4991 setup->sync_method =
4992 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
4993 IEEE80211_SYNC_METHOD_VENDOR :
4994 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
4995
c80d545d
JC
4996 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
4997 setup->path_sel_proto =
4998 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
4999 IEEE80211_PATH_PROTOCOL_VENDOR :
5000 IEEE80211_PATH_PROTOCOL_HWMP;
5001
5002 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
5003 setup->path_metric =
5004 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
5005 IEEE80211_PATH_METRIC_VENDOR :
5006 IEEE80211_PATH_METRIC_AIRTIME;
5007
581a8b0f
JC
5008
5009 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 5010 struct nlattr *ieattr =
581a8b0f 5011 tb[NL80211_MESH_SETUP_IE];
c80d545d
JC
5012 if (!is_valid_ie_attr(ieattr))
5013 return -EINVAL;
581a8b0f
JC
5014 setup->ie = nla_data(ieattr);
5015 setup->ie_len = nla_len(ieattr);
c80d545d 5016 }
bb2798d4
TP
5017 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
5018 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
5019 return -EINVAL;
5020 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
5021 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
5022 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
5023 if (setup->is_secure)
5024 setup->user_mpm = true;
c80d545d 5025
6e16d90b
CT
5026 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
5027 if (!setup->user_mpm)
5028 return -EINVAL;
5029 setup->auth_id =
5030 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
5031 }
5032
c80d545d
JC
5033 return 0;
5034}
5035
24bdd9f4 5036static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 5037 struct genl_info *info)
bd90fdcc
JB
5038{
5039 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5040 struct net_device *dev = info->user_ptr[1];
29cbe68c 5041 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
5042 struct mesh_config cfg;
5043 u32 mask;
5044 int err;
5045
29cbe68c
JB
5046 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
5047 return -EOPNOTSUPP;
5048
24bdd9f4 5049 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
5050 return -EOPNOTSUPP;
5051
24bdd9f4 5052 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
5053 if (err)
5054 return err;
5055
29cbe68c
JB
5056 wdev_lock(wdev);
5057 if (!wdev->mesh_id_len)
5058 err = -ENOLINK;
5059
5060 if (!err)
e35e4d28 5061 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
5062
5063 wdev_unlock(wdev);
5064
5065 return err;
93da9cc1 5066}
5067
f130347c
LR
5068static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
5069{
458f4f9e 5070 const struct ieee80211_regdomain *regdom;
f130347c
LR
5071 struct sk_buff *msg;
5072 void *hdr = NULL;
5073 struct nlattr *nl_reg_rules;
5074 unsigned int i;
f130347c
LR
5075
5076 if (!cfg80211_regdomain)
5fe231e8 5077 return -EINVAL;
f130347c 5078
fd2120ca 5079 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5fe231e8
JB
5080 if (!msg)
5081 return -ENOBUFS;
f130347c 5082
15e47304 5083 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
f130347c
LR
5084 NL80211_CMD_GET_REG);
5085 if (!hdr)
efe1cf0c 5086 goto put_failure;
f130347c 5087
57b5ce07
LR
5088 if (reg_last_request_cell_base() &&
5089 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
5090 NL80211_USER_REG_HINT_CELL_BASE))
5091 goto nla_put_failure;
5092
458f4f9e
JB
5093 rcu_read_lock();
5094 regdom = rcu_dereference(cfg80211_regdomain);
5095
5096 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
5097 (regdom->dfs_region &&
5098 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
5099 goto nla_put_failure_rcu;
5100
f130347c
LR
5101 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
5102 if (!nl_reg_rules)
458f4f9e 5103 goto nla_put_failure_rcu;
f130347c 5104
458f4f9e 5105 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
5106 struct nlattr *nl_reg_rule;
5107 const struct ieee80211_reg_rule *reg_rule;
5108 const struct ieee80211_freq_range *freq_range;
5109 const struct ieee80211_power_rule *power_rule;
97524820 5110 unsigned int max_bandwidth_khz;
f130347c 5111
458f4f9e 5112 reg_rule = &regdom->reg_rules[i];
f130347c
LR
5113 freq_range = &reg_rule->freq_range;
5114 power_rule = &reg_rule->power_rule;
5115
5116 nl_reg_rule = nla_nest_start(msg, i);
5117 if (!nl_reg_rule)
458f4f9e 5118 goto nla_put_failure_rcu;
f130347c 5119
97524820
JD
5120 max_bandwidth_khz = freq_range->max_bandwidth_khz;
5121 if (!max_bandwidth_khz)
5122 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
5123 reg_rule);
5124
9360ffd1
DM
5125 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
5126 reg_rule->flags) ||
5127 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
5128 freq_range->start_freq_khz) ||
5129 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
5130 freq_range->end_freq_khz) ||
5131 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 5132 max_bandwidth_khz) ||
9360ffd1
DM
5133 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
5134 power_rule->max_antenna_gain) ||
5135 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
5136 power_rule->max_eirp))
458f4f9e 5137 goto nla_put_failure_rcu;
f130347c
LR
5138
5139 nla_nest_end(msg, nl_reg_rule);
5140 }
458f4f9e 5141 rcu_read_unlock();
f130347c
LR
5142
5143 nla_nest_end(msg, nl_reg_rules);
5144
5145 genlmsg_end(msg, hdr);
5fe231e8 5146 return genlmsg_reply(msg, info);
f130347c 5147
458f4f9e
JB
5148nla_put_failure_rcu:
5149 rcu_read_unlock();
f130347c
LR
5150nla_put_failure:
5151 genlmsg_cancel(msg, hdr);
efe1cf0c 5152put_failure:
d080e275 5153 nlmsg_free(msg);
5fe231e8 5154 return -EMSGSIZE;
f130347c
LR
5155}
5156
b2e1b302
LR
5157static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5158{
5159 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
5160 struct nlattr *nl_reg_rule;
5161 char *alpha2 = NULL;
5162 int rem_reg_rules = 0, r = 0;
5163 u32 num_rules = 0, rule_idx = 0, size_of_regd;
4c7d3982 5164 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
b2e1b302
LR
5165 struct ieee80211_regdomain *rd = NULL;
5166
5167 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
5168 return -EINVAL;
5169
5170 if (!info->attrs[NL80211_ATTR_REG_RULES])
5171 return -EINVAL;
5172
5173 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
5174
8b60b078
LR
5175 if (info->attrs[NL80211_ATTR_DFS_REGION])
5176 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
5177
b2e1b302 5178 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 5179 rem_reg_rules) {
b2e1b302
LR
5180 num_rules++;
5181 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 5182 return -EINVAL;
b2e1b302
LR
5183 }
5184
e438768f
LR
5185 if (!reg_is_valid_request(alpha2))
5186 return -EINVAL;
5187
b2e1b302 5188 size_of_regd = sizeof(struct ieee80211_regdomain) +
1a919318 5189 num_rules * sizeof(struct ieee80211_reg_rule);
b2e1b302
LR
5190
5191 rd = kzalloc(size_of_regd, GFP_KERNEL);
6913b49a
JB
5192 if (!rd)
5193 return -ENOMEM;
b2e1b302
LR
5194
5195 rd->n_reg_rules = num_rules;
5196 rd->alpha2[0] = alpha2[0];
5197 rd->alpha2[1] = alpha2[1];
5198
8b60b078
LR
5199 /*
5200 * Disable DFS master mode if the DFS region was
5201 * not supported or known on this kernel.
5202 */
5203 if (reg_supported_dfs_region(dfs_region))
5204 rd->dfs_region = dfs_region;
5205
b2e1b302 5206 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 5207 rem_reg_rules) {
ae811e21
JB
5208 r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
5209 nla_data(nl_reg_rule), nla_len(nl_reg_rule),
5210 reg_rule_policy);
5211 if (r)
5212 goto bad_reg;
b2e1b302
LR
5213 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
5214 if (r)
5215 goto bad_reg;
5216
5217 rule_idx++;
5218
d0e18f83
LR
5219 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
5220 r = -EINVAL;
b2e1b302 5221 goto bad_reg;
d0e18f83 5222 }
b2e1b302
LR
5223 }
5224
b2e1b302 5225 r = set_regdom(rd);
6913b49a 5226 /* set_regdom took ownership */
1a919318 5227 rd = NULL;
b2e1b302 5228
d2372b31 5229 bad_reg:
b2e1b302 5230 kfree(rd);
d0e18f83 5231 return r;
b2e1b302
LR
5232}
5233
83f5e2cf
JB
5234static int validate_scan_freqs(struct nlattr *freqs)
5235{
5236 struct nlattr *attr1, *attr2;
5237 int n_channels = 0, tmp1, tmp2;
5238
5239 nla_for_each_nested(attr1, freqs, tmp1) {
5240 n_channels++;
5241 /*
5242 * Some hardware has a limited channel list for
5243 * scanning, and it is pretty much nonsensical
5244 * to scan for a channel twice, so disallow that
5245 * and don't require drivers to check that the
5246 * channel list they get isn't longer than what
5247 * they can scan, as long as they can scan all
5248 * the channels they registered at once.
5249 */
5250 nla_for_each_nested(attr2, freqs, tmp2)
5251 if (attr1 != attr2 &&
5252 nla_get_u32(attr1) == nla_get_u32(attr2))
5253 return 0;
5254 }
5255
5256 return n_channels;
5257}
5258
2a519311
JB
5259static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5260{
4c476991 5261 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 5262 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 5263 struct cfg80211_scan_request *request;
2a519311
JB
5264 struct nlattr *attr;
5265 struct wiphy *wiphy;
83f5e2cf 5266 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 5267 size_t ie_len;
2a519311 5268
f4a11bb0
JB
5269 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
5270 return -EINVAL;
5271
79c97e97 5272 wiphy = &rdev->wiphy;
2a519311 5273
4c476991
JB
5274 if (!rdev->ops->scan)
5275 return -EOPNOTSUPP;
2a519311 5276
f9f47529
JB
5277 if (rdev->scan_req) {
5278 err = -EBUSY;
5279 goto unlock;
5280 }
2a519311
JB
5281
5282 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
5283 n_channels = validate_scan_freqs(
5284 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
f9f47529
JB
5285 if (!n_channels) {
5286 err = -EINVAL;
5287 goto unlock;
5288 }
2a519311 5289 } else {
bdfbec2d 5290 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
5291 }
5292
5293 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
5294 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
5295 n_ssids++;
5296
f9f47529
JB
5297 if (n_ssids > wiphy->max_scan_ssids) {
5298 err = -EINVAL;
5299 goto unlock;
5300 }
2a519311 5301
70692ad2
JM
5302 if (info->attrs[NL80211_ATTR_IE])
5303 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5304 else
5305 ie_len = 0;
5306
f9f47529
JB
5307 if (ie_len > wiphy->max_scan_ie_len) {
5308 err = -EINVAL;
5309 goto unlock;
5310 }
18a83659 5311
2a519311 5312 request = kzalloc(sizeof(*request)
a2cd43c5
LC
5313 + sizeof(*request->ssids) * n_ssids
5314 + sizeof(*request->channels) * n_channels
70692ad2 5315 + ie_len, GFP_KERNEL);
f9f47529
JB
5316 if (!request) {
5317 err = -ENOMEM;
5318 goto unlock;
5319 }
2a519311 5320
2a519311 5321 if (n_ssids)
5ba63533 5322 request->ssids = (void *)&request->channels[n_channels];
2a519311 5323 request->n_ssids = n_ssids;
70692ad2
JM
5324 if (ie_len) {
5325 if (request->ssids)
5326 request->ie = (void *)(request->ssids + n_ssids);
5327 else
5328 request->ie = (void *)(request->channels + n_channels);
5329 }
2a519311 5330
584991dc 5331 i = 0;
2a519311
JB
5332 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
5333 /* user specified, bail out if channel not found */
2a519311 5334 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
5335 struct ieee80211_channel *chan;
5336
5337 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
5338
5339 if (!chan) {
2a519311
JB
5340 err = -EINVAL;
5341 goto out_free;
5342 }
584991dc
JB
5343
5344 /* ignore disabled channels */
5345 if (chan->flags & IEEE80211_CHAN_DISABLED)
5346 continue;
5347
5348 request->channels[i] = chan;
2a519311
JB
5349 i++;
5350 }
5351 } else {
34850ab2
JB
5352 enum ieee80211_band band;
5353
2a519311 5354 /* all channels */
2a519311
JB
5355 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
5356 int j;
5357 if (!wiphy->bands[band])
5358 continue;
5359 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
5360 struct ieee80211_channel *chan;
5361
5362 chan = &wiphy->bands[band]->channels[j];
5363
5364 if (chan->flags & IEEE80211_CHAN_DISABLED)
5365 continue;
5366
5367 request->channels[i] = chan;
2a519311
JB
5368 i++;
5369 }
5370 }
5371 }
5372
584991dc
JB
5373 if (!i) {
5374 err = -EINVAL;
5375 goto out_free;
5376 }
5377
5378 request->n_channels = i;
5379
2a519311
JB
5380 i = 0;
5381 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
5382 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 5383 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
5384 err = -EINVAL;
5385 goto out_free;
5386 }
57a27e1d 5387 request->ssids[i].ssid_len = nla_len(attr);
2a519311 5388 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
5389 i++;
5390 }
5391 }
5392
70692ad2
JM
5393 if (info->attrs[NL80211_ATTR_IE]) {
5394 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
5395 memcpy((void *)request->ie,
5396 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
5397 request->ie_len);
5398 }
5399
34850ab2 5400 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
a401d2bb
JB
5401 if (wiphy->bands[i])
5402 request->rates[i] =
5403 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
5404
5405 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
5406 nla_for_each_nested(attr,
5407 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
5408 tmp) {
5409 enum ieee80211_band band = nla_type(attr);
5410
84404623 5411 if (band < 0 || band >= IEEE80211_NUM_BANDS) {
34850ab2
JB
5412 err = -EINVAL;
5413 goto out_free;
5414 }
1b09cd82
FF
5415
5416 if (!wiphy->bands[band])
5417 continue;
5418
34850ab2
JB
5419 err = ieee80211_get_ratemask(wiphy->bands[band],
5420 nla_data(attr),
5421 nla_len(attr),
5422 &request->rates[band]);
5423 if (err)
5424 goto out_free;
5425 }
5426 }
5427
46856bbf 5428 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
ed473771
SL
5429 request->flags = nla_get_u32(
5430 info->attrs[NL80211_ATTR_SCAN_FLAGS]);
00c3a6ed
JB
5431 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
5432 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
46856bbf
SL
5433 err = -EOPNOTSUPP;
5434 goto out_free;
5435 }
5436 }
ed473771 5437
e9f935e3
RM
5438 request->no_cck =
5439 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
5440
fd014284 5441 request->wdev = wdev;
79c97e97 5442 request->wiphy = &rdev->wiphy;
15d6030b 5443 request->scan_start = jiffies;
2a519311 5444
79c97e97 5445 rdev->scan_req = request;
e35e4d28 5446 err = rdev_scan(rdev, request);
2a519311 5447
463d0183 5448 if (!err) {
fd014284
JB
5449 nl80211_send_scan_start(rdev, wdev);
5450 if (wdev->netdev)
5451 dev_hold(wdev->netdev);
4c476991 5452 } else {
2a519311 5453 out_free:
79c97e97 5454 rdev->scan_req = NULL;
2a519311
JB
5455 kfree(request);
5456 }
3b85875a 5457
f9f47529 5458 unlock:
2a519311
JB
5459 return err;
5460}
5461
807f8a8c
LC
5462static int nl80211_start_sched_scan(struct sk_buff *skb,
5463 struct genl_info *info)
5464{
5465 struct cfg80211_sched_scan_request *request;
5466 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5467 struct net_device *dev = info->user_ptr[1];
807f8a8c
LC
5468 struct nlattr *attr;
5469 struct wiphy *wiphy;
a1f1c21c 5470 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i;
bbe6ad6d 5471 u32 interval;
807f8a8c
LC
5472 enum ieee80211_band band;
5473 size_t ie_len;
a1f1c21c 5474 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 5475 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c
LC
5476
5477 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
5478 !rdev->ops->sched_scan_start)
5479 return -EOPNOTSUPP;
5480
5481 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
5482 return -EINVAL;
5483
bbe6ad6d
LC
5484 if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
5485 return -EINVAL;
5486
5487 interval = nla_get_u32(info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
5488 if (interval == 0)
5489 return -EINVAL;
5490
807f8a8c
LC
5491 wiphy = &rdev->wiphy;
5492
5493 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
5494 n_channels = validate_scan_freqs(
5495 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
5496 if (!n_channels)
5497 return -EINVAL;
5498 } else {
bdfbec2d 5499 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
5500 }
5501
5502 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
5503 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
5504 tmp)
5505 n_ssids++;
5506
93b6aa69 5507 if (n_ssids > wiphy->max_sched_scan_ssids)
807f8a8c
LC
5508 return -EINVAL;
5509
ea73cbce
JB
5510 /*
5511 * First, count the number of 'real' matchsets. Due to an issue with
5512 * the old implementation, matchsets containing only the RSSI attribute
5513 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
5514 * RSSI for all matchsets, rather than their own matchset for reporting
5515 * all APs with a strong RSSI. This is needed to be compatible with
5516 * older userspace that treated a matchset with only the RSSI as the
5517 * global RSSI for all other matchsets - if there are other matchsets.
5518 */
5519 if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c
LC
5520 nla_for_each_nested(attr,
5521 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
5522 tmp) {
5523 struct nlattr *rssi;
5524
5525 err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
5526 nla_data(attr), nla_len(attr),
5527 nl80211_match_policy);
5528 if (err)
5529 return err;
5530 /* add other standalone attributes here */
5531 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
5532 n_match_sets++;
5533 continue;
5534 }
5535 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
5536 if (rssi)
5537 default_match_rssi = nla_get_s32(rssi);
5538 }
5539 }
5540
5541 /* However, if there's no other matchset, add the RSSI one */
5542 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
5543 n_match_sets = 1;
a1f1c21c
LC
5544
5545 if (n_match_sets > wiphy->max_match_sets)
5546 return -EINVAL;
5547
807f8a8c
LC
5548 if (info->attrs[NL80211_ATTR_IE])
5549 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5550 else
5551 ie_len = 0;
5552
5a865bad 5553 if (ie_len > wiphy->max_sched_scan_ie_len)
807f8a8c
LC
5554 return -EINVAL;
5555
c10841ca
LC
5556 if (rdev->sched_scan_req) {
5557 err = -EINPROGRESS;
5558 goto out;
5559 }
5560
807f8a8c 5561 request = kzalloc(sizeof(*request)
a2cd43c5 5562 + sizeof(*request->ssids) * n_ssids
a1f1c21c 5563 + sizeof(*request->match_sets) * n_match_sets
a2cd43c5 5564 + sizeof(*request->channels) * n_channels
807f8a8c 5565 + ie_len, GFP_KERNEL);
c10841ca
LC
5566 if (!request) {
5567 err = -ENOMEM;
5568 goto out;
5569 }
807f8a8c
LC
5570
5571 if (n_ssids)
5572 request->ssids = (void *)&request->channels[n_channels];
5573 request->n_ssids = n_ssids;
5574 if (ie_len) {
5575 if (request->ssids)
5576 request->ie = (void *)(request->ssids + n_ssids);
5577 else
5578 request->ie = (void *)(request->channels + n_channels);
5579 }
5580
a1f1c21c
LC
5581 if (n_match_sets) {
5582 if (request->ie)
5583 request->match_sets = (void *)(request->ie + ie_len);
5584 else if (request->ssids)
5585 request->match_sets =
5586 (void *)(request->ssids + n_ssids);
5587 else
5588 request->match_sets =
5589 (void *)(request->channels + n_channels);
5590 }
5591 request->n_match_sets = n_match_sets;
5592
807f8a8c
LC
5593 i = 0;
5594 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
5595 /* user specified, bail out if channel not found */
5596 nla_for_each_nested(attr,
5597 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES],
5598 tmp) {
5599 struct ieee80211_channel *chan;
5600
5601 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
5602
5603 if (!chan) {
5604 err = -EINVAL;
5605 goto out_free;
5606 }
5607
5608 /* ignore disabled channels */
5609 if (chan->flags & IEEE80211_CHAN_DISABLED)
5610 continue;
5611
5612 request->channels[i] = chan;
5613 i++;
5614 }
5615 } else {
5616 /* all channels */
5617 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
5618 int j;
5619 if (!wiphy->bands[band])
5620 continue;
5621 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
5622 struct ieee80211_channel *chan;
5623
5624 chan = &wiphy->bands[band]->channels[j];
5625
5626 if (chan->flags & IEEE80211_CHAN_DISABLED)
5627 continue;
5628
5629 request->channels[i] = chan;
5630 i++;
5631 }
5632 }
5633 }
5634
5635 if (!i) {
5636 err = -EINVAL;
5637 goto out_free;
5638 }
5639
5640 request->n_channels = i;
5641
5642 i = 0;
5643 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
5644 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
5645 tmp) {
57a27e1d 5646 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
5647 err = -EINVAL;
5648 goto out_free;
5649 }
57a27e1d 5650 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
5651 memcpy(request->ssids[i].ssid, nla_data(attr),
5652 nla_len(attr));
807f8a8c
LC
5653 i++;
5654 }
5655 }
5656
a1f1c21c
LC
5657 i = 0;
5658 if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
5659 nla_for_each_nested(attr,
5660 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
5661 tmp) {
88e920b4 5662 struct nlattr *ssid, *rssi;
a1f1c21c 5663
ae811e21
JB
5664 err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
5665 nla_data(attr), nla_len(attr),
5666 nl80211_match_policy);
5667 if (err)
5668 goto out_free;
4a4ab0d7 5669 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
a1f1c21c 5670 if (ssid) {
ea73cbce
JB
5671 if (WARN_ON(i >= n_match_sets)) {
5672 /* this indicates a programming error,
5673 * the loop above should have verified
5674 * things properly
5675 */
5676 err = -EINVAL;
5677 goto out_free;
5678 }
5679
a1f1c21c
LC
5680 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
5681 err = -EINVAL;
5682 goto out_free;
5683 }
5684 memcpy(request->match_sets[i].ssid.ssid,
5685 nla_data(ssid), nla_len(ssid));
5686 request->match_sets[i].ssid.ssid_len =
5687 nla_len(ssid);
ea73cbce
JB
5688 /* special attribute - old implemenation w/a */
5689 request->match_sets[i].rssi_thold =
5690 default_match_rssi;
5691 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
5692 if (rssi)
5693 request->match_sets[i].rssi_thold =
5694 nla_get_s32(rssi);
a1f1c21c
LC
5695 }
5696 i++;
5697 }
ea73cbce
JB
5698
5699 /* there was no other matchset, so the RSSI one is alone */
5700 if (i == 0)
5701 request->match_sets[0].rssi_thold = default_match_rssi;
5702
5703 request->min_rssi_thold = INT_MAX;
5704 for (i = 0; i < n_match_sets; i++)
5705 request->min_rssi_thold =
5706 min(request->match_sets[i].rssi_thold,
5707 request->min_rssi_thold);
5708 } else {
5709 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
5710 }
5711
807f8a8c
LC
5712 if (info->attrs[NL80211_ATTR_IE]) {
5713 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5714 memcpy((void *)request->ie,
5715 nla_data(info->attrs[NL80211_ATTR_IE]),
5716 request->ie_len);
5717 }
5718
46856bbf 5719 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
ed473771
SL
5720 request->flags = nla_get_u32(
5721 info->attrs[NL80211_ATTR_SCAN_FLAGS]);
00c3a6ed
JB
5722 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
5723 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
46856bbf
SL
5724 err = -EOPNOTSUPP;
5725 goto out_free;
5726 }
5727 }
ed473771 5728
807f8a8c
LC
5729 request->dev = dev;
5730 request->wiphy = &rdev->wiphy;
bbe6ad6d 5731 request->interval = interval;
15d6030b 5732 request->scan_start = jiffies;
807f8a8c 5733
e35e4d28 5734 err = rdev_sched_scan_start(rdev, dev, request);
807f8a8c
LC
5735 if (!err) {
5736 rdev->sched_scan_req = request;
5737 nl80211_send_sched_scan(rdev, dev,
5738 NL80211_CMD_START_SCHED_SCAN);
5739 goto out;
5740 }
5741
5742out_free:
5743 kfree(request);
5744out:
5745 return err;
5746}
5747
5748static int nl80211_stop_sched_scan(struct sk_buff *skb,
5749 struct genl_info *info)
5750{
5751 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5752
5753 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
5754 !rdev->ops->sched_scan_stop)
5755 return -EOPNOTSUPP;
5756
5fe231e8 5757 return __cfg80211_stop_sched_scan(rdev, false);
807f8a8c
LC
5758}
5759
04f39047
SW
5760static int nl80211_start_radar_detection(struct sk_buff *skb,
5761 struct genl_info *info)
5762{
5763 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5764 struct net_device *dev = info->user_ptr[1];
5765 struct wireless_dev *wdev = dev->ieee80211_ptr;
5766 struct cfg80211_chan_def chandef;
55f7435c 5767 enum nl80211_dfs_regions dfs_region;
04f39047
SW
5768 int err;
5769
55f7435c
LR
5770 dfs_region = reg_get_dfs_region(wdev->wiphy);
5771 if (dfs_region == NL80211_DFS_UNSET)
5772 return -EINVAL;
5773
04f39047
SW
5774 err = nl80211_parse_chandef(rdev, info, &chandef);
5775 if (err)
5776 return err;
5777
ff311bc1
SW
5778 if (netif_carrier_ok(dev))
5779 return -EBUSY;
5780
04f39047
SW
5781 if (wdev->cac_started)
5782 return -EBUSY;
5783
5784 err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef);
5785 if (err < 0)
5786 return err;
5787
5788 if (err == 0)
5789 return -EINVAL;
5790
fe7c3a1f 5791 if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef))
04f39047
SW
5792 return -EINVAL;
5793
5794 if (!rdev->ops->start_radar_detection)
5795 return -EOPNOTSUPP;
5796
04f39047
SW
5797 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
5798 chandef.chan, CHAN_MODE_SHARED,
5799 BIT(chandef.width));
5800 if (err)
5fe231e8 5801 return err;
04f39047
SW
5802
5803 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
5804 if (!err) {
9e0e2961 5805 wdev->chandef = chandef;
04f39047
SW
5806 wdev->cac_started = true;
5807 wdev->cac_start_time = jiffies;
5808 }
04f39047
SW
5809 return err;
5810}
5811
16ef1fe2
SW
5812static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
5813{
5814 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5815 struct net_device *dev = info->user_ptr[1];
5816 struct wireless_dev *wdev = dev->ieee80211_ptr;
5817 struct cfg80211_csa_settings params;
5818 /* csa_attrs is defined static to avoid waste of stack size - this
5819 * function is called under RTNL lock, so this should not be a problem.
5820 */
5821 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
5822 u8 radar_detect_width = 0;
5823 int err;
ee4bc9e7 5824 bool need_new_beacon = false;
16ef1fe2
SW
5825
5826 if (!rdev->ops->channel_switch ||
5827 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
5828 return -EOPNOTSUPP;
5829
ee4bc9e7
SW
5830 switch (dev->ieee80211_ptr->iftype) {
5831 case NL80211_IFTYPE_AP:
5832 case NL80211_IFTYPE_P2P_GO:
5833 need_new_beacon = true;
5834
5835 /* useless if AP is not running */
5836 if (!wdev->beacon_interval)
1ff79dfa 5837 return -ENOTCONN;
ee4bc9e7
SW
5838 break;
5839 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
5840 if (!wdev->ssid_len)
5841 return -ENOTCONN;
5842 break;
c6da674a 5843 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
5844 if (!wdev->mesh_id_len)
5845 return -ENOTCONN;
ee4bc9e7
SW
5846 break;
5847 default:
16ef1fe2 5848 return -EOPNOTSUPP;
ee4bc9e7 5849 }
16ef1fe2
SW
5850
5851 memset(&params, 0, sizeof(params));
5852
5853 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
5854 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
5855 return -EINVAL;
5856
5857 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 5858 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
5859 return -EINVAL;
5860
5861 params.count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
5862
ee4bc9e7
SW
5863 if (!need_new_beacon)
5864 goto skip_beacons;
5865
16ef1fe2
SW
5866 err = nl80211_parse_beacon(info->attrs, &params.beacon_after);
5867 if (err)
5868 return err;
5869
5870 err = nla_parse_nested(csa_attrs, NL80211_ATTR_MAX,
5871 info->attrs[NL80211_ATTR_CSA_IES],
5872 nl80211_policy);
5873 if (err)
5874 return err;
5875
5876 err = nl80211_parse_beacon(csa_attrs, &params.beacon_csa);
5877 if (err)
5878 return err;
5879
5880 if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON])
5881 return -EINVAL;
5882
5883 params.counter_offset_beacon =
5884 nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
5885 if (params.counter_offset_beacon >= params.beacon_csa.tail_len)
5886 return -EINVAL;
5887
5888 /* sanity check - counters should be the same */
5889 if (params.beacon_csa.tail[params.counter_offset_beacon] !=
5890 params.count)
5891 return -EINVAL;
5892
5893 if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) {
5894 params.counter_offset_presp =
5895 nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
5896 if (params.counter_offset_presp >=
5897 params.beacon_csa.probe_resp_len)
5898 return -EINVAL;
5899
5900 if (params.beacon_csa.probe_resp[params.counter_offset_presp] !=
5901 params.count)
5902 return -EINVAL;
5903 }
5904
ee4bc9e7 5905skip_beacons:
16ef1fe2
SW
5906 err = nl80211_parse_chandef(rdev, info, &params.chandef);
5907 if (err)
5908 return err;
5909
5910 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
5911 return -EINVAL;
5912
ee4bc9e7 5913 if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP ||
5336fa88
SW
5914 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO ||
5915 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_ADHOC) {
ee4bc9e7
SW
5916 err = cfg80211_chandef_dfs_required(wdev->wiphy,
5917 &params.chandef);
5918 if (err < 0) {
5919 return err;
5920 } else if (err) {
5921 radar_detect_width = BIT(params.chandef.width);
5922 params.radar_required = true;
5923 }
16ef1fe2
SW
5924 }
5925
5926 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
5927 params.chandef.chan,
5928 CHAN_MODE_SHARED,
5929 radar_detect_width);
5930 if (err)
5931 return err;
5932
5933 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
5934 params.block_tx = true;
5935
c56589ed
SW
5936 wdev_lock(wdev);
5937 err = rdev_channel_switch(rdev, dev, &params);
5938 wdev_unlock(wdev);
5939
5940 return err;
16ef1fe2
SW
5941}
5942
9720bb3a
JB
5943static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
5944 u32 seq, int flags,
2a519311 5945 struct cfg80211_registered_device *rdev,
48ab905d
JB
5946 struct wireless_dev *wdev,
5947 struct cfg80211_internal_bss *intbss)
2a519311 5948{
48ab905d 5949 struct cfg80211_bss *res = &intbss->pub;
9caf0364 5950 const struct cfg80211_bss_ies *ies;
2a519311
JB
5951 void *hdr;
5952 struct nlattr *bss;
8cef2c9d 5953 bool tsf = false;
48ab905d
JB
5954
5955 ASSERT_WDEV_LOCK(wdev);
2a519311 5956
15e47304 5957 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
5958 NL80211_CMD_NEW_SCAN_RESULTS);
5959 if (!hdr)
5960 return -1;
5961
9720bb3a
JB
5962 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
5963
97990a06
JB
5964 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
5965 goto nla_put_failure;
5966 if (wdev->netdev &&
9360ffd1
DM
5967 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
5968 goto nla_put_failure;
97990a06
JB
5969 if (nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
5970 goto nla_put_failure;
2a519311
JB
5971
5972 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
5973 if (!bss)
5974 goto nla_put_failure;
9360ffd1 5975 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 5976 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 5977 goto nla_put_failure;
9caf0364
JB
5978
5979 rcu_read_lock();
5980 ies = rcu_dereference(res->ies);
8cef2c9d
JB
5981 if (ies) {
5982 if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
5983 goto fail_unlock_rcu;
5984 tsf = true;
5985 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
5986 ies->len, ies->data))
5987 goto fail_unlock_rcu;
9caf0364
JB
5988 }
5989 ies = rcu_dereference(res->beacon_ies);
8cef2c9d
JB
5990 if (ies) {
5991 if (!tsf && nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
5992 goto fail_unlock_rcu;
5993 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
5994 ies->len, ies->data))
5995 goto fail_unlock_rcu;
9caf0364
JB
5996 }
5997 rcu_read_unlock();
5998
9360ffd1
DM
5999 if (res->beacon_interval &&
6000 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
6001 goto nla_put_failure;
6002 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
6003 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
dcd6eac1 6004 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
6005 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
6006 jiffies_to_msecs(jiffies - intbss->ts)))
6007 goto nla_put_failure;
2a519311 6008
77965c97 6009 switch (rdev->wiphy.signal_type) {
2a519311 6010 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
6011 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
6012 goto nla_put_failure;
2a519311
JB
6013 break;
6014 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
6015 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
6016 goto nla_put_failure;
2a519311
JB
6017 break;
6018 default:
6019 break;
6020 }
6021
48ab905d 6022 switch (wdev->iftype) {
074ac8df 6023 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 6024 case NL80211_IFTYPE_STATION:
9360ffd1
DM
6025 if (intbss == wdev->current_bss &&
6026 nla_put_u32(msg, NL80211_BSS_STATUS,
6027 NL80211_BSS_STATUS_ASSOCIATED))
6028 goto nla_put_failure;
48ab905d
JB
6029 break;
6030 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
6031 if (intbss == wdev->current_bss &&
6032 nla_put_u32(msg, NL80211_BSS_STATUS,
6033 NL80211_BSS_STATUS_IBSS_JOINED))
6034 goto nla_put_failure;
48ab905d
JB
6035 break;
6036 default:
6037 break;
6038 }
6039
2a519311
JB
6040 nla_nest_end(msg, bss);
6041
6042 return genlmsg_end(msg, hdr);
6043
8cef2c9d
JB
6044 fail_unlock_rcu:
6045 rcu_read_unlock();
2a519311
JB
6046 nla_put_failure:
6047 genlmsg_cancel(msg, hdr);
6048 return -EMSGSIZE;
6049}
6050
97990a06 6051static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 6052{
48ab905d 6053 struct cfg80211_registered_device *rdev;
2a519311 6054 struct cfg80211_internal_bss *scan;
48ab905d 6055 struct wireless_dev *wdev;
97990a06 6056 int start = cb->args[2], idx = 0;
2a519311
JB
6057 int err;
6058
97990a06 6059 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
6060 if (err)
6061 return err;
2a519311 6062
48ab905d
JB
6063 wdev_lock(wdev);
6064 spin_lock_bh(&rdev->bss_lock);
6065 cfg80211_bss_expire(rdev);
6066
9720bb3a
JB
6067 cb->seq = rdev->bss_generation;
6068
48ab905d 6069 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
6070 if (++idx <= start)
6071 continue;
9720bb3a 6072 if (nl80211_send_bss(skb, cb,
2a519311 6073 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 6074 rdev, wdev, scan) < 0) {
2a519311 6075 idx--;
67748893 6076 break;
2a519311
JB
6077 }
6078 }
6079
48ab905d
JB
6080 spin_unlock_bh(&rdev->bss_lock);
6081 wdev_unlock(wdev);
2a519311 6082
97990a06
JB
6083 cb->args[2] = idx;
6084 nl80211_finish_wdev_dump(rdev);
2a519311 6085
67748893 6086 return skb->len;
2a519311
JB
6087}
6088
15e47304 6089static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
61fa713c
HS
6090 int flags, struct net_device *dev,
6091 struct survey_info *survey)
6092{
6093 void *hdr;
6094 struct nlattr *infoattr;
6095
15e47304 6096 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
6097 NL80211_CMD_NEW_SURVEY_RESULTS);
6098 if (!hdr)
6099 return -ENOMEM;
6100
9360ffd1
DM
6101 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
6102 goto nla_put_failure;
61fa713c
HS
6103
6104 infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
6105 if (!infoattr)
6106 goto nla_put_failure;
6107
9360ffd1
DM
6108 if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
6109 survey->channel->center_freq))
6110 goto nla_put_failure;
6111
6112 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
6113 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
6114 goto nla_put_failure;
6115 if ((survey->filled & SURVEY_INFO_IN_USE) &&
6116 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
6117 goto nla_put_failure;
6118 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME) &&
6119 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
6120 survey->channel_time))
6121 goto nla_put_failure;
6122 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) &&
6123 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
6124 survey->channel_time_busy))
6125 goto nla_put_failure;
6126 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) &&
6127 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
6128 survey->channel_time_ext_busy))
6129 goto nla_put_failure;
6130 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) &&
6131 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
6132 survey->channel_time_rx))
6133 goto nla_put_failure;
6134 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) &&
6135 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
6136 survey->channel_time_tx))
6137 goto nla_put_failure;
61fa713c
HS
6138
6139 nla_nest_end(msg, infoattr);
6140
6141 return genlmsg_end(msg, hdr);
6142
6143 nla_put_failure:
6144 genlmsg_cancel(msg, hdr);
6145 return -EMSGSIZE;
6146}
6147
6148static int nl80211_dump_survey(struct sk_buff *skb,
6149 struct netlink_callback *cb)
6150{
6151 struct survey_info survey;
6152 struct cfg80211_registered_device *dev;
97990a06
JB
6153 struct wireless_dev *wdev;
6154 int survey_idx = cb->args[2];
61fa713c
HS
6155 int res;
6156
97990a06 6157 res = nl80211_prepare_wdev_dump(skb, cb, &dev, &wdev);
67748893
JB
6158 if (res)
6159 return res;
61fa713c 6160
97990a06
JB
6161 if (!wdev->netdev) {
6162 res = -EINVAL;
6163 goto out_err;
6164 }
6165
61fa713c
HS
6166 if (!dev->ops->dump_survey) {
6167 res = -EOPNOTSUPP;
6168 goto out_err;
6169 }
6170
6171 while (1) {
180cdc79
LR
6172 struct ieee80211_channel *chan;
6173
97990a06 6174 res = rdev_dump_survey(dev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
6175 if (res == -ENOENT)
6176 break;
6177 if (res)
6178 goto out_err;
6179
180cdc79
LR
6180 /* Survey without a channel doesn't make sense */
6181 if (!survey.channel) {
6182 res = -EINVAL;
6183 goto out;
6184 }
6185
6186 chan = ieee80211_get_channel(&dev->wiphy,
6187 survey.channel->center_freq);
6188 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
6189 survey_idx++;
6190 continue;
6191 }
6192
61fa713c 6193 if (nl80211_send_survey(skb,
15e47304 6194 NETLINK_CB(cb->skb).portid,
61fa713c 6195 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 6196 wdev->netdev, &survey) < 0)
61fa713c
HS
6197 goto out;
6198 survey_idx++;
6199 }
6200
6201 out:
97990a06 6202 cb->args[2] = survey_idx;
61fa713c
HS
6203 res = skb->len;
6204 out_err:
97990a06 6205 nl80211_finish_wdev_dump(dev);
61fa713c
HS
6206 return res;
6207}
6208
b23aa676
SO
6209static bool nl80211_valid_wpa_versions(u32 wpa_versions)
6210{
6211 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
6212 NL80211_WPA_VERSION_2));
6213}
6214
636a5d36
JM
6215static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
6216{
4c476991
JB
6217 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6218 struct net_device *dev = info->user_ptr[1];
19957bb3 6219 struct ieee80211_channel *chan;
e39e5b5e
JM
6220 const u8 *bssid, *ssid, *ie = NULL, *sae_data = NULL;
6221 int err, ssid_len, ie_len = 0, sae_data_len = 0;
19957bb3 6222 enum nl80211_auth_type auth_type;
fffd0934 6223 struct key_parse key;
d5cdfacb 6224 bool local_state_change;
636a5d36 6225
f4a11bb0
JB
6226 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
6227 return -EINVAL;
6228
6229 if (!info->attrs[NL80211_ATTR_MAC])
6230 return -EINVAL;
6231
1778092e
JM
6232 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
6233 return -EINVAL;
6234
19957bb3
JB
6235 if (!info->attrs[NL80211_ATTR_SSID])
6236 return -EINVAL;
6237
6238 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
6239 return -EINVAL;
6240
fffd0934
JB
6241 err = nl80211_parse_key(info, &key);
6242 if (err)
6243 return err;
6244
6245 if (key.idx >= 0) {
e31b8213
JB
6246 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
6247 return -EINVAL;
fffd0934
JB
6248 if (!key.p.key || !key.p.key_len)
6249 return -EINVAL;
6250 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
6251 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
6252 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
6253 key.p.key_len != WLAN_KEY_LEN_WEP104))
6254 return -EINVAL;
6255 if (key.idx > 4)
6256 return -EINVAL;
6257 } else {
6258 key.p.key_len = 0;
6259 key.p.key = NULL;
6260 }
6261
afea0b7a
JB
6262 if (key.idx >= 0) {
6263 int i;
6264 bool ok = false;
6265 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
6266 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
6267 ok = true;
6268 break;
6269 }
6270 }
4c476991
JB
6271 if (!ok)
6272 return -EINVAL;
afea0b7a
JB
6273 }
6274
4c476991
JB
6275 if (!rdev->ops->auth)
6276 return -EOPNOTSUPP;
636a5d36 6277
074ac8df 6278 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
6279 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
6280 return -EOPNOTSUPP;
eec60b03 6281
19957bb3 6282 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
664834de
JM
6283 chan = nl80211_get_valid_chan(&rdev->wiphy,
6284 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
6285 if (!chan)
4c476991 6286 return -EINVAL;
636a5d36 6287
19957bb3
JB
6288 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
6289 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
6290
6291 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
6292 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
6293 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
6294 }
6295
19957bb3 6296 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 6297 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 6298 return -EINVAL;
636a5d36 6299
e39e5b5e
JM
6300 if (auth_type == NL80211_AUTHTYPE_SAE &&
6301 !info->attrs[NL80211_ATTR_SAE_DATA])
6302 return -EINVAL;
6303
6304 if (info->attrs[NL80211_ATTR_SAE_DATA]) {
6305 if (auth_type != NL80211_AUTHTYPE_SAE)
6306 return -EINVAL;
6307 sae_data = nla_data(info->attrs[NL80211_ATTR_SAE_DATA]);
6308 sae_data_len = nla_len(info->attrs[NL80211_ATTR_SAE_DATA]);
6309 /* need to include at least Auth Transaction and Status Code */
6310 if (sae_data_len < 4)
6311 return -EINVAL;
6312 }
6313
d5cdfacb
JM
6314 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
6315
95de817b
JB
6316 /*
6317 * Since we no longer track auth state, ignore
6318 * requests to only change local state.
6319 */
6320 if (local_state_change)
6321 return 0;
6322
91bf9b26
JB
6323 wdev_lock(dev->ieee80211_ptr);
6324 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
6325 ssid, ssid_len, ie, ie_len,
6326 key.p.key, key.p.key_len, key.idx,
6327 sae_data, sae_data_len);
6328 wdev_unlock(dev->ieee80211_ptr);
6329 return err;
636a5d36
JM
6330}
6331
c0692b8f
JB
6332static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
6333 struct genl_info *info,
3dc27d25
JB
6334 struct cfg80211_crypto_settings *settings,
6335 int cipher_limit)
b23aa676 6336{
c0b2bbd8
JB
6337 memset(settings, 0, sizeof(*settings));
6338
b23aa676
SO
6339 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
6340
c0692b8f
JB
6341 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
6342 u16 proto;
6343 proto = nla_get_u16(
6344 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
6345 settings->control_port_ethertype = cpu_to_be16(proto);
6346 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
6347 proto != ETH_P_PAE)
6348 return -EINVAL;
6349 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
6350 settings->control_port_no_encrypt = true;
6351 } else
6352 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
6353
b23aa676
SO
6354 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
6355 void *data;
6356 int len, i;
6357
6358 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
6359 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
6360 settings->n_ciphers_pairwise = len / sizeof(u32);
6361
6362 if (len % sizeof(u32))
6363 return -EINVAL;
6364
3dc27d25 6365 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
6366 return -EINVAL;
6367
6368 memcpy(settings->ciphers_pairwise, data, len);
6369
6370 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
6371 if (!cfg80211_supported_cipher_suite(
6372 &rdev->wiphy,
b23aa676
SO
6373 settings->ciphers_pairwise[i]))
6374 return -EINVAL;
6375 }
6376
6377 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
6378 settings->cipher_group =
6379 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
6380 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
6381 settings->cipher_group))
b23aa676
SO
6382 return -EINVAL;
6383 }
6384
6385 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
6386 settings->wpa_versions =
6387 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
6388 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
6389 return -EINVAL;
6390 }
6391
6392 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
6393 void *data;
6d30240e 6394 int len;
b23aa676
SO
6395
6396 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
6397 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
6398 settings->n_akm_suites = len / sizeof(u32);
6399
6400 if (len % sizeof(u32))
6401 return -EINVAL;
6402
1b9ca027
JM
6403 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
6404 return -EINVAL;
6405
b23aa676 6406 memcpy(settings->akm_suites, data, len);
b23aa676
SO
6407 }
6408
6409 return 0;
6410}
6411
636a5d36
JM
6412static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
6413{
4c476991
JB
6414 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6415 struct net_device *dev = info->user_ptr[1];
f444de05 6416 struct ieee80211_channel *chan;
f62fab73
JB
6417 struct cfg80211_assoc_request req = {};
6418 const u8 *bssid, *ssid;
6419 int err, ssid_len = 0;
636a5d36 6420
f4a11bb0
JB
6421 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
6422 return -EINVAL;
6423
6424 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
6425 !info->attrs[NL80211_ATTR_SSID] ||
6426 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
6427 return -EINVAL;
6428
4c476991
JB
6429 if (!rdev->ops->assoc)
6430 return -EOPNOTSUPP;
636a5d36 6431
074ac8df 6432 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
6433 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
6434 return -EOPNOTSUPP;
eec60b03 6435
19957bb3 6436 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 6437
664834de
JM
6438 chan = nl80211_get_valid_chan(&rdev->wiphy,
6439 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
6440 if (!chan)
4c476991 6441 return -EINVAL;
636a5d36 6442
19957bb3
JB
6443 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
6444 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
6445
6446 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
6447 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
6448 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
6449 }
6450
dc6382ce 6451 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 6452 enum nl80211_mfp mfp =
dc6382ce 6453 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 6454 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 6455 req.use_mfp = true;
4c476991
JB
6456 else if (mfp != NL80211_MFP_NO)
6457 return -EINVAL;
dc6382ce
JM
6458 }
6459
3e5d7649 6460 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 6461 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 6462
7e7c8926 6463 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 6464 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
6465
6466 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
6467 memcpy(&req.ht_capa_mask,
6468 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
6469 sizeof(req.ht_capa_mask));
7e7c8926
BG
6470
6471 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 6472 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 6473 return -EINVAL;
f62fab73
JB
6474 memcpy(&req.ht_capa,
6475 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
6476 sizeof(req.ht_capa));
7e7c8926
BG
6477 }
6478
ee2aca34 6479 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 6480 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34
JB
6481
6482 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
6483 memcpy(&req.vht_capa_mask,
6484 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
6485 sizeof(req.vht_capa_mask));
ee2aca34
JB
6486
6487 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 6488 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 6489 return -EINVAL;
f62fab73
JB
6490 memcpy(&req.vht_capa,
6491 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
6492 sizeof(req.vht_capa));
ee2aca34
JB
6493 }
6494
f62fab73 6495 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
6496 if (!err) {
6497 wdev_lock(dev->ieee80211_ptr);
f62fab73
JB
6498 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
6499 ssid, ssid_len, &req);
91bf9b26
JB
6500 wdev_unlock(dev->ieee80211_ptr);
6501 }
636a5d36 6502
636a5d36
JM
6503 return err;
6504}
6505
6506static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
6507{
4c476991
JB
6508 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6509 struct net_device *dev = info->user_ptr[1];
19957bb3 6510 const u8 *ie = NULL, *bssid;
91bf9b26 6511 int ie_len = 0, err;
19957bb3 6512 u16 reason_code;
d5cdfacb 6513 bool local_state_change;
636a5d36 6514
f4a11bb0
JB
6515 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
6516 return -EINVAL;
6517
6518 if (!info->attrs[NL80211_ATTR_MAC])
6519 return -EINVAL;
6520
6521 if (!info->attrs[NL80211_ATTR_REASON_CODE])
6522 return -EINVAL;
6523
4c476991
JB
6524 if (!rdev->ops->deauth)
6525 return -EOPNOTSUPP;
636a5d36 6526
074ac8df 6527 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
6528 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
6529 return -EOPNOTSUPP;
eec60b03 6530
19957bb3 6531 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 6532
19957bb3
JB
6533 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
6534 if (reason_code == 0) {
f4a11bb0 6535 /* Reason Code 0 is reserved */
4c476991 6536 return -EINVAL;
255e737e 6537 }
636a5d36
JM
6538
6539 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
6540 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
6541 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
6542 }
6543
d5cdfacb
JM
6544 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
6545
91bf9b26
JB
6546 wdev_lock(dev->ieee80211_ptr);
6547 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
6548 local_state_change);
6549 wdev_unlock(dev->ieee80211_ptr);
6550 return err;
636a5d36
JM
6551}
6552
6553static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
6554{
4c476991
JB
6555 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6556 struct net_device *dev = info->user_ptr[1];
19957bb3 6557 const u8 *ie = NULL, *bssid;
91bf9b26 6558 int ie_len = 0, err;
19957bb3 6559 u16 reason_code;
d5cdfacb 6560 bool local_state_change;
636a5d36 6561
f4a11bb0
JB
6562 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
6563 return -EINVAL;
6564
6565 if (!info->attrs[NL80211_ATTR_MAC])
6566 return -EINVAL;
6567
6568 if (!info->attrs[NL80211_ATTR_REASON_CODE])
6569 return -EINVAL;
6570
4c476991
JB
6571 if (!rdev->ops->disassoc)
6572 return -EOPNOTSUPP;
636a5d36 6573
074ac8df 6574 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
6575 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
6576 return -EOPNOTSUPP;
eec60b03 6577
19957bb3 6578 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 6579
19957bb3
JB
6580 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
6581 if (reason_code == 0) {
f4a11bb0 6582 /* Reason Code 0 is reserved */
4c476991 6583 return -EINVAL;
255e737e 6584 }
636a5d36
JM
6585
6586 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
6587 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
6588 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
6589 }
6590
d5cdfacb
JM
6591 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
6592
91bf9b26
JB
6593 wdev_lock(dev->ieee80211_ptr);
6594 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
6595 local_state_change);
6596 wdev_unlock(dev->ieee80211_ptr);
6597 return err;
636a5d36
JM
6598}
6599
dd5b4cc7
FF
6600static bool
6601nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
6602 int mcast_rate[IEEE80211_NUM_BANDS],
6603 int rateval)
6604{
6605 struct wiphy *wiphy = &rdev->wiphy;
6606 bool found = false;
6607 int band, i;
6608
6609 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
6610 struct ieee80211_supported_band *sband;
6611
6612 sband = wiphy->bands[band];
6613 if (!sband)
6614 continue;
6615
6616 for (i = 0; i < sband->n_bitrates; i++) {
6617 if (sband->bitrates[i].bitrate == rateval) {
6618 mcast_rate[band] = i + 1;
6619 found = true;
6620 break;
6621 }
6622 }
6623 }
6624
6625 return found;
6626}
6627
04a773ad
JB
6628static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
6629{
4c476991
JB
6630 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6631 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
6632 struct cfg80211_ibss_params ibss;
6633 struct wiphy *wiphy;
fffd0934 6634 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
6635 int err;
6636
8e30bc55
JB
6637 memset(&ibss, 0, sizeof(ibss));
6638
04a773ad
JB
6639 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
6640 return -EINVAL;
6641
683b6d3b 6642 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
6643 !nla_len(info->attrs[NL80211_ATTR_SSID]))
6644 return -EINVAL;
6645
8e30bc55
JB
6646 ibss.beacon_interval = 100;
6647
6648 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
6649 ibss.beacon_interval =
6650 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
6651 if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000)
6652 return -EINVAL;
6653 }
6654
4c476991
JB
6655 if (!rdev->ops->join_ibss)
6656 return -EOPNOTSUPP;
04a773ad 6657
4c476991
JB
6658 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
6659 return -EOPNOTSUPP;
04a773ad 6660
79c97e97 6661 wiphy = &rdev->wiphy;
04a773ad 6662
39193498 6663 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 6664 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
6665
6666 if (!is_valid_ether_addr(ibss.bssid))
6667 return -EINVAL;
6668 }
04a773ad
JB
6669 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
6670 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
6671
6672 if (info->attrs[NL80211_ATTR_IE]) {
6673 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
6674 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
6675 }
6676
683b6d3b
JB
6677 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
6678 if (err)
6679 return err;
04a773ad 6680
683b6d3b 6681 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
54858ee5
AS
6682 return -EINVAL;
6683
2f301ab2 6684 switch (ibss.chandef.width) {
bf372645
SW
6685 case NL80211_CHAN_WIDTH_5:
6686 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
6687 case NL80211_CHAN_WIDTH_20_NOHT:
6688 break;
6689 case NL80211_CHAN_WIDTH_20:
6690 case NL80211_CHAN_WIDTH_40:
6691 if (rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)
6692 break;
6693 default:
c04d6150 6694 return -EINVAL;
2f301ab2 6695 }
db9c64cf 6696
04a773ad 6697 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
6698 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
6699
fbd2c8dc
TP
6700 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
6701 u8 *rates =
6702 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
6703 int n_rates =
6704 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
6705 struct ieee80211_supported_band *sband =
683b6d3b 6706 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 6707
34850ab2
JB
6708 err = ieee80211_get_ratemask(sband, rates, n_rates,
6709 &ibss.basic_rates);
6710 if (err)
6711 return err;
fbd2c8dc 6712 }
dd5b4cc7 6713
803768f5
SW
6714 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
6715 memcpy(&ibss.ht_capa_mask,
6716 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
6717 sizeof(ibss.ht_capa_mask));
6718
6719 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
6720 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
6721 return -EINVAL;
6722 memcpy(&ibss.ht_capa,
6723 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
6724 sizeof(ibss.ht_capa));
6725 }
6726
dd5b4cc7
FF
6727 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
6728 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
6729 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
6730 return -EINVAL;
fbd2c8dc 6731
4c476991 6732 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
6733 bool no_ht = false;
6734
4c476991 6735 connkeys = nl80211_parse_connkeys(rdev,
de7044ee
SM
6736 info->attrs[NL80211_ATTR_KEYS],
6737 &no_ht);
4c476991
JB
6738 if (IS_ERR(connkeys))
6739 return PTR_ERR(connkeys);
de7044ee 6740
3d9d1d66
JB
6741 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
6742 no_ht) {
de7044ee
SM
6743 kfree(connkeys);
6744 return -EINVAL;
6745 }
4c476991 6746 }
04a773ad 6747
267335d6
AQ
6748 ibss.control_port =
6749 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
6750
5336fa88
SW
6751 ibss.userspace_handles_dfs =
6752 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
6753
4c476991 6754 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934
JB
6755 if (err)
6756 kfree(connkeys);
04a773ad
JB
6757 return err;
6758}
6759
6760static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
6761{
4c476991
JB
6762 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6763 struct net_device *dev = info->user_ptr[1];
04a773ad 6764
4c476991
JB
6765 if (!rdev->ops->leave_ibss)
6766 return -EOPNOTSUPP;
04a773ad 6767
4c476991
JB
6768 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
6769 return -EOPNOTSUPP;
04a773ad 6770
4c476991 6771 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
6772}
6773
f4e583c8
AQ
6774static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
6775{
6776 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6777 struct net_device *dev = info->user_ptr[1];
6778 int mcast_rate[IEEE80211_NUM_BANDS];
6779 u32 nla_rate;
6780 int err;
6781
6782 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
6783 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6784 return -EOPNOTSUPP;
6785
6786 if (!rdev->ops->set_mcast_rate)
6787 return -EOPNOTSUPP;
6788
6789 memset(mcast_rate, 0, sizeof(mcast_rate));
6790
6791 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
6792 return -EINVAL;
6793
6794 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
6795 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
6796 return -EINVAL;
6797
6798 err = rdev->ops->set_mcast_rate(&rdev->wiphy, dev, mcast_rate);
6799
6800 return err;
6801}
6802
ad7e718c
JB
6803static struct sk_buff *
6804__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6805 int approxlen, u32 portid, u32 seq,
6806 enum nl80211_commands cmd,
567ffc35
JB
6807 enum nl80211_attrs attr,
6808 const struct nl80211_vendor_cmd_info *info,
6809 gfp_t gfp)
ad7e718c
JB
6810{
6811 struct sk_buff *skb;
6812 void *hdr;
6813 struct nlattr *data;
6814
6815 skb = nlmsg_new(approxlen + 100, gfp);
6816 if (!skb)
6817 return NULL;
6818
6819 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
6820 if (!hdr) {
6821 kfree_skb(skb);
6822 return NULL;
6823 }
6824
6825 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
6826 goto nla_put_failure;
567ffc35
JB
6827
6828 if (info) {
6829 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
6830 info->vendor_id))
6831 goto nla_put_failure;
6832 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
6833 info->subcmd))
6834 goto nla_put_failure;
6835 }
6836
ad7e718c
JB
6837 data = nla_nest_start(skb, attr);
6838
6839 ((void **)skb->cb)[0] = rdev;
6840 ((void **)skb->cb)[1] = hdr;
6841 ((void **)skb->cb)[2] = data;
6842
6843 return skb;
6844
6845 nla_put_failure:
6846 kfree_skb(skb);
6847 return NULL;
6848}
f4e583c8 6849
e03ad6ea
JB
6850struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6851 enum nl80211_commands cmd,
6852 enum nl80211_attrs attr,
6853 int vendor_event_idx,
6854 int approxlen, gfp_t gfp)
6855{
6856 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
6857 const struct nl80211_vendor_cmd_info *info;
6858
6859 switch (cmd) {
6860 case NL80211_CMD_TESTMODE:
6861 if (WARN_ON(vendor_event_idx != -1))
6862 return NULL;
6863 info = NULL;
6864 break;
6865 case NL80211_CMD_VENDOR:
6866 if (WARN_ON(vendor_event_idx < 0 ||
6867 vendor_event_idx >= wiphy->n_vendor_events))
6868 return NULL;
6869 info = &wiphy->vendor_events[vendor_event_idx];
6870 break;
6871 default:
6872 WARN_ON(1);
6873 return NULL;
6874 }
6875
6876 return __cfg80211_alloc_vendor_skb(rdev, approxlen, 0, 0,
6877 cmd, attr, info, gfp);
6878}
6879EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
6880
6881void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
6882{
6883 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
6884 void *hdr = ((void **)skb->cb)[1];
6885 struct nlattr *data = ((void **)skb->cb)[2];
6886 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
6887
6888 nla_nest_end(skb, data);
6889 genlmsg_end(skb, hdr);
6890
6891 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
6892 mcgrp = NL80211_MCGRP_VENDOR;
6893
6894 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0,
6895 mcgrp, gfp);
6896}
6897EXPORT_SYMBOL(__cfg80211_send_event_skb);
6898
aff89a9b 6899#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
6900static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
6901{
4c476991 6902 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fc73f11f
DS
6903 struct wireless_dev *wdev =
6904 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
aff89a9b
JB
6905 int err;
6906
fc73f11f
DS
6907 if (!rdev->ops->testmode_cmd)
6908 return -EOPNOTSUPP;
6909
6910 if (IS_ERR(wdev)) {
6911 err = PTR_ERR(wdev);
6912 if (err != -EINVAL)
6913 return err;
6914 wdev = NULL;
6915 } else if (wdev->wiphy != &rdev->wiphy) {
6916 return -EINVAL;
6917 }
6918
aff89a9b
JB
6919 if (!info->attrs[NL80211_ATTR_TESTDATA])
6920 return -EINVAL;
6921
ad7e718c 6922 rdev->cur_cmd_info = info;
fc73f11f 6923 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
6924 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
6925 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 6926 rdev->cur_cmd_info = NULL;
aff89a9b 6927
aff89a9b
JB
6928 return err;
6929}
6930
71063f0e
WYG
6931static int nl80211_testmode_dump(struct sk_buff *skb,
6932 struct netlink_callback *cb)
6933{
00918d33 6934 struct cfg80211_registered_device *rdev;
71063f0e
WYG
6935 int err;
6936 long phy_idx;
6937 void *data = NULL;
6938 int data_len = 0;
6939
5fe231e8
JB
6940 rtnl_lock();
6941
71063f0e
WYG
6942 if (cb->args[0]) {
6943 /*
6944 * 0 is a valid index, but not valid for args[0],
6945 * so we need to offset by 1.
6946 */
6947 phy_idx = cb->args[0] - 1;
6948 } else {
6949 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
6950 nl80211_fam.attrbuf, nl80211_fam.maxattr,
6951 nl80211_policy);
6952 if (err)
5fe231e8 6953 goto out_err;
00918d33 6954
2bd7e35d
JB
6955 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
6956 nl80211_fam.attrbuf);
6957 if (IS_ERR(rdev)) {
5fe231e8
JB
6958 err = PTR_ERR(rdev);
6959 goto out_err;
00918d33 6960 }
2bd7e35d
JB
6961 phy_idx = rdev->wiphy_idx;
6962 rdev = NULL;
2bd7e35d 6963
71063f0e
WYG
6964 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
6965 cb->args[1] =
6966 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
6967 }
6968
6969 if (cb->args[1]) {
6970 data = nla_data((void *)cb->args[1]);
6971 data_len = nla_len((void *)cb->args[1]);
6972 }
6973
00918d33
JB
6974 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
6975 if (!rdev) {
5fe231e8
JB
6976 err = -ENOENT;
6977 goto out_err;
71063f0e 6978 }
71063f0e 6979
00918d33 6980 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
6981 err = -EOPNOTSUPP;
6982 goto out_err;
6983 }
6984
6985 while (1) {
15e47304 6986 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
6987 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6988 NL80211_CMD_TESTMODE);
6989 struct nlattr *tmdata;
6990
cb35fba3
DC
6991 if (!hdr)
6992 break;
6993
9360ffd1 6994 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
6995 genlmsg_cancel(skb, hdr);
6996 break;
6997 }
6998
6999 tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
7000 if (!tmdata) {
7001 genlmsg_cancel(skb, hdr);
7002 break;
7003 }
e35e4d28 7004 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
7005 nla_nest_end(skb, tmdata);
7006
7007 if (err == -ENOBUFS || err == -ENOENT) {
7008 genlmsg_cancel(skb, hdr);
7009 break;
7010 } else if (err) {
7011 genlmsg_cancel(skb, hdr);
7012 goto out_err;
7013 }
7014
7015 genlmsg_end(skb, hdr);
7016 }
7017
7018 err = skb->len;
7019 /* see above */
7020 cb->args[0] = phy_idx + 1;
7021 out_err:
5fe231e8 7022 rtnl_unlock();
71063f0e
WYG
7023 return err;
7024}
aff89a9b
JB
7025#endif
7026
b23aa676
SO
7027static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
7028{
4c476991
JB
7029 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7030 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
7031 struct cfg80211_connect_params connect;
7032 struct wiphy *wiphy;
fffd0934 7033 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
7034 int err;
7035
7036 memset(&connect, 0, sizeof(connect));
7037
7038 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
7039 return -EINVAL;
7040
7041 if (!info->attrs[NL80211_ATTR_SSID] ||
7042 !nla_len(info->attrs[NL80211_ATTR_SSID]))
7043 return -EINVAL;
7044
7045 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
7046 connect.auth_type =
7047 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
7048 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
7049 NL80211_CMD_CONNECT))
b23aa676
SO
7050 return -EINVAL;
7051 } else
7052 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
7053
7054 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
7055
c0692b8f 7056 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 7057 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
7058 if (err)
7059 return err;
b23aa676 7060
074ac8df 7061 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7062 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
7063 return -EOPNOTSUPP;
b23aa676 7064
79c97e97 7065 wiphy = &rdev->wiphy;
b23aa676 7066
4486ea98
BS
7067 connect.bg_scan_period = -1;
7068 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
7069 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
7070 connect.bg_scan_period =
7071 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
7072 }
7073
b23aa676
SO
7074 if (info->attrs[NL80211_ATTR_MAC])
7075 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
7076 else if (info->attrs[NL80211_ATTR_MAC_HINT])
7077 connect.bssid_hint =
7078 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
7079 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
7080 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
7081
7082 if (info->attrs[NL80211_ATTR_IE]) {
7083 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
7084 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
7085 }
7086
cee00a95
JM
7087 if (info->attrs[NL80211_ATTR_USE_MFP]) {
7088 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
7089 if (connect.mfp != NL80211_MFP_REQUIRED &&
7090 connect.mfp != NL80211_MFP_NO)
7091 return -EINVAL;
7092 } else {
7093 connect.mfp = NL80211_MFP_NO;
7094 }
7095
b23aa676 7096 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
664834de
JM
7097 connect.channel = nl80211_get_valid_chan(
7098 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
7099 if (!connect.channel)
1df4a510
JM
7100 return -EINVAL;
7101 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
664834de
JM
7102 connect.channel_hint = nl80211_get_valid_chan(
7103 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
7104 if (!connect.channel_hint)
4c476991 7105 return -EINVAL;
b23aa676
SO
7106 }
7107
fffd0934
JB
7108 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
7109 connkeys = nl80211_parse_connkeys(rdev,
de7044ee 7110 info->attrs[NL80211_ATTR_KEYS], NULL);
4c476991
JB
7111 if (IS_ERR(connkeys))
7112 return PTR_ERR(connkeys);
fffd0934
JB
7113 }
7114
7e7c8926
BG
7115 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
7116 connect.flags |= ASSOC_REQ_DISABLE_HT;
7117
7118 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7119 memcpy(&connect.ht_capa_mask,
7120 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
7121 sizeof(connect.ht_capa_mask));
7122
7123 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e
WY
7124 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
7125 kfree(connkeys);
7e7c8926 7126 return -EINVAL;
b4e4f47e 7127 }
7e7c8926
BG
7128 memcpy(&connect.ht_capa,
7129 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
7130 sizeof(connect.ht_capa));
7131 }
7132
ee2aca34
JB
7133 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
7134 connect.flags |= ASSOC_REQ_DISABLE_VHT;
7135
7136 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
7137 memcpy(&connect.vht_capa_mask,
7138 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
7139 sizeof(connect.vht_capa_mask));
7140
7141 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
7142 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
7143 kfree(connkeys);
7144 return -EINVAL;
7145 }
7146 memcpy(&connect.vht_capa,
7147 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
7148 sizeof(connect.vht_capa));
7149 }
7150
83739b03
JB
7151 wdev_lock(dev->ieee80211_ptr);
7152 err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL);
7153 wdev_unlock(dev->ieee80211_ptr);
fffd0934
JB
7154 if (err)
7155 kfree(connkeys);
b23aa676
SO
7156 return err;
7157}
7158
7159static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
7160{
4c476991
JB
7161 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7162 struct net_device *dev = info->user_ptr[1];
b23aa676 7163 u16 reason;
83739b03 7164 int ret;
b23aa676
SO
7165
7166 if (!info->attrs[NL80211_ATTR_REASON_CODE])
7167 reason = WLAN_REASON_DEAUTH_LEAVING;
7168 else
7169 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
7170
7171 if (reason == 0)
7172 return -EINVAL;
7173
074ac8df 7174 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7175 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
7176 return -EOPNOTSUPP;
b23aa676 7177
83739b03
JB
7178 wdev_lock(dev->ieee80211_ptr);
7179 ret = cfg80211_disconnect(rdev, dev, reason, true);
7180 wdev_unlock(dev->ieee80211_ptr);
7181 return ret;
b23aa676
SO
7182}
7183
463d0183
JB
7184static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
7185{
4c476991 7186 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
7187 struct net *net;
7188 int err;
7189 u32 pid;
7190
7191 if (!info->attrs[NL80211_ATTR_PID])
7192 return -EINVAL;
7193
7194 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
7195
463d0183 7196 net = get_net_ns_by_pid(pid);
4c476991
JB
7197 if (IS_ERR(net))
7198 return PTR_ERR(net);
463d0183
JB
7199
7200 err = 0;
7201
7202 /* check if anything to do */
4c476991
JB
7203 if (!net_eq(wiphy_net(&rdev->wiphy), net))
7204 err = cfg80211_switch_netns(rdev, net);
463d0183 7205
463d0183 7206 put_net(net);
463d0183
JB
7207 return err;
7208}
7209
67fbb16b
SO
7210static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
7211{
4c476991 7212 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
7213 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
7214 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 7215 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
7216 struct cfg80211_pmksa pmksa;
7217
7218 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
7219
7220 if (!info->attrs[NL80211_ATTR_MAC])
7221 return -EINVAL;
7222
7223 if (!info->attrs[NL80211_ATTR_PMKID])
7224 return -EINVAL;
7225
67fbb16b
SO
7226 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
7227 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
7228
074ac8df 7229 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7230 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
7231 return -EOPNOTSUPP;
67fbb16b
SO
7232
7233 switch (info->genlhdr->cmd) {
7234 case NL80211_CMD_SET_PMKSA:
7235 rdev_ops = rdev->ops->set_pmksa;
7236 break;
7237 case NL80211_CMD_DEL_PMKSA:
7238 rdev_ops = rdev->ops->del_pmksa;
7239 break;
7240 default:
7241 WARN_ON(1);
7242 break;
7243 }
7244
4c476991
JB
7245 if (!rdev_ops)
7246 return -EOPNOTSUPP;
67fbb16b 7247
4c476991 7248 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
7249}
7250
7251static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
7252{
4c476991
JB
7253 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7254 struct net_device *dev = info->user_ptr[1];
67fbb16b 7255
074ac8df 7256 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7257 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
7258 return -EOPNOTSUPP;
67fbb16b 7259
4c476991
JB
7260 if (!rdev->ops->flush_pmksa)
7261 return -EOPNOTSUPP;
67fbb16b 7262
e35e4d28 7263 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
7264}
7265
109086ce
AN
7266static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
7267{
7268 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7269 struct net_device *dev = info->user_ptr[1];
7270 u8 action_code, dialog_token;
7271 u16 status_code;
7272 u8 *peer;
7273
7274 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
7275 !rdev->ops->tdls_mgmt)
7276 return -EOPNOTSUPP;
7277
7278 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
7279 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
7280 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
7281 !info->attrs[NL80211_ATTR_IE] ||
7282 !info->attrs[NL80211_ATTR_MAC])
7283 return -EINVAL;
7284
7285 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
7286 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
7287 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
7288 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
7289
e35e4d28
HG
7290 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
7291 dialog_token, status_code,
7292 nla_data(info->attrs[NL80211_ATTR_IE]),
7293 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
7294}
7295
7296static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
7297{
7298 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7299 struct net_device *dev = info->user_ptr[1];
7300 enum nl80211_tdls_operation operation;
7301 u8 *peer;
7302
7303 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
7304 !rdev->ops->tdls_oper)
7305 return -EOPNOTSUPP;
7306
7307 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
7308 !info->attrs[NL80211_ATTR_MAC])
7309 return -EINVAL;
7310
7311 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
7312 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
7313
e35e4d28 7314 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
7315}
7316
9588bbd5
JM
7317static int nl80211_remain_on_channel(struct sk_buff *skb,
7318 struct genl_info *info)
7319{
4c476991 7320 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 7321 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 7322 struct cfg80211_chan_def chandef;
9588bbd5
JM
7323 struct sk_buff *msg;
7324 void *hdr;
7325 u64 cookie;
683b6d3b 7326 u32 duration;
9588bbd5
JM
7327 int err;
7328
7329 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
7330 !info->attrs[NL80211_ATTR_DURATION])
7331 return -EINVAL;
7332
7333 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
7334
ebf348fc
JB
7335 if (!rdev->ops->remain_on_channel ||
7336 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
7337 return -EOPNOTSUPP;
7338
9588bbd5 7339 /*
ebf348fc
JB
7340 * We should be on that channel for at least a minimum amount of
7341 * time (10ms) but no longer than the driver supports.
9588bbd5 7342 */
ebf348fc 7343 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 7344 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
7345 return -EINVAL;
7346
683b6d3b
JB
7347 err = nl80211_parse_chandef(rdev, info, &chandef);
7348 if (err)
7349 return err;
9588bbd5
JM
7350
7351 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
7352 if (!msg)
7353 return -ENOMEM;
9588bbd5 7354
15e47304 7355 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 7356 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
7357 if (!hdr) {
7358 err = -ENOBUFS;
9588bbd5
JM
7359 goto free_msg;
7360 }
7361
683b6d3b
JB
7362 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
7363 duration, &cookie);
9588bbd5
JM
7364
7365 if (err)
7366 goto free_msg;
7367
9360ffd1
DM
7368 if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
7369 goto nla_put_failure;
9588bbd5
JM
7370
7371 genlmsg_end(msg, hdr);
4c476991
JB
7372
7373 return genlmsg_reply(msg, info);
9588bbd5
JM
7374
7375 nla_put_failure:
7376 err = -ENOBUFS;
7377 free_msg:
7378 nlmsg_free(msg);
9588bbd5
JM
7379 return err;
7380}
7381
7382static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
7383 struct genl_info *info)
7384{
4c476991 7385 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 7386 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 7387 u64 cookie;
9588bbd5
JM
7388
7389 if (!info->attrs[NL80211_ATTR_COOKIE])
7390 return -EINVAL;
7391
4c476991
JB
7392 if (!rdev->ops->cancel_remain_on_channel)
7393 return -EOPNOTSUPP;
9588bbd5 7394
9588bbd5
JM
7395 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
7396
e35e4d28 7397 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
7398}
7399
13ae75b1
JM
7400static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
7401 u8 *rates, u8 rates_len)
7402{
7403 u8 i;
7404 u32 mask = 0;
7405
7406 for (i = 0; i < rates_len; i++) {
7407 int rate = (rates[i] & 0x7f) * 5;
7408 int ridx;
7409 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
7410 struct ieee80211_rate *srate =
7411 &sband->bitrates[ridx];
7412 if (rate == srate->bitrate) {
7413 mask |= 1 << ridx;
7414 break;
7415 }
7416 }
7417 if (ridx == sband->n_bitrates)
7418 return 0; /* rate not found */
7419 }
7420
7421 return mask;
7422}
7423
24db78c0
SW
7424static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
7425 u8 *rates, u8 rates_len,
7426 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
7427{
7428 u8 i;
7429
7430 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
7431
7432 for (i = 0; i < rates_len; i++) {
7433 int ridx, rbit;
7434
7435 ridx = rates[i] / 8;
7436 rbit = BIT(rates[i] % 8);
7437
7438 /* check validity */
910570b5 7439 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
24db78c0
SW
7440 return false;
7441
7442 /* check availability */
7443 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
7444 mcs[ridx] |= rbit;
7445 else
7446 return false;
7447 }
7448
7449 return true;
7450}
7451
204e35a9
JD
7452static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
7453{
7454 u16 mcs_mask = 0;
7455
7456 switch (vht_mcs_map) {
7457 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
7458 break;
7459 case IEEE80211_VHT_MCS_SUPPORT_0_7:
7460 mcs_mask = 0x00FF;
7461 break;
7462 case IEEE80211_VHT_MCS_SUPPORT_0_8:
7463 mcs_mask = 0x01FF;
7464 break;
7465 case IEEE80211_VHT_MCS_SUPPORT_0_9:
7466 mcs_mask = 0x03FF;
7467 break;
7468 default:
7469 break;
7470 }
7471
7472 return mcs_mask;
7473}
7474
7475static void vht_build_mcs_mask(u16 vht_mcs_map,
7476 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
7477{
7478 u8 nss;
7479
7480 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
7481 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
7482 vht_mcs_map >>= 2;
7483 }
7484}
7485
7486static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
7487 struct nl80211_txrate_vht *txrate,
7488 u16 mcs[NL80211_VHT_NSS_MAX])
7489{
7490 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
7491 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
7492 u8 i;
7493
7494 if (!sband->vht_cap.vht_supported)
7495 return false;
7496
7497 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
7498
7499 /* Build vht_mcs_mask from VHT capabilities */
7500 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
7501
7502 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
7503 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
7504 mcs[i] = txrate->mcs[i];
7505 else
7506 return false;
7507 }
7508
7509 return true;
7510}
7511
b54452b0 7512static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
13ae75b1
JM
7513 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
7514 .len = NL80211_MAX_SUPP_RATES },
d1e33e65
JD
7515 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
7516 .len = NL80211_MAX_SUPP_HT_RATES },
204e35a9 7517 [NL80211_TXRATE_VHT] = { .len = sizeof(struct nl80211_txrate_vht)},
0b9323f6 7518 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
13ae75b1
JM
7519};
7520
7521static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
7522 struct genl_info *info)
7523{
7524 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4c476991 7525 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13ae75b1 7526 struct cfg80211_bitrate_mask mask;
4c476991
JB
7527 int rem, i;
7528 struct net_device *dev = info->user_ptr[1];
13ae75b1
JM
7529 struct nlattr *tx_rates;
7530 struct ieee80211_supported_band *sband;
204e35a9 7531 u16 vht_tx_mcs_map;
13ae75b1 7532
4c476991
JB
7533 if (!rdev->ops->set_bitrate_mask)
7534 return -EOPNOTSUPP;
13ae75b1
JM
7535
7536 memset(&mask, 0, sizeof(mask));
7537 /* Default to all rates enabled */
7538 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
7539 sband = rdev->wiphy.bands[i];
7869303b
JD
7540
7541 if (!sband)
7542 continue;
7543
7544 mask.control[i].legacy = (1 << sband->n_bitrates) - 1;
d1e33e65 7545 memcpy(mask.control[i].ht_mcs,
7869303b 7546 sband->ht_cap.mcs.rx_mask,
d1e33e65 7547 sizeof(mask.control[i].ht_mcs));
204e35a9
JD
7548
7549 if (!sband->vht_cap.vht_supported)
7550 continue;
7551
7552 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
7553 vht_build_mcs_mask(vht_tx_mcs_map, mask.control[i].vht_mcs);
13ae75b1
JM
7554 }
7555
b9243ab0
JD
7556 /* if no rates are given set it back to the defaults */
7557 if (!info->attrs[NL80211_ATTR_TX_RATES])
7558 goto out;
7559
13ae75b1
JM
7560 /*
7561 * The nested attribute uses enum nl80211_band as the index. This maps
7562 * directly to the enum ieee80211_band values used in cfg80211.
7563 */
24db78c0 7564 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
ae811e21 7565 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
13ae75b1 7566 enum ieee80211_band band = nla_type(tx_rates);
ae811e21
JB
7567 int err;
7568
4c476991
JB
7569 if (band < 0 || band >= IEEE80211_NUM_BANDS)
7570 return -EINVAL;
13ae75b1 7571 sband = rdev->wiphy.bands[band];
4c476991
JB
7572 if (sband == NULL)
7573 return -EINVAL;
ae811e21
JB
7574 err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
7575 nla_len(tx_rates), nl80211_txattr_policy);
7576 if (err)
7577 return err;
13ae75b1
JM
7578 if (tb[NL80211_TXRATE_LEGACY]) {
7579 mask.control[band].legacy = rateset_to_mask(
7580 sband,
7581 nla_data(tb[NL80211_TXRATE_LEGACY]),
7582 nla_len(tb[NL80211_TXRATE_LEGACY]));
218d2e26
BS
7583 if ((mask.control[band].legacy == 0) &&
7584 nla_len(tb[NL80211_TXRATE_LEGACY]))
7585 return -EINVAL;
24db78c0 7586 }
d1e33e65 7587 if (tb[NL80211_TXRATE_HT]) {
24db78c0
SW
7588 if (!ht_rateset_to_mask(
7589 sband,
d1e33e65
JD
7590 nla_data(tb[NL80211_TXRATE_HT]),
7591 nla_len(tb[NL80211_TXRATE_HT]),
7592 mask.control[band].ht_mcs))
24db78c0
SW
7593 return -EINVAL;
7594 }
204e35a9
JD
7595 if (tb[NL80211_TXRATE_VHT]) {
7596 if (!vht_set_mcs_mask(
7597 sband,
7598 nla_data(tb[NL80211_TXRATE_VHT]),
7599 mask.control[band].vht_mcs))
7600 return -EINVAL;
7601 }
0b9323f6
JD
7602 if (tb[NL80211_TXRATE_GI]) {
7603 mask.control[band].gi =
7604 nla_get_u8(tb[NL80211_TXRATE_GI]);
7605 if (mask.control[band].gi > NL80211_TXRATE_FORCE_LGI)
7606 return -EINVAL;
7607 }
24db78c0
SW
7608
7609 if (mask.control[band].legacy == 0) {
204e35a9
JD
7610 /* don't allow empty legacy rates if HT or VHT
7611 * are not even supported.
7612 */
7613 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
7614 rdev->wiphy.bands[band]->vht_cap.vht_supported))
24db78c0
SW
7615 return -EINVAL;
7616
7617 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
d1e33e65 7618 if (mask.control[band].ht_mcs[i])
204e35a9
JD
7619 goto out;
7620
7621 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
7622 if (mask.control[band].vht_mcs[i])
7623 goto out;
24db78c0
SW
7624
7625 /* legacy and mcs rates may not be both empty */
204e35a9 7626 return -EINVAL;
13ae75b1
JM
7627 }
7628 }
7629
b9243ab0 7630out:
e35e4d28 7631 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
7632}
7633
2e161f78 7634static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 7635{
4c476991 7636 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 7637 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 7638 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
7639
7640 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
7641 return -EINVAL;
7642
2e161f78
JB
7643 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
7644 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 7645
71bbc994
JB
7646 switch (wdev->iftype) {
7647 case NL80211_IFTYPE_STATION:
7648 case NL80211_IFTYPE_ADHOC:
7649 case NL80211_IFTYPE_P2P_CLIENT:
7650 case NL80211_IFTYPE_AP:
7651 case NL80211_IFTYPE_AP_VLAN:
7652 case NL80211_IFTYPE_MESH_POINT:
7653 case NL80211_IFTYPE_P2P_GO:
98104fde 7654 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994
JB
7655 break;
7656 default:
4c476991 7657 return -EOPNOTSUPP;
71bbc994 7658 }
026331c4
JM
7659
7660 /* not much point in registering if we can't reply */
4c476991
JB
7661 if (!rdev->ops->mgmt_tx)
7662 return -EOPNOTSUPP;
026331c4 7663
15e47304 7664 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
026331c4
JM
7665 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
7666 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
026331c4
JM
7667}
7668
2e161f78 7669static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 7670{
4c476991 7671 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 7672 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 7673 struct cfg80211_chan_def chandef;
026331c4 7674 int err;
d64d373f 7675 void *hdr = NULL;
026331c4 7676 u64 cookie;
e247bd90 7677 struct sk_buff *msg = NULL;
b176e629
AO
7678 struct cfg80211_mgmt_tx_params params = {
7679 .dont_wait_for_ack =
7680 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
7681 };
026331c4 7682
683b6d3b 7683 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
7684 return -EINVAL;
7685
4c476991
JB
7686 if (!rdev->ops->mgmt_tx)
7687 return -EOPNOTSUPP;
026331c4 7688
71bbc994 7689 switch (wdev->iftype) {
ea141b75
AQ
7690 case NL80211_IFTYPE_P2P_DEVICE:
7691 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
7692 return -EINVAL;
71bbc994
JB
7693 case NL80211_IFTYPE_STATION:
7694 case NL80211_IFTYPE_ADHOC:
7695 case NL80211_IFTYPE_P2P_CLIENT:
7696 case NL80211_IFTYPE_AP:
7697 case NL80211_IFTYPE_AP_VLAN:
7698 case NL80211_IFTYPE_MESH_POINT:
7699 case NL80211_IFTYPE_P2P_GO:
7700 break;
7701 default:
4c476991 7702 return -EOPNOTSUPP;
71bbc994 7703 }
026331c4 7704
f7ca38df 7705 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 7706 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 7707 return -EINVAL;
b176e629 7708 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
7709
7710 /*
7711 * We should wait on the channel for at least a minimum amount
7712 * of time (10ms) but no longer than the driver supports.
7713 */
b176e629
AO
7714 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
7715 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc
JB
7716 return -EINVAL;
7717
f7ca38df
JB
7718 }
7719
b176e629 7720 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 7721
b176e629 7722 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
7723 return -EINVAL;
7724
b176e629 7725 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 7726
ea141b75
AQ
7727 /* get the channel if any has been specified, otherwise pass NULL to
7728 * the driver. The latter will use the current one
7729 */
7730 chandef.chan = NULL;
7731 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
7732 err = nl80211_parse_chandef(rdev, info, &chandef);
7733 if (err)
7734 return err;
7735 }
7736
b176e629 7737 if (!chandef.chan && params.offchan)
ea141b75 7738 return -EINVAL;
026331c4 7739
b176e629 7740 if (!params.dont_wait_for_ack) {
e247bd90
JB
7741 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7742 if (!msg)
7743 return -ENOMEM;
026331c4 7744
15e47304 7745 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 7746 NL80211_CMD_FRAME);
cb35fba3
DC
7747 if (!hdr) {
7748 err = -ENOBUFS;
e247bd90
JB
7749 goto free_msg;
7750 }
026331c4 7751 }
e247bd90 7752
b176e629
AO
7753 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
7754 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
7755 params.chan = chandef.chan;
7756 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
7757 if (err)
7758 goto free_msg;
7759
e247bd90 7760 if (msg) {
9360ffd1
DM
7761 if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
7762 goto nla_put_failure;
026331c4 7763
e247bd90
JB
7764 genlmsg_end(msg, hdr);
7765 return genlmsg_reply(msg, info);
7766 }
7767
7768 return 0;
026331c4
JM
7769
7770 nla_put_failure:
7771 err = -ENOBUFS;
7772 free_msg:
7773 nlmsg_free(msg);
026331c4
JM
7774 return err;
7775}
7776
f7ca38df
JB
7777static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
7778{
7779 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 7780 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
7781 u64 cookie;
7782
7783 if (!info->attrs[NL80211_ATTR_COOKIE])
7784 return -EINVAL;
7785
7786 if (!rdev->ops->mgmt_tx_cancel_wait)
7787 return -EOPNOTSUPP;
7788
71bbc994
JB
7789 switch (wdev->iftype) {
7790 case NL80211_IFTYPE_STATION:
7791 case NL80211_IFTYPE_ADHOC:
7792 case NL80211_IFTYPE_P2P_CLIENT:
7793 case NL80211_IFTYPE_AP:
7794 case NL80211_IFTYPE_AP_VLAN:
7795 case NL80211_IFTYPE_P2P_GO:
98104fde 7796 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994
JB
7797 break;
7798 default:
f7ca38df 7799 return -EOPNOTSUPP;
71bbc994 7800 }
f7ca38df
JB
7801
7802 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
7803
e35e4d28 7804 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
7805}
7806
ffb9eb3d
KV
7807static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
7808{
4c476991 7809 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 7810 struct wireless_dev *wdev;
4c476991 7811 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
7812 u8 ps_state;
7813 bool state;
7814 int err;
7815
4c476991
JB
7816 if (!info->attrs[NL80211_ATTR_PS_STATE])
7817 return -EINVAL;
ffb9eb3d
KV
7818
7819 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
7820
4c476991
JB
7821 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
7822 return -EINVAL;
ffb9eb3d
KV
7823
7824 wdev = dev->ieee80211_ptr;
7825
4c476991
JB
7826 if (!rdev->ops->set_power_mgmt)
7827 return -EOPNOTSUPP;
ffb9eb3d
KV
7828
7829 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
7830
7831 if (state == wdev->ps)
4c476991 7832 return 0;
ffb9eb3d 7833
e35e4d28 7834 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
7835 if (!err)
7836 wdev->ps = state;
ffb9eb3d
KV
7837 return err;
7838}
7839
7840static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
7841{
4c476991 7842 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
7843 enum nl80211_ps_state ps_state;
7844 struct wireless_dev *wdev;
4c476991 7845 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
7846 struct sk_buff *msg;
7847 void *hdr;
7848 int err;
7849
ffb9eb3d
KV
7850 wdev = dev->ieee80211_ptr;
7851
4c476991
JB
7852 if (!rdev->ops->set_power_mgmt)
7853 return -EOPNOTSUPP;
ffb9eb3d
KV
7854
7855 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
7856 if (!msg)
7857 return -ENOMEM;
ffb9eb3d 7858
15e47304 7859 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
7860 NL80211_CMD_GET_POWER_SAVE);
7861 if (!hdr) {
4c476991 7862 err = -ENOBUFS;
ffb9eb3d
KV
7863 goto free_msg;
7864 }
7865
7866 if (wdev->ps)
7867 ps_state = NL80211_PS_ENABLED;
7868 else
7869 ps_state = NL80211_PS_DISABLED;
7870
9360ffd1
DM
7871 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
7872 goto nla_put_failure;
ffb9eb3d
KV
7873
7874 genlmsg_end(msg, hdr);
4c476991 7875 return genlmsg_reply(msg, info);
ffb9eb3d 7876
4c476991 7877 nla_put_failure:
ffb9eb3d 7878 err = -ENOBUFS;
4c476991 7879 free_msg:
ffb9eb3d 7880 nlmsg_free(msg);
ffb9eb3d
KV
7881 return err;
7882}
7883
94e860f1
JB
7884static const struct nla_policy
7885nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
d6dc1a38
JO
7886 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
7887 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
7888 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
7889 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
7890 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
7891 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
d6dc1a38
JO
7892};
7893
84f10708 7894static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 7895 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
7896{
7897 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 7898 struct net_device *dev = info->user_ptr[1];
1da5fcc8 7899 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 7900
d9d8b019 7901 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
7902 return -EINVAL;
7903
84f10708
TP
7904 if (!rdev->ops->set_cqm_txe_config)
7905 return -EOPNOTSUPP;
7906
7907 if (wdev->iftype != NL80211_IFTYPE_STATION &&
7908 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
7909 return -EOPNOTSUPP;
7910
e35e4d28 7911 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
7912}
7913
d6dc1a38
JO
7914static int nl80211_set_cqm_rssi(struct genl_info *info,
7915 s32 threshold, u32 hysteresis)
7916{
4c476991 7917 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 7918 struct net_device *dev = info->user_ptr[1];
1da5fcc8 7919 struct wireless_dev *wdev = dev->ieee80211_ptr;
d6dc1a38
JO
7920
7921 if (threshold > 0)
7922 return -EINVAL;
7923
1da5fcc8
JB
7924 /* disabling - hysteresis should also be zero then */
7925 if (threshold == 0)
7926 hysteresis = 0;
d6dc1a38 7927
4c476991
JB
7928 if (!rdev->ops->set_cqm_rssi_config)
7929 return -EOPNOTSUPP;
d6dc1a38 7930
074ac8df 7931 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7932 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
7933 return -EOPNOTSUPP;
d6dc1a38 7934
e35e4d28 7935 return rdev_set_cqm_rssi_config(rdev, dev, threshold, hysteresis);
d6dc1a38
JO
7936}
7937
7938static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
7939{
7940 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
7941 struct nlattr *cqm;
7942 int err;
7943
7944 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
7945 if (!cqm)
7946 return -EINVAL;
d6dc1a38
JO
7947
7948 err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
7949 nl80211_attr_cqm_policy);
7950 if (err)
1da5fcc8 7951 return err;
d6dc1a38
JO
7952
7953 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
7954 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
1da5fcc8
JB
7955 s32 threshold = nla_get_s32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
7956 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 7957
1da5fcc8
JB
7958 return nl80211_set_cqm_rssi(info, threshold, hysteresis);
7959 }
7960
7961 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
7962 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
7963 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
7964 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
7965 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
7966 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
7967
7968 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
7969 }
7970
7971 return -EINVAL;
d6dc1a38
JO
7972}
7973
29cbe68c
JB
7974static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
7975{
7976 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7977 struct net_device *dev = info->user_ptr[1];
7978 struct mesh_config cfg;
c80d545d 7979 struct mesh_setup setup;
29cbe68c
JB
7980 int err;
7981
7982 /* start with default */
7983 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 7984 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 7985
24bdd9f4 7986 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 7987 /* and parse parameters if given */
24bdd9f4 7988 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
7989 if (err)
7990 return err;
7991 }
7992
7993 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
7994 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
7995 return -EINVAL;
7996
c80d545d
JC
7997 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
7998 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
7999
4bb62344
CYY
8000 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
8001 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
8002 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
8003 return -EINVAL;
8004
9bdbf04d
MP
8005 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
8006 setup.beacon_interval =
8007 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
8008 if (setup.beacon_interval < 10 ||
8009 setup.beacon_interval > 10000)
8010 return -EINVAL;
8011 }
8012
8013 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
8014 setup.dtim_period =
8015 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
8016 if (setup.dtim_period < 1 || setup.dtim_period > 100)
8017 return -EINVAL;
8018 }
8019
c80d545d
JC
8020 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
8021 /* parse additional setup parameters if given */
8022 err = nl80211_parse_mesh_setup(info, &setup);
8023 if (err)
8024 return err;
8025 }
8026
d37bb18a
TP
8027 if (setup.user_mpm)
8028 cfg.auto_open_plinks = false;
8029
cc1d2806 8030 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
8031 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
8032 if (err)
8033 return err;
cc1d2806
JB
8034 } else {
8035 /* cfg80211_join_mesh() will sort it out */
683b6d3b 8036 setup.chandef.chan = NULL;
cc1d2806
JB
8037 }
8038
ffb3cf30
AN
8039 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
8040 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8041 int n_rates =
8042 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8043 struct ieee80211_supported_band *sband;
8044
8045 if (!setup.chandef.chan)
8046 return -EINVAL;
8047
8048 sband = rdev->wiphy.bands[setup.chandef.chan->band];
8049
8050 err = ieee80211_get_ratemask(sband, rates, n_rates,
8051 &setup.basic_rates);
8052 if (err)
8053 return err;
8054 }
8055
c80d545d 8056 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
29cbe68c
JB
8057}
8058
8059static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
8060{
8061 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8062 struct net_device *dev = info->user_ptr[1];
8063
8064 return cfg80211_leave_mesh(rdev, dev);
8065}
8066
dfb89c56 8067#ifdef CONFIG_PM
bb92d199
AK
8068static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
8069 struct cfg80211_registered_device *rdev)
8070{
6abb9cb9 8071 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
8072 struct nlattr *nl_pats, *nl_pat;
8073 int i, pat_len;
8074
6abb9cb9 8075 if (!wowlan->n_patterns)
bb92d199
AK
8076 return 0;
8077
8078 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
8079 if (!nl_pats)
8080 return -ENOBUFS;
8081
6abb9cb9 8082 for (i = 0; i < wowlan->n_patterns; i++) {
bb92d199
AK
8083 nl_pat = nla_nest_start(msg, i + 1);
8084 if (!nl_pat)
8085 return -ENOBUFS;
6abb9cb9 8086 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 8087 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 8088 wowlan->patterns[i].mask) ||
50ac6607
AK
8089 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
8090 wowlan->patterns[i].pattern) ||
8091 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 8092 wowlan->patterns[i].pkt_offset))
bb92d199
AK
8093 return -ENOBUFS;
8094 nla_nest_end(msg, nl_pat);
8095 }
8096 nla_nest_end(msg, nl_pats);
8097
8098 return 0;
8099}
8100
2a0e047e
JB
8101static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
8102 struct cfg80211_wowlan_tcp *tcp)
8103{
8104 struct nlattr *nl_tcp;
8105
8106 if (!tcp)
8107 return 0;
8108
8109 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
8110 if (!nl_tcp)
8111 return -ENOBUFS;
8112
8113 if (nla_put_be32(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
8114 nla_put_be32(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
8115 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
8116 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
8117 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
8118 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
8119 tcp->payload_len, tcp->payload) ||
8120 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
8121 tcp->data_interval) ||
8122 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
8123 tcp->wake_len, tcp->wake_data) ||
8124 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
8125 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
8126 return -ENOBUFS;
8127
8128 if (tcp->payload_seq.len &&
8129 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
8130 sizeof(tcp->payload_seq), &tcp->payload_seq))
8131 return -ENOBUFS;
8132
8133 if (tcp->payload_tok.len &&
8134 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
8135 sizeof(tcp->payload_tok) + tcp->tokens_size,
8136 &tcp->payload_tok))
8137 return -ENOBUFS;
8138
e248ad30
JB
8139 nla_nest_end(msg, nl_tcp);
8140
2a0e047e
JB
8141 return 0;
8142}
8143
ff1b6e69
JB
8144static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
8145{
8146 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8147 struct sk_buff *msg;
8148 void *hdr;
2a0e047e 8149 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 8150
964dc9e2 8151 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
8152 return -EOPNOTSUPP;
8153
6abb9cb9 8154 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 8155 /* adjust size to have room for all the data */
6abb9cb9
JB
8156 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
8157 rdev->wiphy.wowlan_config->tcp->payload_len +
8158 rdev->wiphy.wowlan_config->tcp->wake_len +
8159 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
8160 }
8161
8162 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
8163 if (!msg)
8164 return -ENOMEM;
8165
15e47304 8166 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
8167 NL80211_CMD_GET_WOWLAN);
8168 if (!hdr)
8169 goto nla_put_failure;
8170
6abb9cb9 8171 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
8172 struct nlattr *nl_wowlan;
8173
8174 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
8175 if (!nl_wowlan)
8176 goto nla_put_failure;
8177
6abb9cb9 8178 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 8179 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 8180 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 8181 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 8182 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 8183 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 8184 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 8185 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 8186 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 8187 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 8188 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 8189 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 8190 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
8191 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
8192 goto nla_put_failure;
2a0e047e 8193
bb92d199
AK
8194 if (nl80211_send_wowlan_patterns(msg, rdev))
8195 goto nla_put_failure;
2a0e047e 8196
6abb9cb9
JB
8197 if (nl80211_send_wowlan_tcp(msg,
8198 rdev->wiphy.wowlan_config->tcp))
2a0e047e
JB
8199 goto nla_put_failure;
8200
ff1b6e69
JB
8201 nla_nest_end(msg, nl_wowlan);
8202 }
8203
8204 genlmsg_end(msg, hdr);
8205 return genlmsg_reply(msg, info);
8206
8207nla_put_failure:
8208 nlmsg_free(msg);
8209 return -ENOBUFS;
8210}
8211
2a0e047e
JB
8212static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
8213 struct nlattr *attr,
8214 struct cfg80211_wowlan *trig)
8215{
8216 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
8217 struct cfg80211_wowlan_tcp *cfg;
8218 struct nl80211_wowlan_tcp_data_token *tok = NULL;
8219 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
8220 u32 size;
8221 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
8222 int err, port;
8223
964dc9e2 8224 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
8225 return -EINVAL;
8226
8227 err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP,
8228 nla_data(attr), nla_len(attr),
8229 nl80211_wowlan_tcp_policy);
8230 if (err)
8231 return err;
8232
8233 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
8234 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
8235 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
8236 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
8237 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
8238 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
8239 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
8240 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
8241 return -EINVAL;
8242
8243 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 8244 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
8245 return -EINVAL;
8246
8247 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 8248 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 8249 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
8250 return -EINVAL;
8251
8252 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 8253 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
8254 return -EINVAL;
8255
8256 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
8257 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
8258 return -EINVAL;
8259
8260 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
8261 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
8262
8263 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
8264 tokens_size = tokln - sizeof(*tok);
8265
8266 if (!tok->len || tokens_size % tok->len)
8267 return -EINVAL;
964dc9e2 8268 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 8269 return -EINVAL;
964dc9e2 8270 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 8271 return -EINVAL;
964dc9e2 8272 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 8273 return -EINVAL;
964dc9e2 8274 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
8275 return -EINVAL;
8276 if (tok->offset + tok->len > data_size)
8277 return -EINVAL;
8278 }
8279
8280 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
8281 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 8282 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
8283 return -EINVAL;
8284 if (seq->len == 0 || seq->len > 4)
8285 return -EINVAL;
8286 if (seq->len + seq->offset > data_size)
8287 return -EINVAL;
8288 }
8289
8290 size = sizeof(*cfg);
8291 size += data_size;
8292 size += wake_size + wake_mask_size;
8293 size += tokens_size;
8294
8295 cfg = kzalloc(size, GFP_KERNEL);
8296 if (!cfg)
8297 return -ENOMEM;
8298 cfg->src = nla_get_be32(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
8299 cfg->dst = nla_get_be32(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
8300 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
8301 ETH_ALEN);
8302 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
8303 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
8304 else
8305 port = 0;
8306#ifdef CONFIG_INET
8307 /* allocate a socket and port for it and use it */
8308 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
8309 IPPROTO_TCP, &cfg->sock, 1);
8310 if (err) {
8311 kfree(cfg);
8312 return err;
8313 }
8314 if (inet_csk_get_port(cfg->sock->sk, port)) {
8315 sock_release(cfg->sock);
8316 kfree(cfg);
8317 return -EADDRINUSE;
8318 }
8319 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
8320#else
8321 if (!port) {
8322 kfree(cfg);
8323 return -EINVAL;
8324 }
8325 cfg->src_port = port;
8326#endif
8327
8328 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
8329 cfg->payload_len = data_size;
8330 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
8331 memcpy((void *)cfg->payload,
8332 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
8333 data_size);
8334 if (seq)
8335 cfg->payload_seq = *seq;
8336 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
8337 cfg->wake_len = wake_size;
8338 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
8339 memcpy((void *)cfg->wake_data,
8340 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
8341 wake_size);
8342 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
8343 data_size + wake_size;
8344 memcpy((void *)cfg->wake_mask,
8345 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
8346 wake_mask_size);
8347 if (tok) {
8348 cfg->tokens_size = tokens_size;
8349 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
8350 }
8351
8352 trig->tcp = cfg;
8353
8354 return 0;
8355}
8356
ff1b6e69
JB
8357static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
8358{
8359 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8360 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 8361 struct cfg80211_wowlan new_triggers = {};
ae33bd81 8362 struct cfg80211_wowlan *ntrig;
964dc9e2 8363 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 8364 int err, i;
6abb9cb9 8365 bool prev_enabled = rdev->wiphy.wowlan_config;
ff1b6e69 8366
964dc9e2 8367 if (!wowlan)
ff1b6e69
JB
8368 return -EOPNOTSUPP;
8369
ae33bd81
JB
8370 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
8371 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 8372 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
8373 goto set_wakeup;
8374 }
ff1b6e69
JB
8375
8376 err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG,
8377 nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
8378 nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
8379 nl80211_wowlan_policy);
8380 if (err)
8381 return err;
8382
8383 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
8384 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
8385 return -EINVAL;
8386 new_triggers.any = true;
8387 }
8388
8389 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
8390 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
8391 return -EINVAL;
8392 new_triggers.disconnect = true;
8393 }
8394
8395 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
8396 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
8397 return -EINVAL;
8398 new_triggers.magic_pkt = true;
8399 }
8400
77dbbb13
JB
8401 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
8402 return -EINVAL;
8403
8404 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
8405 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
8406 return -EINVAL;
8407 new_triggers.gtk_rekey_failure = true;
8408 }
8409
8410 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
8411 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
8412 return -EINVAL;
8413 new_triggers.eap_identity_req = true;
8414 }
8415
8416 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
8417 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
8418 return -EINVAL;
8419 new_triggers.four_way_handshake = true;
8420 }
8421
8422 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
8423 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
8424 return -EINVAL;
8425 new_triggers.rfkill_release = true;
8426 }
8427
ff1b6e69
JB
8428 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
8429 struct nlattr *pat;
8430 int n_patterns = 0;
bb92d199 8431 int rem, pat_len, mask_len, pkt_offset;
50ac6607 8432 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69
JB
8433
8434 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
8435 rem)
8436 n_patterns++;
8437 if (n_patterns > wowlan->n_patterns)
8438 return -EINVAL;
8439
8440 new_triggers.patterns = kcalloc(n_patterns,
8441 sizeof(new_triggers.patterns[0]),
8442 GFP_KERNEL);
8443 if (!new_triggers.patterns)
8444 return -ENOMEM;
8445
8446 new_triggers.n_patterns = n_patterns;
8447 i = 0;
8448
8449 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
8450 rem) {
50ac6607
AK
8451 nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
8452 nla_len(pat), NULL);
ff1b6e69 8453 err = -EINVAL;
50ac6607
AK
8454 if (!pat_tb[NL80211_PKTPAT_MASK] ||
8455 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 8456 goto error;
50ac6607 8457 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 8458 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 8459 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
8460 goto error;
8461 if (pat_len > wowlan->pattern_max_len ||
8462 pat_len < wowlan->pattern_min_len)
8463 goto error;
8464
50ac6607 8465 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
8466 pkt_offset = 0;
8467 else
8468 pkt_offset = nla_get_u32(
50ac6607 8469 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
8470 if (pkt_offset > wowlan->max_pkt_offset)
8471 goto error;
8472 new_triggers.patterns[i].pkt_offset = pkt_offset;
8473
ff1b6e69
JB
8474 new_triggers.patterns[i].mask =
8475 kmalloc(mask_len + pat_len, GFP_KERNEL);
8476 if (!new_triggers.patterns[i].mask) {
8477 err = -ENOMEM;
8478 goto error;
8479 }
8480 new_triggers.patterns[i].pattern =
8481 new_triggers.patterns[i].mask + mask_len;
8482 memcpy(new_triggers.patterns[i].mask,
50ac6607 8483 nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69
JB
8484 mask_len);
8485 new_triggers.patterns[i].pattern_len = pat_len;
8486 memcpy(new_triggers.patterns[i].pattern,
50ac6607 8487 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
8488 pat_len);
8489 i++;
8490 }
8491 }
8492
2a0e047e
JB
8493 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
8494 err = nl80211_parse_wowlan_tcp(
8495 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
8496 &new_triggers);
8497 if (err)
8498 goto error;
8499 }
8500
ae33bd81
JB
8501 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
8502 if (!ntrig) {
8503 err = -ENOMEM;
8504 goto error;
ff1b6e69 8505 }
ae33bd81 8506 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 8507 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 8508
ae33bd81 8509 set_wakeup:
6abb9cb9
JB
8510 if (rdev->ops->set_wakeup &&
8511 prev_enabled != !!rdev->wiphy.wowlan_config)
8512 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 8513
ff1b6e69
JB
8514 return 0;
8515 error:
8516 for (i = 0; i < new_triggers.n_patterns; i++)
8517 kfree(new_triggers.patterns[i].mask);
8518 kfree(new_triggers.patterns);
2a0e047e
JB
8519 if (new_triggers.tcp && new_triggers.tcp->sock)
8520 sock_release(new_triggers.tcp->sock);
8521 kfree(new_triggers.tcp);
ff1b6e69
JB
8522 return err;
8523}
dfb89c56 8524#endif
ff1b6e69 8525
be29b99a
AK
8526static int nl80211_send_coalesce_rules(struct sk_buff *msg,
8527 struct cfg80211_registered_device *rdev)
8528{
8529 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
8530 int i, j, pat_len;
8531 struct cfg80211_coalesce_rules *rule;
8532
8533 if (!rdev->coalesce->n_rules)
8534 return 0;
8535
8536 nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
8537 if (!nl_rules)
8538 return -ENOBUFS;
8539
8540 for (i = 0; i < rdev->coalesce->n_rules; i++) {
8541 nl_rule = nla_nest_start(msg, i + 1);
8542 if (!nl_rule)
8543 return -ENOBUFS;
8544
8545 rule = &rdev->coalesce->rules[i];
8546 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
8547 rule->delay))
8548 return -ENOBUFS;
8549
8550 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
8551 rule->condition))
8552 return -ENOBUFS;
8553
8554 nl_pats = nla_nest_start(msg,
8555 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
8556 if (!nl_pats)
8557 return -ENOBUFS;
8558
8559 for (j = 0; j < rule->n_patterns; j++) {
8560 nl_pat = nla_nest_start(msg, j + 1);
8561 if (!nl_pat)
8562 return -ENOBUFS;
8563 pat_len = rule->patterns[j].pattern_len;
8564 if (nla_put(msg, NL80211_PKTPAT_MASK,
8565 DIV_ROUND_UP(pat_len, 8),
8566 rule->patterns[j].mask) ||
8567 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
8568 rule->patterns[j].pattern) ||
8569 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
8570 rule->patterns[j].pkt_offset))
8571 return -ENOBUFS;
8572 nla_nest_end(msg, nl_pat);
8573 }
8574 nla_nest_end(msg, nl_pats);
8575 nla_nest_end(msg, nl_rule);
8576 }
8577 nla_nest_end(msg, nl_rules);
8578
8579 return 0;
8580}
8581
8582static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
8583{
8584 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8585 struct sk_buff *msg;
8586 void *hdr;
8587
8588 if (!rdev->wiphy.coalesce)
8589 return -EOPNOTSUPP;
8590
8591 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8592 if (!msg)
8593 return -ENOMEM;
8594
8595 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
8596 NL80211_CMD_GET_COALESCE);
8597 if (!hdr)
8598 goto nla_put_failure;
8599
8600 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
8601 goto nla_put_failure;
8602
8603 genlmsg_end(msg, hdr);
8604 return genlmsg_reply(msg, info);
8605
8606nla_put_failure:
8607 nlmsg_free(msg);
8608 return -ENOBUFS;
8609}
8610
8611void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
8612{
8613 struct cfg80211_coalesce *coalesce = rdev->coalesce;
8614 int i, j;
8615 struct cfg80211_coalesce_rules *rule;
8616
8617 if (!coalesce)
8618 return;
8619
8620 for (i = 0; i < coalesce->n_rules; i++) {
8621 rule = &coalesce->rules[i];
8622 for (j = 0; j < rule->n_patterns; j++)
8623 kfree(rule->patterns[j].mask);
8624 kfree(rule->patterns);
8625 }
8626 kfree(coalesce->rules);
8627 kfree(coalesce);
8628 rdev->coalesce = NULL;
8629}
8630
8631static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
8632 struct nlattr *rule,
8633 struct cfg80211_coalesce_rules *new_rule)
8634{
8635 int err, i;
8636 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
8637 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
8638 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
8639 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
8640
8641 err = nla_parse(tb, NL80211_ATTR_COALESCE_RULE_MAX, nla_data(rule),
8642 nla_len(rule), nl80211_coalesce_policy);
8643 if (err)
8644 return err;
8645
8646 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
8647 new_rule->delay =
8648 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
8649 if (new_rule->delay > coalesce->max_delay)
8650 return -EINVAL;
8651
8652 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
8653 new_rule->condition =
8654 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
8655 if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH &&
8656 new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH)
8657 return -EINVAL;
8658
8659 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
8660 return -EINVAL;
8661
8662 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
8663 rem)
8664 n_patterns++;
8665 if (n_patterns > coalesce->n_patterns)
8666 return -EINVAL;
8667
8668 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
8669 GFP_KERNEL);
8670 if (!new_rule->patterns)
8671 return -ENOMEM;
8672
8673 new_rule->n_patterns = n_patterns;
8674 i = 0;
8675
8676 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
8677 rem) {
8678 nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
8679 nla_len(pat), NULL);
8680 if (!pat_tb[NL80211_PKTPAT_MASK] ||
8681 !pat_tb[NL80211_PKTPAT_PATTERN])
8682 return -EINVAL;
8683 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
8684 mask_len = DIV_ROUND_UP(pat_len, 8);
8685 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
8686 return -EINVAL;
8687 if (pat_len > coalesce->pattern_max_len ||
8688 pat_len < coalesce->pattern_min_len)
8689 return -EINVAL;
8690
8691 if (!pat_tb[NL80211_PKTPAT_OFFSET])
8692 pkt_offset = 0;
8693 else
8694 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
8695 if (pkt_offset > coalesce->max_pkt_offset)
8696 return -EINVAL;
8697 new_rule->patterns[i].pkt_offset = pkt_offset;
8698
8699 new_rule->patterns[i].mask =
8700 kmalloc(mask_len + pat_len, GFP_KERNEL);
8701 if (!new_rule->patterns[i].mask)
8702 return -ENOMEM;
8703 new_rule->patterns[i].pattern =
8704 new_rule->patterns[i].mask + mask_len;
8705 memcpy(new_rule->patterns[i].mask,
8706 nla_data(pat_tb[NL80211_PKTPAT_MASK]), mask_len);
8707 new_rule->patterns[i].pattern_len = pat_len;
8708 memcpy(new_rule->patterns[i].pattern,
8709 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), pat_len);
8710 i++;
8711 }
8712
8713 return 0;
8714}
8715
8716static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
8717{
8718 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8719 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
8720 struct cfg80211_coalesce new_coalesce = {};
8721 struct cfg80211_coalesce *n_coalesce;
8722 int err, rem_rule, n_rules = 0, i, j;
8723 struct nlattr *rule;
8724 struct cfg80211_coalesce_rules *tmp_rule;
8725
8726 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
8727 return -EOPNOTSUPP;
8728
8729 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
8730 cfg80211_rdev_free_coalesce(rdev);
8731 rdev->ops->set_coalesce(&rdev->wiphy, NULL);
8732 return 0;
8733 }
8734
8735 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
8736 rem_rule)
8737 n_rules++;
8738 if (n_rules > coalesce->n_rules)
8739 return -EINVAL;
8740
8741 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
8742 GFP_KERNEL);
8743 if (!new_coalesce.rules)
8744 return -ENOMEM;
8745
8746 new_coalesce.n_rules = n_rules;
8747 i = 0;
8748
8749 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
8750 rem_rule) {
8751 err = nl80211_parse_coalesce_rule(rdev, rule,
8752 &new_coalesce.rules[i]);
8753 if (err)
8754 goto error;
8755
8756 i++;
8757 }
8758
8759 err = rdev->ops->set_coalesce(&rdev->wiphy, &new_coalesce);
8760 if (err)
8761 goto error;
8762
8763 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
8764 if (!n_coalesce) {
8765 err = -ENOMEM;
8766 goto error;
8767 }
8768 cfg80211_rdev_free_coalesce(rdev);
8769 rdev->coalesce = n_coalesce;
8770
8771 return 0;
8772error:
8773 for (i = 0; i < new_coalesce.n_rules; i++) {
8774 tmp_rule = &new_coalesce.rules[i];
8775 for (j = 0; j < tmp_rule->n_patterns; j++)
8776 kfree(tmp_rule->patterns[j].mask);
8777 kfree(tmp_rule->patterns);
8778 }
8779 kfree(new_coalesce.rules);
8780
8781 return err;
8782}
8783
e5497d76
JB
8784static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
8785{
8786 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8787 struct net_device *dev = info->user_ptr[1];
8788 struct wireless_dev *wdev = dev->ieee80211_ptr;
8789 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
8790 struct cfg80211_gtk_rekey_data rekey_data;
8791 int err;
8792
8793 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
8794 return -EINVAL;
8795
8796 err = nla_parse(tb, MAX_NL80211_REKEY_DATA,
8797 nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]),
8798 nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]),
8799 nl80211_rekey_policy);
8800 if (err)
8801 return err;
8802
8803 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
8804 return -ERANGE;
8805 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
8806 return -ERANGE;
8807 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
8808 return -ERANGE;
8809
8810 memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]),
8811 NL80211_KEK_LEN);
8812 memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]),
8813 NL80211_KCK_LEN);
8814 memcpy(rekey_data.replay_ctr,
8815 nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]),
8816 NL80211_REPLAY_CTR_LEN);
8817
8818 wdev_lock(wdev);
8819 if (!wdev->current_bss) {
8820 err = -ENOTCONN;
8821 goto out;
8822 }
8823
8824 if (!rdev->ops->set_rekey_data) {
8825 err = -EOPNOTSUPP;
8826 goto out;
8827 }
8828
e35e4d28 8829 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
8830 out:
8831 wdev_unlock(wdev);
8832 return err;
8833}
8834
28946da7
JB
8835static int nl80211_register_unexpected_frame(struct sk_buff *skb,
8836 struct genl_info *info)
8837{
8838 struct net_device *dev = info->user_ptr[1];
8839 struct wireless_dev *wdev = dev->ieee80211_ptr;
8840
8841 if (wdev->iftype != NL80211_IFTYPE_AP &&
8842 wdev->iftype != NL80211_IFTYPE_P2P_GO)
8843 return -EINVAL;
8844
15e47304 8845 if (wdev->ap_unexpected_nlportid)
28946da7
JB
8846 return -EBUSY;
8847
15e47304 8848 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
8849 return 0;
8850}
8851
7f6cf311
JB
8852static int nl80211_probe_client(struct sk_buff *skb,
8853 struct genl_info *info)
8854{
8855 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8856 struct net_device *dev = info->user_ptr[1];
8857 struct wireless_dev *wdev = dev->ieee80211_ptr;
8858 struct sk_buff *msg;
8859 void *hdr;
8860 const u8 *addr;
8861 u64 cookie;
8862 int err;
8863
8864 if (wdev->iftype != NL80211_IFTYPE_AP &&
8865 wdev->iftype != NL80211_IFTYPE_P2P_GO)
8866 return -EOPNOTSUPP;
8867
8868 if (!info->attrs[NL80211_ATTR_MAC])
8869 return -EINVAL;
8870
8871 if (!rdev->ops->probe_client)
8872 return -EOPNOTSUPP;
8873
8874 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8875 if (!msg)
8876 return -ENOMEM;
8877
15e47304 8878 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 8879 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
8880 if (!hdr) {
8881 err = -ENOBUFS;
7f6cf311
JB
8882 goto free_msg;
8883 }
8884
8885 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
8886
e35e4d28 8887 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
8888 if (err)
8889 goto free_msg;
8890
9360ffd1
DM
8891 if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
8892 goto nla_put_failure;
7f6cf311
JB
8893
8894 genlmsg_end(msg, hdr);
8895
8896 return genlmsg_reply(msg, info);
8897
8898 nla_put_failure:
8899 err = -ENOBUFS;
8900 free_msg:
8901 nlmsg_free(msg);
8902 return err;
8903}
8904
5e760230
JB
8905static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
8906{
8907 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
8908 struct cfg80211_beacon_registration *reg, *nreg;
8909 int rv;
5e760230
JB
8910
8911 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
8912 return -EOPNOTSUPP;
8913
37c73b5f
BG
8914 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
8915 if (!nreg)
8916 return -ENOMEM;
8917
8918 /* First, check if already registered. */
8919 spin_lock_bh(&rdev->beacon_registrations_lock);
8920 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
8921 if (reg->nlportid == info->snd_portid) {
8922 rv = -EALREADY;
8923 goto out_err;
8924 }
8925 }
8926 /* Add it to the list */
8927 nreg->nlportid = info->snd_portid;
8928 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 8929
37c73b5f 8930 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
8931
8932 return 0;
37c73b5f
BG
8933out_err:
8934 spin_unlock_bh(&rdev->beacon_registrations_lock);
8935 kfree(nreg);
8936 return rv;
5e760230
JB
8937}
8938
98104fde
JB
8939static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
8940{
8941 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8942 struct wireless_dev *wdev = info->user_ptr[1];
8943 int err;
8944
8945 if (!rdev->ops->start_p2p_device)
8946 return -EOPNOTSUPP;
8947
8948 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
8949 return -EOPNOTSUPP;
8950
8951 if (wdev->p2p_started)
8952 return 0;
8953
98104fde 8954 err = cfg80211_can_add_interface(rdev, wdev->iftype);
98104fde
JB
8955 if (err)
8956 return err;
8957
eeb126e9 8958 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
8959 if (err)
8960 return err;
8961
8962 wdev->p2p_started = true;
98104fde 8963 rdev->opencount++;
98104fde
JB
8964
8965 return 0;
8966}
8967
8968static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
8969{
8970 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8971 struct wireless_dev *wdev = info->user_ptr[1];
8972
8973 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
8974 return -EOPNOTSUPP;
8975
8976 if (!rdev->ops->stop_p2p_device)
8977 return -EOPNOTSUPP;
8978
f9f47529 8979 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
8980
8981 return 0;
8982}
8983
3713b4e3
JB
8984static int nl80211_get_protocol_features(struct sk_buff *skb,
8985 struct genl_info *info)
8986{
8987 void *hdr;
8988 struct sk_buff *msg;
8989
8990 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8991 if (!msg)
8992 return -ENOMEM;
8993
8994 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
8995 NL80211_CMD_GET_PROTOCOL_FEATURES);
8996 if (!hdr)
8997 goto nla_put_failure;
8998
8999 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
9000 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
9001 goto nla_put_failure;
9002
9003 genlmsg_end(msg, hdr);
9004 return genlmsg_reply(msg, info);
9005
9006 nla_put_failure:
9007 kfree_skb(msg);
9008 return -ENOBUFS;
9009}
9010
355199e0
JM
9011static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
9012{
9013 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9014 struct cfg80211_update_ft_ies_params ft_params;
9015 struct net_device *dev = info->user_ptr[1];
9016
9017 if (!rdev->ops->update_ft_ies)
9018 return -EOPNOTSUPP;
9019
9020 if (!info->attrs[NL80211_ATTR_MDID] ||
9021 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
9022 return -EINVAL;
9023
9024 memset(&ft_params, 0, sizeof(ft_params));
9025 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
9026 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9027 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9028
9029 return rdev_update_ft_ies(rdev, dev, &ft_params);
9030}
9031
5de17984
AS
9032static int nl80211_crit_protocol_start(struct sk_buff *skb,
9033 struct genl_info *info)
9034{
9035 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9036 struct wireless_dev *wdev = info->user_ptr[1];
9037 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
9038 u16 duration;
9039 int ret;
9040
9041 if (!rdev->ops->crit_proto_start)
9042 return -EOPNOTSUPP;
9043
9044 if (WARN_ON(!rdev->ops->crit_proto_stop))
9045 return -EINVAL;
9046
9047 if (rdev->crit_proto_nlportid)
9048 return -EBUSY;
9049
9050 /* determine protocol if provided */
9051 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
9052 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
9053
9054 if (proto >= NUM_NL80211_CRIT_PROTO)
9055 return -EINVAL;
9056
9057 /* timeout must be provided */
9058 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
9059 return -EINVAL;
9060
9061 duration =
9062 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
9063
9064 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
9065 return -ERANGE;
9066
9067 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
9068 if (!ret)
9069 rdev->crit_proto_nlportid = info->snd_portid;
9070
9071 return ret;
9072}
9073
9074static int nl80211_crit_protocol_stop(struct sk_buff *skb,
9075 struct genl_info *info)
9076{
9077 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9078 struct wireless_dev *wdev = info->user_ptr[1];
9079
9080 if (!rdev->ops->crit_proto_stop)
9081 return -EOPNOTSUPP;
9082
9083 if (rdev->crit_proto_nlportid) {
9084 rdev->crit_proto_nlportid = 0;
9085 rdev_crit_proto_stop(rdev, wdev);
9086 }
9087 return 0;
9088}
9089
ad7e718c
JB
9090static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
9091{
9092 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9093 struct wireless_dev *wdev =
9094 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
9095 int i, err;
9096 u32 vid, subcmd;
9097
9098 if (!rdev->wiphy.vendor_commands)
9099 return -EOPNOTSUPP;
9100
9101 if (IS_ERR(wdev)) {
9102 err = PTR_ERR(wdev);
9103 if (err != -EINVAL)
9104 return err;
9105 wdev = NULL;
9106 } else if (wdev->wiphy != &rdev->wiphy) {
9107 return -EINVAL;
9108 }
9109
9110 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
9111 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
9112 return -EINVAL;
9113
9114 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
9115 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
9116 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
9117 const struct wiphy_vendor_command *vcmd;
9118 void *data = NULL;
9119 int len = 0;
9120
9121 vcmd = &rdev->wiphy.vendor_commands[i];
9122
9123 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
9124 continue;
9125
9126 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
9127 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
9128 if (!wdev)
9129 return -EINVAL;
9130 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
9131 !wdev->netdev)
9132 return -EINVAL;
9133
9134 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
9135 if (wdev->netdev &&
9136 !netif_running(wdev->netdev))
9137 return -ENETDOWN;
9138 if (!wdev->netdev && !wdev->p2p_started)
9139 return -ENETDOWN;
9140 }
9141 } else {
9142 wdev = NULL;
9143 }
9144
9145 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
9146 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
9147 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
9148 }
9149
9150 rdev->cur_cmd_info = info;
9151 err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
9152 data, len);
9153 rdev->cur_cmd_info = NULL;
9154 return err;
9155 }
9156
9157 return -EOPNOTSUPP;
9158}
9159
9160struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
9161 enum nl80211_commands cmd,
9162 enum nl80211_attrs attr,
9163 int approxlen)
9164{
9165 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9166
9167 if (WARN_ON(!rdev->cur_cmd_info))
9168 return NULL;
9169
9170 return __cfg80211_alloc_vendor_skb(rdev, approxlen,
9171 rdev->cur_cmd_info->snd_portid,
9172 rdev->cur_cmd_info->snd_seq,
567ffc35 9173 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
9174}
9175EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
9176
9177int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
9178{
9179 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
9180 void *hdr = ((void **)skb->cb)[1];
9181 struct nlattr *data = ((void **)skb->cb)[2];
9182
9183 if (WARN_ON(!rdev->cur_cmd_info)) {
9184 kfree_skb(skb);
9185 return -EINVAL;
9186 }
9187
9188 nla_nest_end(skb, data);
9189 genlmsg_end(skb, hdr);
9190 return genlmsg_reply(skb, rdev->cur_cmd_info);
9191}
9192EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
9193
9194
fa9ffc74
KP
9195static int nl80211_set_qos_map(struct sk_buff *skb,
9196 struct genl_info *info)
9197{
9198 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9199 struct cfg80211_qos_map *qos_map = NULL;
9200 struct net_device *dev = info->user_ptr[1];
9201 u8 *pos, len, num_des, des_len, des;
9202 int ret;
9203
9204 if (!rdev->ops->set_qos_map)
9205 return -EOPNOTSUPP;
9206
9207 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
9208 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
9209 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
9210
9211 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
9212 len > IEEE80211_QOS_MAP_LEN_MAX)
9213 return -EINVAL;
9214
9215 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
9216 if (!qos_map)
9217 return -ENOMEM;
9218
9219 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
9220 if (num_des) {
9221 des_len = num_des *
9222 sizeof(struct cfg80211_dscp_exception);
9223 memcpy(qos_map->dscp_exception, pos, des_len);
9224 qos_map->num_des = num_des;
9225 for (des = 0; des < num_des; des++) {
9226 if (qos_map->dscp_exception[des].up > 7) {
9227 kfree(qos_map);
9228 return -EINVAL;
9229 }
9230 }
9231 pos += des_len;
9232 }
9233 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
9234 }
9235
9236 wdev_lock(dev->ieee80211_ptr);
9237 ret = nl80211_key_allowed(dev->ieee80211_ptr);
9238 if (!ret)
9239 ret = rdev_set_qos_map(rdev, dev, qos_map);
9240 wdev_unlock(dev->ieee80211_ptr);
9241
9242 kfree(qos_map);
9243 return ret;
9244}
9245
4c476991
JB
9246#define NL80211_FLAG_NEED_WIPHY 0x01
9247#define NL80211_FLAG_NEED_NETDEV 0x02
9248#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
9249#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
9250#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
9251 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 9252#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 9253/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
9254#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
9255 NL80211_FLAG_CHECK_NETDEV_UP)
4c476991 9256
f84f771d 9257static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
9258 struct genl_info *info)
9259{
9260 struct cfg80211_registered_device *rdev;
89a54e48 9261 struct wireless_dev *wdev;
4c476991 9262 struct net_device *dev;
4c476991
JB
9263 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
9264
9265 if (rtnl)
9266 rtnl_lock();
9267
9268 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 9269 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
9270 if (IS_ERR(rdev)) {
9271 if (rtnl)
9272 rtnl_unlock();
9273 return PTR_ERR(rdev);
9274 }
9275 info->user_ptr[0] = rdev;
1bf614ef
JB
9276 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
9277 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
9278 ASSERT_RTNL();
9279
89a54e48
JB
9280 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
9281 info->attrs);
9282 if (IS_ERR(wdev)) {
4c476991
JB
9283 if (rtnl)
9284 rtnl_unlock();
89a54e48 9285 return PTR_ERR(wdev);
4c476991 9286 }
89a54e48 9287
89a54e48
JB
9288 dev = wdev->netdev;
9289 rdev = wiphy_to_dev(wdev->wiphy);
9290
1bf614ef
JB
9291 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
9292 if (!dev) {
1bf614ef
JB
9293 if (rtnl)
9294 rtnl_unlock();
9295 return -EINVAL;
9296 }
9297
9298 info->user_ptr[1] = dev;
9299 } else {
9300 info->user_ptr[1] = wdev;
41265714 9301 }
1bf614ef
JB
9302
9303 if (dev) {
9304 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
9305 !netif_running(dev)) {
1bf614ef
JB
9306 if (rtnl)
9307 rtnl_unlock();
9308 return -ENETDOWN;
9309 }
9310
9311 dev_hold(dev);
98104fde
JB
9312 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) {
9313 if (!wdev->p2p_started) {
98104fde
JB
9314 if (rtnl)
9315 rtnl_unlock();
9316 return -ENETDOWN;
9317 }
41265714 9318 }
89a54e48 9319
4c476991 9320 info->user_ptr[0] = rdev;
4c476991
JB
9321 }
9322
9323 return 0;
9324}
9325
f84f771d 9326static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
9327 struct genl_info *info)
9328{
1bf614ef
JB
9329 if (info->user_ptr[1]) {
9330 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
9331 struct wireless_dev *wdev = info->user_ptr[1];
9332
9333 if (wdev->netdev)
9334 dev_put(wdev->netdev);
9335 } else {
9336 dev_put(info->user_ptr[1]);
9337 }
9338 }
4c476991
JB
9339 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
9340 rtnl_unlock();
9341}
9342
4534de83 9343static const struct genl_ops nl80211_ops[] = {
55682965
JB
9344 {
9345 .cmd = NL80211_CMD_GET_WIPHY,
9346 .doit = nl80211_get_wiphy,
9347 .dumpit = nl80211_dump_wiphy,
86e8cf98 9348 .done = nl80211_dump_wiphy_done,
55682965
JB
9349 .policy = nl80211_policy,
9350 /* can be retrieved by unprivileged users */
5fe231e8
JB
9351 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9352 NL80211_FLAG_NEED_RTNL,
55682965
JB
9353 },
9354 {
9355 .cmd = NL80211_CMD_SET_WIPHY,
9356 .doit = nl80211_set_wiphy,
9357 .policy = nl80211_policy,
9358 .flags = GENL_ADMIN_PERM,
4c476991 9359 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
9360 },
9361 {
9362 .cmd = NL80211_CMD_GET_INTERFACE,
9363 .doit = nl80211_get_interface,
9364 .dumpit = nl80211_dump_interface,
9365 .policy = nl80211_policy,
9366 /* can be retrieved by unprivileged users */
5fe231e8
JB
9367 .internal_flags = NL80211_FLAG_NEED_WDEV |
9368 NL80211_FLAG_NEED_RTNL,
55682965
JB
9369 },
9370 {
9371 .cmd = NL80211_CMD_SET_INTERFACE,
9372 .doit = nl80211_set_interface,
9373 .policy = nl80211_policy,
9374 .flags = GENL_ADMIN_PERM,
4c476991
JB
9375 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9376 NL80211_FLAG_NEED_RTNL,
55682965
JB
9377 },
9378 {
9379 .cmd = NL80211_CMD_NEW_INTERFACE,
9380 .doit = nl80211_new_interface,
9381 .policy = nl80211_policy,
9382 .flags = GENL_ADMIN_PERM,
4c476991
JB
9383 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9384 NL80211_FLAG_NEED_RTNL,
55682965
JB
9385 },
9386 {
9387 .cmd = NL80211_CMD_DEL_INTERFACE,
9388 .doit = nl80211_del_interface,
9389 .policy = nl80211_policy,
41ade00f 9390 .flags = GENL_ADMIN_PERM,
84efbb84 9391 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 9392 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
9393 },
9394 {
9395 .cmd = NL80211_CMD_GET_KEY,
9396 .doit = nl80211_get_key,
9397 .policy = nl80211_policy,
9398 .flags = GENL_ADMIN_PERM,
2b5f8b0b 9399 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9400 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
9401 },
9402 {
9403 .cmd = NL80211_CMD_SET_KEY,
9404 .doit = nl80211_set_key,
9405 .policy = nl80211_policy,
9406 .flags = GENL_ADMIN_PERM,
41265714 9407 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9408 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
9409 },
9410 {
9411 .cmd = NL80211_CMD_NEW_KEY,
9412 .doit = nl80211_new_key,
9413 .policy = nl80211_policy,
9414 .flags = GENL_ADMIN_PERM,
41265714 9415 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9416 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
9417 },
9418 {
9419 .cmd = NL80211_CMD_DEL_KEY,
9420 .doit = nl80211_del_key,
9421 .policy = nl80211_policy,
55682965 9422 .flags = GENL_ADMIN_PERM,
41265714 9423 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9424 NL80211_FLAG_NEED_RTNL,
55682965 9425 },
ed1b6cc7
JB
9426 {
9427 .cmd = NL80211_CMD_SET_BEACON,
9428 .policy = nl80211_policy,
9429 .flags = GENL_ADMIN_PERM,
8860020e 9430 .doit = nl80211_set_beacon,
2b5f8b0b 9431 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9432 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
9433 },
9434 {
8860020e 9435 .cmd = NL80211_CMD_START_AP,
ed1b6cc7
JB
9436 .policy = nl80211_policy,
9437 .flags = GENL_ADMIN_PERM,
8860020e 9438 .doit = nl80211_start_ap,
2b5f8b0b 9439 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9440 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
9441 },
9442 {
8860020e 9443 .cmd = NL80211_CMD_STOP_AP,
ed1b6cc7
JB
9444 .policy = nl80211_policy,
9445 .flags = GENL_ADMIN_PERM,
8860020e 9446 .doit = nl80211_stop_ap,
2b5f8b0b 9447 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9448 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 9449 },
5727ef1b
JB
9450 {
9451 .cmd = NL80211_CMD_GET_STATION,
9452 .doit = nl80211_get_station,
2ec600d6 9453 .dumpit = nl80211_dump_station,
5727ef1b 9454 .policy = nl80211_policy,
4c476991
JB
9455 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9456 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
9457 },
9458 {
9459 .cmd = NL80211_CMD_SET_STATION,
9460 .doit = nl80211_set_station,
9461 .policy = nl80211_policy,
9462 .flags = GENL_ADMIN_PERM,
2b5f8b0b 9463 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9464 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
9465 },
9466 {
9467 .cmd = NL80211_CMD_NEW_STATION,
9468 .doit = nl80211_new_station,
9469 .policy = nl80211_policy,
9470 .flags = GENL_ADMIN_PERM,
41265714 9471 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9472 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
9473 },
9474 {
9475 .cmd = NL80211_CMD_DEL_STATION,
9476 .doit = nl80211_del_station,
9477 .policy = nl80211_policy,
2ec600d6 9478 .flags = GENL_ADMIN_PERM,
2b5f8b0b 9479 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9480 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
9481 },
9482 {
9483 .cmd = NL80211_CMD_GET_MPATH,
9484 .doit = nl80211_get_mpath,
9485 .dumpit = nl80211_dump_mpath,
9486 .policy = nl80211_policy,
9487 .flags = GENL_ADMIN_PERM,
41265714 9488 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9489 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
9490 },
9491 {
9492 .cmd = NL80211_CMD_SET_MPATH,
9493 .doit = nl80211_set_mpath,
9494 .policy = nl80211_policy,
9495 .flags = GENL_ADMIN_PERM,
41265714 9496 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9497 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
9498 },
9499 {
9500 .cmd = NL80211_CMD_NEW_MPATH,
9501 .doit = nl80211_new_mpath,
9502 .policy = nl80211_policy,
9503 .flags = GENL_ADMIN_PERM,
41265714 9504 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9505 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
9506 },
9507 {
9508 .cmd = NL80211_CMD_DEL_MPATH,
9509 .doit = nl80211_del_mpath,
9510 .policy = nl80211_policy,
9f1ba906 9511 .flags = GENL_ADMIN_PERM,
2b5f8b0b 9512 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9513 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
9514 },
9515 {
9516 .cmd = NL80211_CMD_SET_BSS,
9517 .doit = nl80211_set_bss,
9518 .policy = nl80211_policy,
b2e1b302 9519 .flags = GENL_ADMIN_PERM,
2b5f8b0b 9520 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9521 NL80211_FLAG_NEED_RTNL,
b2e1b302 9522 },
f130347c
LR
9523 {
9524 .cmd = NL80211_CMD_GET_REG,
9525 .doit = nl80211_get_reg,
9526 .policy = nl80211_policy,
5fe231e8 9527 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
9528 /* can be retrieved by unprivileged users */
9529 },
b2e1b302
LR
9530 {
9531 .cmd = NL80211_CMD_SET_REG,
9532 .doit = nl80211_set_reg,
9533 .policy = nl80211_policy,
9534 .flags = GENL_ADMIN_PERM,
5fe231e8 9535 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302
LR
9536 },
9537 {
9538 .cmd = NL80211_CMD_REQ_SET_REG,
9539 .doit = nl80211_req_set_reg,
9540 .policy = nl80211_policy,
93da9cc1 9541 .flags = GENL_ADMIN_PERM,
9542 },
9543 {
24bdd9f4
JC
9544 .cmd = NL80211_CMD_GET_MESH_CONFIG,
9545 .doit = nl80211_get_mesh_config,
93da9cc1 9546 .policy = nl80211_policy,
9547 /* can be retrieved by unprivileged users */
2b5f8b0b 9548 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9549 NL80211_FLAG_NEED_RTNL,
93da9cc1 9550 },
9551 {
24bdd9f4
JC
9552 .cmd = NL80211_CMD_SET_MESH_CONFIG,
9553 .doit = nl80211_update_mesh_config,
93da9cc1 9554 .policy = nl80211_policy,
9aed3cc1 9555 .flags = GENL_ADMIN_PERM,
29cbe68c 9556 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9557 NL80211_FLAG_NEED_RTNL,
9aed3cc1 9558 },
2a519311
JB
9559 {
9560 .cmd = NL80211_CMD_TRIGGER_SCAN,
9561 .doit = nl80211_trigger_scan,
9562 .policy = nl80211_policy,
9563 .flags = GENL_ADMIN_PERM,
fd014284 9564 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 9565 NL80211_FLAG_NEED_RTNL,
2a519311
JB
9566 },
9567 {
9568 .cmd = NL80211_CMD_GET_SCAN,
9569 .policy = nl80211_policy,
9570 .dumpit = nl80211_dump_scan,
9571 },
807f8a8c
LC
9572 {
9573 .cmd = NL80211_CMD_START_SCHED_SCAN,
9574 .doit = nl80211_start_sched_scan,
9575 .policy = nl80211_policy,
9576 .flags = GENL_ADMIN_PERM,
9577 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9578 NL80211_FLAG_NEED_RTNL,
9579 },
9580 {
9581 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
9582 .doit = nl80211_stop_sched_scan,
9583 .policy = nl80211_policy,
9584 .flags = GENL_ADMIN_PERM,
9585 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9586 NL80211_FLAG_NEED_RTNL,
9587 },
636a5d36
JM
9588 {
9589 .cmd = NL80211_CMD_AUTHENTICATE,
9590 .doit = nl80211_authenticate,
9591 .policy = nl80211_policy,
9592 .flags = GENL_ADMIN_PERM,
41265714 9593 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9594 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
9595 },
9596 {
9597 .cmd = NL80211_CMD_ASSOCIATE,
9598 .doit = nl80211_associate,
9599 .policy = nl80211_policy,
9600 .flags = GENL_ADMIN_PERM,
41265714 9601 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9602 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
9603 },
9604 {
9605 .cmd = NL80211_CMD_DEAUTHENTICATE,
9606 .doit = nl80211_deauthenticate,
9607 .policy = nl80211_policy,
9608 .flags = GENL_ADMIN_PERM,
41265714 9609 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9610 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
9611 },
9612 {
9613 .cmd = NL80211_CMD_DISASSOCIATE,
9614 .doit = nl80211_disassociate,
9615 .policy = nl80211_policy,
9616 .flags = GENL_ADMIN_PERM,
41265714 9617 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9618 NL80211_FLAG_NEED_RTNL,
636a5d36 9619 },
04a773ad
JB
9620 {
9621 .cmd = NL80211_CMD_JOIN_IBSS,
9622 .doit = nl80211_join_ibss,
9623 .policy = nl80211_policy,
9624 .flags = GENL_ADMIN_PERM,
41265714 9625 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9626 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
9627 },
9628 {
9629 .cmd = NL80211_CMD_LEAVE_IBSS,
9630 .doit = nl80211_leave_ibss,
9631 .policy = nl80211_policy,
9632 .flags = GENL_ADMIN_PERM,
41265714 9633 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9634 NL80211_FLAG_NEED_RTNL,
04a773ad 9635 },
aff89a9b
JB
9636#ifdef CONFIG_NL80211_TESTMODE
9637 {
9638 .cmd = NL80211_CMD_TESTMODE,
9639 .doit = nl80211_testmode_do,
71063f0e 9640 .dumpit = nl80211_testmode_dump,
aff89a9b
JB
9641 .policy = nl80211_policy,
9642 .flags = GENL_ADMIN_PERM,
4c476991
JB
9643 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9644 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
9645 },
9646#endif
b23aa676
SO
9647 {
9648 .cmd = NL80211_CMD_CONNECT,
9649 .doit = nl80211_connect,
9650 .policy = nl80211_policy,
9651 .flags = GENL_ADMIN_PERM,
41265714 9652 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9653 NL80211_FLAG_NEED_RTNL,
b23aa676
SO
9654 },
9655 {
9656 .cmd = NL80211_CMD_DISCONNECT,
9657 .doit = nl80211_disconnect,
9658 .policy = nl80211_policy,
9659 .flags = GENL_ADMIN_PERM,
41265714 9660 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9661 NL80211_FLAG_NEED_RTNL,
b23aa676 9662 },
463d0183
JB
9663 {
9664 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
9665 .doit = nl80211_wiphy_netns,
9666 .policy = nl80211_policy,
9667 .flags = GENL_ADMIN_PERM,
4c476991
JB
9668 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9669 NL80211_FLAG_NEED_RTNL,
463d0183 9670 },
61fa713c
HS
9671 {
9672 .cmd = NL80211_CMD_GET_SURVEY,
9673 .policy = nl80211_policy,
9674 .dumpit = nl80211_dump_survey,
9675 },
67fbb16b
SO
9676 {
9677 .cmd = NL80211_CMD_SET_PMKSA,
9678 .doit = nl80211_setdel_pmksa,
9679 .policy = nl80211_policy,
9680 .flags = GENL_ADMIN_PERM,
2b5f8b0b 9681 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9682 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
9683 },
9684 {
9685 .cmd = NL80211_CMD_DEL_PMKSA,
9686 .doit = nl80211_setdel_pmksa,
9687 .policy = nl80211_policy,
9688 .flags = GENL_ADMIN_PERM,
2b5f8b0b 9689 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9690 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
9691 },
9692 {
9693 .cmd = NL80211_CMD_FLUSH_PMKSA,
9694 .doit = nl80211_flush_pmksa,
9695 .policy = nl80211_policy,
9696 .flags = GENL_ADMIN_PERM,
2b5f8b0b 9697 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 9698 NL80211_FLAG_NEED_RTNL,
67fbb16b 9699 },
9588bbd5
JM
9700 {
9701 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
9702 .doit = nl80211_remain_on_channel,
9703 .policy = nl80211_policy,
9704 .flags = GENL_ADMIN_PERM,
71bbc994 9705 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 9706 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
9707 },
9708 {
9709 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
9710 .doit = nl80211_cancel_remain_on_channel,
9711 .policy = nl80211_policy,
9712 .flags = GENL_ADMIN_PERM,
71bbc994 9713 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 9714 NL80211_FLAG_NEED_RTNL,
9588bbd5 9715 },
13ae75b1
JM
9716 {
9717 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
9718 .doit = nl80211_set_tx_bitrate_mask,
9719 .policy = nl80211_policy,
9720 .flags = GENL_ADMIN_PERM,
4c476991
JB
9721 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9722 NL80211_FLAG_NEED_RTNL,
13ae75b1 9723 },
026331c4 9724 {
2e161f78
JB
9725 .cmd = NL80211_CMD_REGISTER_FRAME,
9726 .doit = nl80211_register_mgmt,
026331c4
JM
9727 .policy = nl80211_policy,
9728 .flags = GENL_ADMIN_PERM,
71bbc994 9729 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 9730 NL80211_FLAG_NEED_RTNL,
026331c4
JM
9731 },
9732 {
2e161f78
JB
9733 .cmd = NL80211_CMD_FRAME,
9734 .doit = nl80211_tx_mgmt,
026331c4 9735 .policy = nl80211_policy,
f7ca38df 9736 .flags = GENL_ADMIN_PERM,
71bbc994 9737 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
9738 NL80211_FLAG_NEED_RTNL,
9739 },
9740 {
9741 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
9742 .doit = nl80211_tx_mgmt_cancel_wait,
9743 .policy = nl80211_policy,
026331c4 9744 .flags = GENL_ADMIN_PERM,
71bbc994 9745 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 9746 NL80211_FLAG_NEED_RTNL,
026331c4 9747 },
ffb9eb3d
KV
9748 {
9749 .cmd = NL80211_CMD_SET_POWER_SAVE,
9750 .doit = nl80211_set_power_save,
9751 .policy = nl80211_policy,
9752 .flags = GENL_ADMIN_PERM,
4c476991
JB
9753 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9754 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
9755 },
9756 {
9757 .cmd = NL80211_CMD_GET_POWER_SAVE,
9758 .doit = nl80211_get_power_save,
9759 .policy = nl80211_policy,
9760 /* can be retrieved by unprivileged users */
4c476991
JB
9761 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9762 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 9763 },
d6dc1a38
JO
9764 {
9765 .cmd = NL80211_CMD_SET_CQM,
9766 .doit = nl80211_set_cqm,
9767 .policy = nl80211_policy,
9768 .flags = GENL_ADMIN_PERM,
4c476991
JB
9769 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9770 NL80211_FLAG_NEED_RTNL,
d6dc1a38 9771 },
f444de05
JB
9772 {
9773 .cmd = NL80211_CMD_SET_CHANNEL,
9774 .doit = nl80211_set_channel,
9775 .policy = nl80211_policy,
9776 .flags = GENL_ADMIN_PERM,
4c476991
JB
9777 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9778 NL80211_FLAG_NEED_RTNL,
f444de05 9779 },
e8347eba
BJ
9780 {
9781 .cmd = NL80211_CMD_SET_WDS_PEER,
9782 .doit = nl80211_set_wds_peer,
9783 .policy = nl80211_policy,
9784 .flags = GENL_ADMIN_PERM,
43b19952
JB
9785 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9786 NL80211_FLAG_NEED_RTNL,
e8347eba 9787 },
29cbe68c
JB
9788 {
9789 .cmd = NL80211_CMD_JOIN_MESH,
9790 .doit = nl80211_join_mesh,
9791 .policy = nl80211_policy,
9792 .flags = GENL_ADMIN_PERM,
9793 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9794 NL80211_FLAG_NEED_RTNL,
9795 },
9796 {
9797 .cmd = NL80211_CMD_LEAVE_MESH,
9798 .doit = nl80211_leave_mesh,
9799 .policy = nl80211_policy,
9800 .flags = GENL_ADMIN_PERM,
9801 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9802 NL80211_FLAG_NEED_RTNL,
9803 },
dfb89c56 9804#ifdef CONFIG_PM
ff1b6e69
JB
9805 {
9806 .cmd = NL80211_CMD_GET_WOWLAN,
9807 .doit = nl80211_get_wowlan,
9808 .policy = nl80211_policy,
9809 /* can be retrieved by unprivileged users */
9810 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9811 NL80211_FLAG_NEED_RTNL,
9812 },
9813 {
9814 .cmd = NL80211_CMD_SET_WOWLAN,
9815 .doit = nl80211_set_wowlan,
9816 .policy = nl80211_policy,
9817 .flags = GENL_ADMIN_PERM,
9818 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9819 NL80211_FLAG_NEED_RTNL,
9820 },
dfb89c56 9821#endif
e5497d76
JB
9822 {
9823 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
9824 .doit = nl80211_set_rekey_data,
9825 .policy = nl80211_policy,
9826 .flags = GENL_ADMIN_PERM,
9827 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9828 NL80211_FLAG_NEED_RTNL,
9829 },
109086ce
AN
9830 {
9831 .cmd = NL80211_CMD_TDLS_MGMT,
9832 .doit = nl80211_tdls_mgmt,
9833 .policy = nl80211_policy,
9834 .flags = GENL_ADMIN_PERM,
9835 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9836 NL80211_FLAG_NEED_RTNL,
9837 },
9838 {
9839 .cmd = NL80211_CMD_TDLS_OPER,
9840 .doit = nl80211_tdls_oper,
9841 .policy = nl80211_policy,
9842 .flags = GENL_ADMIN_PERM,
9843 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9844 NL80211_FLAG_NEED_RTNL,
9845 },
28946da7
JB
9846 {
9847 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
9848 .doit = nl80211_register_unexpected_frame,
9849 .policy = nl80211_policy,
9850 .flags = GENL_ADMIN_PERM,
9851 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9852 NL80211_FLAG_NEED_RTNL,
9853 },
7f6cf311
JB
9854 {
9855 .cmd = NL80211_CMD_PROBE_CLIENT,
9856 .doit = nl80211_probe_client,
9857 .policy = nl80211_policy,
9858 .flags = GENL_ADMIN_PERM,
2b5f8b0b 9859 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
9860 NL80211_FLAG_NEED_RTNL,
9861 },
5e760230
JB
9862 {
9863 .cmd = NL80211_CMD_REGISTER_BEACONS,
9864 .doit = nl80211_register_beacons,
9865 .policy = nl80211_policy,
9866 .flags = GENL_ADMIN_PERM,
9867 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9868 NL80211_FLAG_NEED_RTNL,
9869 },
1d9d9213
SW
9870 {
9871 .cmd = NL80211_CMD_SET_NOACK_MAP,
9872 .doit = nl80211_set_noack_map,
9873 .policy = nl80211_policy,
9874 .flags = GENL_ADMIN_PERM,
9875 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9876 NL80211_FLAG_NEED_RTNL,
9877 },
98104fde
JB
9878 {
9879 .cmd = NL80211_CMD_START_P2P_DEVICE,
9880 .doit = nl80211_start_p2p_device,
9881 .policy = nl80211_policy,
9882 .flags = GENL_ADMIN_PERM,
9883 .internal_flags = NL80211_FLAG_NEED_WDEV |
9884 NL80211_FLAG_NEED_RTNL,
9885 },
9886 {
9887 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
9888 .doit = nl80211_stop_p2p_device,
9889 .policy = nl80211_policy,
9890 .flags = GENL_ADMIN_PERM,
9891 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
9892 NL80211_FLAG_NEED_RTNL,
9893 },
f4e583c8
AQ
9894 {
9895 .cmd = NL80211_CMD_SET_MCAST_RATE,
9896 .doit = nl80211_set_mcast_rate,
77765eaf
VT
9897 .policy = nl80211_policy,
9898 .flags = GENL_ADMIN_PERM,
9899 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9900 NL80211_FLAG_NEED_RTNL,
9901 },
9902 {
9903 .cmd = NL80211_CMD_SET_MAC_ACL,
9904 .doit = nl80211_set_mac_acl,
f4e583c8
AQ
9905 .policy = nl80211_policy,
9906 .flags = GENL_ADMIN_PERM,
9907 .internal_flags = NL80211_FLAG_NEED_NETDEV |
9908 NL80211_FLAG_NEED_RTNL,
9909 },
04f39047
SW
9910 {
9911 .cmd = NL80211_CMD_RADAR_DETECT,
9912 .doit = nl80211_start_radar_detection,
9913 .policy = nl80211_policy,
9914 .flags = GENL_ADMIN_PERM,
9915 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9916 NL80211_FLAG_NEED_RTNL,
9917 },
3713b4e3
JB
9918 {
9919 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
9920 .doit = nl80211_get_protocol_features,
9921 .policy = nl80211_policy,
9922 },
355199e0
JM
9923 {
9924 .cmd = NL80211_CMD_UPDATE_FT_IES,
9925 .doit = nl80211_update_ft_ies,
9926 .policy = nl80211_policy,
9927 .flags = GENL_ADMIN_PERM,
9928 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9929 NL80211_FLAG_NEED_RTNL,
9930 },
5de17984
AS
9931 {
9932 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
9933 .doit = nl80211_crit_protocol_start,
9934 .policy = nl80211_policy,
9935 .flags = GENL_ADMIN_PERM,
9936 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
9937 NL80211_FLAG_NEED_RTNL,
9938 },
9939 {
9940 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
9941 .doit = nl80211_crit_protocol_stop,
9942 .policy = nl80211_policy,
9943 .flags = GENL_ADMIN_PERM,
9944 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
9945 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
9946 },
9947 {
9948 .cmd = NL80211_CMD_GET_COALESCE,
9949 .doit = nl80211_get_coalesce,
9950 .policy = nl80211_policy,
9951 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9952 NL80211_FLAG_NEED_RTNL,
9953 },
9954 {
9955 .cmd = NL80211_CMD_SET_COALESCE,
9956 .doit = nl80211_set_coalesce,
9957 .policy = nl80211_policy,
9958 .flags = GENL_ADMIN_PERM,
9959 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9960 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
9961 },
9962 {
9963 .cmd = NL80211_CMD_CHANNEL_SWITCH,
9964 .doit = nl80211_channel_switch,
9965 .policy = nl80211_policy,
9966 .flags = GENL_ADMIN_PERM,
9967 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9968 NL80211_FLAG_NEED_RTNL,
9969 },
ad7e718c
JB
9970 {
9971 .cmd = NL80211_CMD_VENDOR,
9972 .doit = nl80211_vendor_cmd,
9973 .policy = nl80211_policy,
9974 .flags = GENL_ADMIN_PERM,
9975 .internal_flags = NL80211_FLAG_NEED_WIPHY |
9976 NL80211_FLAG_NEED_RTNL,
9977 },
fa9ffc74
KP
9978 {
9979 .cmd = NL80211_CMD_SET_QOS_MAP,
9980 .doit = nl80211_set_qos_map,
9981 .policy = nl80211_policy,
9982 .flags = GENL_ADMIN_PERM,
9983 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
9984 NL80211_FLAG_NEED_RTNL,
9985 },
55682965 9986};
9588bbd5 9987
55682965
JB
9988/* notification functions */
9989
9990void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
9991{
9992 struct sk_buff *msg;
86e8cf98 9993 struct nl80211_dump_wiphy_state state = {};
55682965 9994
fd2120ca 9995 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
9996 if (!msg)
9997 return;
9998
86e8cf98 9999 if (nl80211_send_wiphy(rdev, msg, 0, 0, 0, &state) < 0) {
55682965
JB
10000 nlmsg_free(msg);
10001 return;
10002 }
10003
68eb5503 10004 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10005 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
10006}
10007
362a415d
JB
10008static int nl80211_add_scan_req(struct sk_buff *msg,
10009 struct cfg80211_registered_device *rdev)
10010{
10011 struct cfg80211_scan_request *req = rdev->scan_req;
10012 struct nlattr *nest;
10013 int i;
10014
10015 if (WARN_ON(!req))
10016 return 0;
10017
10018 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
10019 if (!nest)
10020 goto nla_put_failure;
9360ffd1
DM
10021 for (i = 0; i < req->n_ssids; i++) {
10022 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
10023 goto nla_put_failure;
10024 }
362a415d
JB
10025 nla_nest_end(msg, nest);
10026
10027 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
10028 if (!nest)
10029 goto nla_put_failure;
9360ffd1
DM
10030 for (i = 0; i < req->n_channels; i++) {
10031 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
10032 goto nla_put_failure;
10033 }
362a415d
JB
10034 nla_nest_end(msg, nest);
10035
9360ffd1
DM
10036 if (req->ie &&
10037 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
10038 goto nla_put_failure;
362a415d 10039
ae917c9f
JB
10040 if (req->flags &&
10041 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
10042 goto nla_put_failure;
ed473771 10043
362a415d
JB
10044 return 0;
10045 nla_put_failure:
10046 return -ENOBUFS;
10047}
10048
a538e2d5
JB
10049static int nl80211_send_scan_msg(struct sk_buff *msg,
10050 struct cfg80211_registered_device *rdev,
fd014284 10051 struct wireless_dev *wdev,
15e47304 10052 u32 portid, u32 seq, int flags,
a538e2d5 10053 u32 cmd)
2a519311
JB
10054{
10055 void *hdr;
10056
15e47304 10057 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
10058 if (!hdr)
10059 return -1;
10060
9360ffd1 10061 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
10062 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
10063 wdev->netdev->ifindex)) ||
10064 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
9360ffd1 10065 goto nla_put_failure;
2a519311 10066
362a415d
JB
10067 /* ignore errors and send incomplete event anyway */
10068 nl80211_add_scan_req(msg, rdev);
2a519311
JB
10069
10070 return genlmsg_end(msg, hdr);
10071
10072 nla_put_failure:
10073 genlmsg_cancel(msg, hdr);
10074 return -EMSGSIZE;
10075}
10076
807f8a8c
LC
10077static int
10078nl80211_send_sched_scan_msg(struct sk_buff *msg,
10079 struct cfg80211_registered_device *rdev,
10080 struct net_device *netdev,
15e47304 10081 u32 portid, u32 seq, int flags, u32 cmd)
807f8a8c
LC
10082{
10083 void *hdr;
10084
15e47304 10085 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
807f8a8c
LC
10086 if (!hdr)
10087 return -1;
10088
9360ffd1
DM
10089 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10090 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
10091 goto nla_put_failure;
807f8a8c
LC
10092
10093 return genlmsg_end(msg, hdr);
10094
10095 nla_put_failure:
10096 genlmsg_cancel(msg, hdr);
10097 return -EMSGSIZE;
10098}
10099
a538e2d5 10100void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 10101 struct wireless_dev *wdev)
a538e2d5
JB
10102{
10103 struct sk_buff *msg;
10104
58050fce 10105 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
10106 if (!msg)
10107 return;
10108
fd014284 10109 if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
10110 NL80211_CMD_TRIGGER_SCAN) < 0) {
10111 nlmsg_free(msg);
10112 return;
10113 }
10114
68eb5503 10115 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10116 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
10117}
10118
2a519311 10119void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
fd014284 10120 struct wireless_dev *wdev)
2a519311
JB
10121{
10122 struct sk_buff *msg;
10123
fd2120ca 10124 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311
JB
10125 if (!msg)
10126 return;
10127
fd014284 10128 if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5 10129 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311
JB
10130 nlmsg_free(msg);
10131 return;
10132 }
10133
68eb5503 10134 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10135 NL80211_MCGRP_SCAN, GFP_KERNEL);
2a519311
JB
10136}
10137
10138void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
fd014284 10139 struct wireless_dev *wdev)
2a519311
JB
10140{
10141 struct sk_buff *msg;
10142
fd2120ca 10143 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311
JB
10144 if (!msg)
10145 return;
10146
fd014284 10147 if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5 10148 NL80211_CMD_SCAN_ABORTED) < 0) {
2a519311
JB
10149 nlmsg_free(msg);
10150 return;
10151 }
10152
68eb5503 10153 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10154 NL80211_MCGRP_SCAN, GFP_KERNEL);
2a519311
JB
10155}
10156
807f8a8c
LC
10157void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
10158 struct net_device *netdev)
10159{
10160 struct sk_buff *msg;
10161
10162 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10163 if (!msg)
10164 return;
10165
10166 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0,
10167 NL80211_CMD_SCHED_SCAN_RESULTS) < 0) {
10168 nlmsg_free(msg);
10169 return;
10170 }
10171
68eb5503 10172 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10173 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
10174}
10175
10176void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
10177 struct net_device *netdev, u32 cmd)
10178{
10179 struct sk_buff *msg;
10180
58050fce 10181 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
10182 if (!msg)
10183 return;
10184
10185 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
10186 nlmsg_free(msg);
10187 return;
10188 }
10189
68eb5503 10190 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10191 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
10192}
10193
73d54c9e
LR
10194/*
10195 * This can happen on global regulatory changes or device specific settings
10196 * based on custom world regulatory domains.
10197 */
10198void nl80211_send_reg_change_event(struct regulatory_request *request)
10199{
10200 struct sk_buff *msg;
10201 void *hdr;
10202
fd2120ca 10203 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
73d54c9e
LR
10204 if (!msg)
10205 return;
10206
10207 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
10208 if (!hdr) {
10209 nlmsg_free(msg);
10210 return;
10211 }
10212
10213 /* Userspace can always count this one always being set */
9360ffd1
DM
10214 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
10215 goto nla_put_failure;
10216
10217 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
10218 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
10219 NL80211_REGDOM_TYPE_WORLD))
10220 goto nla_put_failure;
10221 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
10222 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
10223 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
10224 goto nla_put_failure;
10225 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
10226 request->intersect) {
10227 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
10228 NL80211_REGDOM_TYPE_INTERSECTION))
10229 goto nla_put_failure;
10230 } else {
10231 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
10232 NL80211_REGDOM_TYPE_COUNTRY) ||
10233 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
10234 request->alpha2))
10235 goto nla_put_failure;
10236 }
10237
f4173766 10238 if (request->wiphy_idx != WIPHY_IDX_INVALID &&
9360ffd1
DM
10239 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
10240 goto nla_put_failure;
73d54c9e 10241
3b7b72ee 10242 genlmsg_end(msg, hdr);
73d54c9e 10243
bc43b28c 10244 rcu_read_lock();
68eb5503 10245 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 10246 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 10247 rcu_read_unlock();
73d54c9e
LR
10248
10249 return;
10250
10251nla_put_failure:
10252 genlmsg_cancel(msg, hdr);
10253 nlmsg_free(msg);
10254}
10255
6039f6d2
JM
10256static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
10257 struct net_device *netdev,
10258 const u8 *buf, size_t len,
e6d6e342 10259 enum nl80211_commands cmd, gfp_t gfp)
6039f6d2
JM
10260{
10261 struct sk_buff *msg;
10262 void *hdr;
10263
e6d6e342 10264 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
6039f6d2
JM
10265 if (!msg)
10266 return;
10267
10268 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
10269 if (!hdr) {
10270 nlmsg_free(msg);
10271 return;
10272 }
10273
9360ffd1
DM
10274 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10275 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
10276 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
10277 goto nla_put_failure;
6039f6d2 10278
3b7b72ee 10279 genlmsg_end(msg, hdr);
6039f6d2 10280
68eb5503 10281 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10282 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
10283 return;
10284
10285 nla_put_failure:
10286 genlmsg_cancel(msg, hdr);
10287 nlmsg_free(msg);
10288}
10289
10290void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
10291 struct net_device *netdev, const u8 *buf,
10292 size_t len, gfp_t gfp)
6039f6d2
JM
10293{
10294 nl80211_send_mlme_event(rdev, netdev, buf, len,
e6d6e342 10295 NL80211_CMD_AUTHENTICATE, gfp);
6039f6d2
JM
10296}
10297
10298void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
10299 struct net_device *netdev, const u8 *buf,
e6d6e342 10300 size_t len, gfp_t gfp)
6039f6d2 10301{
e6d6e342
JB
10302 nl80211_send_mlme_event(rdev, netdev, buf, len,
10303 NL80211_CMD_ASSOCIATE, gfp);
6039f6d2
JM
10304}
10305
53b46b84 10306void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
10307 struct net_device *netdev, const u8 *buf,
10308 size_t len, gfp_t gfp)
6039f6d2
JM
10309{
10310 nl80211_send_mlme_event(rdev, netdev, buf, len,
e6d6e342 10311 NL80211_CMD_DEAUTHENTICATE, gfp);
6039f6d2
JM
10312}
10313
53b46b84
JM
10314void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
10315 struct net_device *netdev, const u8 *buf,
e6d6e342 10316 size_t len, gfp_t gfp)
6039f6d2
JM
10317{
10318 nl80211_send_mlme_event(rdev, netdev, buf, len,
e6d6e342 10319 NL80211_CMD_DISASSOCIATE, gfp);
6039f6d2
JM
10320}
10321
6ff57cf8
JB
10322void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
10323 size_t len)
cf4e594e 10324{
947add36
JB
10325 struct wireless_dev *wdev = dev->ieee80211_ptr;
10326 struct wiphy *wiphy = wdev->wiphy;
10327 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
6ff57cf8
JB
10328 const struct ieee80211_mgmt *mgmt = (void *)buf;
10329 u32 cmd;
947add36 10330
6ff57cf8
JB
10331 if (WARN_ON(len < 2))
10332 return;
cf4e594e 10333
6ff57cf8
JB
10334 if (ieee80211_is_deauth(mgmt->frame_control))
10335 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
10336 else
10337 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 10338
6ff57cf8
JB
10339 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
10340 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC);
cf4e594e 10341}
6ff57cf8 10342EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 10343
1b06bb40
LR
10344static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
10345 struct net_device *netdev, int cmd,
e6d6e342 10346 const u8 *addr, gfp_t gfp)
1965c853
JM
10347{
10348 struct sk_buff *msg;
10349 void *hdr;
10350
e6d6e342 10351 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
10352 if (!msg)
10353 return;
10354
10355 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
10356 if (!hdr) {
10357 nlmsg_free(msg);
10358 return;
10359 }
10360
9360ffd1
DM
10361 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10362 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
10363 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
10364 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
10365 goto nla_put_failure;
1965c853 10366
3b7b72ee 10367 genlmsg_end(msg, hdr);
1965c853 10368
68eb5503 10369 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10370 NL80211_MCGRP_MLME, gfp);
1965c853
JM
10371 return;
10372
10373 nla_put_failure:
10374 genlmsg_cancel(msg, hdr);
10375 nlmsg_free(msg);
10376}
10377
10378void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
10379 struct net_device *netdev, const u8 *addr,
10380 gfp_t gfp)
1965c853
JM
10381{
10382 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 10383 addr, gfp);
1965c853
JM
10384}
10385
10386void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
10387 struct net_device *netdev, const u8 *addr,
10388 gfp_t gfp)
1965c853 10389{
e6d6e342
JB
10390 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
10391 addr, gfp);
1965c853
JM
10392}
10393
b23aa676
SO
10394void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
10395 struct net_device *netdev, const u8 *bssid,
10396 const u8 *req_ie, size_t req_ie_len,
10397 const u8 *resp_ie, size_t resp_ie_len,
10398 u16 status, gfp_t gfp)
10399{
10400 struct sk_buff *msg;
10401 void *hdr;
10402
58050fce 10403 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
b23aa676
SO
10404 if (!msg)
10405 return;
10406
10407 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
10408 if (!hdr) {
10409 nlmsg_free(msg);
10410 return;
10411 }
10412
9360ffd1
DM
10413 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10414 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
10415 (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) ||
10416 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status) ||
10417 (req_ie &&
10418 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
10419 (resp_ie &&
10420 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
10421 goto nla_put_failure;
b23aa676 10422
3b7b72ee 10423 genlmsg_end(msg, hdr);
b23aa676 10424
68eb5503 10425 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10426 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
10427 return;
10428
10429 nla_put_failure:
10430 genlmsg_cancel(msg, hdr);
10431 nlmsg_free(msg);
10432
10433}
10434
10435void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
10436 struct net_device *netdev, const u8 *bssid,
10437 const u8 *req_ie, size_t req_ie_len,
10438 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
10439{
10440 struct sk_buff *msg;
10441 void *hdr;
10442
58050fce 10443 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
b23aa676
SO
10444 if (!msg)
10445 return;
10446
10447 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
10448 if (!hdr) {
10449 nlmsg_free(msg);
10450 return;
10451 }
10452
9360ffd1
DM
10453 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10454 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
10455 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
10456 (req_ie &&
10457 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
10458 (resp_ie &&
10459 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
10460 goto nla_put_failure;
b23aa676 10461
3b7b72ee 10462 genlmsg_end(msg, hdr);
b23aa676 10463
68eb5503 10464 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10465 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
10466 return;
10467
10468 nla_put_failure:
10469 genlmsg_cancel(msg, hdr);
10470 nlmsg_free(msg);
10471
10472}
10473
10474void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
10475 struct net_device *netdev, u16 reason,
667503dd 10476 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
10477{
10478 struct sk_buff *msg;
10479 void *hdr;
10480
58050fce 10481 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
b23aa676
SO
10482 if (!msg)
10483 return;
10484
10485 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
10486 if (!hdr) {
10487 nlmsg_free(msg);
10488 return;
10489 }
10490
9360ffd1
DM
10491 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10492 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
10493 (from_ap && reason &&
10494 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
10495 (from_ap &&
10496 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
10497 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
10498 goto nla_put_failure;
b23aa676 10499
3b7b72ee 10500 genlmsg_end(msg, hdr);
b23aa676 10501
68eb5503 10502 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10503 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
10504 return;
10505
10506 nla_put_failure:
10507 genlmsg_cancel(msg, hdr);
10508 nlmsg_free(msg);
10509
10510}
10511
04a773ad
JB
10512void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
10513 struct net_device *netdev, const u8 *bssid,
10514 gfp_t gfp)
10515{
10516 struct sk_buff *msg;
10517 void *hdr;
10518
fd2120ca 10519 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
10520 if (!msg)
10521 return;
10522
10523 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
10524 if (!hdr) {
10525 nlmsg_free(msg);
10526 return;
10527 }
10528
9360ffd1
DM
10529 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10530 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
10531 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
10532 goto nla_put_failure;
04a773ad 10533
3b7b72ee 10534 genlmsg_end(msg, hdr);
04a773ad 10535
68eb5503 10536 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10537 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
10538 return;
10539
10540 nla_put_failure:
10541 genlmsg_cancel(msg, hdr);
10542 nlmsg_free(msg);
10543}
10544
947add36
JB
10545void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
10546 const u8* ie, u8 ie_len, gfp_t gfp)
c93b5e71 10547{
947add36
JB
10548 struct wireless_dev *wdev = dev->ieee80211_ptr;
10549 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
c93b5e71
JC
10550 struct sk_buff *msg;
10551 void *hdr;
10552
947add36
JB
10553 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
10554 return;
10555
10556 trace_cfg80211_notify_new_peer_candidate(dev, addr);
10557
c93b5e71
JC
10558 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
10559 if (!msg)
10560 return;
10561
10562 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
10563 if (!hdr) {
10564 nlmsg_free(msg);
10565 return;
10566 }
10567
9360ffd1 10568 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
10569 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
10570 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1
DM
10571 (ie_len && ie &&
10572 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
10573 goto nla_put_failure;
c93b5e71 10574
3b7b72ee 10575 genlmsg_end(msg, hdr);
c93b5e71 10576
68eb5503 10577 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10578 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
10579 return;
10580
10581 nla_put_failure:
10582 genlmsg_cancel(msg, hdr);
10583 nlmsg_free(msg);
10584}
947add36 10585EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 10586
a3b8b056
JM
10587void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
10588 struct net_device *netdev, const u8 *addr,
10589 enum nl80211_key_type key_type, int key_id,
e6d6e342 10590 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
10591{
10592 struct sk_buff *msg;
10593 void *hdr;
10594
e6d6e342 10595 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
10596 if (!msg)
10597 return;
10598
10599 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
10600 if (!hdr) {
10601 nlmsg_free(msg);
10602 return;
10603 }
10604
9360ffd1
DM
10605 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10606 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
10607 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
10608 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
10609 (key_id != -1 &&
10610 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
10611 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
10612 goto nla_put_failure;
a3b8b056 10613
3b7b72ee 10614 genlmsg_end(msg, hdr);
a3b8b056 10615
68eb5503 10616 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10617 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
10618 return;
10619
10620 nla_put_failure:
10621 genlmsg_cancel(msg, hdr);
10622 nlmsg_free(msg);
10623}
10624
6bad8766
LR
10625void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
10626 struct ieee80211_channel *channel_before,
10627 struct ieee80211_channel *channel_after)
10628{
10629 struct sk_buff *msg;
10630 void *hdr;
10631 struct nlattr *nl_freq;
10632
fd2120ca 10633 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
10634 if (!msg)
10635 return;
10636
10637 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
10638 if (!hdr) {
10639 nlmsg_free(msg);
10640 return;
10641 }
10642
10643 /*
10644 * Since we are applying the beacon hint to a wiphy we know its
10645 * wiphy_idx is valid
10646 */
9360ffd1
DM
10647 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
10648 goto nla_put_failure;
6bad8766
LR
10649
10650 /* Before */
10651 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
10652 if (!nl_freq)
10653 goto nla_put_failure;
cdc89b97 10654 if (nl80211_msg_put_channel(msg, channel_before, false))
6bad8766
LR
10655 goto nla_put_failure;
10656 nla_nest_end(msg, nl_freq);
10657
10658 /* After */
10659 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
10660 if (!nl_freq)
10661 goto nla_put_failure;
cdc89b97 10662 if (nl80211_msg_put_channel(msg, channel_after, false))
6bad8766
LR
10663 goto nla_put_failure;
10664 nla_nest_end(msg, nl_freq);
10665
3b7b72ee 10666 genlmsg_end(msg, hdr);
6bad8766 10667
463d0183 10668 rcu_read_lock();
68eb5503 10669 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 10670 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 10671 rcu_read_unlock();
6bad8766
LR
10672
10673 return;
10674
10675nla_put_failure:
10676 genlmsg_cancel(msg, hdr);
10677 nlmsg_free(msg);
10678}
10679
9588bbd5
JM
10680static void nl80211_send_remain_on_chan_event(
10681 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 10682 struct wireless_dev *wdev, u64 cookie,
9588bbd5 10683 struct ieee80211_channel *chan,
9588bbd5
JM
10684 unsigned int duration, gfp_t gfp)
10685{
10686 struct sk_buff *msg;
10687 void *hdr;
10688
10689 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
10690 if (!msg)
10691 return;
10692
10693 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
10694 if (!hdr) {
10695 nlmsg_free(msg);
10696 return;
10697 }
10698
9360ffd1 10699 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
10700 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
10701 wdev->netdev->ifindex)) ||
00f53350 10702 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
9360ffd1 10703 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
10704 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
10705 NL80211_CHAN_NO_HT) ||
9360ffd1
DM
10706 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
10707 goto nla_put_failure;
9588bbd5 10708
9360ffd1
DM
10709 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
10710 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
10711 goto nla_put_failure;
9588bbd5 10712
3b7b72ee 10713 genlmsg_end(msg, hdr);
9588bbd5 10714
68eb5503 10715 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10716 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
10717 return;
10718
10719 nla_put_failure:
10720 genlmsg_cancel(msg, hdr);
10721 nlmsg_free(msg);
10722}
10723
947add36
JB
10724void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
10725 struct ieee80211_channel *chan,
10726 unsigned int duration, gfp_t gfp)
9588bbd5 10727{
947add36
JB
10728 struct wiphy *wiphy = wdev->wiphy;
10729 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
10730
10731 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 10732 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 10733 rdev, wdev, cookie, chan,
42d97a59 10734 duration, gfp);
9588bbd5 10735}
947add36 10736EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 10737
947add36
JB
10738void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
10739 struct ieee80211_channel *chan,
10740 gfp_t gfp)
9588bbd5 10741{
947add36
JB
10742 struct wiphy *wiphy = wdev->wiphy;
10743 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
10744
10745 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 10746 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 10747 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 10748}
947add36 10749EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 10750
947add36
JB
10751void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
10752 struct station_info *sinfo, gfp_t gfp)
98b62183 10753{
947add36
JB
10754 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
10755 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
98b62183
JB
10756 struct sk_buff *msg;
10757
947add36
JB
10758 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
10759
58050fce 10760 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
10761 if (!msg)
10762 return;
10763
66266b3a
JL
10764 if (nl80211_send_station(msg, 0, 0, 0,
10765 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
10766 nlmsg_free(msg);
10767 return;
10768 }
10769
68eb5503 10770 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10771 NL80211_MCGRP_MLME, gfp);
98b62183 10772}
947add36 10773EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 10774
947add36 10775void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
ec15e68b 10776{
947add36
JB
10777 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
10778 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
ec15e68b
JM
10779 struct sk_buff *msg;
10780 void *hdr;
10781
947add36
JB
10782 trace_cfg80211_del_sta(dev, mac_addr);
10783
58050fce 10784 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
ec15e68b
JM
10785 if (!msg)
10786 return;
10787
10788 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION);
10789 if (!hdr) {
10790 nlmsg_free(msg);
10791 return;
10792 }
10793
9360ffd1
DM
10794 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
10795 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
10796 goto nla_put_failure;
ec15e68b 10797
3b7b72ee 10798 genlmsg_end(msg, hdr);
ec15e68b 10799
68eb5503 10800 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10801 NL80211_MCGRP_MLME, gfp);
ec15e68b
JM
10802 return;
10803
10804 nla_put_failure:
10805 genlmsg_cancel(msg, hdr);
10806 nlmsg_free(msg);
10807}
947add36 10808EXPORT_SYMBOL(cfg80211_del_sta);
ec15e68b 10809
947add36
JB
10810void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
10811 enum nl80211_connect_failed_reason reason,
10812 gfp_t gfp)
ed44a951 10813{
947add36
JB
10814 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
10815 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
ed44a951
PP
10816 struct sk_buff *msg;
10817 void *hdr;
10818
10819 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
10820 if (!msg)
10821 return;
10822
10823 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
10824 if (!hdr) {
10825 nlmsg_free(msg);
10826 return;
10827 }
10828
10829 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
10830 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
10831 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
10832 goto nla_put_failure;
10833
10834 genlmsg_end(msg, hdr);
10835
68eb5503 10836 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10837 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
10838 return;
10839
10840 nla_put_failure:
10841 genlmsg_cancel(msg, hdr);
10842 nlmsg_free(msg);
10843}
947add36 10844EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 10845
b92ab5d8
JB
10846static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
10847 const u8 *addr, gfp_t gfp)
28946da7
JB
10848{
10849 struct wireless_dev *wdev = dev->ieee80211_ptr;
10850 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
10851 struct sk_buff *msg;
10852 void *hdr;
15e47304 10853 u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid);
28946da7 10854
15e47304 10855 if (!nlportid)
28946da7
JB
10856 return false;
10857
10858 msg = nlmsg_new(100, gfp);
10859 if (!msg)
10860 return true;
10861
b92ab5d8 10862 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
10863 if (!hdr) {
10864 nlmsg_free(msg);
10865 return true;
10866 }
10867
9360ffd1
DM
10868 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10869 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
10870 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
10871 goto nla_put_failure;
28946da7 10872
9c90a9f6 10873 genlmsg_end(msg, hdr);
15e47304 10874 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
10875 return true;
10876
10877 nla_put_failure:
10878 genlmsg_cancel(msg, hdr);
10879 nlmsg_free(msg);
10880 return true;
10881}
10882
947add36
JB
10883bool cfg80211_rx_spurious_frame(struct net_device *dev,
10884 const u8 *addr, gfp_t gfp)
b92ab5d8 10885{
947add36
JB
10886 struct wireless_dev *wdev = dev->ieee80211_ptr;
10887 bool ret;
10888
10889 trace_cfg80211_rx_spurious_frame(dev, addr);
10890
10891 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
10892 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
10893 trace_cfg80211_return_bool(false);
10894 return false;
10895 }
10896 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
10897 addr, gfp);
10898 trace_cfg80211_return_bool(ret);
10899 return ret;
b92ab5d8 10900}
947add36 10901EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 10902
947add36
JB
10903bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
10904 const u8 *addr, gfp_t gfp)
b92ab5d8 10905{
947add36
JB
10906 struct wireless_dev *wdev = dev->ieee80211_ptr;
10907 bool ret;
10908
10909 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
10910
10911 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
10912 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
10913 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
10914 trace_cfg80211_return_bool(false);
10915 return false;
10916 }
10917 ret = __nl80211_unexpected_frame(dev,
10918 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
10919 addr, gfp);
10920 trace_cfg80211_return_bool(ret);
10921 return ret;
b92ab5d8 10922}
947add36 10923EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 10924
2e161f78 10925int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 10926 struct wireless_dev *wdev, u32 nlportid,
804483e9 10927 int freq, int sig_dbm,
19504cf5 10928 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 10929{
71bbc994 10930 struct net_device *netdev = wdev->netdev;
026331c4
JM
10931 struct sk_buff *msg;
10932 void *hdr;
026331c4
JM
10933
10934 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
10935 if (!msg)
10936 return -ENOMEM;
10937
2e161f78 10938 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
10939 if (!hdr) {
10940 nlmsg_free(msg);
10941 return -ENOMEM;
10942 }
10943
9360ffd1 10944 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
10945 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
10946 netdev->ifindex)) ||
a838490b 10947 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
9360ffd1
DM
10948 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
10949 (sig_dbm &&
10950 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
10951 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
10952 (flags &&
10953 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 10954 goto nla_put_failure;
026331c4 10955
3b7b72ee 10956 genlmsg_end(msg, hdr);
026331c4 10957
15e47304 10958 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
10959
10960 nla_put_failure:
10961 genlmsg_cancel(msg, hdr);
10962 nlmsg_free(msg);
10963 return -ENOBUFS;
10964}
10965
947add36
JB
10966void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
10967 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 10968{
947add36
JB
10969 struct wiphy *wiphy = wdev->wiphy;
10970 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
71bbc994 10971 struct net_device *netdev = wdev->netdev;
026331c4
JM
10972 struct sk_buff *msg;
10973 void *hdr;
10974
947add36
JB
10975 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
10976
026331c4
JM
10977 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
10978 if (!msg)
10979 return;
10980
2e161f78 10981 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
10982 if (!hdr) {
10983 nlmsg_free(msg);
10984 return;
10985 }
10986
9360ffd1 10987 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
10988 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
10989 netdev->ifindex)) ||
a838490b 10990 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) ||
9360ffd1
DM
10991 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
10992 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
10993 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
10994 goto nla_put_failure;
026331c4 10995
3b7b72ee 10996 genlmsg_end(msg, hdr);
026331c4 10997
68eb5503 10998 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 10999 NL80211_MCGRP_MLME, gfp);
026331c4
JM
11000 return;
11001
11002 nla_put_failure:
11003 genlmsg_cancel(msg, hdr);
11004 nlmsg_free(msg);
11005}
947add36 11006EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 11007
947add36
JB
11008void cfg80211_cqm_rssi_notify(struct net_device *dev,
11009 enum nl80211_cqm_rssi_threshold_event rssi_event,
11010 gfp_t gfp)
d6dc1a38 11011{
947add36
JB
11012 struct wireless_dev *wdev = dev->ieee80211_ptr;
11013 struct wiphy *wiphy = wdev->wiphy;
11014 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
d6dc1a38
JO
11015 struct sk_buff *msg;
11016 struct nlattr *pinfoattr;
11017 void *hdr;
11018
947add36
JB
11019 trace_cfg80211_cqm_rssi_notify(dev, rssi_event);
11020
58050fce 11021 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
d6dc1a38
JO
11022 if (!msg)
11023 return;
11024
11025 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
11026 if (!hdr) {
11027 nlmsg_free(msg);
11028 return;
11029 }
11030
9360ffd1 11031 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 11032 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 11033 goto nla_put_failure;
d6dc1a38
JO
11034
11035 pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
11036 if (!pinfoattr)
11037 goto nla_put_failure;
11038
9360ffd1
DM
11039 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
11040 rssi_event))
11041 goto nla_put_failure;
d6dc1a38
JO
11042
11043 nla_nest_end(msg, pinfoattr);
11044
3b7b72ee 11045 genlmsg_end(msg, hdr);
d6dc1a38 11046
68eb5503 11047 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11048 NL80211_MCGRP_MLME, gfp);
d6dc1a38
JO
11049 return;
11050
11051 nla_put_failure:
11052 genlmsg_cancel(msg, hdr);
11053 nlmsg_free(msg);
11054}
947add36 11055EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 11056
947add36
JB
11057static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
11058 struct net_device *netdev, const u8 *bssid,
11059 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
11060{
11061 struct sk_buff *msg;
11062 struct nlattr *rekey_attr;
11063 void *hdr;
11064
58050fce 11065 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
11066 if (!msg)
11067 return;
11068
11069 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
11070 if (!hdr) {
11071 nlmsg_free(msg);
11072 return;
11073 }
11074
9360ffd1
DM
11075 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11076 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
11077 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
11078 goto nla_put_failure;
e5497d76
JB
11079
11080 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
11081 if (!rekey_attr)
11082 goto nla_put_failure;
11083
9360ffd1
DM
11084 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
11085 NL80211_REPLAY_CTR_LEN, replay_ctr))
11086 goto nla_put_failure;
e5497d76
JB
11087
11088 nla_nest_end(msg, rekey_attr);
11089
3b7b72ee 11090 genlmsg_end(msg, hdr);
e5497d76 11091
68eb5503 11092 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11093 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
11094 return;
11095
11096 nla_put_failure:
11097 genlmsg_cancel(msg, hdr);
11098 nlmsg_free(msg);
11099}
11100
947add36
JB
11101void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
11102 const u8 *replay_ctr, gfp_t gfp)
11103{
11104 struct wireless_dev *wdev = dev->ieee80211_ptr;
11105 struct wiphy *wiphy = wdev->wiphy;
11106 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
11107
11108 trace_cfg80211_gtk_rekey_notify(dev, bssid);
11109 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
11110}
11111EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
11112
11113static void
11114nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
11115 struct net_device *netdev, int index,
11116 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
11117{
11118 struct sk_buff *msg;
11119 struct nlattr *attr;
11120 void *hdr;
11121
58050fce 11122 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
11123 if (!msg)
11124 return;
11125
11126 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
11127 if (!hdr) {
11128 nlmsg_free(msg);
11129 return;
11130 }
11131
9360ffd1
DM
11132 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11133 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
11134 goto nla_put_failure;
c9df56b4
JM
11135
11136 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
11137 if (!attr)
11138 goto nla_put_failure;
11139
9360ffd1
DM
11140 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
11141 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
11142 (preauth &&
11143 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
11144 goto nla_put_failure;
c9df56b4
JM
11145
11146 nla_nest_end(msg, attr);
11147
3b7b72ee 11148 genlmsg_end(msg, hdr);
c9df56b4 11149
68eb5503 11150 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11151 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
11152 return;
11153
11154 nla_put_failure:
11155 genlmsg_cancel(msg, hdr);
11156 nlmsg_free(msg);
11157}
11158
947add36
JB
11159void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
11160 const u8 *bssid, bool preauth, gfp_t gfp)
11161{
11162 struct wireless_dev *wdev = dev->ieee80211_ptr;
11163 struct wiphy *wiphy = wdev->wiphy;
11164 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
11165
11166 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
11167 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
11168}
11169EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
11170
11171static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
11172 struct net_device *netdev,
11173 struct cfg80211_chan_def *chandef,
11174 gfp_t gfp)
5314526b
TP
11175{
11176 struct sk_buff *msg;
11177 void *hdr;
11178
58050fce 11179 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
11180 if (!msg)
11181 return;
11182
11183 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CH_SWITCH_NOTIFY);
11184 if (!hdr) {
11185 nlmsg_free(msg);
11186 return;
11187 }
11188
683b6d3b
JB
11189 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
11190 goto nla_put_failure;
11191
11192 if (nl80211_send_chandef(msg, chandef))
7eab0f64 11193 goto nla_put_failure;
5314526b
TP
11194
11195 genlmsg_end(msg, hdr);
11196
68eb5503 11197 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11198 NL80211_MCGRP_MLME, gfp);
5314526b
TP
11199 return;
11200
11201 nla_put_failure:
11202 genlmsg_cancel(msg, hdr);
11203 nlmsg_free(msg);
11204}
11205
947add36
JB
11206void cfg80211_ch_switch_notify(struct net_device *dev,
11207 struct cfg80211_chan_def *chandef)
84f10708 11208{
947add36
JB
11209 struct wireless_dev *wdev = dev->ieee80211_ptr;
11210 struct wiphy *wiphy = wdev->wiphy;
11211 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
11212
e487eaeb 11213 ASSERT_WDEV_LOCK(wdev);
947add36 11214
e487eaeb 11215 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36
JB
11216
11217 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
ee4bc9e7 11218 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
b8456a14
CYY
11219 wdev->iftype != NL80211_IFTYPE_ADHOC &&
11220 wdev->iftype != NL80211_IFTYPE_MESH_POINT))
e487eaeb 11221 return;
947add36 11222
9e0e2961 11223 wdev->chandef = *chandef;
96f55f12 11224 wdev->preset_chandef = *chandef;
947add36 11225 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
947add36
JB
11226}
11227EXPORT_SYMBOL(cfg80211_ch_switch_notify);
11228
11229void cfg80211_cqm_txe_notify(struct net_device *dev,
11230 const u8 *peer, u32 num_packets,
11231 u32 rate, u32 intvl, gfp_t gfp)
11232{
11233 struct wireless_dev *wdev = dev->ieee80211_ptr;
11234 struct wiphy *wiphy = wdev->wiphy;
11235 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
84f10708
TP
11236 struct sk_buff *msg;
11237 struct nlattr *pinfoattr;
11238 void *hdr;
11239
11240 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
11241 if (!msg)
11242 return;
11243
11244 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
11245 if (!hdr) {
11246 nlmsg_free(msg);
11247 return;
11248 }
11249
11250 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 11251 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
84f10708
TP
11252 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer))
11253 goto nla_put_failure;
11254
11255 pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
11256 if (!pinfoattr)
11257 goto nla_put_failure;
11258
11259 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
11260 goto nla_put_failure;
11261
11262 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
11263 goto nla_put_failure;
11264
11265 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
11266 goto nla_put_failure;
11267
11268 nla_nest_end(msg, pinfoattr);
11269
11270 genlmsg_end(msg, hdr);
11271
68eb5503 11272 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11273 NL80211_MCGRP_MLME, gfp);
84f10708
TP
11274 return;
11275
11276 nla_put_failure:
11277 genlmsg_cancel(msg, hdr);
11278 nlmsg_free(msg);
11279}
947add36 11280EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
84f10708 11281
04f39047
SW
11282void
11283nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 11284 const struct cfg80211_chan_def *chandef,
04f39047
SW
11285 enum nl80211_radar_event event,
11286 struct net_device *netdev, gfp_t gfp)
11287{
11288 struct sk_buff *msg;
11289 void *hdr;
11290
11291 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11292 if (!msg)
11293 return;
11294
11295 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
11296 if (!hdr) {
11297 nlmsg_free(msg);
11298 return;
11299 }
11300
11301 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
11302 goto nla_put_failure;
11303
11304 /* NOP and radar events don't need a netdev parameter */
11305 if (netdev) {
11306 struct wireless_dev *wdev = netdev->ieee80211_ptr;
11307
11308 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
11309 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
11310 goto nla_put_failure;
11311 }
11312
11313 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
11314 goto nla_put_failure;
11315
11316 if (nl80211_send_chandef(msg, chandef))
11317 goto nla_put_failure;
11318
9c90a9f6 11319 genlmsg_end(msg, hdr);
04f39047 11320
68eb5503 11321 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11322 NL80211_MCGRP_MLME, gfp);
04f39047
SW
11323 return;
11324
11325 nla_put_failure:
11326 genlmsg_cancel(msg, hdr);
11327 nlmsg_free(msg);
11328}
11329
947add36
JB
11330void cfg80211_cqm_pktloss_notify(struct net_device *dev,
11331 const u8 *peer, u32 num_packets, gfp_t gfp)
c063dbf5 11332{
947add36
JB
11333 struct wireless_dev *wdev = dev->ieee80211_ptr;
11334 struct wiphy *wiphy = wdev->wiphy;
11335 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
c063dbf5
JB
11336 struct sk_buff *msg;
11337 struct nlattr *pinfoattr;
11338 void *hdr;
11339
947add36
JB
11340 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
11341
58050fce 11342 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c063dbf5
JB
11343 if (!msg)
11344 return;
11345
11346 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
11347 if (!hdr) {
11348 nlmsg_free(msg);
11349 return;
11350 }
11351
9360ffd1 11352 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 11353 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
9360ffd1
DM
11354 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer))
11355 goto nla_put_failure;
c063dbf5
JB
11356
11357 pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
11358 if (!pinfoattr)
11359 goto nla_put_failure;
11360
9360ffd1
DM
11361 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
11362 goto nla_put_failure;
c063dbf5
JB
11363
11364 nla_nest_end(msg, pinfoattr);
11365
3b7b72ee 11366 genlmsg_end(msg, hdr);
c063dbf5 11367
68eb5503 11368 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11369 NL80211_MCGRP_MLME, gfp);
c063dbf5
JB
11370 return;
11371
11372 nla_put_failure:
11373 genlmsg_cancel(msg, hdr);
11374 nlmsg_free(msg);
11375}
947add36 11376EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
c063dbf5 11377
7f6cf311
JB
11378void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
11379 u64 cookie, bool acked, gfp_t gfp)
11380{
11381 struct wireless_dev *wdev = dev->ieee80211_ptr;
11382 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
11383 struct sk_buff *msg;
11384 void *hdr;
7f6cf311 11385
4ee3e063
BL
11386 trace_cfg80211_probe_status(dev, addr, cookie, acked);
11387
58050fce 11388 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 11389
7f6cf311
JB
11390 if (!msg)
11391 return;
11392
11393 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
11394 if (!hdr) {
11395 nlmsg_free(msg);
11396 return;
11397 }
11398
9360ffd1
DM
11399 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11400 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
11401 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
11402 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
11403 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
11404 goto nla_put_failure;
7f6cf311 11405
9c90a9f6 11406 genlmsg_end(msg, hdr);
7f6cf311 11407
68eb5503 11408 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11409 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
11410 return;
11411
11412 nla_put_failure:
11413 genlmsg_cancel(msg, hdr);
11414 nlmsg_free(msg);
11415}
11416EXPORT_SYMBOL(cfg80211_probe_status);
11417
5e760230
JB
11418void cfg80211_report_obss_beacon(struct wiphy *wiphy,
11419 const u8 *frame, size_t len,
37c73b5f 11420 int freq, int sig_dbm)
5e760230
JB
11421{
11422 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
11423 struct sk_buff *msg;
11424 void *hdr;
37c73b5f 11425 struct cfg80211_beacon_registration *reg;
5e760230 11426
4ee3e063
BL
11427 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
11428
37c73b5f
BG
11429 spin_lock_bh(&rdev->beacon_registrations_lock);
11430 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
11431 msg = nlmsg_new(len + 100, GFP_ATOMIC);
11432 if (!msg) {
11433 spin_unlock_bh(&rdev->beacon_registrations_lock);
11434 return;
11435 }
5e760230 11436
37c73b5f
BG
11437 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
11438 if (!hdr)
11439 goto nla_put_failure;
5e760230 11440
37c73b5f
BG
11441 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11442 (freq &&
11443 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11444 (sig_dbm &&
11445 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
11446 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
11447 goto nla_put_failure;
5e760230 11448
37c73b5f 11449 genlmsg_end(msg, hdr);
5e760230 11450
37c73b5f
BG
11451 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
11452 }
11453 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
11454 return;
11455
11456 nla_put_failure:
37c73b5f
BG
11457 spin_unlock_bh(&rdev->beacon_registrations_lock);
11458 if (hdr)
11459 genlmsg_cancel(msg, hdr);
5e760230
JB
11460 nlmsg_free(msg);
11461}
11462EXPORT_SYMBOL(cfg80211_report_obss_beacon);
11463
cd8f7cb4
JB
11464#ifdef CONFIG_PM
11465void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
11466 struct cfg80211_wowlan_wakeup *wakeup,
11467 gfp_t gfp)
11468{
11469 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
11470 struct sk_buff *msg;
11471 void *hdr;
9c90a9f6 11472 int size = 200;
cd8f7cb4
JB
11473
11474 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
11475
11476 if (wakeup)
11477 size += wakeup->packet_present_len;
11478
11479 msg = nlmsg_new(size, gfp);
11480 if (!msg)
11481 return;
11482
11483 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
11484 if (!hdr)
11485 goto free_msg;
11486
11487 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11488 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
11489 goto free_msg;
11490
11491 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
11492 wdev->netdev->ifindex))
11493 goto free_msg;
11494
11495 if (wakeup) {
11496 struct nlattr *reasons;
11497
11498 reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
11499 if (!reasons)
11500 goto free_msg;
cd8f7cb4
JB
11501
11502 if (wakeup->disconnect &&
11503 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
11504 goto free_msg;
11505 if (wakeup->magic_pkt &&
11506 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
11507 goto free_msg;
11508 if (wakeup->gtk_rekey_failure &&
11509 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
11510 goto free_msg;
11511 if (wakeup->eap_identity_req &&
11512 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
11513 goto free_msg;
11514 if (wakeup->four_way_handshake &&
11515 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
11516 goto free_msg;
11517 if (wakeup->rfkill_release &&
11518 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
11519 goto free_msg;
11520
11521 if (wakeup->pattern_idx >= 0 &&
11522 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
11523 wakeup->pattern_idx))
11524 goto free_msg;
11525
ae917c9f
JB
11526 if (wakeup->tcp_match &&
11527 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
11528 goto free_msg;
2a0e047e 11529
ae917c9f
JB
11530 if (wakeup->tcp_connlost &&
11531 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
11532 goto free_msg;
2a0e047e 11533
ae917c9f
JB
11534 if (wakeup->tcp_nomoretokens &&
11535 nla_put_flag(msg,
11536 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
11537 goto free_msg;
2a0e047e 11538
cd8f7cb4
JB
11539 if (wakeup->packet) {
11540 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
11541 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
11542
11543 if (!wakeup->packet_80211) {
11544 pkt_attr =
11545 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
11546 len_attr =
11547 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
11548 }
11549
11550 if (wakeup->packet_len &&
11551 nla_put_u32(msg, len_attr, wakeup->packet_len))
11552 goto free_msg;
11553
11554 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
11555 wakeup->packet))
11556 goto free_msg;
11557 }
11558
11559 nla_nest_end(msg, reasons);
11560 }
11561
9c90a9f6 11562 genlmsg_end(msg, hdr);
cd8f7cb4 11563
68eb5503 11564 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11565 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
11566 return;
11567
11568 free_msg:
11569 nlmsg_free(msg);
11570}
11571EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
11572#endif
11573
3475b094
JM
11574void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
11575 enum nl80211_tdls_operation oper,
11576 u16 reason_code, gfp_t gfp)
11577{
11578 struct wireless_dev *wdev = dev->ieee80211_ptr;
11579 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
11580 struct sk_buff *msg;
11581 void *hdr;
3475b094
JM
11582
11583 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
11584 reason_code);
11585
11586 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11587 if (!msg)
11588 return;
11589
11590 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
11591 if (!hdr) {
11592 nlmsg_free(msg);
11593 return;
11594 }
11595
11596 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11597 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
11598 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
11599 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
11600 (reason_code > 0 &&
11601 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
11602 goto nla_put_failure;
11603
9c90a9f6 11604 genlmsg_end(msg, hdr);
3475b094 11605
68eb5503 11606 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11607 NL80211_MCGRP_MLME, gfp);
3475b094
JM
11608 return;
11609
11610 nla_put_failure:
11611 genlmsg_cancel(msg, hdr);
11612 nlmsg_free(msg);
11613}
11614EXPORT_SYMBOL(cfg80211_tdls_oper_request);
11615
026331c4
JM
11616static int nl80211_netlink_notify(struct notifier_block * nb,
11617 unsigned long state,
11618 void *_notify)
11619{
11620 struct netlink_notify *notify = _notify;
11621 struct cfg80211_registered_device *rdev;
11622 struct wireless_dev *wdev;
37c73b5f 11623 struct cfg80211_beacon_registration *reg, *tmp;
026331c4
JM
11624
11625 if (state != NETLINK_URELEASE)
11626 return NOTIFY_DONE;
11627
11628 rcu_read_lock();
11629
5e760230 11630 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
89a54e48 11631 list_for_each_entry_rcu(wdev, &rdev->wdev_list, list)
15e47304 11632 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f
BG
11633
11634 spin_lock_bh(&rdev->beacon_registrations_lock);
11635 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
11636 list) {
11637 if (reg->nlportid == notify->portid) {
11638 list_del(&reg->list);
11639 kfree(reg);
11640 break;
11641 }
11642 }
11643 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230 11644 }
026331c4
JM
11645
11646 rcu_read_unlock();
11647
11648 return NOTIFY_DONE;
11649}
11650
11651static struct notifier_block nl80211_netlink_notifier = {
11652 .notifier_call = nl80211_netlink_notify,
11653};
11654
355199e0
JM
11655void cfg80211_ft_event(struct net_device *netdev,
11656 struct cfg80211_ft_event_params *ft_event)
11657{
11658 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
11659 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
11660 struct sk_buff *msg;
11661 void *hdr;
355199e0
JM
11662
11663 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
11664
11665 if (!ft_event->target_ap)
11666 return;
11667
11668 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11669 if (!msg)
11670 return;
11671
11672 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
11673 if (!hdr)
11674 goto out;
355199e0 11675
ae917c9f
JB
11676 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11677 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
11678 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
11679 goto out;
355199e0 11680
ae917c9f
JB
11681 if (ft_event->ies &&
11682 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
11683 goto out;
11684 if (ft_event->ric_ies &&
11685 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
11686 ft_event->ric_ies))
11687 goto out;
355199e0 11688
9c90a9f6 11689 genlmsg_end(msg, hdr);
355199e0 11690
68eb5503 11691 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 11692 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
11693 return;
11694 out:
11695 nlmsg_free(msg);
355199e0
JM
11696}
11697EXPORT_SYMBOL(cfg80211_ft_event);
11698
5de17984
AS
11699void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
11700{
11701 struct cfg80211_registered_device *rdev;
11702 struct sk_buff *msg;
11703 void *hdr;
11704 u32 nlportid;
11705
11706 rdev = wiphy_to_dev(wdev->wiphy);
11707 if (!rdev->crit_proto_nlportid)
11708 return;
11709
11710 nlportid = rdev->crit_proto_nlportid;
11711 rdev->crit_proto_nlportid = 0;
11712
11713 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11714 if (!msg)
11715 return;
11716
11717 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
11718 if (!hdr)
11719 goto nla_put_failure;
11720
11721 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11722 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
11723 goto nla_put_failure;
11724
11725 genlmsg_end(msg, hdr);
11726
11727 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
11728 return;
11729
11730 nla_put_failure:
11731 if (hdr)
11732 genlmsg_cancel(msg, hdr);
11733 nlmsg_free(msg);
11734
11735}
11736EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
11737
348baf0e
JB
11738void nl80211_send_ap_stopped(struct wireless_dev *wdev)
11739{
11740 struct wiphy *wiphy = wdev->wiphy;
11741 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
11742 struct sk_buff *msg;
11743 void *hdr;
11744
11745 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11746 if (!msg)
11747 return;
11748
11749 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
11750 if (!hdr)
11751 goto out;
11752
11753 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11754 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
11755 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
11756 goto out;
11757
11758 genlmsg_end(msg, hdr);
11759
11760 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
11761 NL80211_MCGRP_MLME, GFP_KERNEL);
11762 return;
11763 out:
11764 nlmsg_free(msg);
11765}
11766
55682965
JB
11767/* initialisation/exit functions */
11768
11769int nl80211_init(void)
11770{
0d63cbb5 11771 int err;
55682965 11772
2a94fe48
JB
11773 err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops,
11774 nl80211_mcgrps);
55682965
JB
11775 if (err)
11776 return err;
11777
026331c4
JM
11778 err = netlink_register_notifier(&nl80211_netlink_notifier);
11779 if (err)
11780 goto err_out;
11781
55682965
JB
11782 return 0;
11783 err_out:
11784 genl_unregister_family(&nl80211_fam);
11785 return err;
11786}
11787
11788void nl80211_exit(void)
11789{
026331c4 11790 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
11791 genl_unregister_family(&nl80211_fam);
11792}