]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - net/wireless/nl80211.c
cfg80211: support virtual interfaces with different beacon intervals
[mirror_ubuntu-bionic-kernel.git] / net / wireless / nl80211.c
CommitLineData
55682965
JB
1/*
2 * This is the new netlink-based wireless configuration interface.
3 *
026331c4 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
2740f0cf 5 * Copyright 2013-2014 Intel Mobile Communications GmbH
0c9ca11b 6 * Copyright 2015-2016 Intel Deutschland GmbH
55682965
JB
7 */
8
9#include <linux/if.h>
10#include <linux/module.h>
11#include <linux/err.h>
5a0e3ad6 12#include <linux/slab.h>
55682965
JB
13#include <linux/list.h>
14#include <linux/if_ether.h>
15#include <linux/ieee80211.h>
16#include <linux/nl80211.h>
17#include <linux/rtnetlink.h>
18#include <linux/netlink.h>
2a519311 19#include <linux/etherdevice.h>
463d0183 20#include <net/net_namespace.h>
55682965
JB
21#include <net/genetlink.h>
22#include <net/cfg80211.h>
463d0183 23#include <net/sock.h>
2a0e047e 24#include <net/inet_connection_sock.h>
55682965
JB
25#include "core.h"
26#include "nl80211.h"
b2e1b302 27#include "reg.h"
e35e4d28 28#include "rdev-ops.h"
55682965 29
5fb628e9
JM
30static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
31 struct genl_info *info,
32 struct cfg80211_crypto_settings *settings,
33 int cipher_limit);
34
f84f771d 35static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991 36 struct genl_info *info);
f84f771d 37static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
38 struct genl_info *info);
39
55682965
JB
40/* the netlink family */
41static struct genl_family nl80211_fam = {
fb4e1568
MH
42 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
43 .name = NL80211_GENL_NAME, /* have users key off the name instead */
44 .hdrsize = 0, /* no private header */
45 .version = 1, /* no particular meaning now */
55682965 46 .maxattr = NL80211_ATTR_MAX,
463d0183 47 .netnsok = true,
4c476991
JB
48 .pre_doit = nl80211_pre_doit,
49 .post_doit = nl80211_post_doit,
55682965
JB
50};
51
2a94fe48
JB
52/* multicast groups */
53enum nl80211_multicast_groups {
54 NL80211_MCGRP_CONFIG,
55 NL80211_MCGRP_SCAN,
56 NL80211_MCGRP_REGULATORY,
57 NL80211_MCGRP_MLME,
567ffc35 58 NL80211_MCGRP_VENDOR,
50bcd31d 59 NL80211_MCGRP_NAN,
2a94fe48
JB
60 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
61};
62
63static const struct genl_multicast_group nl80211_mcgrps[] = {
71b836ec
JB
64 [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
65 [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
66 [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
67 [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
68 [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
50bcd31d 69 [NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
2a94fe48 70#ifdef CONFIG_NL80211_TESTMODE
71b836ec 71 [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
2a94fe48
JB
72#endif
73};
74
89a54e48
JB
75/* returns ERR_PTR values */
76static struct wireless_dev *
77__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
55682965 78{
89a54e48
JB
79 struct cfg80211_registered_device *rdev;
80 struct wireless_dev *result = NULL;
81 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
82 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
83 u64 wdev_id;
84 int wiphy_idx = -1;
85 int ifidx = -1;
55682965 86
5fe231e8 87 ASSERT_RTNL();
55682965 88
89a54e48
JB
89 if (!have_ifidx && !have_wdev_id)
90 return ERR_PTR(-EINVAL);
55682965 91
89a54e48
JB
92 if (have_ifidx)
93 ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
94 if (have_wdev_id) {
95 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
96 wiphy_idx = wdev_id >> 32;
55682965
JB
97 }
98
89a54e48
JB
99 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
100 struct wireless_dev *wdev;
101
102 if (wiphy_net(&rdev->wiphy) != netns)
103 continue;
104
105 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
106 continue;
107
53873f13 108 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
89a54e48
JB
109 if (have_ifidx && wdev->netdev &&
110 wdev->netdev->ifindex == ifidx) {
111 result = wdev;
112 break;
113 }
114 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
115 result = wdev;
116 break;
117 }
118 }
89a54e48
JB
119
120 if (result)
121 break;
122 }
123
124 if (result)
125 return result;
126 return ERR_PTR(-ENODEV);
55682965
JB
127}
128
a9455408 129static struct cfg80211_registered_device *
878d9ec7 130__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
a9455408 131{
7fee4778
JB
132 struct cfg80211_registered_device *rdev = NULL, *tmp;
133 struct net_device *netdev;
a9455408 134
5fe231e8 135 ASSERT_RTNL();
a9455408 136
878d9ec7 137 if (!attrs[NL80211_ATTR_WIPHY] &&
89a54e48
JB
138 !attrs[NL80211_ATTR_IFINDEX] &&
139 !attrs[NL80211_ATTR_WDEV])
7fee4778
JB
140 return ERR_PTR(-EINVAL);
141
878d9ec7 142 if (attrs[NL80211_ATTR_WIPHY])
7fee4778 143 rdev = cfg80211_rdev_by_wiphy_idx(
878d9ec7 144 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
a9455408 145
89a54e48
JB
146 if (attrs[NL80211_ATTR_WDEV]) {
147 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
148 struct wireless_dev *wdev;
149 bool found = false;
150
151 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
152 if (tmp) {
153 /* make sure wdev exists */
53873f13 154 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
89a54e48
JB
155 if (wdev->identifier != (u32)wdev_id)
156 continue;
157 found = true;
158 break;
159 }
89a54e48
JB
160
161 if (!found)
162 tmp = NULL;
163
164 if (rdev && tmp != rdev)
165 return ERR_PTR(-EINVAL);
166 rdev = tmp;
167 }
168 }
169
878d9ec7
JB
170 if (attrs[NL80211_ATTR_IFINDEX]) {
171 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
7a087e74 172
7f2b8562 173 netdev = __dev_get_by_index(netns, ifindex);
7fee4778
JB
174 if (netdev) {
175 if (netdev->ieee80211_ptr)
f26cbf40
ZG
176 tmp = wiphy_to_rdev(
177 netdev->ieee80211_ptr->wiphy);
7fee4778
JB
178 else
179 tmp = NULL;
180
7fee4778
JB
181 /* not wireless device -- return error */
182 if (!tmp)
183 return ERR_PTR(-EINVAL);
184
185 /* mismatch -- return error */
186 if (rdev && tmp != rdev)
187 return ERR_PTR(-EINVAL);
188
189 rdev = tmp;
a9455408 190 }
a9455408 191 }
a9455408 192
4f7eff10
JB
193 if (!rdev)
194 return ERR_PTR(-ENODEV);
a9455408 195
4f7eff10
JB
196 if (netns != wiphy_net(&rdev->wiphy))
197 return ERR_PTR(-ENODEV);
198
199 return rdev;
a9455408
JB
200}
201
202/*
203 * This function returns a pointer to the driver
204 * that the genl_info item that is passed refers to.
a9455408
JB
205 *
206 * The result of this can be a PTR_ERR and hence must
207 * be checked with IS_ERR() for errors.
208 */
209static struct cfg80211_registered_device *
4f7eff10 210cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
a9455408 211{
5fe231e8 212 return __cfg80211_rdev_from_attrs(netns, info->attrs);
a9455408
JB
213}
214
55682965 215/* policy for the attributes */
8cd4d456 216static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
55682965
JB
217 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
218 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 219 .len = 20-1 },
31888487 220 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 221
72bdcf34 222 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 223 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
3d9d1d66
JB
224 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
225 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
226 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
227
b9a5f8ca
JM
228 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
229 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
230 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
231 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 232 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
3057dbfd 233 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
55682965
JB
234
235 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
236 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
237 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 238
e007b857
EP
239 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
240 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
41ade00f 241
b9454e83 242 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
243 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
244 .len = WLAN_MAX_KEY_LEN },
245 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
246 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
247 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 248 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
e31b8213 249 [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
ed1b6cc7
JB
250
251 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
252 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
253 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
254 .len = IEEE80211_MAX_DATA_LEN },
255 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
256 .len = IEEE80211_MAX_DATA_LEN },
5727ef1b
JB
257 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
258 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
259 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
260 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
261 .len = NL80211_MAX_SUPP_RATES },
2ec600d6 262 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
5727ef1b 263 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 264 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 265 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 266 .len = IEEE80211_MAX_MESH_ID_LEN },
2ec600d6 267 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
9f1ba906 268
b2e1b302
LR
269 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
270 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
271
9f1ba906
JM
272 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
273 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
274 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
275 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
276 .len = NL80211_MAX_SUPP_RATES },
50b12f59 277 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 278
24bdd9f4 279 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 280 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 281
6c739419 282 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
9aed3cc1
JM
283
284 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
285 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
286 .len = IEEE80211_MAX_DATA_LEN },
2a519311
JB
287 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
288 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
289
290 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
291 .len = IEEE80211_MAX_SSID_LEN },
292 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
293 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 294 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 295 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
dc6382ce 296 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
eccb8e8f
JB
297 [NL80211_ATTR_STA_FLAGS2] = {
298 .len = sizeof(struct nl80211_sta_flag_update),
299 },
3f77316c 300 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
301 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
302 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
b23aa676
SO
303 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
304 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
305 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 306 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 307 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
67fbb16b
SO
308 [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
309 .len = WLAN_PMKID_LEN },
9588bbd5
JM
310 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
311 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 312 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
313 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
314 .len = IEEE80211_MAX_DATA_LEN },
315 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ffb9eb3d 316 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
d6dc1a38 317 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 318 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 319 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
320 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
321 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 322 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
323 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
324 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 325 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 326 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 327 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 328 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
9c3990aa 329 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
bbe6ad6d 330 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 331 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 332 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
32e9de84 333 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
9946ecfb
JM
334 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
335 .len = IEEE80211_MAX_DATA_LEN },
336 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
337 .len = IEEE80211_MAX_DATA_LEN },
f4b34b55 338 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 339 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 340 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
341 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
342 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
343 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
344 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
345 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 346 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 347 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
348 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
349 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 350 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
351 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
352 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
353 .len = NL80211_HT_CAPABILITY_LEN
354 },
1d9d9213 355 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 356 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 357 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 358 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 359 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
e39e5b5e 360 [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, },
f461be3e 361 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
ed473771 362 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
53cabad7
JB
363 [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
364 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
77765eaf
VT
365 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
366 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
367 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
368 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 369 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
370 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
371 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
372 .len = NL80211_VHT_CAPABILITY_LEN,
373 },
355199e0
JM
374 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
375 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
376 .len = IEEE80211_MAX_DATA_LEN },
5e4b6f56 377 [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
16ef1fe2
SW
378 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
379 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
380 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
9a774c78
AO
381 [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY },
382 [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY },
c01fc9ad
SD
383 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
384 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
5336fa88 385 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 386 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
387 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
388 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
389 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
fa9ffc74
KP
390 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
391 .len = IEEE80211_QOS_MAP_LEN_MAX },
1df4a510
JM
392 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
393 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
df942e7b 394 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
18e5ca65 395 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
34d22ce2 396 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
bab5ab7d 397 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
960d01ac
JB
398 [NL80211_ATTR_TSID] = { .type = NLA_U8 },
399 [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
400 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
18998c38 401 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
ad2b26ab 402 [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
1bdd716c 403 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
4b681c82 404 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
9c748934 405 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
05050753 406 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
34d50519 407 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
38de03d2 408 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
17b94247 409 [NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 },
c6e6a0c8
AE
410 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
411 .len = VHT_MUMIMO_GROUPS_DATA_LEN
412 },
413 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
cb3b7d87
AB
414 [NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 },
415 [NL80211_ATTR_NAN_DUAL] = { .type = NLA_U8 },
a442b761 416 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
55682965
JB
417};
418
e31b8213 419/* policy for the key attributes */
b54452b0 420static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 421 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
422 [NL80211_KEY_IDX] = { .type = NLA_U8 },
423 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 424 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
425 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
426 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
e31b8213 427 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
dbd2fd65
JB
428 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
429};
430
431/* policy for the key default flags */
432static const struct nla_policy
433nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
434 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
435 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
436};
437
ff1b6e69
JB
438/* policy for WoWLAN attributes */
439static const struct nla_policy
440nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
441 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
442 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
443 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
444 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
445 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
446 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
447 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
448 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 449 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 450 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
451};
452
453static const struct nla_policy
454nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
455 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
456 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
457 [NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
458 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
459 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
460 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
461 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
462 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
463 },
464 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
465 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
466 },
467 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
468 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
469 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
ff1b6e69
JB
470};
471
be29b99a
AK
472/* policy for coalesce rule attributes */
473static const struct nla_policy
474nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
475 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
476 [NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U32 },
477 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
478};
479
e5497d76
JB
480/* policy for GTK rekey offload attributes */
481static const struct nla_policy
482nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
483 [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
484 [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
485 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
486};
487
a1f1c21c
LC
488static const struct nla_policy
489nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 490 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 491 .len = IEEE80211_MAX_SSID_LEN },
88e920b4 492 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
a1f1c21c
LC
493};
494
3b06d277
AS
495static const struct nla_policy
496nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
497 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
498 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
499};
500
38de03d2
AS
501static const struct nla_policy
502nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
503 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
504 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
505 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
506 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
507 },
508};
509
a442b761
AB
510/* policy for NAN function attributes */
511static const struct nla_policy
512nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
513 [NL80211_NAN_FUNC_TYPE] = { .type = NLA_U8 },
514 [NL80211_NAN_FUNC_SERVICE_ID] = { .type = NLA_BINARY,
515 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
516 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
517 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
518 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
519 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
520 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
521 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = { .len = ETH_ALEN },
522 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
523 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
524 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
525 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
526 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
527 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
528 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
529 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
530 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
531};
532
533/* policy for Service Response Filter attributes */
534static const struct nla_policy
535nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
536 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
537 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
538 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
539 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
540 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
541};
542
97990a06
JB
543static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
544 struct netlink_callback *cb,
545 struct cfg80211_registered_device **rdev,
546 struct wireless_dev **wdev)
a043897a 547{
97990a06 548 int err;
a043897a 549
97990a06 550 rtnl_lock();
a043897a 551
97990a06
JB
552 if (!cb->args[0]) {
553 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
554 nl80211_fam.attrbuf, nl80211_fam.maxattr,
555 nl80211_policy);
556 if (err)
557 goto out_unlock;
67748893 558
97990a06
JB
559 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
560 nl80211_fam.attrbuf);
561 if (IS_ERR(*wdev)) {
562 err = PTR_ERR(*wdev);
563 goto out_unlock;
564 }
f26cbf40 565 *rdev = wiphy_to_rdev((*wdev)->wiphy);
c319d50b
JB
566 /* 0 is the first index - add 1 to parse only once */
567 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
568 cb->args[1] = (*wdev)->identifier;
569 } else {
c319d50b
JB
570 /* subtract the 1 again here */
571 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
97990a06 572 struct wireless_dev *tmp;
67748893 573
97990a06
JB
574 if (!wiphy) {
575 err = -ENODEV;
576 goto out_unlock;
577 }
f26cbf40 578 *rdev = wiphy_to_rdev(wiphy);
97990a06 579 *wdev = NULL;
67748893 580
53873f13 581 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
582 if (tmp->identifier == cb->args[1]) {
583 *wdev = tmp;
584 break;
585 }
586 }
67748893 587
97990a06
JB
588 if (!*wdev) {
589 err = -ENODEV;
590 goto out_unlock;
591 }
67748893
JB
592 }
593
67748893 594 return 0;
97990a06 595 out_unlock:
67748893
JB
596 rtnl_unlock();
597 return err;
598}
599
97990a06 600static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
67748893 601{
67748893
JB
602 rtnl_unlock();
603}
604
f4a11bb0
JB
605/* IE validation */
606static bool is_valid_ie_attr(const struct nlattr *attr)
607{
608 const u8 *pos;
609 int len;
610
611 if (!attr)
612 return true;
613
614 pos = nla_data(attr);
615 len = nla_len(attr);
616
617 while (len) {
618 u8 elemlen;
619
620 if (len < 2)
621 return false;
622 len -= 2;
623
624 elemlen = pos[1];
625 if (elemlen > len)
626 return false;
627
628 len -= elemlen;
629 pos += 2 + elemlen;
630 }
631
632 return true;
633}
634
55682965 635/* message building helper */
15e47304 636static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
55682965
JB
637 int flags, u8 cmd)
638{
639 /* since there is no private header just add the generic one */
15e47304 640 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
641}
642
5dab3b8a 643static int nl80211_msg_put_channel(struct sk_buff *msg,
cdc89b97
JB
644 struct ieee80211_channel *chan,
645 bool large)
5dab3b8a 646{
ea077c1c
RL
647 /* Some channels must be completely excluded from the
648 * list to protect old user-space tools from breaking
649 */
650 if (!large && chan->flags &
651 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
652 return 0;
653
9360ffd1
DM
654 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
655 chan->center_freq))
656 goto nla_put_failure;
5dab3b8a 657
9360ffd1
DM
658 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
659 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
660 goto nla_put_failure;
8fe02e16
LR
661 if (chan->flags & IEEE80211_CHAN_NO_IR) {
662 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
663 goto nla_put_failure;
664 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
665 goto nla_put_failure;
666 }
cdc89b97
JB
667 if (chan->flags & IEEE80211_CHAN_RADAR) {
668 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
669 goto nla_put_failure;
670 if (large) {
671 u32 time;
672
673 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
674
675 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
676 chan->dfs_state))
677 goto nla_put_failure;
678 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
679 time))
680 goto nla_put_failure;
089027e5
JD
681 if (nla_put_u32(msg,
682 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
683 chan->dfs_cac_ms))
684 goto nla_put_failure;
cdc89b97
JB
685 }
686 }
5dab3b8a 687
fe1abafd
JB
688 if (large) {
689 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
690 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
691 goto nla_put_failure;
692 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
693 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
694 goto nla_put_failure;
695 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
696 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
697 goto nla_put_failure;
698 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
699 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
700 goto nla_put_failure;
570dbde1
DS
701 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
702 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
703 goto nla_put_failure;
06f207fc
AN
704 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
705 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 706 goto nla_put_failure;
ea077c1c
RL
707 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
708 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
709 goto nla_put_failure;
710 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
711 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
712 goto nla_put_failure;
fe1abafd
JB
713 }
714
9360ffd1
DM
715 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
716 DBM_TO_MBM(chan->max_power)))
717 goto nla_put_failure;
5dab3b8a
LR
718
719 return 0;
720
721 nla_put_failure:
722 return -ENOBUFS;
723}
724
55682965
JB
725/* netlink command implementations */
726
b9454e83
JB
727struct key_parse {
728 struct key_params p;
729 int idx;
e31b8213 730 int type;
b9454e83 731 bool def, defmgmt;
dbd2fd65 732 bool def_uni, def_multi;
b9454e83
JB
733};
734
735static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
736{
737 struct nlattr *tb[NL80211_KEY_MAX + 1];
738 int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
739 nl80211_key_policy);
740 if (err)
741 return err;
742
743 k->def = !!tb[NL80211_KEY_DEFAULT];
744 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
745
dbd2fd65
JB
746 if (k->def) {
747 k->def_uni = true;
748 k->def_multi = true;
749 }
750 if (k->defmgmt)
751 k->def_multi = true;
752
b9454e83
JB
753 if (tb[NL80211_KEY_IDX])
754 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
755
756 if (tb[NL80211_KEY_DATA]) {
757 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
758 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
759 }
760
761 if (tb[NL80211_KEY_SEQ]) {
762 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
763 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
764 }
765
766 if (tb[NL80211_KEY_CIPHER])
767 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
768
e31b8213
JB
769 if (tb[NL80211_KEY_TYPE]) {
770 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
771 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
772 return -EINVAL;
773 }
774
dbd2fd65
JB
775 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
776 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 777
2da8f419
JB
778 err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
779 tb[NL80211_KEY_DEFAULT_TYPES],
780 nl80211_key_default_policy);
dbd2fd65
JB
781 if (err)
782 return err;
783
784 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
785 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
786 }
787
b9454e83
JB
788 return 0;
789}
790
791static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
792{
793 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
794 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
795 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
796 }
797
798 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
799 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
800 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
801 }
802
803 if (info->attrs[NL80211_ATTR_KEY_IDX])
804 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
805
806 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
807 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
808
809 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
810 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
811
dbd2fd65
JB
812 if (k->def) {
813 k->def_uni = true;
814 k->def_multi = true;
815 }
816 if (k->defmgmt)
817 k->def_multi = true;
818
e31b8213
JB
819 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
820 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
821 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
822 return -EINVAL;
823 }
824
dbd2fd65
JB
825 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
826 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
827 int err = nla_parse_nested(
828 kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
829 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
830 nl80211_key_default_policy);
831 if (err)
832 return err;
833
834 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
835 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
836 }
837
b9454e83
JB
838 return 0;
839}
840
841static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
842{
843 int err;
844
845 memset(k, 0, sizeof(*k));
846 k->idx = -1;
e31b8213 847 k->type = -1;
b9454e83
JB
848
849 if (info->attrs[NL80211_ATTR_KEY])
850 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
851 else
852 err = nl80211_parse_key_old(info, k);
853
854 if (err)
855 return err;
856
857 if (k->def && k->defmgmt)
858 return -EINVAL;
859
dbd2fd65
JB
860 if (k->defmgmt) {
861 if (k->def_uni || !k->def_multi)
862 return -EINVAL;
863 }
864
b9454e83
JB
865 if (k->idx != -1) {
866 if (k->defmgmt) {
867 if (k->idx < 4 || k->idx > 5)
868 return -EINVAL;
869 } else if (k->def) {
870 if (k->idx < 0 || k->idx > 3)
871 return -EINVAL;
872 } else {
873 if (k->idx < 0 || k->idx > 5)
874 return -EINVAL;
875 }
876 }
877
878 return 0;
879}
880
fffd0934
JB
881static struct cfg80211_cached_keys *
882nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
de7044ee 883 struct nlattr *keys, bool *no_ht)
fffd0934
JB
884{
885 struct key_parse parse;
886 struct nlattr *key;
887 struct cfg80211_cached_keys *result;
888 int rem, err, def = 0;
f1c1f17a
JB
889 bool have_key = false;
890
891 nla_for_each_nested(key, keys, rem) {
892 have_key = true;
893 break;
894 }
895
896 if (!have_key)
897 return NULL;
fffd0934
JB
898
899 result = kzalloc(sizeof(*result), GFP_KERNEL);
900 if (!result)
901 return ERR_PTR(-ENOMEM);
902
903 result->def = -1;
fffd0934
JB
904
905 nla_for_each_nested(key, keys, rem) {
906 memset(&parse, 0, sizeof(parse));
907 parse.idx = -1;
908
909 err = nl80211_parse_key_new(key, &parse);
910 if (err)
911 goto error;
912 err = -EINVAL;
913 if (!parse.p.key)
914 goto error;
42ee231c 915 if (parse.idx < 0 || parse.idx > 3)
fffd0934
JB
916 goto error;
917 if (parse.def) {
918 if (def)
919 goto error;
920 def = 1;
921 result->def = parse.idx;
dbd2fd65
JB
922 if (!parse.def_uni || !parse.def_multi)
923 goto error;
fffd0934
JB
924 } else if (parse.defmgmt)
925 goto error;
926 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 927 parse.idx, false, NULL);
fffd0934
JB
928 if (err)
929 goto error;
386b1f27
JB
930 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
931 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
932 err = -EINVAL;
933 goto error;
934 }
fffd0934
JB
935 result->params[parse.idx].cipher = parse.p.cipher;
936 result->params[parse.idx].key_len = parse.p.key_len;
937 result->params[parse.idx].key = result->data[parse.idx];
938 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 939
386b1f27
JB
940 /* must be WEP key if we got here */
941 if (no_ht)
942 *no_ht = true;
fffd0934
JB
943 }
944
f1c1f17a
JB
945 if (result->def < 0) {
946 err = -EINVAL;
947 goto error;
948 }
949
fffd0934
JB
950 return result;
951 error:
952 kfree(result);
953 return ERR_PTR(err);
954}
955
956static int nl80211_key_allowed(struct wireless_dev *wdev)
957{
958 ASSERT_WDEV_LOCK(wdev);
959
fffd0934
JB
960 switch (wdev->iftype) {
961 case NL80211_IFTYPE_AP:
962 case NL80211_IFTYPE_AP_VLAN:
074ac8df 963 case NL80211_IFTYPE_P2P_GO:
ff973af7 964 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
965 break;
966 case NL80211_IFTYPE_ADHOC:
fffd0934 967 case NL80211_IFTYPE_STATION:
074ac8df 968 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 969 if (!wdev->current_bss)
fffd0934
JB
970 return -ENOLINK;
971 break;
de4fcbad 972 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 973 case NL80211_IFTYPE_OCB:
de4fcbad 974 case NL80211_IFTYPE_MONITOR:
cb3b7d87 975 case NL80211_IFTYPE_NAN:
de4fcbad
JB
976 case NL80211_IFTYPE_P2P_DEVICE:
977 case NL80211_IFTYPE_WDS:
978 case NUM_NL80211_IFTYPES:
fffd0934
JB
979 return -EINVAL;
980 }
981
982 return 0;
983}
984
664834de
JM
985static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
986 struct nlattr *tb)
987{
988 struct ieee80211_channel *chan;
989
990 if (tb == NULL)
991 return NULL;
992 chan = ieee80211_get_channel(wiphy, nla_get_u32(tb));
993 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
994 return NULL;
995 return chan;
996}
997
7527a782
JB
998static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
999{
1000 struct nlattr *nl_modes = nla_nest_start(msg, attr);
1001 int i;
1002
1003 if (!nl_modes)
1004 goto nla_put_failure;
1005
1006 i = 0;
1007 while (ifmodes) {
9360ffd1
DM
1008 if ((ifmodes & 1) && nla_put_flag(msg, i))
1009 goto nla_put_failure;
7527a782
JB
1010 ifmodes >>= 1;
1011 i++;
1012 }
1013
1014 nla_nest_end(msg, nl_modes);
1015 return 0;
1016
1017nla_put_failure:
1018 return -ENOBUFS;
1019}
1020
1021static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1022 struct sk_buff *msg,
1023 bool large)
7527a782
JB
1024{
1025 struct nlattr *nl_combis;
1026 int i, j;
1027
1028 nl_combis = nla_nest_start(msg,
1029 NL80211_ATTR_INTERFACE_COMBINATIONS);
1030 if (!nl_combis)
1031 goto nla_put_failure;
1032
1033 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1034 const struct ieee80211_iface_combination *c;
1035 struct nlattr *nl_combi, *nl_limits;
1036
1037 c = &wiphy->iface_combinations[i];
1038
1039 nl_combi = nla_nest_start(msg, i + 1);
1040 if (!nl_combi)
1041 goto nla_put_failure;
1042
1043 nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
1044 if (!nl_limits)
1045 goto nla_put_failure;
1046
1047 for (j = 0; j < c->n_limits; j++) {
1048 struct nlattr *nl_limit;
1049
1050 nl_limit = nla_nest_start(msg, j + 1);
1051 if (!nl_limit)
1052 goto nla_put_failure;
9360ffd1
DM
1053 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1054 c->limits[j].max))
1055 goto nla_put_failure;
7527a782
JB
1056 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1057 c->limits[j].types))
1058 goto nla_put_failure;
1059 nla_nest_end(msg, nl_limit);
1060 }
1061
1062 nla_nest_end(msg, nl_limits);
1063
9360ffd1
DM
1064 if (c->beacon_int_infra_match &&
1065 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1066 goto nla_put_failure;
1067 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1068 c->num_different_channels) ||
1069 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1070 c->max_interfaces))
1071 goto nla_put_failure;
cdc89b97 1072 if (large &&
8c48b50a
FF
1073 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1074 c->radar_detect_widths) ||
1075 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1076 c->radar_detect_regions)))
cdc89b97 1077 goto nla_put_failure;
0c317a02
PK
1078 if (c->beacon_int_min_gcd &&
1079 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1080 c->beacon_int_min_gcd))
1081 goto nla_put_failure;
7527a782
JB
1082
1083 nla_nest_end(msg, nl_combi);
1084 }
1085
1086 nla_nest_end(msg, nl_combis);
1087
1088 return 0;
1089nla_put_failure:
1090 return -ENOBUFS;
1091}
1092
3713b4e3 1093#ifdef CONFIG_PM
b56cf720
JB
1094static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1095 struct sk_buff *msg)
1096{
964dc9e2 1097 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1098 struct nlattr *nl_tcp;
1099
1100 if (!tcp)
1101 return 0;
1102
1103 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
1104 if (!nl_tcp)
1105 return -ENOBUFS;
1106
1107 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1108 tcp->data_payload_max))
1109 return -ENOBUFS;
1110
1111 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1112 tcp->data_payload_max))
1113 return -ENOBUFS;
1114
1115 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1116 return -ENOBUFS;
1117
1118 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1119 sizeof(*tcp->tok), tcp->tok))
1120 return -ENOBUFS;
1121
1122 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1123 tcp->data_interval_max))
1124 return -ENOBUFS;
1125
1126 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1127 tcp->wake_payload_max))
1128 return -ENOBUFS;
1129
1130 nla_nest_end(msg, nl_tcp);
1131 return 0;
1132}
1133
3713b4e3 1134static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1135 struct cfg80211_registered_device *rdev,
b56cf720 1136 bool large)
55682965 1137{
3713b4e3 1138 struct nlattr *nl_wowlan;
55682965 1139
1b8ec87a 1140 if (!rdev->wiphy.wowlan)
3713b4e3 1141 return 0;
55682965 1142
3713b4e3
JB
1143 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
1144 if (!nl_wowlan)
1145 return -ENOBUFS;
9360ffd1 1146
1b8ec87a 1147 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1148 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1149 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1150 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1151 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1152 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1153 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1154 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1155 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1156 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1157 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1158 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1159 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1160 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1161 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1162 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1163 return -ENOBUFS;
9360ffd1 1164
1b8ec87a 1165 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1166 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1167 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1168 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1169 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1170 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1171 };
9360ffd1 1172
3713b4e3
JB
1173 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1174 sizeof(pat), &pat))
1175 return -ENOBUFS;
1176 }
9360ffd1 1177
75453ccb
LC
1178 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1179 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1180 rdev->wiphy.wowlan->max_nd_match_sets))
1181 return -ENOBUFS;
1182
1b8ec87a 1183 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1184 return -ENOBUFS;
1185
3713b4e3 1186 nla_nest_end(msg, nl_wowlan);
9360ffd1 1187
3713b4e3
JB
1188 return 0;
1189}
1190#endif
9360ffd1 1191
be29b99a 1192static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1193 struct cfg80211_registered_device *rdev)
be29b99a
AK
1194{
1195 struct nl80211_coalesce_rule_support rule;
1196
1b8ec87a 1197 if (!rdev->wiphy.coalesce)
be29b99a
AK
1198 return 0;
1199
1b8ec87a
ZG
1200 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1201 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1202 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1203 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1204 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1205 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1206
1207 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1208 return -ENOBUFS;
1209
1210 return 0;
1211}
1212
3713b4e3
JB
1213static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1214 struct ieee80211_supported_band *sband)
1215{
1216 struct nlattr *nl_rates, *nl_rate;
1217 struct ieee80211_rate *rate;
1218 int i;
87bbbe22 1219
3713b4e3
JB
1220 /* add HT info */
1221 if (sband->ht_cap.ht_supported &&
1222 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1223 sizeof(sband->ht_cap.mcs),
1224 &sband->ht_cap.mcs) ||
1225 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1226 sband->ht_cap.cap) ||
1227 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1228 sband->ht_cap.ampdu_factor) ||
1229 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1230 sband->ht_cap.ampdu_density)))
1231 return -ENOBUFS;
afe0cbf8 1232
3713b4e3
JB
1233 /* add VHT info */
1234 if (sband->vht_cap.vht_supported &&
1235 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1236 sizeof(sband->vht_cap.vht_mcs),
1237 &sband->vht_cap.vht_mcs) ||
1238 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1239 sband->vht_cap.cap)))
1240 return -ENOBUFS;
f59ac048 1241
3713b4e3
JB
1242 /* add bitrates */
1243 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
1244 if (!nl_rates)
1245 return -ENOBUFS;
ee688b00 1246
3713b4e3
JB
1247 for (i = 0; i < sband->n_bitrates; i++) {
1248 nl_rate = nla_nest_start(msg, i);
1249 if (!nl_rate)
1250 return -ENOBUFS;
ee688b00 1251
3713b4e3
JB
1252 rate = &sband->bitrates[i];
1253 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1254 rate->bitrate))
1255 return -ENOBUFS;
1256 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1257 nla_put_flag(msg,
1258 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1259 return -ENOBUFS;
ee688b00 1260
3713b4e3
JB
1261 nla_nest_end(msg, nl_rate);
1262 }
d51626df 1263
3713b4e3 1264 nla_nest_end(msg, nl_rates);
bf0c111e 1265
3713b4e3
JB
1266 return 0;
1267}
ee688b00 1268
3713b4e3
JB
1269static int
1270nl80211_send_mgmt_stypes(struct sk_buff *msg,
1271 const struct ieee80211_txrx_stypes *mgmt_stypes)
1272{
1273 u16 stypes;
1274 struct nlattr *nl_ftypes, *nl_ifs;
1275 enum nl80211_iftype ift;
1276 int i;
ee688b00 1277
3713b4e3
JB
1278 if (!mgmt_stypes)
1279 return 0;
5dab3b8a 1280
3713b4e3
JB
1281 nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES);
1282 if (!nl_ifs)
1283 return -ENOBUFS;
e2f367f2 1284
3713b4e3
JB
1285 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1286 nl_ftypes = nla_nest_start(msg, ift);
1287 if (!nl_ftypes)
1288 return -ENOBUFS;
1289 i = 0;
1290 stypes = mgmt_stypes[ift].tx;
1291 while (stypes) {
1292 if ((stypes & 1) &&
1293 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1294 (i << 4) | IEEE80211_FTYPE_MGMT))
1295 return -ENOBUFS;
1296 stypes >>= 1;
1297 i++;
ee688b00 1298 }
3713b4e3
JB
1299 nla_nest_end(msg, nl_ftypes);
1300 }
ee688b00 1301
3713b4e3 1302 nla_nest_end(msg, nl_ifs);
ee688b00 1303
3713b4e3
JB
1304 nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES);
1305 if (!nl_ifs)
1306 return -ENOBUFS;
ee688b00 1307
3713b4e3
JB
1308 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1309 nl_ftypes = nla_nest_start(msg, ift);
1310 if (!nl_ftypes)
1311 return -ENOBUFS;
1312 i = 0;
1313 stypes = mgmt_stypes[ift].rx;
1314 while (stypes) {
1315 if ((stypes & 1) &&
1316 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1317 (i << 4) | IEEE80211_FTYPE_MGMT))
1318 return -ENOBUFS;
1319 stypes >>= 1;
1320 i++;
1321 }
1322 nla_nest_end(msg, nl_ftypes);
1323 }
1324 nla_nest_end(msg, nl_ifs);
ee688b00 1325
3713b4e3
JB
1326 return 0;
1327}
ee688b00 1328
86e8cf98
JB
1329struct nl80211_dump_wiphy_state {
1330 s64 filter_wiphy;
1331 long start;
019ae3a9 1332 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
1333 bool split;
1334};
1335
1b8ec87a 1336static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 1337 enum nl80211_commands cmd,
3713b4e3 1338 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 1339 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
1340{
1341 void *hdr;
1342 struct nlattr *nl_bands, *nl_band;
1343 struct nlattr *nl_freqs, *nl_freq;
1344 struct nlattr *nl_cmds;
57fbcce3 1345 enum nl80211_band band;
3713b4e3
JB
1346 struct ieee80211_channel *chan;
1347 int i;
1348 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 1349 rdev->wiphy.mgmt_stypes;
fe1abafd 1350 u32 features;
ee688b00 1351
3bb20556 1352 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
1353 if (!hdr)
1354 return -ENOBUFS;
ee688b00 1355
86e8cf98
JB
1356 if (WARN_ON(!state))
1357 return -EINVAL;
ee688b00 1358
1b8ec87a 1359 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 1360 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 1361 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
1362 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1363 cfg80211_rdev_list_generation))
8fdc621d
JB
1364 goto nla_put_failure;
1365
3bb20556
JB
1366 if (cmd != NL80211_CMD_NEW_WIPHY)
1367 goto finish;
1368
86e8cf98 1369 switch (state->split_start) {
3713b4e3
JB
1370 case 0:
1371 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 1372 rdev->wiphy.retry_short) ||
3713b4e3 1373 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 1374 rdev->wiphy.retry_long) ||
3713b4e3 1375 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 1376 rdev->wiphy.frag_threshold) ||
3713b4e3 1377 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 1378 rdev->wiphy.rts_threshold) ||
3713b4e3 1379 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 1380 rdev->wiphy.coverage_class) ||
3713b4e3 1381 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 1382 rdev->wiphy.max_scan_ssids) ||
3713b4e3 1383 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 1384 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 1385 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 1386 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 1387 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 1388 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 1389 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
3b06d277
AS
1390 rdev->wiphy.max_match_sets) ||
1391 nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
1392 rdev->wiphy.max_sched_scan_plans) ||
1393 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
1394 rdev->wiphy.max_sched_scan_plan_interval) ||
1395 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
1396 rdev->wiphy.max_sched_scan_plan_iterations))
9360ffd1 1397 goto nla_put_failure;
3713b4e3 1398
1b8ec87a 1399 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 1400 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 1401 goto nla_put_failure;
1b8ec87a 1402 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
1403 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
1404 goto nla_put_failure;
1b8ec87a 1405 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
1406 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
1407 goto nla_put_failure;
1b8ec87a 1408 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
1409 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
1410 goto nla_put_failure;
1b8ec87a 1411 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
1412 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
1413 goto nla_put_failure;
1b8ec87a 1414 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 1415 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 1416 goto nla_put_failure;
86e8cf98
JB
1417 state->split_start++;
1418 if (state->split)
3713b4e3
JB
1419 break;
1420 case 1:
1421 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
1422 sizeof(u32) * rdev->wiphy.n_cipher_suites,
1423 rdev->wiphy.cipher_suites))
3713b4e3 1424 goto nla_put_failure;
4745fc09 1425
3713b4e3 1426 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 1427 rdev->wiphy.max_num_pmkids))
3713b4e3 1428 goto nla_put_failure;
b23aa676 1429
1b8ec87a 1430 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 1431 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 1432 goto nla_put_failure;
b23aa676 1433
3713b4e3 1434 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 1435 rdev->wiphy.available_antennas_tx) ||
3713b4e3 1436 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 1437 rdev->wiphy.available_antennas_rx))
9360ffd1 1438 goto nla_put_failure;
b23aa676 1439
1b8ec87a 1440 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 1441 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 1442 rdev->wiphy.probe_resp_offload))
3713b4e3 1443 goto nla_put_failure;
8fdc621d 1444
1b8ec87a
ZG
1445 if ((rdev->wiphy.available_antennas_tx ||
1446 rdev->wiphy.available_antennas_rx) &&
1447 rdev->ops->get_antenna) {
3713b4e3
JB
1448 u32 tx_ant = 0, rx_ant = 0;
1449 int res;
7a087e74 1450
1b8ec87a 1451 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
1452 if (!res) {
1453 if (nla_put_u32(msg,
1454 NL80211_ATTR_WIPHY_ANTENNA_TX,
1455 tx_ant) ||
1456 nla_put_u32(msg,
1457 NL80211_ATTR_WIPHY_ANTENNA_RX,
1458 rx_ant))
1459 goto nla_put_failure;
1460 }
1461 }
a293911d 1462
86e8cf98
JB
1463 state->split_start++;
1464 if (state->split)
3713b4e3
JB
1465 break;
1466 case 2:
1467 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 1468 rdev->wiphy.interface_modes))
3713b4e3 1469 goto nla_put_failure;
86e8cf98
JB
1470 state->split_start++;
1471 if (state->split)
3713b4e3
JB
1472 break;
1473 case 3:
1474 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1475 if (!nl_bands)
1476 goto nla_put_failure;
f7ca38df 1477
86e8cf98 1478 for (band = state->band_start;
57fbcce3 1479 band < NUM_NL80211_BANDS; band++) {
3713b4e3 1480 struct ieee80211_supported_band *sband;
2e161f78 1481
1b8ec87a 1482 sband = rdev->wiphy.bands[band];
2e161f78 1483
3713b4e3
JB
1484 if (!sband)
1485 continue;
1486
1487 nl_band = nla_nest_start(msg, band);
1488 if (!nl_band)
2e161f78 1489 goto nla_put_failure;
3713b4e3 1490
86e8cf98 1491 switch (state->chan_start) {
3713b4e3
JB
1492 case 0:
1493 if (nl80211_send_band_rateinfo(msg, sband))
9360ffd1 1494 goto nla_put_failure;
86e8cf98
JB
1495 state->chan_start++;
1496 if (state->split)
3713b4e3
JB
1497 break;
1498 default:
1499 /* add frequencies */
1500 nl_freqs = nla_nest_start(
1501 msg, NL80211_BAND_ATTR_FREQS);
1502 if (!nl_freqs)
1503 goto nla_put_failure;
1504
86e8cf98 1505 for (i = state->chan_start - 1;
3713b4e3
JB
1506 i < sband->n_channels;
1507 i++) {
1508 nl_freq = nla_nest_start(msg, i);
1509 if (!nl_freq)
1510 goto nla_put_failure;
1511
1512 chan = &sband->channels[i];
1513
86e8cf98
JB
1514 if (nl80211_msg_put_channel(
1515 msg, chan,
1516 state->split))
3713b4e3
JB
1517 goto nla_put_failure;
1518
1519 nla_nest_end(msg, nl_freq);
86e8cf98 1520 if (state->split)
3713b4e3
JB
1521 break;
1522 }
1523 if (i < sband->n_channels)
86e8cf98 1524 state->chan_start = i + 2;
3713b4e3 1525 else
86e8cf98 1526 state->chan_start = 0;
3713b4e3
JB
1527 nla_nest_end(msg, nl_freqs);
1528 }
1529
1530 nla_nest_end(msg, nl_band);
1531
86e8cf98 1532 if (state->split) {
3713b4e3 1533 /* start again here */
86e8cf98 1534 if (state->chan_start)
3713b4e3
JB
1535 band--;
1536 break;
2e161f78 1537 }
2e161f78 1538 }
3713b4e3 1539 nla_nest_end(msg, nl_bands);
2e161f78 1540
57fbcce3 1541 if (band < NUM_NL80211_BANDS)
86e8cf98 1542 state->band_start = band + 1;
3713b4e3 1543 else
86e8cf98 1544 state->band_start = 0;
74b70a4e 1545
3713b4e3 1546 /* if bands & channels are done, continue outside */
86e8cf98
JB
1547 if (state->band_start == 0 && state->chan_start == 0)
1548 state->split_start++;
1549 if (state->split)
3713b4e3
JB
1550 break;
1551 case 4:
1552 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
1553 if (!nl_cmds)
2e161f78
JB
1554 goto nla_put_failure;
1555
3713b4e3
JB
1556 i = 0;
1557#define CMD(op, n) \
1558 do { \
1b8ec87a 1559 if (rdev->ops->op) { \
3713b4e3
JB
1560 i++; \
1561 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1562 goto nla_put_failure; \
1563 } \
1564 } while (0)
1565
1566 CMD(add_virtual_intf, NEW_INTERFACE);
1567 CMD(change_virtual_intf, SET_INTERFACE);
1568 CMD(add_key, NEW_KEY);
1569 CMD(start_ap, START_AP);
1570 CMD(add_station, NEW_STATION);
1571 CMD(add_mpath, NEW_MPATH);
1572 CMD(update_mesh_config, SET_MESH_CONFIG);
1573 CMD(change_bss, SET_BSS);
1574 CMD(auth, AUTHENTICATE);
1575 CMD(assoc, ASSOCIATE);
1576 CMD(deauth, DEAUTHENTICATE);
1577 CMD(disassoc, DISASSOCIATE);
1578 CMD(join_ibss, JOIN_IBSS);
1579 CMD(join_mesh, JOIN_MESH);
1580 CMD(set_pmksa, SET_PMKSA);
1581 CMD(del_pmksa, DEL_PMKSA);
1582 CMD(flush_pmksa, FLUSH_PMKSA);
1b8ec87a 1583 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
3713b4e3
JB
1584 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1585 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1586 CMD(mgmt_tx, FRAME);
1587 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1b8ec87a 1588 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
3713b4e3
JB
1589 i++;
1590 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
2e161f78 1591 goto nla_put_failure;
2e161f78 1592 }
1b8ec87a
ZG
1593 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
1594 rdev->ops->join_mesh) {
3713b4e3
JB
1595 i++;
1596 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1597 goto nla_put_failure;
1598 }
1599 CMD(set_wds_peer, SET_WDS_PEER);
1b8ec87a 1600 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
3713b4e3
JB
1601 CMD(tdls_mgmt, TDLS_MGMT);
1602 CMD(tdls_oper, TDLS_OPER);
1603 }
1b8ec87a 1604 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
3713b4e3
JB
1605 CMD(sched_scan_start, START_SCHED_SCAN);
1606 CMD(probe_client, PROBE_CLIENT);
1607 CMD(set_noack_map, SET_NOACK_MAP);
1b8ec87a 1608 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
3713b4e3
JB
1609 i++;
1610 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1611 goto nla_put_failure;
1612 }
1613 CMD(start_p2p_device, START_P2P_DEVICE);
1614 CMD(set_mcast_rate, SET_MCAST_RATE);
02df00eb
JB
1615#ifdef CONFIG_NL80211_TESTMODE
1616 CMD(testmode_cmd, TESTMODE);
1617#endif
86e8cf98 1618 if (state->split) {
5de17984
AS
1619 CMD(crit_proto_start, CRIT_PROTOCOL_START);
1620 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 1621 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 1622 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 1623 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
1624 if (rdev->wiphy.features &
1625 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 1626 CMD(add_tx_ts, ADD_TX_TS);
5de17984 1627 }
02df00eb 1628 /* add into the if now */
3713b4e3 1629#undef CMD
ff1b6e69 1630
1b8ec87a 1631 if (rdev->ops->connect || rdev->ops->auth) {
3713b4e3
JB
1632 i++;
1633 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
9360ffd1 1634 goto nla_put_failure;
ff1b6e69
JB
1635 }
1636
1b8ec87a 1637 if (rdev->ops->disconnect || rdev->ops->deauth) {
3713b4e3
JB
1638 i++;
1639 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1640 goto nla_put_failure;
1641 }
1642
1643 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
1644 state->split_start++;
1645 if (state->split)
3713b4e3
JB
1646 break;
1647 case 5:
1b8ec87a
ZG
1648 if (rdev->ops->remain_on_channel &&
1649 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
1650 nla_put_u32(msg,
1651 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 1652 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
1653 goto nla_put_failure;
1654
1b8ec87a 1655 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
1656 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
1657 goto nla_put_failure;
1658
1659 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
1660 goto nla_put_failure;
86e8cf98
JB
1661 state->split_start++;
1662 if (state->split)
3713b4e3
JB
1663 break;
1664 case 6:
1665#ifdef CONFIG_PM
1b8ec87a 1666 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 1667 goto nla_put_failure;
86e8cf98
JB
1668 state->split_start++;
1669 if (state->split)
3713b4e3
JB
1670 break;
1671#else
86e8cf98 1672 state->split_start++;
dfb89c56 1673#endif
3713b4e3
JB
1674 case 7:
1675 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 1676 rdev->wiphy.software_iftypes))
3713b4e3 1677 goto nla_put_failure;
ff1b6e69 1678
1b8ec87a 1679 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 1680 state->split))
3713b4e3 1681 goto nla_put_failure;
7527a782 1682
86e8cf98
JB
1683 state->split_start++;
1684 if (state->split)
3713b4e3
JB
1685 break;
1686 case 8:
1b8ec87a 1687 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 1688 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 1689 rdev->wiphy.ap_sme_capa))
3713b4e3 1690 goto nla_put_failure;
7527a782 1691
1b8ec87a 1692 features = rdev->wiphy.features;
fe1abafd
JB
1693 /*
1694 * We can only add the per-channel limit information if the
1695 * dump is split, otherwise it makes it too big. Therefore
1696 * only advertise it in that case.
1697 */
86e8cf98 1698 if (state->split)
fe1abafd
JB
1699 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
1700 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 1701 goto nla_put_failure;
562a7480 1702
1b8ec87a 1703 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 1704 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
1705 sizeof(*rdev->wiphy.ht_capa_mod_mask),
1706 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 1707 goto nla_put_failure;
1f074bd8 1708
1b8ec87a
ZG
1709 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
1710 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 1711 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 1712 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 1713 goto nla_put_failure;
7e7c8926 1714
3713b4e3
JB
1715 /*
1716 * Any information below this point is only available to
1717 * applications that can deal with it being split. This
1718 * helps ensure that newly added capabilities don't break
1719 * older tools by overrunning their buffers.
1720 *
1721 * We still increment split_start so that in the split
1722 * case we'll continue with more data in the next round,
1723 * but break unconditionally so unsplit data stops here.
1724 */
86e8cf98 1725 state->split_start++;
3713b4e3
JB
1726 break;
1727 case 9:
1b8ec87a 1728 if (rdev->wiphy.extended_capabilities &&
fe1abafd 1729 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
1730 rdev->wiphy.extended_capabilities_len,
1731 rdev->wiphy.extended_capabilities) ||
fe1abafd 1732 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
1733 rdev->wiphy.extended_capabilities_len,
1734 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 1735 goto nla_put_failure;
a50df0c4 1736
1b8ec87a 1737 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 1738 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
1739 sizeof(*rdev->wiphy.vht_capa_mod_mask),
1740 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
1741 goto nla_put_failure;
1742
be29b99a
AK
1743 state->split_start++;
1744 break;
1745 case 10:
1b8ec87a 1746 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
1747 goto nla_put_failure;
1748
1b8ec87a 1749 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
1750 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
1751 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
1752 goto nla_put_failure;
b43504cf 1753
1b8ec87a 1754 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 1755 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 1756 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
1757 goto nla_put_failure;
1758
ad7e718c
JB
1759 state->split_start++;
1760 break;
1761 case 11:
1b8ec87a 1762 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
1763 const struct nl80211_vendor_cmd_info *info;
1764 struct nlattr *nested;
1765
1766 nested = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1767 if (!nested)
1768 goto nla_put_failure;
1769
1b8ec87a
ZG
1770 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
1771 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
1772 if (nla_put(msg, i + 1, sizeof(*info), info))
1773 goto nla_put_failure;
1774 }
1775 nla_nest_end(msg, nested);
1776 }
1777
1b8ec87a 1778 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
1779 const struct nl80211_vendor_cmd_info *info;
1780 struct nlattr *nested;
ad7e718c 1781
567ffc35
JB
1782 nested = nla_nest_start(msg,
1783 NL80211_ATTR_VENDOR_EVENTS);
1784 if (!nested)
ad7e718c 1785 goto nla_put_failure;
567ffc35 1786
1b8ec87a
ZG
1787 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
1788 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
1789 if (nla_put(msg, i + 1, sizeof(*info), info))
1790 goto nla_put_failure;
1791 }
1792 nla_nest_end(msg, nested);
1793 }
9a774c78
AO
1794 state->split_start++;
1795 break;
1796 case 12:
1797 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
1798 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
1799 rdev->wiphy.max_num_csa_counters))
1800 goto nla_put_failure;
01e0daa4 1801
1bdd716c
AN
1802 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
1803 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
1804 goto nla_put_failure;
1805
d75bb06b
GKS
1806 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
1807 sizeof(rdev->wiphy.ext_features),
1808 rdev->wiphy.ext_features))
1809 goto nla_put_failure;
1810
38de03d2
AS
1811 if (rdev->wiphy.bss_select_support) {
1812 struct nlattr *nested;
1813 u32 bss_select_support = rdev->wiphy.bss_select_support;
1814
1815 nested = nla_nest_start(msg, NL80211_ATTR_BSS_SELECT);
1816 if (!nested)
1817 goto nla_put_failure;
1818
1819 i = 0;
1820 while (bss_select_support) {
1821 if ((bss_select_support & 1) &&
1822 nla_put_flag(msg, i))
1823 goto nla_put_failure;
1824 i++;
1825 bss_select_support >>= 1;
1826 }
1827 nla_nest_end(msg, nested);
1828 }
1829
019ae3a9
KV
1830 state->split_start++;
1831 break;
1832 case 13:
1833 if (rdev->wiphy.num_iftype_ext_capab &&
1834 rdev->wiphy.iftype_ext_capab) {
1835 struct nlattr *nested_ext_capab, *nested;
1836
1837 nested = nla_nest_start(msg,
1838 NL80211_ATTR_IFTYPE_EXT_CAPA);
1839 if (!nested)
1840 goto nla_put_failure;
1841
1842 for (i = state->capa_start;
1843 i < rdev->wiphy.num_iftype_ext_capab; i++) {
1844 const struct wiphy_iftype_ext_capab *capab;
1845
1846 capab = &rdev->wiphy.iftype_ext_capab[i];
1847
1848 nested_ext_capab = nla_nest_start(msg, i);
1849 if (!nested_ext_capab ||
1850 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
1851 capab->iftype) ||
1852 nla_put(msg, NL80211_ATTR_EXT_CAPA,
1853 capab->extended_capabilities_len,
1854 capab->extended_capabilities) ||
1855 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1856 capab->extended_capabilities_len,
1857 capab->extended_capabilities_mask))
1858 goto nla_put_failure;
1859
1860 nla_nest_end(msg, nested_ext_capab);
1861 if (state->split)
1862 break;
1863 }
1864 nla_nest_end(msg, nested);
1865 if (i < rdev->wiphy.num_iftype_ext_capab) {
1866 state->capa_start = i + 1;
1867 break;
1868 }
1869 }
1870
3713b4e3 1871 /* done */
86e8cf98 1872 state->split_start = 0;
3713b4e3
JB
1873 break;
1874 }
3bb20556 1875 finish:
053c095a
JB
1876 genlmsg_end(msg, hdr);
1877 return 0;
55682965
JB
1878
1879 nla_put_failure:
bc3ed28c
TG
1880 genlmsg_cancel(msg, hdr);
1881 return -EMSGSIZE;
55682965
JB
1882}
1883
86e8cf98
JB
1884static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
1885 struct netlink_callback *cb,
1886 struct nl80211_dump_wiphy_state *state)
1887{
1888 struct nlattr **tb = nl80211_fam.attrbuf;
1889 int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1890 tb, nl80211_fam.maxattr, nl80211_policy);
1891 /* ignore parse errors for backward compatibility */
1892 if (ret)
1893 return 0;
1894
1895 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
1896 if (tb[NL80211_ATTR_WIPHY])
1897 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1898 if (tb[NL80211_ATTR_WDEV])
1899 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
1900 if (tb[NL80211_ATTR_IFINDEX]) {
1901 struct net_device *netdev;
1902 struct cfg80211_registered_device *rdev;
1903 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1904
7f2b8562 1905 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
86e8cf98
JB
1906 if (!netdev)
1907 return -ENODEV;
1908 if (netdev->ieee80211_ptr) {
f26cbf40 1909 rdev = wiphy_to_rdev(
86e8cf98
JB
1910 netdev->ieee80211_ptr->wiphy);
1911 state->filter_wiphy = rdev->wiphy_idx;
1912 }
86e8cf98
JB
1913 }
1914
1915 return 0;
1916}
1917
55682965
JB
1918static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1919{
645e77de 1920 int idx = 0, ret;
86e8cf98 1921 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 1922 struct cfg80211_registered_device *rdev;
3a5a423b 1923
5fe231e8 1924 rtnl_lock();
86e8cf98
JB
1925 if (!state) {
1926 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
1927 if (!state) {
1928 rtnl_unlock();
86e8cf98 1929 return -ENOMEM;
3713b4e3 1930 }
86e8cf98
JB
1931 state->filter_wiphy = -1;
1932 ret = nl80211_dump_wiphy_parse(skb, cb, state);
1933 if (ret) {
1934 kfree(state);
1935 rtnl_unlock();
1936 return ret;
3713b4e3 1937 }
86e8cf98 1938 cb->args[0] = (long)state;
3713b4e3
JB
1939 }
1940
1b8ec87a
ZG
1941 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1942 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 1943 continue;
86e8cf98 1944 if (++idx <= state->start)
55682965 1945 continue;
86e8cf98 1946 if (state->filter_wiphy != -1 &&
1b8ec87a 1947 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
1948 continue;
1949 /* attempt to fit multiple wiphy data chunks into the skb */
1950 do {
3bb20556
JB
1951 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
1952 skb,
3713b4e3
JB
1953 NETLINK_CB(cb->skb).portid,
1954 cb->nlh->nlmsg_seq,
86e8cf98 1955 NLM_F_MULTI, state);
3713b4e3
JB
1956 if (ret < 0) {
1957 /*
1958 * If sending the wiphy data didn't fit (ENOBUFS
1959 * or EMSGSIZE returned), this SKB is still
1960 * empty (so it's not too big because another
1961 * wiphy dataset is already in the skb) and
1962 * we've not tried to adjust the dump allocation
1963 * yet ... then adjust the alloc size to be
1964 * bigger, and return 1 but with the empty skb.
1965 * This results in an empty message being RX'ed
1966 * in userspace, but that is ignored.
1967 *
1968 * We can then retry with the larger buffer.
1969 */
1970 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 1971 !skb->len && !state->split &&
3713b4e3
JB
1972 cb->min_dump_alloc < 4096) {
1973 cb->min_dump_alloc = 4096;
f12cb289 1974 state->split_start = 0;
d98cae64 1975 rtnl_unlock();
3713b4e3
JB
1976 return 1;
1977 }
1978 idx--;
1979 break;
645e77de 1980 }
86e8cf98 1981 } while (state->split_start > 0);
3713b4e3 1982 break;
55682965 1983 }
5fe231e8 1984 rtnl_unlock();
55682965 1985
86e8cf98 1986 state->start = idx;
55682965
JB
1987
1988 return skb->len;
1989}
1990
86e8cf98
JB
1991static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
1992{
1993 kfree((void *)cb->args[0]);
1994 return 0;
1995}
1996
55682965
JB
1997static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
1998{
1999 struct sk_buff *msg;
1b8ec87a 2000 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 2001 struct nl80211_dump_wiphy_state state = {};
55682965 2002
645e77de 2003 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 2004 if (!msg)
4c476991 2005 return -ENOMEM;
55682965 2006
3bb20556
JB
2007 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
2008 info->snd_portid, info->snd_seq, 0,
86e8cf98 2009 &state) < 0) {
4c476991
JB
2010 nlmsg_free(msg);
2011 return -ENOBUFS;
2012 }
55682965 2013
134e6375 2014 return genlmsg_reply(msg, info);
55682965
JB
2015}
2016
31888487
JM
2017static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
2018 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
2019 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
2020 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
2021 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
2022 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
2023};
2024
2025static int parse_txq_params(struct nlattr *tb[],
2026 struct ieee80211_txq_params *txq_params)
2027{
a3304b0a 2028 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
2029 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
2030 !tb[NL80211_TXQ_ATTR_AIFS])
2031 return -EINVAL;
2032
a3304b0a 2033 txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
2034 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
2035 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
2036 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
2037 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
2038
a3304b0a
JB
2039 if (txq_params->ac >= NL80211_NUM_ACS)
2040 return -EINVAL;
2041
31888487
JM
2042 return 0;
2043}
2044
f444de05
JB
2045static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2046{
2047 /*
cc1d2806
JB
2048 * You can only set the channel explicitly for WDS interfaces,
2049 * all others have their channel managed via their respective
2050 * "establish a connection" command (connect, join, ...)
2051 *
2052 * For AP/GO and mesh mode, the channel can be set with the
2053 * channel userspace API, but is only stored and passed to the
2054 * low-level driver when the AP starts or the mesh is joined.
2055 * This is for backward compatibility, userspace can also give
2056 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
2057 *
2058 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
2059 * whatever else is going on, so they have their own special
2060 * operation to set the monitor channel if possible.
f444de05
JB
2061 */
2062 return !wdev ||
2063 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 2064 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
2065 wdev->iftype == NL80211_IFTYPE_MONITOR ||
2066 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
2067}
2068
683b6d3b
JB
2069static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2070 struct genl_info *info,
2071 struct cfg80211_chan_def *chandef)
2072{
dbeca2ea 2073 u32 control_freq;
683b6d3b
JB
2074
2075 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
2076 return -EINVAL;
2077
2078 control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
2079
2080 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
3d9d1d66
JB
2081 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
2082 chandef->center_freq1 = control_freq;
2083 chandef->center_freq2 = 0;
683b6d3b
JB
2084
2085 /* Primary channel not allowed */
2086 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
2087 return -EINVAL;
2088
3d9d1d66
JB
2089 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2090 enum nl80211_channel_type chantype;
2091
2092 chantype = nla_get_u32(
2093 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
2094
2095 switch (chantype) {
2096 case NL80211_CHAN_NO_HT:
2097 case NL80211_CHAN_HT20:
2098 case NL80211_CHAN_HT40PLUS:
2099 case NL80211_CHAN_HT40MINUS:
2100 cfg80211_chandef_create(chandef, chandef->chan,
2101 chantype);
2102 break;
2103 default:
2104 return -EINVAL;
2105 }
2106 } else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
2107 chandef->width =
2108 nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]);
2109 if (info->attrs[NL80211_ATTR_CENTER_FREQ1])
2110 chandef->center_freq1 =
2111 nla_get_u32(
2112 info->attrs[NL80211_ATTR_CENTER_FREQ1]);
2113 if (info->attrs[NL80211_ATTR_CENTER_FREQ2])
2114 chandef->center_freq2 =
2115 nla_get_u32(
2116 info->attrs[NL80211_ATTR_CENTER_FREQ2]);
2117 }
2118
9f5e8f6e 2119 if (!cfg80211_chandef_valid(chandef))
3d9d1d66
JB
2120 return -EINVAL;
2121
9f5e8f6e
JB
2122 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
2123 IEEE80211_CHAN_DISABLED))
3d9d1d66
JB
2124 return -EINVAL;
2125
2f301ab2
SW
2126 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
2127 chandef->width == NL80211_CHAN_WIDTH_10) &&
2128 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ))
2129 return -EINVAL;
2130
683b6d3b
JB
2131 return 0;
2132}
2133
f444de05 2134static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 2135 struct net_device *dev,
f444de05
JB
2136 struct genl_info *info)
2137{
683b6d3b 2138 struct cfg80211_chan_def chandef;
f444de05 2139 int result;
e8c9bd5b 2140 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 2141 struct wireless_dev *wdev = NULL;
e8c9bd5b 2142
e16821bc
JM
2143 if (dev)
2144 wdev = dev->ieee80211_ptr;
f444de05
JB
2145 if (!nl80211_can_set_dev_channel(wdev))
2146 return -EOPNOTSUPP;
e16821bc
JM
2147 if (wdev)
2148 iftype = wdev->iftype;
f444de05 2149
683b6d3b
JB
2150 result = nl80211_parse_chandef(rdev, info, &chandef);
2151 if (result)
2152 return result;
f444de05 2153
e8c9bd5b 2154 switch (iftype) {
aa430da4
JB
2155 case NL80211_IFTYPE_AP:
2156 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
2157 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
2158 iftype)) {
aa430da4
JB
2159 result = -EINVAL;
2160 break;
2161 }
e16821bc
JM
2162 if (wdev->beacon_interval) {
2163 if (!dev || !rdev->ops->set_ap_chanwidth ||
2164 !(rdev->wiphy.features &
2165 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
2166 result = -EBUSY;
2167 break;
2168 }
2169
2170 /* Only allow dynamic channel width changes */
2171 if (chandef.chan != wdev->preset_chandef.chan) {
2172 result = -EBUSY;
2173 break;
2174 }
2175 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
2176 if (result)
2177 break;
2178 }
683b6d3b 2179 wdev->preset_chandef = chandef;
aa430da4
JB
2180 result = 0;
2181 break;
cc1d2806 2182 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 2183 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 2184 break;
e8c9bd5b 2185 case NL80211_IFTYPE_MONITOR:
683b6d3b 2186 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 2187 break;
aa430da4 2188 default:
e8c9bd5b 2189 result = -EINVAL;
f444de05 2190 }
f444de05
JB
2191
2192 return result;
2193}
2194
2195static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
2196{
4c476991
JB
2197 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2198 struct net_device *netdev = info->user_ptr[1];
f444de05 2199
e16821bc 2200 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
2201}
2202
e8347eba
BJ
2203static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
2204{
43b19952
JB
2205 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2206 struct net_device *dev = info->user_ptr[1];
2207 struct wireless_dev *wdev = dev->ieee80211_ptr;
388ac775 2208 const u8 *bssid;
e8347eba
BJ
2209
2210 if (!info->attrs[NL80211_ATTR_MAC])
2211 return -EINVAL;
2212
43b19952
JB
2213 if (netif_running(dev))
2214 return -EBUSY;
e8347eba 2215
43b19952
JB
2216 if (!rdev->ops->set_wds_peer)
2217 return -EOPNOTSUPP;
e8347eba 2218
43b19952
JB
2219 if (wdev->iftype != NL80211_IFTYPE_WDS)
2220 return -EOPNOTSUPP;
e8347eba
BJ
2221
2222 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
e35e4d28 2223 return rdev_set_wds_peer(rdev, dev, bssid);
e8347eba
BJ
2224}
2225
55682965
JB
2226static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2227{
2228 struct cfg80211_registered_device *rdev;
f444de05
JB
2229 struct net_device *netdev = NULL;
2230 struct wireless_dev *wdev;
a1e567c8 2231 int result = 0, rem_txq_params = 0;
31888487 2232 struct nlattr *nl_txq_params;
b9a5f8ca
JM
2233 u32 changed;
2234 u8 retry_short = 0, retry_long = 0;
2235 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 2236 u8 coverage_class = 0;
55682965 2237
5fe231e8
JB
2238 ASSERT_RTNL();
2239
f444de05
JB
2240 /*
2241 * Try to find the wiphy and netdev. Normally this
2242 * function shouldn't need the netdev, but this is
2243 * done for backward compatibility -- previously
2244 * setting the channel was done per wiphy, but now
2245 * it is per netdev. Previous userland like hostapd
2246 * also passed a netdev to set_wiphy, so that it is
2247 * possible to let that go to the right netdev!
2248 */
4bbf4d56 2249
f444de05
JB
2250 if (info->attrs[NL80211_ATTR_IFINDEX]) {
2251 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
2252
7f2b8562 2253 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 2254 if (netdev && netdev->ieee80211_ptr)
f26cbf40 2255 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 2256 else
f444de05 2257 netdev = NULL;
4bbf4d56
JB
2258 }
2259
f444de05 2260 if (!netdev) {
878d9ec7
JB
2261 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
2262 info->attrs);
5fe231e8 2263 if (IS_ERR(rdev))
4c476991 2264 return PTR_ERR(rdev);
f444de05
JB
2265 wdev = NULL;
2266 netdev = NULL;
2267 result = 0;
71fe96bf 2268 } else
f444de05 2269 wdev = netdev->ieee80211_ptr;
f444de05
JB
2270
2271 /*
2272 * end workaround code, by now the rdev is available
2273 * and locked, and wdev may or may not be NULL.
2274 */
4bbf4d56
JB
2275
2276 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
2277 result = cfg80211_dev_rename(
2278 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56 2279
4bbf4d56 2280 if (result)
7f2b8562 2281 return result;
31888487
JM
2282
2283 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
2284 struct ieee80211_txq_params txq_params;
2285 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
2286
7f2b8562
YX
2287 if (!rdev->ops->set_txq_params)
2288 return -EOPNOTSUPP;
31888487 2289
7f2b8562
YX
2290 if (!netdev)
2291 return -EINVAL;
f70f01c2 2292
133a3ff2 2293 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
7f2b8562
YX
2294 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2295 return -EINVAL;
133a3ff2 2296
7f2b8562
YX
2297 if (!netif_running(netdev))
2298 return -ENETDOWN;
2b5f8b0b 2299
31888487
JM
2300 nla_for_each_nested(nl_txq_params,
2301 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
2302 rem_txq_params) {
ae811e21
JB
2303 result = nla_parse(tb, NL80211_TXQ_ATTR_MAX,
2304 nla_data(nl_txq_params),
2305 nla_len(nl_txq_params),
2306 txq_params_policy);
2307 if (result)
2308 return result;
31888487
JM
2309 result = parse_txq_params(tb, &txq_params);
2310 if (result)
7f2b8562 2311 return result;
31888487 2312
e35e4d28
HG
2313 result = rdev_set_txq_params(rdev, netdev,
2314 &txq_params);
31888487 2315 if (result)
7f2b8562 2316 return result;
31888487
JM
2317 }
2318 }
55682965 2319
72bdcf34 2320 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
2321 result = __nl80211_set_channel(
2322 rdev,
2323 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
2324 info);
72bdcf34 2325 if (result)
7f2b8562 2326 return result;
72bdcf34
JM
2327 }
2328
98d2ff8b 2329 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 2330 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
2331 enum nl80211_tx_power_setting type;
2332 int idx, mbm = 0;
2333
c8442118
JB
2334 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
2335 txp_wdev = NULL;
2336
7f2b8562
YX
2337 if (!rdev->ops->set_tx_power)
2338 return -EOPNOTSUPP;
98d2ff8b
JO
2339
2340 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
2341 type = nla_get_u32(info->attrs[idx]);
2342
2343 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
7f2b8562
YX
2344 (type != NL80211_TX_POWER_AUTOMATIC))
2345 return -EINVAL;
98d2ff8b
JO
2346
2347 if (type != NL80211_TX_POWER_AUTOMATIC) {
2348 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
2349 mbm = nla_get_u32(info->attrs[idx]);
2350 }
2351
c8442118 2352 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 2353 if (result)
7f2b8562 2354 return result;
98d2ff8b
JO
2355 }
2356
afe0cbf8
BR
2357 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
2358 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
2359 u32 tx_ant, rx_ant;
7a087e74 2360
7f531e03
BR
2361 if ((!rdev->wiphy.available_antennas_tx &&
2362 !rdev->wiphy.available_antennas_rx) ||
7f2b8562
YX
2363 !rdev->ops->set_antenna)
2364 return -EOPNOTSUPP;
afe0cbf8
BR
2365
2366 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
2367 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
2368
a7ffac95 2369 /* reject antenna configurations which don't match the
7f531e03
BR
2370 * available antenna masks, except for the "all" mask */
2371 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
7f2b8562
YX
2372 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
2373 return -EINVAL;
a7ffac95 2374
7f531e03
BR
2375 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
2376 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 2377
e35e4d28 2378 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 2379 if (result)
7f2b8562 2380 return result;
afe0cbf8
BR
2381 }
2382
b9a5f8ca
JM
2383 changed = 0;
2384
2385 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
2386 retry_short = nla_get_u8(
2387 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562
YX
2388 if (retry_short == 0)
2389 return -EINVAL;
2390
b9a5f8ca
JM
2391 changed |= WIPHY_PARAM_RETRY_SHORT;
2392 }
2393
2394 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
2395 retry_long = nla_get_u8(
2396 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562
YX
2397 if (retry_long == 0)
2398 return -EINVAL;
2399
b9a5f8ca
JM
2400 changed |= WIPHY_PARAM_RETRY_LONG;
2401 }
2402
2403 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
2404 frag_threshold = nla_get_u32(
2405 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
7f2b8562
YX
2406 if (frag_threshold < 256)
2407 return -EINVAL;
2408
b9a5f8ca
JM
2409 if (frag_threshold != (u32) -1) {
2410 /*
2411 * Fragments (apart from the last one) are required to
2412 * have even length. Make the fragmentation code
2413 * simpler by stripping LSB should someone try to use
2414 * odd threshold value.
2415 */
2416 frag_threshold &= ~0x1;
2417 }
2418 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
2419 }
2420
2421 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
2422 rts_threshold = nla_get_u32(
2423 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
2424 changed |= WIPHY_PARAM_RTS_THRESHOLD;
2425 }
2426
81077e82 2427 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
3057dbfd
LB
2428 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK])
2429 return -EINVAL;
2430
81077e82
LT
2431 coverage_class = nla_get_u8(
2432 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
2433 changed |= WIPHY_PARAM_COVERAGE_CLASS;
2434 }
2435
3057dbfd
LB
2436 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
2437 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION))
2438 return -EOPNOTSUPP;
2439
2440 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
2441 }
2442
b9a5f8ca
JM
2443 if (changed) {
2444 u8 old_retry_short, old_retry_long;
2445 u32 old_frag_threshold, old_rts_threshold;
81077e82 2446 u8 old_coverage_class;
b9a5f8ca 2447
7f2b8562
YX
2448 if (!rdev->ops->set_wiphy_params)
2449 return -EOPNOTSUPP;
b9a5f8ca
JM
2450
2451 old_retry_short = rdev->wiphy.retry_short;
2452 old_retry_long = rdev->wiphy.retry_long;
2453 old_frag_threshold = rdev->wiphy.frag_threshold;
2454 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 2455 old_coverage_class = rdev->wiphy.coverage_class;
b9a5f8ca
JM
2456
2457 if (changed & WIPHY_PARAM_RETRY_SHORT)
2458 rdev->wiphy.retry_short = retry_short;
2459 if (changed & WIPHY_PARAM_RETRY_LONG)
2460 rdev->wiphy.retry_long = retry_long;
2461 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
2462 rdev->wiphy.frag_threshold = frag_threshold;
2463 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
2464 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
2465 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
2466 rdev->wiphy.coverage_class = coverage_class;
b9a5f8ca 2467
e35e4d28 2468 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
2469 if (result) {
2470 rdev->wiphy.retry_short = old_retry_short;
2471 rdev->wiphy.retry_long = old_retry_long;
2472 rdev->wiphy.frag_threshold = old_frag_threshold;
2473 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 2474 rdev->wiphy.coverage_class = old_coverage_class;
9189ee31 2475 return result;
b9a5f8ca
JM
2476 }
2477 }
7f2b8562 2478 return 0;
55682965
JB
2479}
2480
71bbc994
JB
2481static inline u64 wdev_id(struct wireless_dev *wdev)
2482{
2483 return (u64)wdev->identifier |
f26cbf40 2484 ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32);
71bbc994 2485}
55682965 2486
683b6d3b 2487static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 2488 const struct cfg80211_chan_def *chandef)
683b6d3b 2489{
601555cd
JB
2490 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
2491 return -EINVAL;
3d9d1d66 2492
683b6d3b
JB
2493 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
2494 chandef->chan->center_freq))
2495 return -ENOBUFS;
3d9d1d66
JB
2496 switch (chandef->width) {
2497 case NL80211_CHAN_WIDTH_20_NOHT:
2498 case NL80211_CHAN_WIDTH_20:
2499 case NL80211_CHAN_WIDTH_40:
2500 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2501 cfg80211_get_chandef_type(chandef)))
2502 return -ENOBUFS;
2503 break;
2504 default:
2505 break;
2506 }
2507 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
2508 return -ENOBUFS;
2509 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
2510 return -ENOBUFS;
2511 if (chandef->center_freq2 &&
2512 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
2513 return -ENOBUFS;
2514 return 0;
2515}
2516
15e47304 2517static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 2518 struct cfg80211_registered_device *rdev,
8f894be2 2519 struct wireless_dev *wdev, bool removal)
55682965 2520{
72fb2abc 2521 struct net_device *dev = wdev->netdev;
8f894be2 2522 u8 cmd = NL80211_CMD_NEW_INTERFACE;
55682965
JB
2523 void *hdr;
2524
8f894be2
TB
2525 if (removal)
2526 cmd = NL80211_CMD_DEL_INTERFACE;
2527
2528 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
2529 if (!hdr)
2530 return -1;
2531
72fb2abc
JB
2532 if (dev &&
2533 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 2534 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
2535 goto nla_put_failure;
2536
2537 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2538 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
2539 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
2540 NL80211_ATTR_PAD) ||
98104fde 2541 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
2542 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2543 rdev->devlist_generation ^
2544 (cfg80211_rdev_list_generation << 2)))
2545 goto nla_put_failure;
f5ea9120 2546
5b7ccaf3 2547 if (rdev->ops->get_channel) {
683b6d3b
JB
2548 int ret;
2549 struct cfg80211_chan_def chandef;
2550
2551 ret = rdev_get_channel(rdev, wdev, &chandef);
2552 if (ret == 0) {
2553 if (nl80211_send_chandef(msg, &chandef))
2554 goto nla_put_failure;
2555 }
d91df0e3
PF
2556 }
2557
d55d0d59
RM
2558 if (rdev->ops->get_tx_power) {
2559 int dbm, ret;
2560
2561 ret = rdev_get_tx_power(rdev, wdev, &dbm);
2562 if (ret == 0 &&
2563 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
2564 DBM_TO_MBM(dbm)))
2565 goto nla_put_failure;
2566 }
2567
b84e7a05
AQ
2568 if (wdev->ssid_len) {
2569 if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
2570 goto nla_put_failure;
2571 }
2572
053c095a
JB
2573 genlmsg_end(msg, hdr);
2574 return 0;
55682965
JB
2575
2576 nla_put_failure:
bc3ed28c
TG
2577 genlmsg_cancel(msg, hdr);
2578 return -EMSGSIZE;
55682965
JB
2579}
2580
2581static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
2582{
2583 int wp_idx = 0;
2584 int if_idx = 0;
2585 int wp_start = cb->args[0];
2586 int if_start = cb->args[1];
b7fb44da 2587 int filter_wiphy = -1;
f5ea9120 2588 struct cfg80211_registered_device *rdev;
55682965
JB
2589 struct wireless_dev *wdev;
2590
5fe231e8 2591 rtnl_lock();
b7fb44da
DK
2592 if (!cb->args[2]) {
2593 struct nl80211_dump_wiphy_state state = {
2594 .filter_wiphy = -1,
2595 };
2596 int ret;
2597
2598 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
2599 if (ret)
2600 return ret;
2601
2602 filter_wiphy = state.filter_wiphy;
2603
2604 /*
2605 * if filtering, set cb->args[2] to +1 since 0 is the default
2606 * value needed to determine that parsing is necessary.
2607 */
2608 if (filter_wiphy >= 0)
2609 cb->args[2] = filter_wiphy + 1;
2610 else
2611 cb->args[2] = -1;
2612 } else if (cb->args[2] > 0) {
2613 filter_wiphy = cb->args[2] - 1;
2614 }
2615
f5ea9120
JB
2616 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2617 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2618 continue;
bba95fef
JB
2619 if (wp_idx < wp_start) {
2620 wp_idx++;
55682965 2621 continue;
bba95fef 2622 }
b7fb44da
DK
2623
2624 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
2625 continue;
2626
55682965
JB
2627 if_idx = 0;
2628
53873f13 2629 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
2630 if (if_idx < if_start) {
2631 if_idx++;
55682965 2632 continue;
bba95fef 2633 }
15e47304 2634 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 2635 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8f894be2 2636 rdev, wdev, false) < 0) {
bba95fef
JB
2637 goto out;
2638 }
2639 if_idx++;
55682965 2640 }
bba95fef
JB
2641
2642 wp_idx++;
55682965 2643 }
bba95fef 2644 out:
5fe231e8 2645 rtnl_unlock();
55682965
JB
2646
2647 cb->args[0] = wp_idx;
2648 cb->args[1] = if_idx;
2649
2650 return skb->len;
2651}
2652
2653static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
2654{
2655 struct sk_buff *msg;
1b8ec87a 2656 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 2657 struct wireless_dev *wdev = info->user_ptr[1];
55682965 2658
fd2120ca 2659 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 2660 if (!msg)
4c476991 2661 return -ENOMEM;
55682965 2662
15e47304 2663 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 2664 rdev, wdev, false) < 0) {
4c476991
JB
2665 nlmsg_free(msg);
2666 return -ENOBUFS;
2667 }
55682965 2668
134e6375 2669 return genlmsg_reply(msg, info);
55682965
JB
2670}
2671
66f7ac50
MW
2672static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
2673 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
2674 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
2675 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
2676 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
2677 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 2678 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
2679};
2680
2681static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
2682{
2683 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
2684 int flag;
2685
2686 *mntrflags = 0;
2687
2688 if (!nla)
2689 return -EINVAL;
2690
2691 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
2692 nla, mntr_flags_policy))
2693 return -EINVAL;
2694
2695 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
2696 if (flags[flag])
2697 *mntrflags |= (1<<flag);
2698
2699 return 0;
2700}
2701
9bc383de 2702static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
2703 struct net_device *netdev, u8 use_4addr,
2704 enum nl80211_iftype iftype)
9bc383de 2705{
ad4bb6f8 2706 if (!use_4addr) {
f350a0a8 2707 if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT))
ad4bb6f8 2708 return -EBUSY;
9bc383de 2709 return 0;
ad4bb6f8 2710 }
9bc383de
JB
2711
2712 switch (iftype) {
2713 case NL80211_IFTYPE_AP_VLAN:
2714 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
2715 return 0;
2716 break;
2717 case NL80211_IFTYPE_STATION:
2718 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
2719 return 0;
2720 break;
2721 default:
2722 break;
2723 }
2724
2725 return -EOPNOTSUPP;
2726}
2727
55682965
JB
2728static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
2729{
4c476991 2730 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2731 struct vif_params params;
e36d56b6 2732 int err;
04a773ad 2733 enum nl80211_iftype otype, ntype;
4c476991 2734 struct net_device *dev = info->user_ptr[1];
92ffe055 2735 u32 _flags, *flags = NULL;
ac7f9cfa 2736 bool change = false;
55682965 2737
2ec600d6
LCC
2738 memset(&params, 0, sizeof(params));
2739
04a773ad 2740 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 2741
723b038d 2742 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 2743 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 2744 if (otype != ntype)
ac7f9cfa 2745 change = true;
4c476991
JB
2746 if (ntype > NL80211_IFTYPE_MAX)
2747 return -EINVAL;
723b038d
JB
2748 }
2749
92ffe055 2750 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
2751 struct wireless_dev *wdev = dev->ieee80211_ptr;
2752
4c476991
JB
2753 if (ntype != NL80211_IFTYPE_MESH_POINT)
2754 return -EINVAL;
29cbe68c
JB
2755 if (netif_running(dev))
2756 return -EBUSY;
2757
2758 wdev_lock(wdev);
2759 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2760 IEEE80211_MAX_MESH_ID_LEN);
2761 wdev->mesh_id_up_len =
2762 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2763 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
2764 wdev->mesh_id_up_len);
2765 wdev_unlock(wdev);
2ec600d6
LCC
2766 }
2767
8b787643
FF
2768 if (info->attrs[NL80211_ATTR_4ADDR]) {
2769 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
2770 change = true;
ad4bb6f8 2771 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 2772 if (err)
4c476991 2773 return err;
8b787643
FF
2774 } else {
2775 params.use_4addr = -1;
2776 }
2777
92ffe055 2778 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
4c476991
JB
2779 if (ntype != NL80211_IFTYPE_MONITOR)
2780 return -EINVAL;
92ffe055
JB
2781 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
2782 &_flags);
ac7f9cfa 2783 if (err)
4c476991 2784 return err;
ac7f9cfa
JB
2785
2786 flags = &_flags;
2787 change = true;
92ffe055 2788 }
3b85875a 2789
c6e6a0c8
AE
2790 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
2791 const u8 *mumimo_groups;
2792 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2793
2794 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2795 return -EOPNOTSUPP;
2796
2797 mumimo_groups =
2798 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
2799
2800 /* bits 0 and 63 are reserved and must be zero */
2801 if ((mumimo_groups[0] & BIT(7)) ||
2802 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(0)))
2803 return -EINVAL;
2804
2805 memcpy(params.vht_mumimo_groups, mumimo_groups,
2806 VHT_MUMIMO_GROUPS_DATA_LEN);
2807 change = true;
2808 }
2809
2810 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
2811 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
2812
2813 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
2814 return -EOPNOTSUPP;
2815
2816 nla_memcpy(params.macaddr,
2817 info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR],
2818 ETH_ALEN);
2819 change = true;
2820 }
2821
18003297 2822 if (flags && (*flags & MONITOR_FLAG_ACTIVE) &&
e057d3c3
FF
2823 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2824 return -EOPNOTSUPP;
2825
ac7f9cfa 2826 if (change)
3d54d255 2827 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
ac7f9cfa
JB
2828 else
2829 err = 0;
60719ffd 2830
9bc383de
JB
2831 if (!err && params.use_4addr != -1)
2832 dev->ieee80211_ptr->use_4addr = params.use_4addr;
2833
55682965
JB
2834 return err;
2835}
2836
2837static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2838{
4c476991 2839 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 2840 struct vif_params params;
84efbb84 2841 struct wireless_dev *wdev;
896ff063 2842 struct sk_buff *msg;
55682965
JB
2843 int err;
2844 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
66f7ac50 2845 u32 flags;
55682965 2846
78f22b6a
JB
2847 /* to avoid failing a new interface creation due to pending removal */
2848 cfg80211_destroy_ifaces(rdev);
2849
2ec600d6
LCC
2850 memset(&params, 0, sizeof(params));
2851
55682965
JB
2852 if (!info->attrs[NL80211_ATTR_IFNAME])
2853 return -EINVAL;
2854
2855 if (info->attrs[NL80211_ATTR_IFTYPE]) {
2856 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
2857 if (type > NL80211_IFTYPE_MAX)
2858 return -EINVAL;
2859 }
2860
79c97e97 2861 if (!rdev->ops->add_virtual_intf ||
4c476991
JB
2862 !(rdev->wiphy.interface_modes & (1 << type)))
2863 return -EOPNOTSUPP;
55682965 2864
cb3b7d87 2865 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
2866 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
2867 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
2868 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
2869 ETH_ALEN);
2870 if (!is_valid_ether_addr(params.macaddr))
2871 return -EADDRNOTAVAIL;
2872 }
2873
9bc383de 2874 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 2875 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 2876 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 2877 if (err)
4c476991 2878 return err;
9bc383de 2879 }
8b787643 2880
66f7ac50
MW
2881 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
2882 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
2883 &flags);
e057d3c3 2884
18003297 2885 if (!err && (flags & MONITOR_FLAG_ACTIVE) &&
e057d3c3
FF
2886 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2887 return -EOPNOTSUPP;
2888
a18c7192
JB
2889 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2890 if (!msg)
2891 return -ENOMEM;
2892
e35e4d28
HG
2893 wdev = rdev_add_virtual_intf(rdev,
2894 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
6bab2e19
TG
2895 NET_NAME_USER, type, err ? NULL : &flags,
2896 &params);
d687cbb7
RM
2897 if (WARN_ON(!wdev)) {
2898 nlmsg_free(msg);
2899 return -EPROTO;
2900 } else if (IS_ERR(wdev)) {
1c90f9d4 2901 nlmsg_free(msg);
84efbb84 2902 return PTR_ERR(wdev);
1c90f9d4 2903 }
2ec600d6 2904
18e5ca65 2905 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
2906 wdev->owner_nlportid = info->snd_portid;
2907
98104fde
JB
2908 switch (type) {
2909 case NL80211_IFTYPE_MESH_POINT:
2910 if (!info->attrs[NL80211_ATTR_MESH_ID])
2911 break;
29cbe68c
JB
2912 wdev_lock(wdev);
2913 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
2914 IEEE80211_MAX_MESH_ID_LEN);
2915 wdev->mesh_id_up_len =
2916 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
2917 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
2918 wdev->mesh_id_up_len);
2919 wdev_unlock(wdev);
98104fde 2920 break;
cb3b7d87 2921 case NL80211_IFTYPE_NAN:
98104fde
JB
2922 case NL80211_IFTYPE_P2P_DEVICE:
2923 /*
cb3b7d87 2924 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
2925 * through the netdev notifier and must be added here
2926 */
2927 mutex_init(&wdev->mtx);
2928 INIT_LIST_HEAD(&wdev->event_list);
2929 spin_lock_init(&wdev->event_lock);
2930 INIT_LIST_HEAD(&wdev->mgmt_registrations);
2931 spin_lock_init(&wdev->mgmt_registrations_lock);
2932
98104fde 2933 wdev->identifier = ++rdev->wdev_id;
53873f13 2934 list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
98104fde 2935 rdev->devlist_generation++;
98104fde
JB
2936 break;
2937 default:
2938 break;
29cbe68c
JB
2939 }
2940
15e47304 2941 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
8f894be2 2942 rdev, wdev, false) < 0) {
1c90f9d4
JB
2943 nlmsg_free(msg);
2944 return -ENOBUFS;
2945 }
2946
896ff063
DK
2947 /*
2948 * For wdevs which have no associated netdev object (e.g. of type
2949 * NL80211_IFTYPE_P2P_DEVICE), emit the NEW_INTERFACE event here.
2950 * For all other types, the event will be generated from the
2951 * netdev notifier
2952 */
2953 if (!wdev->netdev)
2954 nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
8f894be2 2955
1c90f9d4 2956 return genlmsg_reply(msg, info);
55682965
JB
2957}
2958
2959static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
2960{
4c476991 2961 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 2962 struct wireless_dev *wdev = info->user_ptr[1];
55682965 2963
4c476991
JB
2964 if (!rdev->ops->del_virtual_intf)
2965 return -EOPNOTSUPP;
55682965 2966
84efbb84
JB
2967 /*
2968 * If we remove a wireless device without a netdev then clear
2969 * user_ptr[1] so that nl80211_post_doit won't dereference it
2970 * to check if it needs to do dev_put(). Otherwise it crashes
2971 * since the wdev has been freed, unlike with a netdev where
2972 * we need the dev_put() for the netdev to really be freed.
2973 */
2974 if (!wdev->netdev)
2975 info->user_ptr[1] = NULL;
2976
7f8ed01e 2977 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
2978}
2979
1d9d9213
SW
2980static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
2981{
2982 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2983 struct net_device *dev = info->user_ptr[1];
2984 u16 noack_map;
2985
2986 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
2987 return -EINVAL;
2988
2989 if (!rdev->ops->set_noack_map)
2990 return -EOPNOTSUPP;
2991
2992 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
2993
e35e4d28 2994 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
2995}
2996
41ade00f
JB
2997struct get_key_cookie {
2998 struct sk_buff *msg;
2999 int error;
b9454e83 3000 int idx;
41ade00f
JB
3001};
3002
3003static void get_key_callback(void *c, struct key_params *params)
3004{
b9454e83 3005 struct nlattr *key;
41ade00f
JB
3006 struct get_key_cookie *cookie = c;
3007
9360ffd1
DM
3008 if ((params->key &&
3009 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
3010 params->key_len, params->key)) ||
3011 (params->seq &&
3012 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
3013 params->seq_len, params->seq)) ||
3014 (params->cipher &&
3015 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
3016 params->cipher)))
3017 goto nla_put_failure;
41ade00f 3018
b9454e83
JB
3019 key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
3020 if (!key)
3021 goto nla_put_failure;
3022
9360ffd1
DM
3023 if ((params->key &&
3024 nla_put(cookie->msg, NL80211_KEY_DATA,
3025 params->key_len, params->key)) ||
3026 (params->seq &&
3027 nla_put(cookie->msg, NL80211_KEY_SEQ,
3028 params->seq_len, params->seq)) ||
3029 (params->cipher &&
3030 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
3031 params->cipher)))
3032 goto nla_put_failure;
b9454e83 3033
9360ffd1
DM
3034 if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx))
3035 goto nla_put_failure;
b9454e83
JB
3036
3037 nla_nest_end(cookie->msg, key);
3038
41ade00f
JB
3039 return;
3040 nla_put_failure:
3041 cookie->error = 1;
3042}
3043
3044static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
3045{
4c476991 3046 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3047 int err;
4c476991 3048 struct net_device *dev = info->user_ptr[1];
41ade00f 3049 u8 key_idx = 0;
e31b8213
JB
3050 const u8 *mac_addr = NULL;
3051 bool pairwise;
41ade00f
JB
3052 struct get_key_cookie cookie = {
3053 .error = 0,
3054 };
3055 void *hdr;
3056 struct sk_buff *msg;
3057
3058 if (info->attrs[NL80211_ATTR_KEY_IDX])
3059 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
3060
3cfcf6ac 3061 if (key_idx > 5)
41ade00f
JB
3062 return -EINVAL;
3063
3064 if (info->attrs[NL80211_ATTR_MAC])
3065 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3066
e31b8213
JB
3067 pairwise = !!mac_addr;
3068 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
3069 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 3070
e31b8213
JB
3071 if (kt >= NUM_NL80211_KEYTYPES)
3072 return -EINVAL;
3073 if (kt != NL80211_KEYTYPE_GROUP &&
3074 kt != NL80211_KEYTYPE_PAIRWISE)
3075 return -EINVAL;
3076 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
3077 }
3078
4c476991
JB
3079 if (!rdev->ops->get_key)
3080 return -EOPNOTSUPP;
41ade00f 3081
0fa7b391
JB
3082 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3083 return -ENOENT;
3084
fd2120ca 3085 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
3086 if (!msg)
3087 return -ENOMEM;
41ade00f 3088
15e47304 3089 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 3090 NL80211_CMD_NEW_KEY);
cb35fba3 3091 if (!hdr)
9fe271af 3092 goto nla_put_failure;
41ade00f
JB
3093
3094 cookie.msg = msg;
b9454e83 3095 cookie.idx = key_idx;
41ade00f 3096
9360ffd1
DM
3097 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3098 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
3099 goto nla_put_failure;
3100 if (mac_addr &&
3101 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
3102 goto nla_put_failure;
41ade00f 3103
e35e4d28
HG
3104 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
3105 get_key_callback);
41ade00f
JB
3106
3107 if (err)
6c95e2a2 3108 goto free_msg;
41ade00f
JB
3109
3110 if (cookie.error)
3111 goto nla_put_failure;
3112
3113 genlmsg_end(msg, hdr);
4c476991 3114 return genlmsg_reply(msg, info);
41ade00f
JB
3115
3116 nla_put_failure:
3117 err = -ENOBUFS;
6c95e2a2 3118 free_msg:
41ade00f 3119 nlmsg_free(msg);
41ade00f
JB
3120 return err;
3121}
3122
3123static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
3124{
4c476991 3125 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 3126 struct key_parse key;
41ade00f 3127 int err;
4c476991 3128 struct net_device *dev = info->user_ptr[1];
41ade00f 3129
b9454e83
JB
3130 err = nl80211_parse_key(info, &key);
3131 if (err)
3132 return err;
41ade00f 3133
b9454e83 3134 if (key.idx < 0)
41ade00f
JB
3135 return -EINVAL;
3136
b9454e83
JB
3137 /* only support setting default key */
3138 if (!key.def && !key.defmgmt)
41ade00f
JB
3139 return -EINVAL;
3140
dbd2fd65 3141 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 3142
dbd2fd65
JB
3143 if (key.def) {
3144 if (!rdev->ops->set_default_key) {
3145 err = -EOPNOTSUPP;
3146 goto out;
3147 }
41ade00f 3148
dbd2fd65
JB
3149 err = nl80211_key_allowed(dev->ieee80211_ptr);
3150 if (err)
3151 goto out;
3152
e35e4d28 3153 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
3154 key.def_uni, key.def_multi);
3155
3156 if (err)
3157 goto out;
fffd0934 3158
3d23e349 3159#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
3160 dev->ieee80211_ptr->wext.default_key = key.idx;
3161#endif
3162 } else {
3163 if (key.def_uni || !key.def_multi) {
3164 err = -EINVAL;
3165 goto out;
3166 }
3167
3168 if (!rdev->ops->set_default_mgmt_key) {
3169 err = -EOPNOTSUPP;
3170 goto out;
3171 }
3172
3173 err = nl80211_key_allowed(dev->ieee80211_ptr);
3174 if (err)
3175 goto out;
3176
e35e4d28 3177 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
3178 if (err)
3179 goto out;
3180
3181#ifdef CONFIG_CFG80211_WEXT
3182 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 3183#endif
dbd2fd65
JB
3184 }
3185
3186 out:
fffd0934 3187 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3188
41ade00f
JB
3189 return err;
3190}
3191
3192static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
3193{
4c476991 3194 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 3195 int err;
4c476991 3196 struct net_device *dev = info->user_ptr[1];
b9454e83 3197 struct key_parse key;
e31b8213 3198 const u8 *mac_addr = NULL;
41ade00f 3199
b9454e83
JB
3200 err = nl80211_parse_key(info, &key);
3201 if (err)
3202 return err;
41ade00f 3203
b9454e83 3204 if (!key.p.key)
41ade00f
JB
3205 return -EINVAL;
3206
41ade00f
JB
3207 if (info->attrs[NL80211_ATTR_MAC])
3208 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3209
e31b8213
JB
3210 if (key.type == -1) {
3211 if (mac_addr)
3212 key.type = NL80211_KEYTYPE_PAIRWISE;
3213 else
3214 key.type = NL80211_KEYTYPE_GROUP;
3215 }
3216
3217 /* for now */
3218 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3219 key.type != NL80211_KEYTYPE_GROUP)
3220 return -EINVAL;
3221
4c476991
JB
3222 if (!rdev->ops->add_key)
3223 return -EOPNOTSUPP;
25e47c18 3224
e31b8213
JB
3225 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
3226 key.type == NL80211_KEYTYPE_PAIRWISE,
3227 mac_addr))
4c476991 3228 return -EINVAL;
41ade00f 3229
fffd0934
JB
3230 wdev_lock(dev->ieee80211_ptr);
3231 err = nl80211_key_allowed(dev->ieee80211_ptr);
3232 if (!err)
e35e4d28
HG
3233 err = rdev_add_key(rdev, dev, key.idx,
3234 key.type == NL80211_KEYTYPE_PAIRWISE,
3235 mac_addr, &key.p);
fffd0934 3236 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3237
41ade00f
JB
3238 return err;
3239}
3240
3241static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
3242{
4c476991 3243 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3244 int err;
4c476991 3245 struct net_device *dev = info->user_ptr[1];
41ade00f 3246 u8 *mac_addr = NULL;
b9454e83 3247 struct key_parse key;
41ade00f 3248
b9454e83
JB
3249 err = nl80211_parse_key(info, &key);
3250 if (err)
3251 return err;
41ade00f
JB
3252
3253 if (info->attrs[NL80211_ATTR_MAC])
3254 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3255
e31b8213
JB
3256 if (key.type == -1) {
3257 if (mac_addr)
3258 key.type = NL80211_KEYTYPE_PAIRWISE;
3259 else
3260 key.type = NL80211_KEYTYPE_GROUP;
3261 }
3262
3263 /* for now */
3264 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3265 key.type != NL80211_KEYTYPE_GROUP)
3266 return -EINVAL;
3267
4c476991
JB
3268 if (!rdev->ops->del_key)
3269 return -EOPNOTSUPP;
41ade00f 3270
fffd0934
JB
3271 wdev_lock(dev->ieee80211_ptr);
3272 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 3273
0fa7b391 3274 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
3275 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3276 err = -ENOENT;
3277
fffd0934 3278 if (!err)
e35e4d28
HG
3279 err = rdev_del_key(rdev, dev, key.idx,
3280 key.type == NL80211_KEYTYPE_PAIRWISE,
3281 mac_addr);
41ade00f 3282
3d23e349 3283#ifdef CONFIG_CFG80211_WEXT
08645126 3284 if (!err) {
b9454e83 3285 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 3286 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 3287 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
3288 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
3289 }
3290#endif
fffd0934 3291 wdev_unlock(dev->ieee80211_ptr);
08645126 3292
41ade00f
JB
3293 return err;
3294}
3295
77765eaf
VT
3296/* This function returns an error or the number of nested attributes */
3297static int validate_acl_mac_addrs(struct nlattr *nl_attr)
3298{
3299 struct nlattr *attr;
3300 int n_entries = 0, tmp;
3301
3302 nla_for_each_nested(attr, nl_attr, tmp) {
3303 if (nla_len(attr) != ETH_ALEN)
3304 return -EINVAL;
3305
3306 n_entries++;
3307 }
3308
3309 return n_entries;
3310}
3311
3312/*
3313 * This function parses ACL information and allocates memory for ACL data.
3314 * On successful return, the calling function is responsible to free the
3315 * ACL buffer returned by this function.
3316 */
3317static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
3318 struct genl_info *info)
3319{
3320 enum nl80211_acl_policy acl_policy;
3321 struct nlattr *attr;
3322 struct cfg80211_acl_data *acl;
3323 int i = 0, n_entries, tmp;
3324
3325 if (!wiphy->max_acl_mac_addrs)
3326 return ERR_PTR(-EOPNOTSUPP);
3327
3328 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
3329 return ERR_PTR(-EINVAL);
3330
3331 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
3332 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
3333 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
3334 return ERR_PTR(-EINVAL);
3335
3336 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
3337 return ERR_PTR(-EINVAL);
3338
3339 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
3340 if (n_entries < 0)
3341 return ERR_PTR(n_entries);
3342
3343 if (n_entries > wiphy->max_acl_mac_addrs)
3344 return ERR_PTR(-ENOTSUPP);
3345
3346 acl = kzalloc(sizeof(*acl) + (sizeof(struct mac_address) * n_entries),
3347 GFP_KERNEL);
3348 if (!acl)
3349 return ERR_PTR(-ENOMEM);
3350
3351 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
3352 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
3353 i++;
3354 }
3355
3356 acl->n_acl_entries = n_entries;
3357 acl->acl_policy = acl_policy;
3358
3359 return acl;
3360}
3361
3362static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
3363{
3364 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3365 struct net_device *dev = info->user_ptr[1];
3366 struct cfg80211_acl_data *acl;
3367 int err;
3368
3369 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3370 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3371 return -EOPNOTSUPP;
3372
3373 if (!dev->ieee80211_ptr->beacon_interval)
3374 return -EINVAL;
3375
3376 acl = parse_acl_data(&rdev->wiphy, info);
3377 if (IS_ERR(acl))
3378 return PTR_ERR(acl);
3379
3380 err = rdev_set_mac_acl(rdev, dev, acl);
3381
3382 kfree(acl);
3383
3384 return err;
3385}
3386
a7c7fbff
PK
3387static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
3388 u8 *rates, u8 rates_len)
3389{
3390 u8 i;
3391 u32 mask = 0;
3392
3393 for (i = 0; i < rates_len; i++) {
3394 int rate = (rates[i] & 0x7f) * 5;
3395 int ridx;
3396
3397 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
3398 struct ieee80211_rate *srate =
3399 &sband->bitrates[ridx];
3400 if (rate == srate->bitrate) {
3401 mask |= 1 << ridx;
3402 break;
3403 }
3404 }
3405 if (ridx == sband->n_bitrates)
3406 return 0; /* rate not found */
3407 }
3408
3409 return mask;
3410}
3411
3412static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
3413 u8 *rates, u8 rates_len,
3414 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
3415{
3416 u8 i;
3417
3418 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
3419
3420 for (i = 0; i < rates_len; i++) {
3421 int ridx, rbit;
3422
3423 ridx = rates[i] / 8;
3424 rbit = BIT(rates[i] % 8);
3425
3426 /* check validity */
3427 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
3428 return false;
3429
3430 /* check availability */
3431 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
3432 mcs[ridx] |= rbit;
3433 else
3434 return false;
3435 }
3436
3437 return true;
3438}
3439
3440static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
3441{
3442 u16 mcs_mask = 0;
3443
3444 switch (vht_mcs_map) {
3445 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
3446 break;
3447 case IEEE80211_VHT_MCS_SUPPORT_0_7:
3448 mcs_mask = 0x00FF;
3449 break;
3450 case IEEE80211_VHT_MCS_SUPPORT_0_8:
3451 mcs_mask = 0x01FF;
3452 break;
3453 case IEEE80211_VHT_MCS_SUPPORT_0_9:
3454 mcs_mask = 0x03FF;
3455 break;
3456 default:
3457 break;
3458 }
3459
3460 return mcs_mask;
3461}
3462
3463static void vht_build_mcs_mask(u16 vht_mcs_map,
3464 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
3465{
3466 u8 nss;
3467
3468 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
3469 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
3470 vht_mcs_map >>= 2;
3471 }
3472}
3473
3474static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
3475 struct nl80211_txrate_vht *txrate,
3476 u16 mcs[NL80211_VHT_NSS_MAX])
3477{
3478 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3479 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
3480 u8 i;
3481
3482 if (!sband->vht_cap.vht_supported)
3483 return false;
3484
3485 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
3486
3487 /* Build vht_mcs_mask from VHT capabilities */
3488 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
3489
3490 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
3491 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
3492 mcs[i] = txrate->mcs[i];
3493 else
3494 return false;
3495 }
3496
3497 return true;
3498}
3499
3500static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
3501 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
3502 .len = NL80211_MAX_SUPP_RATES },
3503 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
3504 .len = NL80211_MAX_SUPP_HT_RATES },
3505 [NL80211_TXRATE_VHT] = { .len = sizeof(struct nl80211_txrate_vht)},
3506 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
3507};
3508
3509static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
3510 struct cfg80211_bitrate_mask *mask)
3511{
3512 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
3513 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3514 int rem, i;
3515 struct nlattr *tx_rates;
3516 struct ieee80211_supported_band *sband;
3517 u16 vht_tx_mcs_map;
3518
3519 memset(mask, 0, sizeof(*mask));
3520 /* Default to all rates enabled */
3521 for (i = 0; i < NUM_NL80211_BANDS; i++) {
3522 sband = rdev->wiphy.bands[i];
3523
3524 if (!sband)
3525 continue;
3526
3527 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
3528 memcpy(mask->control[i].ht_mcs,
3529 sband->ht_cap.mcs.rx_mask,
3530 sizeof(mask->control[i].ht_mcs));
3531
3532 if (!sband->vht_cap.vht_supported)
3533 continue;
3534
3535 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
3536 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
3537 }
3538
3539 /* if no rates are given set it back to the defaults */
3540 if (!info->attrs[NL80211_ATTR_TX_RATES])
3541 goto out;
3542
3543 /* The nested attribute uses enum nl80211_band as the index. This maps
3544 * directly to the enum nl80211_band values used in cfg80211.
3545 */
3546 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
3547 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
3548 enum nl80211_band band = nla_type(tx_rates);
3549 int err;
3550
3551 if (band < 0 || band >= NUM_NL80211_BANDS)
3552 return -EINVAL;
3553 sband = rdev->wiphy.bands[band];
3554 if (sband == NULL)
3555 return -EINVAL;
3556 err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
3557 nla_len(tx_rates), nl80211_txattr_policy);
3558 if (err)
3559 return err;
3560 if (tb[NL80211_TXRATE_LEGACY]) {
3561 mask->control[band].legacy = rateset_to_mask(
3562 sband,
3563 nla_data(tb[NL80211_TXRATE_LEGACY]),
3564 nla_len(tb[NL80211_TXRATE_LEGACY]));
3565 if ((mask->control[band].legacy == 0) &&
3566 nla_len(tb[NL80211_TXRATE_LEGACY]))
3567 return -EINVAL;
3568 }
3569 if (tb[NL80211_TXRATE_HT]) {
3570 if (!ht_rateset_to_mask(
3571 sband,
3572 nla_data(tb[NL80211_TXRATE_HT]),
3573 nla_len(tb[NL80211_TXRATE_HT]),
3574 mask->control[band].ht_mcs))
3575 return -EINVAL;
3576 }
3577 if (tb[NL80211_TXRATE_VHT]) {
3578 if (!vht_set_mcs_mask(
3579 sband,
3580 nla_data(tb[NL80211_TXRATE_VHT]),
3581 mask->control[band].vht_mcs))
3582 return -EINVAL;
3583 }
3584 if (tb[NL80211_TXRATE_GI]) {
3585 mask->control[band].gi =
3586 nla_get_u8(tb[NL80211_TXRATE_GI]);
3587 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
3588 return -EINVAL;
3589 }
3590
3591 if (mask->control[band].legacy == 0) {
3592 /* don't allow empty legacy rates if HT or VHT
3593 * are not even supported.
3594 */
3595 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
3596 rdev->wiphy.bands[band]->vht_cap.vht_supported))
3597 return -EINVAL;
3598
3599 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
3600 if (mask->control[band].ht_mcs[i])
3601 goto out;
3602
3603 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
3604 if (mask->control[band].vht_mcs[i])
3605 goto out;
3606
3607 /* legacy and mcs rates may not be both empty */
3608 return -EINVAL;
3609 }
3610 }
3611
3612out:
3613 return 0;
3614}
3615
8564e382
JB
3616static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
3617 enum nl80211_band band,
3618 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 3619{
8564e382
JB
3620 u32 count_ht, count_vht, i;
3621 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
3622
3623 /* Allow only one rate */
3624 if (hweight32(rate) > 1)
3625 return -EINVAL;
3626
3627 count_ht = 0;
3628 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 3629 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 3630 return -EINVAL;
8564e382 3631 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
3632 count_ht++;
3633 if (count_ht > 1)
3634 return -EINVAL;
3635 }
3636 if (count_ht && rate)
3637 return -EINVAL;
3638 }
3639
3640 count_vht = 0;
3641 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 3642 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 3643 return -EINVAL;
8564e382 3644 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
3645 count_vht++;
3646 if (count_vht > 1)
3647 return -EINVAL;
3648 }
3649 if (count_vht && rate)
3650 return -EINVAL;
3651 }
3652
3653 if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht))
3654 return -EINVAL;
3655
8564e382
JB
3656 if (rate &&
3657 !wiphy_ext_feature_isset(&rdev->wiphy,
3658 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
3659 return -EINVAL;
3660 if (count_ht &&
3661 !wiphy_ext_feature_isset(&rdev->wiphy,
3662 NL80211_EXT_FEATURE_BEACON_RATE_HT))
3663 return -EINVAL;
3664 if (count_vht &&
3665 !wiphy_ext_feature_isset(&rdev->wiphy,
3666 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
3667 return -EINVAL;
3668
a7c7fbff
PK
3669 return 0;
3670}
3671
a1193be8 3672static int nl80211_parse_beacon(struct nlattr *attrs[],
8860020e 3673 struct cfg80211_beacon_data *bcn)
ed1b6cc7 3674{
8860020e 3675 bool haveinfo = false;
ed1b6cc7 3676
a1193be8
SW
3677 if (!is_valid_ie_attr(attrs[NL80211_ATTR_BEACON_TAIL]) ||
3678 !is_valid_ie_attr(attrs[NL80211_ATTR_IE]) ||
3679 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
3680 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_ASSOC_RESP]))
f4a11bb0
JB
3681 return -EINVAL;
3682
8860020e 3683 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 3684
a1193be8
SW
3685 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
3686 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
3687 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
3688 if (!bcn->head_len)
3689 return -EINVAL;
3690 haveinfo = true;
ed1b6cc7
JB
3691 }
3692
a1193be8
SW
3693 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
3694 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
3695 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 3696 haveinfo = true;
ed1b6cc7
JB
3697 }
3698
4c476991
JB
3699 if (!haveinfo)
3700 return -EINVAL;
3b85875a 3701
a1193be8
SW
3702 if (attrs[NL80211_ATTR_IE]) {
3703 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
3704 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
3705 }
3706
a1193be8 3707 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 3708 bcn->proberesp_ies =
a1193be8 3709 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 3710 bcn->proberesp_ies_len =
a1193be8 3711 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
3712 }
3713
a1193be8 3714 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 3715 bcn->assocresp_ies =
a1193be8 3716 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 3717 bcn->assocresp_ies_len =
a1193be8 3718 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
3719 }
3720
a1193be8
SW
3721 if (attrs[NL80211_ATTR_PROBE_RESP]) {
3722 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
3723 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
3724 }
3725
8860020e
JB
3726 return 0;
3727}
3728
46c1dd0c
FF
3729static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3730 struct cfg80211_ap_settings *params)
3731{
3732 struct wireless_dev *wdev;
3733 bool ret = false;
3734
53873f13 3735 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
3736 if (wdev->iftype != NL80211_IFTYPE_AP &&
3737 wdev->iftype != NL80211_IFTYPE_P2P_GO)
3738 continue;
3739
683b6d3b 3740 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
3741 continue;
3742
683b6d3b 3743 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
3744 ret = true;
3745 break;
3746 }
3747
46c1dd0c
FF
3748 return ret;
3749}
3750
e39e5b5e
JM
3751static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
3752 enum nl80211_auth_type auth_type,
3753 enum nl80211_commands cmd)
3754{
3755 if (auth_type > NL80211_AUTHTYPE_MAX)
3756 return false;
3757
3758 switch (cmd) {
3759 case NL80211_CMD_AUTHENTICATE:
3760 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
3761 auth_type == NL80211_AUTHTYPE_SAE)
3762 return false;
3763 return true;
3764 case NL80211_CMD_CONNECT:
3765 case NL80211_CMD_START_AP:
3766 /* SAE not supported yet */
3767 if (auth_type == NL80211_AUTHTYPE_SAE)
3768 return false;
3769 return true;
3770 default:
3771 return false;
3772 }
3773}
3774
8860020e
JB
3775static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3776{
3777 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3778 struct net_device *dev = info->user_ptr[1];
3779 struct wireless_dev *wdev = dev->ieee80211_ptr;
3780 struct cfg80211_ap_settings params;
3781 int err;
3782
3783 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3784 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3785 return -EOPNOTSUPP;
3786
3787 if (!rdev->ops->start_ap)
3788 return -EOPNOTSUPP;
3789
3790 if (wdev->beacon_interval)
3791 return -EALREADY;
3792
3793 memset(&params, 0, sizeof(params));
3794
3795 /* these are required for START_AP */
3796 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
3797 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
3798 !info->attrs[NL80211_ATTR_BEACON_HEAD])
3799 return -EINVAL;
3800
a1193be8 3801 err = nl80211_parse_beacon(info->attrs, &params.beacon);
8860020e
JB
3802 if (err)
3803 return err;
3804
3805 params.beacon_interval =
3806 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3807 params.dtim_period =
3808 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
3809
0c317a02
PK
3810 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
3811 params.beacon_interval);
8860020e
JB
3812 if (err)
3813 return err;
3814
3815 /*
3816 * In theory, some of these attributes should be required here
3817 * but since they were not used when the command was originally
3818 * added, keep them optional for old user space programs to let
3819 * them continue to work with drivers that do not need the
3820 * additional information -- drivers must check!
3821 */
3822 if (info->attrs[NL80211_ATTR_SSID]) {
3823 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3824 params.ssid_len =
3825 nla_len(info->attrs[NL80211_ATTR_SSID]);
3826 if (params.ssid_len == 0 ||
3827 params.ssid_len > IEEE80211_MAX_SSID_LEN)
3828 return -EINVAL;
3829 }
3830
3831 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
3832 params.hidden_ssid = nla_get_u32(
3833 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
3834 if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
3835 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
3836 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
3837 return -EINVAL;
3838 }
3839
3840 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
3841
3842 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
3843 params.auth_type = nla_get_u32(
3844 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
3845 if (!nl80211_valid_auth_type(rdev, params.auth_type,
3846 NL80211_CMD_START_AP))
8860020e
JB
3847 return -EINVAL;
3848 } else
3849 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
3850
3851 err = nl80211_crypto_settings(rdev, info, &params.crypto,
3852 NL80211_MAX_NR_CIPHER_SUITES);
3853 if (err)
3854 return err;
3855
1b658f11
VT
3856 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
3857 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
3858 return -EOPNOTSUPP;
3859 params.inactivity_timeout = nla_get_u16(
3860 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
3861 }
3862
53cabad7
JB
3863 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
3864 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3865 return -EINVAL;
3866 params.p2p_ctwindow =
3867 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
3868 if (params.p2p_ctwindow > 127)
3869 return -EINVAL;
3870 if (params.p2p_ctwindow != 0 &&
3871 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
3872 return -EINVAL;
3873 }
3874
3875 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
3876 u8 tmp;
3877
3878 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3879 return -EINVAL;
3880 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
3881 if (tmp > 1)
3882 return -EINVAL;
3883 params.p2p_opp_ps = tmp;
3884 if (params.p2p_opp_ps != 0 &&
3885 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
3886 return -EINVAL;
3887 }
3888
aa430da4 3889 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
3890 err = nl80211_parse_chandef(rdev, info, &params.chandef);
3891 if (err)
3892 return err;
3893 } else if (wdev->preset_chandef.chan) {
3894 params.chandef = wdev->preset_chandef;
46c1dd0c 3895 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
3896 return -EINVAL;
3897
923b352f
AN
3898 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
3899 wdev->iftype))
aa430da4
JB
3900 return -EINVAL;
3901
a7c7fbff
PK
3902 if (info->attrs[NL80211_ATTR_TX_RATES]) {
3903 err = nl80211_parse_tx_bitrate_mask(info, &params.beacon_rate);
3904 if (err)
3905 return err;
3906
8564e382
JB
3907 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
3908 &params.beacon_rate);
a7c7fbff
PK
3909 if (err)
3910 return err;
3911 }
3912
18998c38
EP
3913 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
3914 params.smps_mode =
3915 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
3916 switch (params.smps_mode) {
3917 case NL80211_SMPS_OFF:
3918 break;
3919 case NL80211_SMPS_STATIC:
3920 if (!(rdev->wiphy.features &
3921 NL80211_FEATURE_STATIC_SMPS))
3922 return -EINVAL;
3923 break;
3924 case NL80211_SMPS_DYNAMIC:
3925 if (!(rdev->wiphy.features &
3926 NL80211_FEATURE_DYNAMIC_SMPS))
3927 return -EINVAL;
3928 break;
3929 default:
3930 return -EINVAL;
3931 }
3932 } else {
3933 params.smps_mode = NL80211_SMPS_OFF;
3934 }
3935
6e8ef842
PK
3936 params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
3937 if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
3938 return -EOPNOTSUPP;
3939
4baf6bea
OO
3940 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
3941 params.acl = parse_acl_data(&rdev->wiphy, info);
3942 if (IS_ERR(params.acl))
3943 return PTR_ERR(params.acl);
3944 }
3945
c56589ed 3946 wdev_lock(wdev);
e35e4d28 3947 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 3948 if (!err) {
683b6d3b 3949 wdev->preset_chandef = params.chandef;
8860020e 3950 wdev->beacon_interval = params.beacon_interval;
9e0e2961 3951 wdev->chandef = params.chandef;
06e191e2
AQ
3952 wdev->ssid_len = params.ssid_len;
3953 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
46c1dd0c 3954 }
c56589ed 3955 wdev_unlock(wdev);
77765eaf
VT
3956
3957 kfree(params.acl);
3958
56d1893d 3959 return err;
ed1b6cc7
JB
3960}
3961
8860020e
JB
3962static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
3963{
3964 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3965 struct net_device *dev = info->user_ptr[1];
3966 struct wireless_dev *wdev = dev->ieee80211_ptr;
3967 struct cfg80211_beacon_data params;
3968 int err;
3969
3970 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3971 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3972 return -EOPNOTSUPP;
3973
3974 if (!rdev->ops->change_beacon)
3975 return -EOPNOTSUPP;
3976
3977 if (!wdev->beacon_interval)
3978 return -EINVAL;
3979
a1193be8 3980 err = nl80211_parse_beacon(info->attrs, &params);
8860020e
JB
3981 if (err)
3982 return err;
3983
c56589ed
SW
3984 wdev_lock(wdev);
3985 err = rdev_change_beacon(rdev, dev, &params);
3986 wdev_unlock(wdev);
3987
3988 return err;
8860020e
JB
3989}
3990
3991static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 3992{
4c476991
JB
3993 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3994 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 3995
7c8d5e03 3996 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
3997}
3998
5727ef1b
JB
3999static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
4000 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
4001 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
4002 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 4003 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 4004 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 4005 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
4006};
4007
eccb8e8f 4008static int parse_station_flags(struct genl_info *info,
bdd3ae3d 4009 enum nl80211_iftype iftype,
eccb8e8f 4010 struct station_parameters *params)
5727ef1b
JB
4011{
4012 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 4013 struct nlattr *nla;
5727ef1b
JB
4014 int flag;
4015
eccb8e8f
JB
4016 /*
4017 * Try parsing the new attribute first so userspace
4018 * can specify both for older kernels.
4019 */
4020 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
4021 if (nla) {
4022 struct nl80211_sta_flag_update *sta_flags;
4023
4024 sta_flags = nla_data(nla);
4025 params->sta_flags_mask = sta_flags->mask;
4026 params->sta_flags_set = sta_flags->set;
77ee7c89 4027 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
4028 if ((params->sta_flags_mask |
4029 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
4030 return -EINVAL;
4031 return 0;
4032 }
4033
4034 /* if present, parse the old attribute */
5727ef1b 4035
eccb8e8f 4036 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
4037 if (!nla)
4038 return 0;
4039
4040 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
4041 nla, sta_flags_policy))
4042 return -EINVAL;
4043
bdd3ae3d
JB
4044 /*
4045 * Only allow certain flags for interface types so that
4046 * other attributes are silently ignored. Remember that
4047 * this is backward compatibility code with old userspace
4048 * and shouldn't be hit in other cases anyway.
4049 */
4050 switch (iftype) {
4051 case NL80211_IFTYPE_AP:
4052 case NL80211_IFTYPE_AP_VLAN:
4053 case NL80211_IFTYPE_P2P_GO:
4054 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4055 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4056 BIT(NL80211_STA_FLAG_WME) |
4057 BIT(NL80211_STA_FLAG_MFP);
4058 break;
4059 case NL80211_IFTYPE_P2P_CLIENT:
4060 case NL80211_IFTYPE_STATION:
4061 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4062 BIT(NL80211_STA_FLAG_TDLS_PEER);
4063 break;
4064 case NL80211_IFTYPE_MESH_POINT:
4065 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4066 BIT(NL80211_STA_FLAG_MFP) |
4067 BIT(NL80211_STA_FLAG_AUTHORIZED);
4068 default:
4069 return -EINVAL;
4070 }
5727ef1b 4071
3383b5a6
JB
4072 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
4073 if (flags[flag]) {
eccb8e8f 4074 params->sta_flags_set |= (1<<flag);
5727ef1b 4075
3383b5a6
JB
4076 /* no longer support new API additions in old API */
4077 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
4078 return -EINVAL;
4079 }
4080 }
4081
5727ef1b
JB
4082 return 0;
4083}
4084
c8dcfd8a
FF
4085static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
4086 int attr)
4087{
4088 struct nlattr *rate;
8eb41c8d
VK
4089 u32 bitrate;
4090 u16 bitrate_compat;
b51f3bee 4091 enum nl80211_attrs rate_flg;
c8dcfd8a
FF
4092
4093 rate = nla_nest_start(msg, attr);
4094 if (!rate)
db9c64cf 4095 return false;
c8dcfd8a
FF
4096
4097 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
4098 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
4099 /* report 16-bit bitrate only if we can */
4100 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
4101 if (bitrate > 0 &&
4102 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
4103 return false;
4104 if (bitrate_compat > 0 &&
4105 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
4106 return false;
4107
b51f3bee
JB
4108 switch (info->bw) {
4109 case RATE_INFO_BW_5:
4110 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
4111 break;
4112 case RATE_INFO_BW_10:
4113 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
4114 break;
4115 default:
4116 WARN_ON(1);
4117 /* fall through */
4118 case RATE_INFO_BW_20:
4119 rate_flg = 0;
4120 break;
4121 case RATE_INFO_BW_40:
4122 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
4123 break;
4124 case RATE_INFO_BW_80:
4125 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
4126 break;
4127 case RATE_INFO_BW_160:
4128 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
4129 break;
4130 }
4131
4132 if (rate_flg && nla_put_flag(msg, rate_flg))
4133 return false;
4134
db9c64cf
JB
4135 if (info->flags & RATE_INFO_FLAGS_MCS) {
4136 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
4137 return false;
db9c64cf
JB
4138 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4139 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4140 return false;
4141 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
4142 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
4143 return false;
4144 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
4145 return false;
db9c64cf
JB
4146 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4147 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4148 return false;
4149 }
c8dcfd8a
FF
4150
4151 nla_nest_end(msg, rate);
4152 return true;
c8dcfd8a
FF
4153}
4154
119363c7
FF
4155static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
4156 int id)
4157{
4158 void *attr;
4159 int i = 0;
4160
4161 if (!mask)
4162 return true;
4163
4164 attr = nla_nest_start(msg, id);
4165 if (!attr)
4166 return false;
4167
4168 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
4169 if (!(mask & BIT(i)))
4170 continue;
4171
4172 if (nla_put_u8(msg, i, signal[i]))
4173 return false;
4174 }
4175
4176 nla_nest_end(msg, attr);
4177
4178 return true;
4179}
4180
cf5ead82
JB
4181static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
4182 u32 seq, int flags,
66266b3a
JL
4183 struct cfg80211_registered_device *rdev,
4184 struct net_device *dev,
98b62183 4185 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
4186{
4187 void *hdr;
f4263c98 4188 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 4189
cf5ead82 4190 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
fd5b74dc
JB
4191 if (!hdr)
4192 return -1;
4193
9360ffd1
DM
4194 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4195 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
4196 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
4197 goto nla_put_failure;
f5ea9120 4198
2ec600d6
LCC
4199 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
4200 if (!sinfoattr)
fd5b74dc 4201 goto nla_put_failure;
319090bf
JB
4202
4203#define PUT_SINFO(attr, memb, type) do { \
d686b920 4204 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
739960f1 4205 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
319090bf
JB
4206 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
4207 sinfo->memb)) \
4208 goto nla_put_failure; \
4209 } while (0)
d686b920
JB
4210#define PUT_SINFO_U64(attr, memb) do { \
4211 if (sinfo->filled & (1ULL << NL80211_STA_INFO_ ## attr) && \
4212 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
4213 sinfo->memb, NL80211_STA_INFO_PAD)) \
4214 goto nla_put_failure; \
4215 } while (0)
319090bf
JB
4216
4217 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
4218 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
4219
4220 if (sinfo->filled & (BIT(NL80211_STA_INFO_RX_BYTES) |
4221 BIT(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 4222 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 4223 (u32)sinfo->rx_bytes))
9360ffd1 4224 goto nla_put_failure;
319090bf
JB
4225
4226 if (sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES) |
4227 BIT(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 4228 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
4229 (u32)sinfo->tx_bytes))
4230 goto nla_put_failure;
319090bf 4231
d686b920
JB
4232 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
4233 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
4234 PUT_SINFO(LLID, llid, u16);
4235 PUT_SINFO(PLID, plid, u16);
4236 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 4237 PUT_SINFO_U64(RX_DURATION, rx_duration);
319090bf 4238
66266b3a
JL
4239 switch (rdev->wiphy.signal_type) {
4240 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
4241 PUT_SINFO(SIGNAL, signal, u8);
4242 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
4243 break;
4244 default:
4245 break;
4246 }
319090bf 4247 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
4248 if (!nl80211_put_signal(msg, sinfo->chains,
4249 sinfo->chain_signal,
4250 NL80211_STA_INFO_CHAIN_SIGNAL))
4251 goto nla_put_failure;
4252 }
319090bf 4253 if (sinfo->filled & BIT(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
4254 if (!nl80211_put_signal(msg, sinfo->chains,
4255 sinfo->chain_signal_avg,
4256 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
4257 goto nla_put_failure;
4258 }
319090bf 4259 if (sinfo->filled & BIT(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
4260 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
4261 NL80211_STA_INFO_TX_BITRATE))
4262 goto nla_put_failure;
4263 }
319090bf 4264 if (sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
4265 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
4266 NL80211_STA_INFO_RX_BITRATE))
420e7fab 4267 goto nla_put_failure;
420e7fab 4268 }
319090bf
JB
4269
4270 PUT_SINFO(RX_PACKETS, rx_packets, u32);
4271 PUT_SINFO(TX_PACKETS, tx_packets, u32);
4272 PUT_SINFO(TX_RETRIES, tx_retries, u32);
4273 PUT_SINFO(TX_FAILED, tx_failed, u32);
4274 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
4275 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
4276 PUT_SINFO(LOCAL_PM, local_pm, u32);
4277 PUT_SINFO(PEER_PM, peer_pm, u32);
4278 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
4279
4280 if (sinfo->filled & BIT(NL80211_STA_INFO_BSS_PARAM)) {
f4263c98
PS
4281 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
4282 if (!bss_param)
4283 goto nla_put_failure;
4284
9360ffd1
DM
4285 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
4286 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
4287 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
4288 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
4289 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
4290 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
4291 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
4292 sinfo->bss_param.dtim_period) ||
4293 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
4294 sinfo->bss_param.beacon_interval))
4295 goto nla_put_failure;
f4263c98
PS
4296
4297 nla_nest_end(msg, bss_param);
4298 }
319090bf 4299 if ((sinfo->filled & BIT(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
4300 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
4301 sizeof(struct nl80211_sta_flag_update),
4302 &sinfo->sta_flags))
4303 goto nla_put_failure;
319090bf 4304
d686b920
JB
4305 PUT_SINFO_U64(T_OFFSET, t_offset);
4306 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
4307 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 4308 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
319090bf
JB
4309
4310#undef PUT_SINFO
d686b920 4311#undef PUT_SINFO_U64
6de39808
JB
4312
4313 if (sinfo->filled & BIT(NL80211_STA_INFO_TID_STATS)) {
4314 struct nlattr *tidsattr;
4315 int tid;
4316
4317 tidsattr = nla_nest_start(msg, NL80211_STA_INFO_TID_STATS);
4318 if (!tidsattr)
4319 goto nla_put_failure;
4320
4321 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
4322 struct cfg80211_tid_stats *tidstats;
4323 struct nlattr *tidattr;
4324
4325 tidstats = &sinfo->pertid[tid];
4326
4327 if (!tidstats->filled)
4328 continue;
4329
4330 tidattr = nla_nest_start(msg, tid + 1);
4331 if (!tidattr)
4332 goto nla_put_failure;
4333
d686b920 4334#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 4335 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
4336 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
4337 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
4338 goto nla_put_failure; \
4339 } while (0)
4340
d686b920
JB
4341 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
4342 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
4343 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
4344 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 4345
d686b920 4346#undef PUT_TIDVAL_U64
6de39808
JB
4347 nla_nest_end(msg, tidattr);
4348 }
4349
4350 nla_nest_end(msg, tidsattr);
4351 }
4352
2ec600d6 4353 nla_nest_end(msg, sinfoattr);
fd5b74dc 4354
319090bf 4355 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
4356 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
4357 sinfo->assoc_req_ies))
4358 goto nla_put_failure;
50d3dfb7 4359
053c095a
JB
4360 genlmsg_end(msg, hdr);
4361 return 0;
fd5b74dc
JB
4362
4363 nla_put_failure:
bc3ed28c
TG
4364 genlmsg_cancel(msg, hdr);
4365 return -EMSGSIZE;
fd5b74dc
JB
4366}
4367
2ec600d6 4368static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 4369 struct netlink_callback *cb)
2ec600d6 4370{
2ec600d6 4371 struct station_info sinfo;
1b8ec87a 4372 struct cfg80211_registered_device *rdev;
97990a06 4373 struct wireless_dev *wdev;
2ec600d6 4374 u8 mac_addr[ETH_ALEN];
97990a06 4375 int sta_idx = cb->args[2];
2ec600d6 4376 int err;
2ec600d6 4377
1b8ec87a 4378 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
4379 if (err)
4380 return err;
bba95fef 4381
97990a06
JB
4382 if (!wdev->netdev) {
4383 err = -EINVAL;
4384 goto out_err;
4385 }
4386
1b8ec87a 4387 if (!rdev->ops->dump_station) {
eec60b03 4388 err = -EOPNOTSUPP;
bba95fef
JB
4389 goto out_err;
4390 }
4391
bba95fef 4392 while (1) {
f612cedf 4393 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 4394 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
e35e4d28 4395 mac_addr, &sinfo);
bba95fef
JB
4396 if (err == -ENOENT)
4397 break;
4398 if (err)
3b85875a 4399 goto out_err;
bba95fef 4400
cf5ead82 4401 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 4402 NETLINK_CB(cb->skb).portid,
bba95fef 4403 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 4404 rdev, wdev->netdev, mac_addr,
bba95fef
JB
4405 &sinfo) < 0)
4406 goto out;
4407
4408 sta_idx++;
4409 }
4410
bba95fef 4411 out:
97990a06 4412 cb->args[2] = sta_idx;
bba95fef 4413 err = skb->len;
bba95fef 4414 out_err:
1b8ec87a 4415 nl80211_finish_wdev_dump(rdev);
bba95fef
JB
4416
4417 return err;
2ec600d6 4418}
fd5b74dc 4419
5727ef1b
JB
4420static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
4421{
4c476991
JB
4422 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4423 struct net_device *dev = info->user_ptr[1];
2ec600d6 4424 struct station_info sinfo;
fd5b74dc
JB
4425 struct sk_buff *msg;
4426 u8 *mac_addr = NULL;
4c476991 4427 int err;
fd5b74dc 4428
2ec600d6 4429 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc
JB
4430
4431 if (!info->attrs[NL80211_ATTR_MAC])
4432 return -EINVAL;
4433
4434 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4435
4c476991
JB
4436 if (!rdev->ops->get_station)
4437 return -EOPNOTSUPP;
3b85875a 4438
e35e4d28 4439 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 4440 if (err)
4c476991 4441 return err;
2ec600d6 4442
fd2120ca 4443 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
fd5b74dc 4444 if (!msg)
4c476991 4445 return -ENOMEM;
fd5b74dc 4446
cf5ead82
JB
4447 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
4448 info->snd_portid, info->snd_seq, 0,
66266b3a 4449 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991
JB
4450 nlmsg_free(msg);
4451 return -ENOBUFS;
4452 }
3b85875a 4453
4c476991 4454 return genlmsg_reply(msg, info);
5727ef1b
JB
4455}
4456
77ee7c89
JB
4457int cfg80211_check_station_change(struct wiphy *wiphy,
4458 struct station_parameters *params,
4459 enum cfg80211_station_type statype)
4460{
e4208427
AB
4461 if (params->listen_interval != -1 &&
4462 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 4463 return -EINVAL;
e4208427 4464
17b94247
AB
4465 if (params->support_p2p_ps != -1 &&
4466 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
4467 return -EINVAL;
4468
c72e1140 4469 if (params->aid &&
e4208427
AB
4470 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
4471 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
4472 return -EINVAL;
4473
4474 /* When you run into this, adjust the code below for the new flag */
4475 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
4476
4477 switch (statype) {
eef941e6
TP
4478 case CFG80211_STA_MESH_PEER_KERNEL:
4479 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
4480 /*
4481 * No ignoring the TDLS flag here -- the userspace mesh
4482 * code doesn't have the bug of including TDLS in the
4483 * mask everywhere.
4484 */
4485 if (params->sta_flags_mask &
4486 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4487 BIT(NL80211_STA_FLAG_MFP) |
4488 BIT(NL80211_STA_FLAG_AUTHORIZED)))
4489 return -EINVAL;
4490 break;
4491 case CFG80211_STA_TDLS_PEER_SETUP:
4492 case CFG80211_STA_TDLS_PEER_ACTIVE:
4493 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
4494 return -EINVAL;
4495 /* ignore since it can't change */
4496 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
4497 break;
4498 default:
4499 /* disallow mesh-specific things */
4500 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
4501 return -EINVAL;
4502 if (params->local_pm)
4503 return -EINVAL;
4504 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
4505 return -EINVAL;
4506 }
4507
4508 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
4509 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
4510 /* TDLS can't be set, ... */
4511 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
4512 return -EINVAL;
4513 /*
4514 * ... but don't bother the driver with it. This works around
4515 * a hostapd/wpa_supplicant issue -- it always includes the
4516 * TLDS_PEER flag in the mask even for AP mode.
4517 */
4518 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
4519 }
4520
47edb11b
AB
4521 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
4522 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
4523 /* reject other things that can't change */
4524 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
4525 return -EINVAL;
4526 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
4527 return -EINVAL;
4528 if (params->supported_rates)
4529 return -EINVAL;
4530 if (params->ext_capab || params->ht_capa || params->vht_capa)
4531 return -EINVAL;
4532 }
4533
47edb11b
AB
4534 if (statype != CFG80211_STA_AP_CLIENT &&
4535 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
4536 if (params->vlan)
4537 return -EINVAL;
4538 }
4539
4540 switch (statype) {
4541 case CFG80211_STA_AP_MLME_CLIENT:
4542 /* Use this only for authorizing/unauthorizing a station */
4543 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4544 return -EOPNOTSUPP;
4545 break;
4546 case CFG80211_STA_AP_CLIENT:
47edb11b 4547 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
4548 /* accept only the listed bits */
4549 if (params->sta_flags_mask &
4550 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
4551 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4552 BIT(NL80211_STA_FLAG_ASSOCIATED) |
4553 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4554 BIT(NL80211_STA_FLAG_WME) |
4555 BIT(NL80211_STA_FLAG_MFP)))
4556 return -EINVAL;
4557
4558 /* but authenticated/associated only if driver handles it */
4559 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
4560 params->sta_flags_mask &
4561 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4562 BIT(NL80211_STA_FLAG_ASSOCIATED)))
4563 return -EINVAL;
4564 break;
4565 case CFG80211_STA_IBSS:
4566 case CFG80211_STA_AP_STA:
4567 /* reject any changes other than AUTHORIZED */
4568 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
4569 return -EINVAL;
4570 break;
4571 case CFG80211_STA_TDLS_PEER_SETUP:
4572 /* reject any changes other than AUTHORIZED or WME */
4573 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
4574 BIT(NL80211_STA_FLAG_WME)))
4575 return -EINVAL;
4576 /* force (at least) rates when authorizing */
4577 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
4578 !params->supported_rates)
4579 return -EINVAL;
4580 break;
4581 case CFG80211_STA_TDLS_PEER_ACTIVE:
4582 /* reject any changes */
4583 return -EINVAL;
eef941e6 4584 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
4585 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
4586 return -EINVAL;
4587 break;
eef941e6 4588 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
4589 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
4590 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
4591 return -EINVAL;
4592 break;
4593 }
4594
4595 return 0;
4596}
4597EXPORT_SYMBOL(cfg80211_check_station_change);
4598
5727ef1b 4599/*
c258d2de 4600 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 4601 */
80b99899
JB
4602static struct net_device *get_vlan(struct genl_info *info,
4603 struct cfg80211_registered_device *rdev)
5727ef1b 4604{
463d0183 4605 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
4606 struct net_device *v;
4607 int ret;
4608
4609 if (!vlanattr)
4610 return NULL;
4611
4612 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
4613 if (!v)
4614 return ERR_PTR(-ENODEV);
4615
4616 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
4617 ret = -EINVAL;
4618 goto error;
5727ef1b 4619 }
80b99899 4620
77ee7c89
JB
4621 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4622 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4623 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
4624 ret = -EINVAL;
4625 goto error;
4626 }
4627
80b99899
JB
4628 if (!netif_running(v)) {
4629 ret = -ENETDOWN;
4630 goto error;
4631 }
4632
4633 return v;
4634 error:
4635 dev_put(v);
4636 return ERR_PTR(ret);
5727ef1b
JB
4637}
4638
94e860f1
JB
4639static const struct nla_policy
4640nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
4641 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
4642 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
4643};
4644
ff276691
JB
4645static int nl80211_parse_sta_wme(struct genl_info *info,
4646 struct station_parameters *params)
df881293 4647{
df881293
JM
4648 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
4649 struct nlattr *nla;
4650 int err;
4651
df881293
JM
4652 /* parse WME attributes if present */
4653 if (!info->attrs[NL80211_ATTR_STA_WME])
4654 return 0;
4655
4656 nla = info->attrs[NL80211_ATTR_STA_WME];
4657 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
4658 nl80211_sta_wme_policy);
4659 if (err)
4660 return err;
4661
4662 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
4663 params->uapsd_queues = nla_get_u8(
4664 tb[NL80211_STA_WME_UAPSD_QUEUES]);
4665 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
4666 return -EINVAL;
4667
4668 if (tb[NL80211_STA_WME_MAX_SP])
4669 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
4670
4671 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
4672 return -EINVAL;
4673
4674 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
4675
4676 return 0;
4677}
4678
c01fc9ad
SD
4679static int nl80211_parse_sta_channel_info(struct genl_info *info,
4680 struct station_parameters *params)
4681{
4682 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
4683 params->supported_channels =
4684 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
4685 params->supported_channels_len =
4686 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
4687 /*
4688 * Need to include at least one (first channel, number of
4689 * channels) tuple for each subband, and must have proper
4690 * tuples for the rest of the data as well.
4691 */
4692 if (params->supported_channels_len < 2)
4693 return -EINVAL;
4694 if (params->supported_channels_len % 2)
4695 return -EINVAL;
4696 }
4697
4698 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
4699 params->supported_oper_classes =
4700 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
4701 params->supported_oper_classes_len =
4702 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
4703 /*
4704 * The value of the Length field of the Supported Operating
4705 * Classes element is between 2 and 253.
4706 */
4707 if (params->supported_oper_classes_len < 2 ||
4708 params->supported_oper_classes_len > 253)
4709 return -EINVAL;
4710 }
4711 return 0;
4712}
4713
ff276691
JB
4714static int nl80211_set_station_tdls(struct genl_info *info,
4715 struct station_parameters *params)
4716{
c01fc9ad 4717 int err;
ff276691 4718 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
4719 if (info->attrs[NL80211_ATTR_PEER_AID])
4720 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
4721 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
4722 params->ht_capa =
4723 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
4724 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
4725 params->vht_capa =
4726 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
4727
c01fc9ad
SD
4728 err = nl80211_parse_sta_channel_info(info, params);
4729 if (err)
4730 return err;
4731
ff276691
JB
4732 return nl80211_parse_sta_wme(info, params);
4733}
4734
5727ef1b
JB
4735static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
4736{
4c476991 4737 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 4738 struct net_device *dev = info->user_ptr[1];
5727ef1b 4739 struct station_parameters params;
77ee7c89
JB
4740 u8 *mac_addr;
4741 int err;
5727ef1b
JB
4742
4743 memset(&params, 0, sizeof(params));
4744
77ee7c89
JB
4745 if (!rdev->ops->change_station)
4746 return -EOPNOTSUPP;
4747
e4208427
AB
4748 /*
4749 * AID and listen_interval properties can be set only for unassociated
4750 * station. Include these parameters here and will check them in
4751 * cfg80211_check_station_change().
4752 */
a9bc31e4
AB
4753 if (info->attrs[NL80211_ATTR_STA_AID])
4754 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427
AB
4755
4756 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
4757 params.listen_interval =
4758 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
4759 else
4760 params.listen_interval = -1;
5727ef1b 4761
17b94247
AB
4762 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
4763 u8 tmp;
4764
4765 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
4766 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
4767 return -EINVAL;
4768
4769 params.support_p2p_ps = tmp;
4770 } else {
4771 params.support_p2p_ps = -1;
4772 }
4773
5727ef1b
JB
4774 if (!info->attrs[NL80211_ATTR_MAC])
4775 return -EINVAL;
4776
4777 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4778
4779 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
4780 params.supported_rates =
4781 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4782 params.supported_rates_len =
4783 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4784 }
4785
9d62a986
JM
4786 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
4787 params.capability =
4788 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
4789 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
4790 }
4791
4792 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
4793 params.ext_capab =
4794 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4795 params.ext_capab_len =
4796 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4797 }
4798
bdd3ae3d 4799 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
4800 return -EINVAL;
4801
f8bacc21 4802 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
2ec600d6 4803 params.plink_action =
f8bacc21
JB
4804 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
4805 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
4806 return -EINVAL;
4807 }
2ec600d6 4808
f8bacc21 4809 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 4810 params.plink_state =
f8bacc21
JB
4811 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
4812 if (params.plink_state >= NUM_NL80211_PLINK_STATES)
4813 return -EINVAL;
7d27a0ba
MH
4814 if (info->attrs[NL80211_ATTR_MESH_PEER_AID]) {
4815 params.peer_aid = nla_get_u16(
4816 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
4817 if (params.peer_aid > IEEE80211_MAX_AID)
4818 return -EINVAL;
4819 }
f8bacc21
JB
4820 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
4821 }
9c3990aa 4822
3b1c5a53
MP
4823 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) {
4824 enum nl80211_mesh_power_mode pm = nla_get_u32(
4825 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
4826
4827 if (pm <= NL80211_MESH_POWER_UNKNOWN ||
4828 pm > NL80211_MESH_POWER_MAX)
4829 return -EINVAL;
4830
4831 params.local_pm = pm;
4832 }
4833
77ee7c89
JB
4834 /* Include parameters for TDLS peer (will check later) */
4835 err = nl80211_set_station_tdls(info, &params);
4836 if (err)
4837 return err;
4838
4839 params.vlan = get_vlan(info, rdev);
4840 if (IS_ERR(params.vlan))
4841 return PTR_ERR(params.vlan);
4842
a97f4424
JB
4843 switch (dev->ieee80211_ptr->iftype) {
4844 case NL80211_IFTYPE_AP:
4845 case NL80211_IFTYPE_AP_VLAN:
074ac8df 4846 case NL80211_IFTYPE_P2P_GO:
074ac8df 4847 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 4848 case NL80211_IFTYPE_STATION:
267335d6 4849 case NL80211_IFTYPE_ADHOC:
a97f4424 4850 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
4851 break;
4852 default:
77ee7c89
JB
4853 err = -EOPNOTSUPP;
4854 goto out_put_vlan;
034d655e
JB
4855 }
4856
77ee7c89 4857 /* driver will call cfg80211_check_station_change() */
e35e4d28 4858 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 4859
77ee7c89 4860 out_put_vlan:
5727ef1b
JB
4861 if (params.vlan)
4862 dev_put(params.vlan);
3b85875a 4863
5727ef1b
JB
4864 return err;
4865}
4866
4867static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
4868{
4c476991 4869 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 4870 int err;
4c476991 4871 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
4872 struct station_parameters params;
4873 u8 *mac_addr = NULL;
bda95eb1
JB
4874 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4875 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
4876
4877 memset(&params, 0, sizeof(params));
4878
984c311b
JB
4879 if (!rdev->ops->add_station)
4880 return -EOPNOTSUPP;
4881
5727ef1b
JB
4882 if (!info->attrs[NL80211_ATTR_MAC])
4883 return -EINVAL;
4884
5727ef1b
JB
4885 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
4886 return -EINVAL;
4887
4888 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
4889 return -EINVAL;
4890
5e4b6f56
JM
4891 if (!info->attrs[NL80211_ATTR_STA_AID] &&
4892 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
4893 return -EINVAL;
4894
5727ef1b
JB
4895 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4896 params.supported_rates =
4897 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4898 params.supported_rates_len =
4899 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
4900 params.listen_interval =
4901 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 4902
17b94247
AB
4903 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
4904 u8 tmp;
4905
4906 tmp = nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
4907 if (tmp >= NUM_NL80211_P2P_PS_STATUS)
4908 return -EINVAL;
4909
4910 params.support_p2p_ps = tmp;
4911 } else {
4912 /*
4913 * if not specified, assume it's supported for P2P GO interface,
4914 * and is NOT supported for AP interface
4915 */
4916 params.support_p2p_ps =
4917 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
4918 }
4919
3d124ea2 4920 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 4921 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
4922 else
4923 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
0e956c13
TLSC
4924 if (!params.aid || params.aid > IEEE80211_MAX_AID)
4925 return -EINVAL;
51b50fbe 4926
9d62a986
JM
4927 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
4928 params.capability =
4929 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
4930 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
4931 }
4932
4933 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
4934 params.ext_capab =
4935 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4936 params.ext_capab_len =
4937 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
4938 }
4939
36aedc90
JM
4940 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
4941 params.ht_capa =
4942 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 4943
f461be3e
MP
4944 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
4945 params.vht_capa =
4946 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
4947
60f4a7b1
MK
4948 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
4949 params.opmode_notif_used = true;
4950 params.opmode_notif =
4951 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
4952 }
4953
f8bacc21 4954 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) {
96b78dff 4955 params.plink_action =
f8bacc21
JB
4956 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
4957 if (params.plink_action >= NUM_NL80211_PLINK_ACTIONS)
4958 return -EINVAL;
4959 }
96b78dff 4960
c01fc9ad
SD
4961 err = nl80211_parse_sta_channel_info(info, &params);
4962 if (err)
4963 return err;
4964
ff276691
JB
4965 err = nl80211_parse_sta_wme(info, &params);
4966 if (err)
4967 return err;
bdd90d5e 4968
bdd3ae3d 4969 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
4970 return -EINVAL;
4971
496fcc29
JB
4972 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
4973 * as userspace might just pass through the capabilities from the IEs
4974 * directly, rather than enforcing this restriction and returning an
4975 * error in this case.
4976 */
4977 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
4978 params.ht_capa = NULL;
4979 params.vht_capa = NULL;
4980 }
4981
77ee7c89
JB
4982 /* When you run into this, adjust the code below for the new flag */
4983 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
4984
bdd90d5e
JB
4985 switch (dev->ieee80211_ptr->iftype) {
4986 case NL80211_IFTYPE_AP:
4987 case NL80211_IFTYPE_AP_VLAN:
4988 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
4989 /* ignore WME attributes if iface/sta is not capable */
4990 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
4991 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
4992 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 4993
bdd90d5e 4994 /* TDLS peers cannot be added */
3d124ea2
JM
4995 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
4996 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 4997 return -EINVAL;
bdd90d5e
JB
4998 /* but don't bother the driver with it */
4999 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 5000
d582cffb
JB
5001 /* allow authenticated/associated only if driver handles it */
5002 if (!(rdev->wiphy.features &
5003 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 5004 params.sta_flags_mask & auth_assoc)
d582cffb
JB
5005 return -EINVAL;
5006
bda95eb1
JB
5007 /* Older userspace, or userspace wanting to be compatible with
5008 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
5009 * and assoc flags in the mask, but assumes the station will be
5010 * added as associated anyway since this was the required driver
5011 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
5012 * introduced.
5013 * In order to not bother drivers with this quirk in the API
5014 * set the flags in both the mask and set for new stations in
5015 * this case.
5016 */
5017 if (!(params.sta_flags_mask & auth_assoc)) {
5018 params.sta_flags_mask |= auth_assoc;
5019 params.sta_flags_set |= auth_assoc;
5020 }
5021
bdd90d5e
JB
5022 /* must be last in here for error handling */
5023 params.vlan = get_vlan(info, rdev);
5024 if (IS_ERR(params.vlan))
5025 return PTR_ERR(params.vlan);
5026 break;
5027 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
5028 /* ignore uAPSD data */
5029 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5030
d582cffb
JB
5031 /* associated is disallowed */
5032 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
5033 return -EINVAL;
bdd90d5e 5034 /* TDLS peers cannot be added */
3d124ea2
JM
5035 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5036 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
5037 return -EINVAL;
5038 break;
5039 case NL80211_IFTYPE_STATION:
93d08f0b 5040 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
5041 /* ignore uAPSD data */
5042 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5043
77ee7c89
JB
5044 /* these are disallowed */
5045 if (params.sta_flags_mask &
5046 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
5047 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 5048 return -EINVAL;
bdd90d5e
JB
5049 /* Only TDLS peers can be added */
5050 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
5051 return -EINVAL;
5052 /* Can only add if TDLS ... */
5053 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
5054 return -EOPNOTSUPP;
5055 /* ... with external setup is supported */
5056 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
5057 return -EOPNOTSUPP;
77ee7c89
JB
5058 /*
5059 * Older wpa_supplicant versions always mark the TDLS peer
5060 * as authorized, but it shouldn't yet be.
5061 */
5062 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
5063 break;
5064 default:
5065 return -EOPNOTSUPP;
c75786c9
EP
5066 }
5067
bdd90d5e 5068 /* be aware of params.vlan when changing code here */
5727ef1b 5069
e35e4d28 5070 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 5071
5727ef1b
JB
5072 if (params.vlan)
5073 dev_put(params.vlan);
5727ef1b
JB
5074 return err;
5075}
5076
5077static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
5078{
4c476991
JB
5079 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5080 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
5081 struct station_del_parameters params;
5082
5083 memset(&params, 0, sizeof(params));
5727ef1b
JB
5084
5085 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 5086 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 5087
e80cf853 5088 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
d5d9de02 5089 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
074ac8df 5090 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
5091 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5092 return -EINVAL;
5727ef1b 5093
4c476991
JB
5094 if (!rdev->ops->del_station)
5095 return -EOPNOTSUPP;
3b85875a 5096
98856866
JM
5097 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
5098 params.subtype =
5099 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
5100 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
5101 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
5102 return -EINVAL;
5103 } else {
5104 /* Default to Deauthentication frame */
5105 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
5106 }
5107
5108 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
5109 params.reason_code =
5110 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
5111 if (params.reason_code == 0)
5112 return -EINVAL; /* 0 is reserved */
5113 } else {
5114 /* Default to reason code 2 */
5115 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
5116 }
5117
89c771e5 5118 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
5119}
5120
15e47304 5121static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
5122 int flags, struct net_device *dev,
5123 u8 *dst, u8 *next_hop,
5124 struct mpath_info *pinfo)
5125{
5126 void *hdr;
5127 struct nlattr *pinfoattr;
5128
1ef4c850 5129 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
5130 if (!hdr)
5131 return -1;
5132
9360ffd1
DM
5133 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5134 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
5135 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
5136 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
5137 goto nla_put_failure;
f5ea9120 5138
2ec600d6
LCC
5139 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
5140 if (!pinfoattr)
5141 goto nla_put_failure;
9360ffd1
DM
5142 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
5143 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
5144 pinfo->frame_qlen))
5145 goto nla_put_failure;
5146 if (((pinfo->filled & MPATH_INFO_SN) &&
5147 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
5148 ((pinfo->filled & MPATH_INFO_METRIC) &&
5149 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
5150 pinfo->metric)) ||
5151 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
5152 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
5153 pinfo->exptime)) ||
5154 ((pinfo->filled & MPATH_INFO_FLAGS) &&
5155 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
5156 pinfo->flags)) ||
5157 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
5158 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
5159 pinfo->discovery_timeout)) ||
5160 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
5161 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
5162 pinfo->discovery_retries)))
5163 goto nla_put_failure;
2ec600d6
LCC
5164
5165 nla_nest_end(msg, pinfoattr);
5166
053c095a
JB
5167 genlmsg_end(msg, hdr);
5168 return 0;
2ec600d6
LCC
5169
5170 nla_put_failure:
bc3ed28c
TG
5171 genlmsg_cancel(msg, hdr);
5172 return -EMSGSIZE;
2ec600d6
LCC
5173}
5174
5175static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 5176 struct netlink_callback *cb)
2ec600d6 5177{
2ec600d6 5178 struct mpath_info pinfo;
1b8ec87a 5179 struct cfg80211_registered_device *rdev;
97990a06 5180 struct wireless_dev *wdev;
2ec600d6
LCC
5181 u8 dst[ETH_ALEN];
5182 u8 next_hop[ETH_ALEN];
97990a06 5183 int path_idx = cb->args[2];
2ec600d6 5184 int err;
2ec600d6 5185
1b8ec87a 5186 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
5187 if (err)
5188 return err;
bba95fef 5189
1b8ec87a 5190 if (!rdev->ops->dump_mpath) {
eec60b03 5191 err = -EOPNOTSUPP;
bba95fef
JB
5192 goto out_err;
5193 }
5194
97990a06 5195 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 5196 err = -EOPNOTSUPP;
0448b5fc 5197 goto out_err;
eec60b03
JM
5198 }
5199
bba95fef 5200 while (1) {
1b8ec87a 5201 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 5202 next_hop, &pinfo);
bba95fef 5203 if (err == -ENOENT)
2ec600d6 5204 break;
bba95fef 5205 if (err)
3b85875a 5206 goto out_err;
2ec600d6 5207
15e47304 5208 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 5209 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 5210 wdev->netdev, dst, next_hop,
bba95fef
JB
5211 &pinfo) < 0)
5212 goto out;
2ec600d6 5213
bba95fef 5214 path_idx++;
2ec600d6 5215 }
2ec600d6 5216
bba95fef 5217 out:
97990a06 5218 cb->args[2] = path_idx;
bba95fef 5219 err = skb->len;
bba95fef 5220 out_err:
1b8ec87a 5221 nl80211_finish_wdev_dump(rdev);
bba95fef 5222 return err;
2ec600d6
LCC
5223}
5224
5225static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
5226{
4c476991 5227 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 5228 int err;
4c476991 5229 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5230 struct mpath_info pinfo;
5231 struct sk_buff *msg;
5232 u8 *dst = NULL;
5233 u8 next_hop[ETH_ALEN];
5234
5235 memset(&pinfo, 0, sizeof(pinfo));
5236
5237 if (!info->attrs[NL80211_ATTR_MAC])
5238 return -EINVAL;
5239
5240 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5241
4c476991
JB
5242 if (!rdev->ops->get_mpath)
5243 return -EOPNOTSUPP;
2ec600d6 5244
4c476991
JB
5245 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5246 return -EOPNOTSUPP;
eec60b03 5247
e35e4d28 5248 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 5249 if (err)
4c476991 5250 return err;
2ec600d6 5251
fd2120ca 5252 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 5253 if (!msg)
4c476991 5254 return -ENOMEM;
2ec600d6 5255
15e47304 5256 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
5257 dev, dst, next_hop, &pinfo) < 0) {
5258 nlmsg_free(msg);
5259 return -ENOBUFS;
5260 }
3b85875a 5261
4c476991 5262 return genlmsg_reply(msg, info);
2ec600d6
LCC
5263}
5264
5265static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
5266{
4c476991
JB
5267 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5268 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5269 u8 *dst = NULL;
5270 u8 *next_hop = NULL;
5271
5272 if (!info->attrs[NL80211_ATTR_MAC])
5273 return -EINVAL;
5274
5275 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5276 return -EINVAL;
5277
5278 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5279 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5280
4c476991
JB
5281 if (!rdev->ops->change_mpath)
5282 return -EOPNOTSUPP;
35a8efe1 5283
4c476991
JB
5284 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5285 return -EOPNOTSUPP;
2ec600d6 5286
e35e4d28 5287 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 5288}
4c476991 5289
2ec600d6
LCC
5290static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
5291{
4c476991
JB
5292 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5293 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5294 u8 *dst = NULL;
5295 u8 *next_hop = NULL;
5296
5297 if (!info->attrs[NL80211_ATTR_MAC])
5298 return -EINVAL;
5299
5300 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
5301 return -EINVAL;
5302
5303 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5304 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
5305
4c476991
JB
5306 if (!rdev->ops->add_mpath)
5307 return -EOPNOTSUPP;
35a8efe1 5308
4c476991
JB
5309 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5310 return -EOPNOTSUPP;
2ec600d6 5311
e35e4d28 5312 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
5313}
5314
5315static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
5316{
4c476991
JB
5317 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5318 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
5319 u8 *dst = NULL;
5320
5321 if (info->attrs[NL80211_ATTR_MAC])
5322 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5323
4c476991
JB
5324 if (!rdev->ops->del_mpath)
5325 return -EOPNOTSUPP;
3b85875a 5326
e35e4d28 5327 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
5328}
5329
66be7d2b
HR
5330static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
5331{
5332 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5333 int err;
5334 struct net_device *dev = info->user_ptr[1];
5335 struct mpath_info pinfo;
5336 struct sk_buff *msg;
5337 u8 *dst = NULL;
5338 u8 mpp[ETH_ALEN];
5339
5340 memset(&pinfo, 0, sizeof(pinfo));
5341
5342 if (!info->attrs[NL80211_ATTR_MAC])
5343 return -EINVAL;
5344
5345 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
5346
5347 if (!rdev->ops->get_mpp)
5348 return -EOPNOTSUPP;
5349
5350 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
5351 return -EOPNOTSUPP;
5352
5353 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
5354 if (err)
5355 return err;
5356
5357 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5358 if (!msg)
5359 return -ENOMEM;
5360
5361 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
5362 dev, dst, mpp, &pinfo) < 0) {
5363 nlmsg_free(msg);
5364 return -ENOBUFS;
5365 }
5366
5367 return genlmsg_reply(msg, info);
5368}
5369
5370static int nl80211_dump_mpp(struct sk_buff *skb,
5371 struct netlink_callback *cb)
5372{
5373 struct mpath_info pinfo;
5374 struct cfg80211_registered_device *rdev;
5375 struct wireless_dev *wdev;
5376 u8 dst[ETH_ALEN];
5377 u8 mpp[ETH_ALEN];
5378 int path_idx = cb->args[2];
5379 int err;
5380
5381 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
5382 if (err)
5383 return err;
5384
5385 if (!rdev->ops->dump_mpp) {
5386 err = -EOPNOTSUPP;
5387 goto out_err;
5388 }
5389
5390 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
5391 err = -EOPNOTSUPP;
5392 goto out_err;
5393 }
5394
5395 while (1) {
5396 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
5397 mpp, &pinfo);
5398 if (err == -ENOENT)
5399 break;
5400 if (err)
5401 goto out_err;
5402
5403 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
5404 cb->nlh->nlmsg_seq, NLM_F_MULTI,
5405 wdev->netdev, dst, mpp,
5406 &pinfo) < 0)
5407 goto out;
5408
5409 path_idx++;
5410 }
5411
5412 out:
5413 cb->args[2] = path_idx;
5414 err = skb->len;
5415 out_err:
5416 nl80211_finish_wdev_dump(rdev);
5417 return err;
5418}
5419
9f1ba906
JM
5420static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
5421{
4c476991
JB
5422 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5423 struct net_device *dev = info->user_ptr[1];
c56589ed 5424 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 5425 struct bss_parameters params;
c56589ed 5426 int err;
9f1ba906
JM
5427
5428 memset(&params, 0, sizeof(params));
5429 /* default to not changing parameters */
5430 params.use_cts_prot = -1;
5431 params.use_short_preamble = -1;
5432 params.use_short_slot_time = -1;
fd8aaaf3 5433 params.ap_isolate = -1;
50b12f59 5434 params.ht_opmode = -1;
53cabad7
JB
5435 params.p2p_ctwindow = -1;
5436 params.p2p_opp_ps = -1;
9f1ba906
JM
5437
5438 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
5439 params.use_cts_prot =
5440 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
5441 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
5442 params.use_short_preamble =
5443 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
5444 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
5445 params.use_short_slot_time =
5446 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
5447 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
5448 params.basic_rates =
5449 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5450 params.basic_rates_len =
5451 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5452 }
fd8aaaf3
FF
5453 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
5454 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
5455 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
5456 params.ht_opmode =
5457 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 5458
53cabad7
JB
5459 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
5460 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5461 return -EINVAL;
5462 params.p2p_ctwindow =
5463 nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
5464 if (params.p2p_ctwindow < 0)
5465 return -EINVAL;
5466 if (params.p2p_ctwindow != 0 &&
5467 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
5468 return -EINVAL;
5469 }
5470
5471 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
5472 u8 tmp;
5473
5474 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5475 return -EINVAL;
5476 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
5477 if (tmp > 1)
5478 return -EINVAL;
5479 params.p2p_opp_ps = tmp;
5480 if (params.p2p_opp_ps &&
5481 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
5482 return -EINVAL;
5483 }
5484
4c476991
JB
5485 if (!rdev->ops->change_bss)
5486 return -EOPNOTSUPP;
9f1ba906 5487
074ac8df 5488 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
5489 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5490 return -EOPNOTSUPP;
3b85875a 5491
c56589ed
SW
5492 wdev_lock(wdev);
5493 err = rdev_change_bss(rdev, dev, &params);
5494 wdev_unlock(wdev);
5495
5496 return err;
9f1ba906
JM
5497}
5498
b2e1b302
LR
5499static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
5500{
b2e1b302 5501 char *data = NULL;
05050753 5502 bool is_indoor;
57b5ce07 5503 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
5504 u32 owner_nlportid;
5505
80778f18
LR
5506 /*
5507 * You should only get this when cfg80211 hasn't yet initialized
5508 * completely when built-in to the kernel right between the time
5509 * window between nl80211_init() and regulatory_init(), if that is
5510 * even possible.
5511 */
458f4f9e 5512 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 5513 return -EINPROGRESS;
80778f18 5514
57b5ce07
LR
5515 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
5516 user_reg_hint_type =
5517 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
5518 else
5519 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
5520
5521 switch (user_reg_hint_type) {
5522 case NL80211_USER_REG_HINT_USER:
5523 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
5524 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
5525 return -EINVAL;
5526
5527 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
5528 return regulatory_hint_user(data, user_reg_hint_type);
5529 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
5530 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
5531 owner_nlportid = info->snd_portid;
5532 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
5533 } else {
5534 owner_nlportid = 0;
5535 is_indoor = true;
5536 }
5537
5538 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
5539 default:
5540 return -EINVAL;
5541 }
b2e1b302
LR
5542}
5543
24bdd9f4 5544static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 5545 struct genl_info *info)
93da9cc1 5546{
4c476991 5547 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 5548 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
5549 struct wireless_dev *wdev = dev->ieee80211_ptr;
5550 struct mesh_config cur_params;
5551 int err = 0;
93da9cc1 5552 void *hdr;
5553 struct nlattr *pinfoattr;
5554 struct sk_buff *msg;
5555
29cbe68c
JB
5556 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
5557 return -EOPNOTSUPP;
5558
24bdd9f4 5559 if (!rdev->ops->get_mesh_config)
4c476991 5560 return -EOPNOTSUPP;
f3f92586 5561
29cbe68c
JB
5562 wdev_lock(wdev);
5563 /* If not connected, get default parameters */
5564 if (!wdev->mesh_id_len)
5565 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
5566 else
e35e4d28 5567 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
5568 wdev_unlock(wdev);
5569
93da9cc1 5570 if (err)
4c476991 5571 return err;
93da9cc1 5572
5573 /* Draw up a netlink message to send back */
fd2120ca 5574 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
5575 if (!msg)
5576 return -ENOMEM;
15e47304 5577 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 5578 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 5579 if (!hdr)
efe1cf0c 5580 goto out;
24bdd9f4 5581 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 5582 if (!pinfoattr)
5583 goto nla_put_failure;
9360ffd1
DM
5584 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5585 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
5586 cur_params.dot11MeshRetryTimeout) ||
5587 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
5588 cur_params.dot11MeshConfirmTimeout) ||
5589 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
5590 cur_params.dot11MeshHoldingTimeout) ||
5591 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
5592 cur_params.dot11MeshMaxPeerLinks) ||
5593 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
5594 cur_params.dot11MeshMaxRetries) ||
5595 nla_put_u8(msg, NL80211_MESHCONF_TTL,
5596 cur_params.dot11MeshTTL) ||
5597 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
5598 cur_params.element_ttl) ||
5599 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
5600 cur_params.auto_open_plinks) ||
7eab0f64
JL
5601 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
5602 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
5603 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
5604 cur_params.dot11MeshHWMPmaxPREQretries) ||
5605 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
5606 cur_params.path_refresh_time) ||
5607 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
5608 cur_params.min_discovery_timeout) ||
5609 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
5610 cur_params.dot11MeshHWMPactivePathTimeout) ||
5611 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
5612 cur_params.dot11MeshHWMPpreqMinInterval) ||
5613 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
5614 cur_params.dot11MeshHWMPperrMinInterval) ||
5615 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
5616 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
5617 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
5618 cur_params.dot11MeshHWMPRootMode) ||
5619 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
5620 cur_params.dot11MeshHWMPRannInterval) ||
5621 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
5622 cur_params.dot11MeshGateAnnouncementProtocol) ||
5623 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
5624 cur_params.dot11MeshForwarding) ||
5625 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
5626 cur_params.rssi_threshold) ||
5627 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
5628 cur_params.ht_opmode) ||
5629 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
5630 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
5631 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
5632 cur_params.dot11MeshHWMProotInterval) ||
5633 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
5634 cur_params.dot11MeshHWMPconfirmationInterval) ||
5635 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
5636 cur_params.power_mode) ||
5637 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
5638 cur_params.dot11MeshAwakeWindowDuration) ||
5639 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
5640 cur_params.plink_timeout))
9360ffd1 5641 goto nla_put_failure;
93da9cc1 5642 nla_nest_end(msg, pinfoattr);
5643 genlmsg_end(msg, hdr);
4c476991 5644 return genlmsg_reply(msg, info);
93da9cc1 5645
3b85875a 5646 nla_put_failure:
93da9cc1 5647 genlmsg_cancel(msg, hdr);
efe1cf0c 5648 out:
d080e275 5649 nlmsg_free(msg);
4c476991 5650 return -ENOBUFS;
93da9cc1 5651}
5652
b54452b0 5653static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
93da9cc1 5654 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
5655 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
5656 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
5657 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
5658 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
5659 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
45904f21 5660 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
93da9cc1 5661 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
d299a1f2 5662 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
93da9cc1 5663 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
5664 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
5665 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
5666 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
5667 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
dca7e943 5668 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 },
93da9cc1 5669 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
699403db 5670 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
0507e159 5671 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
16dd7267 5672 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
94f90656 5673 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
a4f606ea
CYY
5674 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
5675 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6
CYY
5676 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
5677 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
728b19e5 5678 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
3b1c5a53
MP
5679 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 },
5680 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 5681 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
93da9cc1 5682};
5683
c80d545d
JC
5684static const struct nla_policy
5685 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 5686 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
5687 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
5688 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 5689 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 5690 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 5691 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
581a8b0f 5692 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
a4f606ea 5693 .len = IEEE80211_MAX_DATA_LEN },
b130e5ce 5694 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
5695};
5696
f151d9db
AB
5697static int nl80211_check_bool(const struct nlattr *nla, u8 min, u8 max, bool *out)
5698{
5699 u8 val = nla_get_u8(nla);
5700 if (val < min || val > max)
5701 return -EINVAL;
5702 *out = val;
5703 return 0;
5704}
5705
5706static int nl80211_check_u8(const struct nlattr *nla, u8 min, u8 max, u8 *out)
5707{
5708 u8 val = nla_get_u8(nla);
5709 if (val < min || val > max)
5710 return -EINVAL;
5711 *out = val;
5712 return 0;
5713}
5714
5715static int nl80211_check_u16(const struct nlattr *nla, u16 min, u16 max, u16 *out)
5716{
5717 u16 val = nla_get_u16(nla);
5718 if (val < min || val > max)
5719 return -EINVAL;
5720 *out = val;
5721 return 0;
5722}
5723
5724static int nl80211_check_u32(const struct nlattr *nla, u32 min, u32 max, u32 *out)
5725{
5726 u32 val = nla_get_u32(nla);
5727 if (val < min || val > max)
5728 return -EINVAL;
5729 *out = val;
5730 return 0;
5731}
5732
5733static int nl80211_check_s32(const struct nlattr *nla, s32 min, s32 max, s32 *out)
5734{
5735 s32 val = nla_get_s32(nla);
5736 if (val < min || val > max)
5737 return -EINVAL;
5738 *out = val;
5739 return 0;
5740}
5741
ff9a71af
JB
5742static int nl80211_check_power_mode(const struct nlattr *nla,
5743 enum nl80211_mesh_power_mode min,
5744 enum nl80211_mesh_power_mode max,
5745 enum nl80211_mesh_power_mode *out)
5746{
5747 u32 val = nla_get_u32(nla);
5748 if (val < min || val > max)
5749 return -EINVAL;
5750 *out = val;
5751 return 0;
5752}
5753
24bdd9f4 5754static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
5755 struct mesh_config *cfg,
5756 u32 *mask_out)
93da9cc1 5757{
93da9cc1 5758 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 5759 u32 mask = 0;
9757235f 5760 u16 ht_opmode;
93da9cc1 5761
ea54fba2
MP
5762#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \
5763do { \
5764 if (tb[attr]) { \
f151d9db 5765 if (fn(tb[attr], min, max, &cfg->param)) \
ea54fba2 5766 return -EINVAL; \
ea54fba2
MP
5767 mask |= (1 << (attr - 1)); \
5768 } \
5769} while (0)
bd90fdcc 5770
24bdd9f4 5771 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 5772 return -EINVAL;
5773 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
24bdd9f4 5774 info->attrs[NL80211_ATTR_MESH_CONFIG],
bd90fdcc 5775 nl80211_meshconf_params_policy))
93da9cc1 5776 return -EINVAL;
5777
93da9cc1 5778 /* This makes sure that there aren't more than 32 mesh config
5779 * parameters (otherwise our bitfield scheme would not work.) */
5780 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
5781
5782 /* Fill in the params struct */
ea54fba2 5783 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255,
a4f606ea 5784 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
f151d9db 5785 nl80211_check_u16);
ea54fba2 5786 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255,
a4f606ea 5787 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
f151d9db 5788 nl80211_check_u16);
ea54fba2 5789 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255,
a4f606ea 5790 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
f151d9db 5791 nl80211_check_u16);
ea54fba2 5792 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255,
a4f606ea 5793 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
f151d9db 5794 nl80211_check_u16);
ea54fba2 5795 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16,
a4f606ea 5796 mask, NL80211_MESHCONF_MAX_RETRIES,
f151d9db 5797 nl80211_check_u8);
ea54fba2 5798 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255,
f151d9db 5799 mask, NL80211_MESHCONF_TTL, nl80211_check_u8);
ea54fba2 5800 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255,
a4f606ea 5801 mask, NL80211_MESHCONF_ELEMENT_TTL,
f151d9db 5802 nl80211_check_u8);
ea54fba2 5803 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1,
a4f606ea 5804 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
f151d9db 5805 nl80211_check_bool);
ea54fba2
MP
5806 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
5807 1, 255, mask,
a4f606ea 5808 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
f151d9db 5809 nl80211_check_u32);
ea54fba2 5810 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255,
a4f606ea 5811 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
f151d9db 5812 nl80211_check_u8);
ea54fba2 5813 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535,
a4f606ea 5814 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
f151d9db 5815 nl80211_check_u32);
ea54fba2 5816 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535,
a4f606ea 5817 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
f151d9db 5818 nl80211_check_u16);
ea54fba2
MP
5819 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
5820 1, 65535, mask,
a4f606ea 5821 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
f151d9db 5822 nl80211_check_u32);
93da9cc1 5823 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
ea54fba2
MP
5824 1, 65535, mask,
5825 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
f151d9db 5826 nl80211_check_u16);
dca7e943 5827 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
ea54fba2
MP
5828 1, 65535, mask,
5829 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
f151d9db 5830 nl80211_check_u16);
93da9cc1 5831 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
5832 dot11MeshHWMPnetDiameterTraversalTime,
5833 1, 65535, mask,
a4f606ea 5834 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
f151d9db 5835 nl80211_check_u16);
ea54fba2
MP
5836 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4,
5837 mask, NL80211_MESHCONF_HWMP_ROOTMODE,
f151d9db 5838 nl80211_check_u8);
ea54fba2
MP
5839 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535,
5840 mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
f151d9db 5841 nl80211_check_u16);
63c5723b 5842 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
5843 dot11MeshGateAnnouncementProtocol, 0, 1,
5844 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
f151d9db 5845 nl80211_check_bool);
ea54fba2 5846 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1,
a4f606ea 5847 mask, NL80211_MESHCONF_FORWARDING,
f151d9db 5848 nl80211_check_bool);
83374fe9 5849 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
a4f606ea 5850 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
f151d9db 5851 nl80211_check_s32);
9757235f
MH
5852 /*
5853 * Check HT operation mode based on
5854 * IEEE 802.11 2012 8.4.2.59 HT Operation element.
5855 */
5856 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
5857 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
5858
5859 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
5860 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
5861 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
5862 return -EINVAL;
5863
5864 if ((ht_opmode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) &&
5865 (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
5866 return -EINVAL;
5867
5868 switch (ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION) {
5869 case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
5870 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
5871 if (ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT)
5872 return -EINVAL;
5873 break;
5874 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
5875 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
5876 if (!(ht_opmode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
5877 return -EINVAL;
5878 break;
5879 }
5880 cfg->ht_opmode = ht_opmode;
5881 }
ac1073a6 5882 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
ea54fba2 5883 1, 65535, mask,
ac1073a6 5884 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
f151d9db 5885 nl80211_check_u32);
ea54fba2 5886 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535,
ac1073a6 5887 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
f151d9db 5888 nl80211_check_u16);
728b19e5 5889 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ea54fba2
MP
5890 dot11MeshHWMPconfirmationInterval,
5891 1, 65535, mask,
728b19e5 5892 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
f151d9db 5893 nl80211_check_u16);
3b1c5a53
MP
5894 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode,
5895 NL80211_MESH_POWER_ACTIVE,
5896 NL80211_MESH_POWER_MAX,
5897 mask, NL80211_MESHCONF_POWER_MODE,
ff9a71af 5898 nl80211_check_power_mode);
3b1c5a53
MP
5899 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration,
5900 0, 65535, mask,
f151d9db 5901 NL80211_MESHCONF_AWAKE_WINDOW, nl80211_check_u16);
31f909a2 5902 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 0, 0xffffffff,
8e7c0538 5903 mask, NL80211_MESHCONF_PLINK_TIMEOUT,
f151d9db 5904 nl80211_check_u32);
bd90fdcc
JB
5905 if (mask_out)
5906 *mask_out = mask;
c80d545d 5907
bd90fdcc
JB
5908 return 0;
5909
5910#undef FILL_IN_MESH_PARAM_IF_SET
5911}
5912
c80d545d
JC
5913static int nl80211_parse_mesh_setup(struct genl_info *info,
5914 struct mesh_setup *setup)
5915{
bb2798d4 5916 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
5917 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
5918
5919 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
5920 return -EINVAL;
5921 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
5922 info->attrs[NL80211_ATTR_MESH_SETUP],
5923 nl80211_mesh_setup_params_policy))
5924 return -EINVAL;
5925
d299a1f2
JC
5926 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
5927 setup->sync_method =
5928 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
5929 IEEE80211_SYNC_METHOD_VENDOR :
5930 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
5931
c80d545d
JC
5932 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
5933 setup->path_sel_proto =
5934 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
5935 IEEE80211_PATH_PROTOCOL_VENDOR :
5936 IEEE80211_PATH_PROTOCOL_HWMP;
5937
5938 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
5939 setup->path_metric =
5940 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
5941 IEEE80211_PATH_METRIC_VENDOR :
5942 IEEE80211_PATH_METRIC_AIRTIME;
5943
581a8b0f 5944 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 5945 struct nlattr *ieattr =
581a8b0f 5946 tb[NL80211_MESH_SETUP_IE];
c80d545d
JC
5947 if (!is_valid_ie_attr(ieattr))
5948 return -EINVAL;
581a8b0f
JC
5949 setup->ie = nla_data(ieattr);
5950 setup->ie_len = nla_len(ieattr);
c80d545d 5951 }
bb2798d4
TP
5952 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
5953 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
5954 return -EINVAL;
5955 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
5956 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
5957 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
5958 if (setup->is_secure)
5959 setup->user_mpm = true;
c80d545d 5960
6e16d90b
CT
5961 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
5962 if (!setup->user_mpm)
5963 return -EINVAL;
5964 setup->auth_id =
5965 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
5966 }
5967
c80d545d
JC
5968 return 0;
5969}
5970
24bdd9f4 5971static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 5972 struct genl_info *info)
bd90fdcc
JB
5973{
5974 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5975 struct net_device *dev = info->user_ptr[1];
29cbe68c 5976 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
5977 struct mesh_config cfg;
5978 u32 mask;
5979 int err;
5980
29cbe68c
JB
5981 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
5982 return -EOPNOTSUPP;
5983
24bdd9f4 5984 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
5985 return -EOPNOTSUPP;
5986
24bdd9f4 5987 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
5988 if (err)
5989 return err;
5990
29cbe68c
JB
5991 wdev_lock(wdev);
5992 if (!wdev->mesh_id_len)
5993 err = -ENOLINK;
5994
5995 if (!err)
e35e4d28 5996 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
5997
5998 wdev_unlock(wdev);
5999
6000 return err;
93da9cc1 6001}
6002
ad30ca2c
AN
6003static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
6004 struct sk_buff *msg)
f130347c 6005{
f130347c
LR
6006 struct nlattr *nl_reg_rules;
6007 unsigned int i;
f130347c 6008
458f4f9e
JB
6009 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
6010 (regdom->dfs_region &&
6011 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 6012 goto nla_put_failure;
458f4f9e 6013
f130347c
LR
6014 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
6015 if (!nl_reg_rules)
ad30ca2c 6016 goto nla_put_failure;
f130347c 6017
458f4f9e 6018 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
6019 struct nlattr *nl_reg_rule;
6020 const struct ieee80211_reg_rule *reg_rule;
6021 const struct ieee80211_freq_range *freq_range;
6022 const struct ieee80211_power_rule *power_rule;
97524820 6023 unsigned int max_bandwidth_khz;
f130347c 6024
458f4f9e 6025 reg_rule = &regdom->reg_rules[i];
f130347c
LR
6026 freq_range = &reg_rule->freq_range;
6027 power_rule = &reg_rule->power_rule;
6028
6029 nl_reg_rule = nla_nest_start(msg, i);
6030 if (!nl_reg_rule)
ad30ca2c 6031 goto nla_put_failure;
f130347c 6032
97524820
JD
6033 max_bandwidth_khz = freq_range->max_bandwidth_khz;
6034 if (!max_bandwidth_khz)
6035 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
6036 reg_rule);
6037
9360ffd1
DM
6038 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
6039 reg_rule->flags) ||
6040 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
6041 freq_range->start_freq_khz) ||
6042 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
6043 freq_range->end_freq_khz) ||
6044 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 6045 max_bandwidth_khz) ||
9360ffd1
DM
6046 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
6047 power_rule->max_antenna_gain) ||
6048 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
6049 power_rule->max_eirp) ||
6050 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
6051 reg_rule->dfs_cac_ms))
ad30ca2c 6052 goto nla_put_failure;
f130347c
LR
6053
6054 nla_nest_end(msg, nl_reg_rule);
6055 }
6056
6057 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
6058 return 0;
6059
6060nla_put_failure:
6061 return -EMSGSIZE;
6062}
6063
6064static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
6065{
6066 const struct ieee80211_regdomain *regdom = NULL;
6067 struct cfg80211_registered_device *rdev;
6068 struct wiphy *wiphy = NULL;
6069 struct sk_buff *msg;
6070 void *hdr;
6071
6072 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6073 if (!msg)
6074 return -ENOBUFS;
6075
6076 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
6077 NL80211_CMD_GET_REG);
6078 if (!hdr)
6079 goto put_failure;
6080
6081 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
6082 bool self_managed;
6083
ad30ca2c
AN
6084 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
6085 if (IS_ERR(rdev)) {
6086 nlmsg_free(msg);
6087 return PTR_ERR(rdev);
6088 }
6089
6090 wiphy = &rdev->wiphy;
1bdd716c
AN
6091 self_managed = wiphy->regulatory_flags &
6092 REGULATORY_WIPHY_SELF_MANAGED;
ad30ca2c
AN
6093 regdom = get_wiphy_regdom(wiphy);
6094
1bdd716c
AN
6095 /* a self-managed-reg device must have a private regdom */
6096 if (WARN_ON(!regdom && self_managed)) {
6097 nlmsg_free(msg);
6098 return -EINVAL;
6099 }
6100
ad30ca2c
AN
6101 if (regdom &&
6102 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6103 goto nla_put_failure;
6104 }
6105
6106 if (!wiphy && reg_last_request_cell_base() &&
6107 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6108 NL80211_USER_REG_HINT_CELL_BASE))
6109 goto nla_put_failure;
6110
6111 rcu_read_lock();
6112
6113 if (!regdom)
6114 regdom = rcu_dereference(cfg80211_regdomain);
6115
6116 if (nl80211_put_regdom(regdom, msg))
6117 goto nla_put_failure_rcu;
6118
6119 rcu_read_unlock();
f130347c
LR
6120
6121 genlmsg_end(msg, hdr);
5fe231e8 6122 return genlmsg_reply(msg, info);
f130347c 6123
458f4f9e
JB
6124nla_put_failure_rcu:
6125 rcu_read_unlock();
f130347c
LR
6126nla_put_failure:
6127 genlmsg_cancel(msg, hdr);
efe1cf0c 6128put_failure:
d080e275 6129 nlmsg_free(msg);
5fe231e8 6130 return -EMSGSIZE;
f130347c
LR
6131}
6132
ad30ca2c
AN
6133static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
6134 u32 seq, int flags, struct wiphy *wiphy,
6135 const struct ieee80211_regdomain *regdom)
6136{
6137 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
6138 NL80211_CMD_GET_REG);
6139
6140 if (!hdr)
6141 return -1;
6142
6143 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
6144
6145 if (nl80211_put_regdom(regdom, msg))
6146 goto nla_put_failure;
6147
6148 if (!wiphy && reg_last_request_cell_base() &&
6149 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6150 NL80211_USER_REG_HINT_CELL_BASE))
6151 goto nla_put_failure;
6152
6153 if (wiphy &&
6154 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6155 goto nla_put_failure;
6156
1bdd716c
AN
6157 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
6158 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
6159 goto nla_put_failure;
6160
053c095a
JB
6161 genlmsg_end(msg, hdr);
6162 return 0;
ad30ca2c
AN
6163
6164nla_put_failure:
6165 genlmsg_cancel(msg, hdr);
6166 return -EMSGSIZE;
6167}
6168
6169static int nl80211_get_reg_dump(struct sk_buff *skb,
6170 struct netlink_callback *cb)
6171{
6172 const struct ieee80211_regdomain *regdom = NULL;
6173 struct cfg80211_registered_device *rdev;
6174 int err, reg_idx, start = cb->args[2];
6175
6176 rtnl_lock();
6177
6178 if (cfg80211_regdomain && start == 0) {
6179 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6180 NLM_F_MULTI, NULL,
6181 rtnl_dereference(cfg80211_regdomain));
6182 if (err < 0)
6183 goto out_err;
6184 }
6185
6186 /* the global regdom is idx 0 */
6187 reg_idx = 1;
6188 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
6189 regdom = get_wiphy_regdom(&rdev->wiphy);
6190 if (!regdom)
6191 continue;
6192
6193 if (++reg_idx <= start)
6194 continue;
6195
6196 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6197 NLM_F_MULTI, &rdev->wiphy, regdom);
6198 if (err < 0) {
6199 reg_idx--;
6200 break;
6201 }
6202 }
6203
6204 cb->args[2] = reg_idx;
6205 err = skb->len;
6206out_err:
6207 rtnl_unlock();
6208 return err;
6209}
6210
b6863036
JB
6211#ifdef CONFIG_CFG80211_CRDA_SUPPORT
6212static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
6213 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
6214 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
6215 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
6216 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
6217 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
6218 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
6219 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
6220};
6221
6222static int parse_reg_rule(struct nlattr *tb[],
6223 struct ieee80211_reg_rule *reg_rule)
6224{
6225 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
6226 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
6227
6228 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
6229 return -EINVAL;
6230 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
6231 return -EINVAL;
6232 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
6233 return -EINVAL;
6234 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
6235 return -EINVAL;
6236 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6237 return -EINVAL;
6238
6239 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
6240
6241 freq_range->start_freq_khz =
6242 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
6243 freq_range->end_freq_khz =
6244 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
6245 freq_range->max_bandwidth_khz =
6246 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
6247
6248 power_rule->max_eirp =
6249 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
6250
6251 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
6252 power_rule->max_antenna_gain =
6253 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
6254
6255 if (tb[NL80211_ATTR_DFS_CAC_TIME])
6256 reg_rule->dfs_cac_ms =
6257 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
6258
6259 return 0;
6260}
6261
b2e1b302
LR
6262static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
6263{
6264 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
6265 struct nlattr *nl_reg_rule;
ea372c54
JB
6266 char *alpha2;
6267 int rem_reg_rules, r;
b2e1b302 6268 u32 num_rules = 0, rule_idx = 0, size_of_regd;
4c7d3982 6269 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 6270 struct ieee80211_regdomain *rd;
b2e1b302
LR
6271
6272 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
6273 return -EINVAL;
6274
6275 if (!info->attrs[NL80211_ATTR_REG_RULES])
6276 return -EINVAL;
6277
6278 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
6279
8b60b078
LR
6280 if (info->attrs[NL80211_ATTR_DFS_REGION])
6281 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
6282
b2e1b302 6283 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6284 rem_reg_rules) {
b2e1b302
LR
6285 num_rules++;
6286 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 6287 return -EINVAL;
b2e1b302
LR
6288 }
6289
e438768f
LR
6290 if (!reg_is_valid_request(alpha2))
6291 return -EINVAL;
6292
b2e1b302 6293 size_of_regd = sizeof(struct ieee80211_regdomain) +
1a919318 6294 num_rules * sizeof(struct ieee80211_reg_rule);
b2e1b302
LR
6295
6296 rd = kzalloc(size_of_regd, GFP_KERNEL);
6913b49a
JB
6297 if (!rd)
6298 return -ENOMEM;
b2e1b302
LR
6299
6300 rd->n_reg_rules = num_rules;
6301 rd->alpha2[0] = alpha2[0];
6302 rd->alpha2[1] = alpha2[1];
6303
8b60b078
LR
6304 /*
6305 * Disable DFS master mode if the DFS region was
6306 * not supported or known on this kernel.
6307 */
6308 if (reg_supported_dfs_region(dfs_region))
6309 rd->dfs_region = dfs_region;
6310
b2e1b302 6311 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 6312 rem_reg_rules) {
ae811e21
JB
6313 r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
6314 nla_data(nl_reg_rule), nla_len(nl_reg_rule),
6315 reg_rule_policy);
6316 if (r)
6317 goto bad_reg;
b2e1b302
LR
6318 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
6319 if (r)
6320 goto bad_reg;
6321
6322 rule_idx++;
6323
d0e18f83
LR
6324 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
6325 r = -EINVAL;
b2e1b302 6326 goto bad_reg;
d0e18f83 6327 }
b2e1b302
LR
6328 }
6329
06627990
JB
6330 /* set_regdom takes ownership of rd */
6331 return set_regdom(rd, REGD_SOURCE_CRDA);
d2372b31 6332 bad_reg:
b2e1b302 6333 kfree(rd);
d0e18f83 6334 return r;
b2e1b302 6335}
b6863036 6336#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 6337
83f5e2cf
JB
6338static int validate_scan_freqs(struct nlattr *freqs)
6339{
6340 struct nlattr *attr1, *attr2;
6341 int n_channels = 0, tmp1, tmp2;
6342
6343 nla_for_each_nested(attr1, freqs, tmp1) {
6344 n_channels++;
6345 /*
6346 * Some hardware has a limited channel list for
6347 * scanning, and it is pretty much nonsensical
6348 * to scan for a channel twice, so disallow that
6349 * and don't require drivers to check that the
6350 * channel list they get isn't longer than what
6351 * they can scan, as long as they can scan all
6352 * the channels they registered at once.
6353 */
6354 nla_for_each_nested(attr2, freqs, tmp2)
6355 if (attr1 != attr2 &&
6356 nla_get_u32(attr1) == nla_get_u32(attr2))
6357 return 0;
6358 }
6359
6360 return n_channels;
6361}
6362
57fbcce3 6363static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 6364{
57fbcce3 6365 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
6366}
6367
6368static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
6369 struct cfg80211_bss_selection *bss_select)
6370{
6371 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
6372 struct nlattr *nest;
6373 int err;
6374 bool found = false;
6375 int i;
6376
6377 /* only process one nested attribute */
6378 nest = nla_data(nla);
6379 if (!nla_ok(nest, nla_len(nest)))
6380 return -EINVAL;
6381
6382 err = nla_parse(attr, NL80211_BSS_SELECT_ATTR_MAX, nla_data(nest),
6383 nla_len(nest), nl80211_bss_select_policy);
6384 if (err)
6385 return err;
6386
6387 /* only one attribute may be given */
6388 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
6389 if (attr[i]) {
6390 if (found)
6391 return -EINVAL;
6392 found = true;
6393 }
6394 }
6395
6396 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
6397
6398 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
6399 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
6400
6401 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
6402 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
6403 bss_select->param.band_pref =
6404 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
6405 if (!is_band_valid(wiphy, bss_select->param.band_pref))
6406 return -EINVAL;
6407 }
6408
6409 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
6410 struct nl80211_bss_select_rssi_adjust *adj_param;
6411
6412 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
6413 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
6414 bss_select->param.adjust.band = adj_param->band;
6415 bss_select->param.adjust.delta = adj_param->delta;
6416 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
6417 return -EINVAL;
6418 }
6419
6420 /* user-space did not provide behaviour attribute */
6421 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
6422 return -EINVAL;
6423
6424 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
6425 return -EINVAL;
6426
6427 return 0;
6428}
6429
ad2b26ab
JB
6430static int nl80211_parse_random_mac(struct nlattr **attrs,
6431 u8 *mac_addr, u8 *mac_addr_mask)
6432{
6433 int i;
6434
6435 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
6436 eth_zero_addr(mac_addr);
6437 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
6438 mac_addr[0] = 0x2;
6439 mac_addr_mask[0] = 0x3;
6440
6441 return 0;
6442 }
6443
6444 /* need both or none */
6445 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
6446 return -EINVAL;
6447
6448 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
6449 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
6450
6451 /* don't allow or configure an mcast address */
6452 if (!is_multicast_ether_addr(mac_addr_mask) ||
6453 is_multicast_ether_addr(mac_addr))
6454 return -EINVAL;
6455
6456 /*
6457 * allow users to pass a MAC address that has bits set outside
6458 * of the mask, but don't bother drivers with having to deal
6459 * with such bits
6460 */
6461 for (i = 0; i < ETH_ALEN; i++)
6462 mac_addr[i] &= mac_addr_mask[i];
6463
6464 return 0;
6465}
6466
2a519311
JB
6467static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
6468{
4c476991 6469 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 6470 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 6471 struct cfg80211_scan_request *request;
2a519311
JB
6472 struct nlattr *attr;
6473 struct wiphy *wiphy;
83f5e2cf 6474 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 6475 size_t ie_len;
2a519311 6476
f4a11bb0
JB
6477 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
6478 return -EINVAL;
6479
79c97e97 6480 wiphy = &rdev->wiphy;
2a519311 6481
cb3b7d87
AB
6482 if (wdev->iftype == NL80211_IFTYPE_NAN)
6483 return -EOPNOTSUPP;
6484
4c476991
JB
6485 if (!rdev->ops->scan)
6486 return -EOPNOTSUPP;
2a519311 6487
f9d15d16 6488 if (rdev->scan_req || rdev->scan_msg) {
f9f47529
JB
6489 err = -EBUSY;
6490 goto unlock;
6491 }
2a519311
JB
6492
6493 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
6494 n_channels = validate_scan_freqs(
6495 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
f9f47529
JB
6496 if (!n_channels) {
6497 err = -EINVAL;
6498 goto unlock;
6499 }
2a519311 6500 } else {
bdfbec2d 6501 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
6502 }
6503
6504 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
6505 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
6506 n_ssids++;
6507
f9f47529
JB
6508 if (n_ssids > wiphy->max_scan_ssids) {
6509 err = -EINVAL;
6510 goto unlock;
6511 }
2a519311 6512
70692ad2
JM
6513 if (info->attrs[NL80211_ATTR_IE])
6514 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
6515 else
6516 ie_len = 0;
6517
f9f47529
JB
6518 if (ie_len > wiphy->max_scan_ie_len) {
6519 err = -EINVAL;
6520 goto unlock;
6521 }
18a83659 6522
2a519311 6523 request = kzalloc(sizeof(*request)
a2cd43c5
LC
6524 + sizeof(*request->ssids) * n_ssids
6525 + sizeof(*request->channels) * n_channels
70692ad2 6526 + ie_len, GFP_KERNEL);
f9f47529
JB
6527 if (!request) {
6528 err = -ENOMEM;
6529 goto unlock;
6530 }
2a519311 6531
2a519311 6532 if (n_ssids)
5ba63533 6533 request->ssids = (void *)&request->channels[n_channels];
2a519311 6534 request->n_ssids = n_ssids;
70692ad2 6535 if (ie_len) {
13874e4b 6536 if (n_ssids)
70692ad2
JM
6537 request->ie = (void *)(request->ssids + n_ssids);
6538 else
6539 request->ie = (void *)(request->channels + n_channels);
6540 }
2a519311 6541
584991dc 6542 i = 0;
2a519311
JB
6543 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
6544 /* user specified, bail out if channel not found */
2a519311 6545 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
6546 struct ieee80211_channel *chan;
6547
6548 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
6549
6550 if (!chan) {
2a519311
JB
6551 err = -EINVAL;
6552 goto out_free;
6553 }
584991dc
JB
6554
6555 /* ignore disabled channels */
6556 if (chan->flags & IEEE80211_CHAN_DISABLED)
6557 continue;
6558
6559 request->channels[i] = chan;
2a519311
JB
6560 i++;
6561 }
6562 } else {
57fbcce3 6563 enum nl80211_band band;
34850ab2 6564
2a519311 6565 /* all channels */
57fbcce3 6566 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 6567 int j;
7a087e74 6568
2a519311
JB
6569 if (!wiphy->bands[band])
6570 continue;
6571 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
6572 struct ieee80211_channel *chan;
6573
6574 chan = &wiphy->bands[band]->channels[j];
6575
6576 if (chan->flags & IEEE80211_CHAN_DISABLED)
6577 continue;
6578
6579 request->channels[i] = chan;
2a519311
JB
6580 i++;
6581 }
6582 }
6583 }
6584
584991dc
JB
6585 if (!i) {
6586 err = -EINVAL;
6587 goto out_free;
6588 }
6589
6590 request->n_channels = i;
6591
2a519311 6592 i = 0;
13874e4b 6593 if (n_ssids) {
2a519311 6594 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 6595 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
6596 err = -EINVAL;
6597 goto out_free;
6598 }
57a27e1d 6599 request->ssids[i].ssid_len = nla_len(attr);
2a519311 6600 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
6601 i++;
6602 }
6603 }
6604
70692ad2
JM
6605 if (info->attrs[NL80211_ATTR_IE]) {
6606 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
6607 memcpy((void *)request->ie,
6608 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
6609 request->ie_len);
6610 }
6611
57fbcce3 6612 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
6613 if (wiphy->bands[i])
6614 request->rates[i] =
6615 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
6616
6617 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
6618 nla_for_each_nested(attr,
6619 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
6620 tmp) {
57fbcce3 6621 enum nl80211_band band = nla_type(attr);
34850ab2 6622
57fbcce3 6623 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
6624 err = -EINVAL;
6625 goto out_free;
6626 }
1b09cd82
FF
6627
6628 if (!wiphy->bands[band])
6629 continue;
6630
34850ab2
JB
6631 err = ieee80211_get_ratemask(wiphy->bands[band],
6632 nla_data(attr),
6633 nla_len(attr),
6634 &request->rates[band]);
6635 if (err)
6636 goto out_free;
6637 }
6638 }
6639
1d76250b
AS
6640 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
6641 if (!wiphy_ext_feature_isset(wiphy,
6642 NL80211_EXT_FEATURE_SET_SCAN_DWELL)) {
6643 err = -EOPNOTSUPP;
6644 goto out_free;
6645 }
6646
6647 request->duration =
6648 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
6649 request->duration_mandatory =
6650 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
6651 }
6652
46856bbf 6653 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
ed473771
SL
6654 request->flags = nla_get_u32(
6655 info->attrs[NL80211_ATTR_SCAN_FLAGS]);
00c3a6ed
JB
6656 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
6657 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
46856bbf
SL
6658 err = -EOPNOTSUPP;
6659 goto out_free;
6660 }
ad2b26ab
JB
6661
6662 if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
6663 if (!(wiphy->features &
6664 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)) {
6665 err = -EOPNOTSUPP;
6666 goto out_free;
6667 }
6668
6669 if (wdev->current_bss) {
6670 err = -EOPNOTSUPP;
6671 goto out_free;
6672 }
6673
6674 err = nl80211_parse_random_mac(info->attrs,
6675 request->mac_addr,
6676 request->mac_addr_mask);
6677 if (err)
6678 goto out_free;
6679 }
46856bbf 6680 }
ed473771 6681
e9f935e3
RM
6682 request->no_cck =
6683 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
6684
818965d3
JM
6685 if (info->attrs[NL80211_ATTR_MAC])
6686 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
6687 ETH_ALEN);
6688 else
6689 eth_broadcast_addr(request->bssid);
6690
fd014284 6691 request->wdev = wdev;
79c97e97 6692 request->wiphy = &rdev->wiphy;
15d6030b 6693 request->scan_start = jiffies;
2a519311 6694
79c97e97 6695 rdev->scan_req = request;
e35e4d28 6696 err = rdev_scan(rdev, request);
2a519311 6697
463d0183 6698 if (!err) {
fd014284
JB
6699 nl80211_send_scan_start(rdev, wdev);
6700 if (wdev->netdev)
6701 dev_hold(wdev->netdev);
4c476991 6702 } else {
2a519311 6703 out_free:
79c97e97 6704 rdev->scan_req = NULL;
2a519311
JB
6705 kfree(request);
6706 }
3b85875a 6707
f9f47529 6708 unlock:
2a519311
JB
6709 return err;
6710}
6711
91d3ab46
VK
6712static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
6713{
6714 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6715 struct wireless_dev *wdev = info->user_ptr[1];
6716
6717 if (!rdev->ops->abort_scan)
6718 return -EOPNOTSUPP;
6719
6720 if (rdev->scan_msg)
6721 return 0;
6722
6723 if (!rdev->scan_req)
6724 return -ENOENT;
6725
6726 rdev_abort_scan(rdev, wdev);
6727 return 0;
6728}
6729
3b06d277
AS
6730static int
6731nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
6732 struct cfg80211_sched_scan_request *request,
6733 struct nlattr **attrs)
6734{
6735 int tmp, err, i = 0;
6736 struct nlattr *attr;
6737
6738 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
6739 u32 interval;
6740
6741 /*
6742 * If scan plans are not specified,
6743 * %NL80211_ATTR_SCHED_SCAN_INTERVAL must be specified. In this
6744 * case one scan plan will be set with the specified scan
6745 * interval and infinite number of iterations.
6746 */
6747 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
6748 return -EINVAL;
6749
6750 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
6751 if (!interval)
6752 return -EINVAL;
6753
6754 request->scan_plans[0].interval =
6755 DIV_ROUND_UP(interval, MSEC_PER_SEC);
6756 if (!request->scan_plans[0].interval)
6757 return -EINVAL;
6758
6759 if (request->scan_plans[0].interval >
6760 wiphy->max_sched_scan_plan_interval)
6761 request->scan_plans[0].interval =
6762 wiphy->max_sched_scan_plan_interval;
6763
6764 return 0;
6765 }
6766
6767 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
6768 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
6769
6770 if (WARN_ON(i >= n_plans))
6771 return -EINVAL;
6772
6773 err = nla_parse(plan, NL80211_SCHED_SCAN_PLAN_MAX,
6774 nla_data(attr), nla_len(attr),
6775 nl80211_plan_policy);
6776 if (err)
6777 return err;
6778
6779 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
6780 return -EINVAL;
6781
6782 request->scan_plans[i].interval =
6783 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
6784 if (!request->scan_plans[i].interval ||
6785 request->scan_plans[i].interval >
6786 wiphy->max_sched_scan_plan_interval)
6787 return -EINVAL;
6788
6789 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
6790 request->scan_plans[i].iterations =
6791 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
6792 if (!request->scan_plans[i].iterations ||
6793 (request->scan_plans[i].iterations >
6794 wiphy->max_sched_scan_plan_iterations))
6795 return -EINVAL;
6796 } else if (i < n_plans - 1) {
6797 /*
6798 * All scan plans but the last one must specify
6799 * a finite number of iterations
6800 */
6801 return -EINVAL;
6802 }
6803
6804 i++;
6805 }
6806
6807 /*
6808 * The last scan plan must not specify the number of
6809 * iterations, it is supposed to run infinitely
6810 */
6811 if (request->scan_plans[n_plans - 1].iterations)
6812 return -EINVAL;
6813
6814 return 0;
6815}
6816
256da02d 6817static struct cfg80211_sched_scan_request *
ad2b26ab 6818nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
256da02d 6819 struct nlattr **attrs)
807f8a8c
LC
6820{
6821 struct cfg80211_sched_scan_request *request;
807f8a8c 6822 struct nlattr *attr;
3b06d277 6823 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 6824 enum nl80211_band band;
807f8a8c 6825 size_t ie_len;
a1f1c21c 6826 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 6827 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 6828
256da02d
LC
6829 if (!is_valid_ie_attr(attrs[NL80211_ATTR_IE]))
6830 return ERR_PTR(-EINVAL);
807f8a8c 6831
256da02d 6832 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 6833 n_channels = validate_scan_freqs(
256da02d 6834 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 6835 if (!n_channels)
256da02d 6836 return ERR_PTR(-EINVAL);
807f8a8c 6837 } else {
bdfbec2d 6838 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
6839 }
6840
256da02d
LC
6841 if (attrs[NL80211_ATTR_SCAN_SSIDS])
6842 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
6843 tmp)
6844 n_ssids++;
6845
93b6aa69 6846 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 6847 return ERR_PTR(-EINVAL);
807f8a8c 6848
ea73cbce
JB
6849 /*
6850 * First, count the number of 'real' matchsets. Due to an issue with
6851 * the old implementation, matchsets containing only the RSSI attribute
6852 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
6853 * RSSI for all matchsets, rather than their own matchset for reporting
6854 * all APs with a strong RSSI. This is needed to be compatible with
6855 * older userspace that treated a matchset with only the RSSI as the
6856 * global RSSI for all other matchsets - if there are other matchsets.
6857 */
256da02d 6858 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 6859 nla_for_each_nested(attr,
256da02d 6860 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
6861 tmp) {
6862 struct nlattr *rssi;
6863
6864 err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
6865 nla_data(attr), nla_len(attr),
6866 nl80211_match_policy);
6867 if (err)
256da02d 6868 return ERR_PTR(err);
ea73cbce
JB
6869 /* add other standalone attributes here */
6870 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
6871 n_match_sets++;
6872 continue;
6873 }
6874 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
6875 if (rssi)
6876 default_match_rssi = nla_get_s32(rssi);
6877 }
6878 }
6879
6880 /* However, if there's no other matchset, add the RSSI one */
6881 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
6882 n_match_sets = 1;
a1f1c21c
LC
6883
6884 if (n_match_sets > wiphy->max_match_sets)
256da02d 6885 return ERR_PTR(-EINVAL);
a1f1c21c 6886
256da02d
LC
6887 if (attrs[NL80211_ATTR_IE])
6888 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
6889 else
6890 ie_len = 0;
6891
5a865bad 6892 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 6893 return ERR_PTR(-EINVAL);
c10841ca 6894
3b06d277
AS
6895 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
6896 /*
6897 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
6898 * each scan plan already specifies its own interval
6899 */
6900 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
6901 return ERR_PTR(-EINVAL);
6902
6903 nla_for_each_nested(attr,
6904 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
6905 n_plans++;
6906 } else {
6907 /*
6908 * The scan interval attribute is kept for backward
6909 * compatibility. If no scan plans are specified and sched scan
6910 * interval is specified, one scan plan will be set with this
6911 * scan interval and infinite number of iterations.
6912 */
6913 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
6914 return ERR_PTR(-EINVAL);
6915
6916 n_plans = 1;
6917 }
6918
6919 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
6920 return ERR_PTR(-EINVAL);
6921
807f8a8c 6922 request = kzalloc(sizeof(*request)
a2cd43c5 6923 + sizeof(*request->ssids) * n_ssids
a1f1c21c 6924 + sizeof(*request->match_sets) * n_match_sets
3b06d277 6925 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 6926 + sizeof(*request->channels) * n_channels
807f8a8c 6927 + ie_len, GFP_KERNEL);
256da02d
LC
6928 if (!request)
6929 return ERR_PTR(-ENOMEM);
807f8a8c
LC
6930
6931 if (n_ssids)
6932 request->ssids = (void *)&request->channels[n_channels];
6933 request->n_ssids = n_ssids;
6934 if (ie_len) {
13874e4b 6935 if (n_ssids)
807f8a8c
LC
6936 request->ie = (void *)(request->ssids + n_ssids);
6937 else
6938 request->ie = (void *)(request->channels + n_channels);
6939 }
6940
a1f1c21c
LC
6941 if (n_match_sets) {
6942 if (request->ie)
6943 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 6944 else if (n_ssids)
a1f1c21c
LC
6945 request->match_sets =
6946 (void *)(request->ssids + n_ssids);
6947 else
6948 request->match_sets =
6949 (void *)(request->channels + n_channels);
6950 }
6951 request->n_match_sets = n_match_sets;
6952
3b06d277
AS
6953 if (n_match_sets)
6954 request->scan_plans = (void *)(request->match_sets +
6955 n_match_sets);
6956 else if (request->ie)
6957 request->scan_plans = (void *)(request->ie + ie_len);
6958 else if (n_ssids)
6959 request->scan_plans = (void *)(request->ssids + n_ssids);
6960 else
6961 request->scan_plans = (void *)(request->channels + n_channels);
6962
6963 request->n_scan_plans = n_plans;
6964
807f8a8c 6965 i = 0;
256da02d 6966 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
6967 /* user specified, bail out if channel not found */
6968 nla_for_each_nested(attr,
256da02d 6969 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
6970 tmp) {
6971 struct ieee80211_channel *chan;
6972
6973 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
6974
6975 if (!chan) {
6976 err = -EINVAL;
6977 goto out_free;
6978 }
6979
6980 /* ignore disabled channels */
6981 if (chan->flags & IEEE80211_CHAN_DISABLED)
6982 continue;
6983
6984 request->channels[i] = chan;
6985 i++;
6986 }
6987 } else {
6988 /* all channels */
57fbcce3 6989 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 6990 int j;
7a087e74 6991
807f8a8c
LC
6992 if (!wiphy->bands[band])
6993 continue;
6994 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
6995 struct ieee80211_channel *chan;
6996
6997 chan = &wiphy->bands[band]->channels[j];
6998
6999 if (chan->flags & IEEE80211_CHAN_DISABLED)
7000 continue;
7001
7002 request->channels[i] = chan;
7003 i++;
7004 }
7005 }
7006 }
7007
7008 if (!i) {
7009 err = -EINVAL;
7010 goto out_free;
7011 }
7012
7013 request->n_channels = i;
7014
7015 i = 0;
13874e4b 7016 if (n_ssids) {
256da02d 7017 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 7018 tmp) {
57a27e1d 7019 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
7020 err = -EINVAL;
7021 goto out_free;
7022 }
57a27e1d 7023 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
7024 memcpy(request->ssids[i].ssid, nla_data(attr),
7025 nla_len(attr));
807f8a8c
LC
7026 i++;
7027 }
7028 }
7029
a1f1c21c 7030 i = 0;
256da02d 7031 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 7032 nla_for_each_nested(attr,
256da02d 7033 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 7034 tmp) {
88e920b4 7035 struct nlattr *ssid, *rssi;
a1f1c21c 7036
ae811e21
JB
7037 err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
7038 nla_data(attr), nla_len(attr),
7039 nl80211_match_policy);
7040 if (err)
7041 goto out_free;
4a4ab0d7 7042 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
a1f1c21c 7043 if (ssid) {
ea73cbce
JB
7044 if (WARN_ON(i >= n_match_sets)) {
7045 /* this indicates a programming error,
7046 * the loop above should have verified
7047 * things properly
7048 */
7049 err = -EINVAL;
7050 goto out_free;
7051 }
7052
a1f1c21c
LC
7053 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
7054 err = -EINVAL;
7055 goto out_free;
7056 }
7057 memcpy(request->match_sets[i].ssid.ssid,
7058 nla_data(ssid), nla_len(ssid));
7059 request->match_sets[i].ssid.ssid_len =
7060 nla_len(ssid);
56ab364f 7061 /* special attribute - old implementation w/a */
ea73cbce
JB
7062 request->match_sets[i].rssi_thold =
7063 default_match_rssi;
7064 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
7065 if (rssi)
7066 request->match_sets[i].rssi_thold =
7067 nla_get_s32(rssi);
a1f1c21c
LC
7068 }
7069 i++;
7070 }
ea73cbce
JB
7071
7072 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 7073 if (i == 0 && n_match_sets)
ea73cbce
JB
7074 request->match_sets[0].rssi_thold = default_match_rssi;
7075
7076 request->min_rssi_thold = INT_MAX;
7077 for (i = 0; i < n_match_sets; i++)
7078 request->min_rssi_thold =
7079 min(request->match_sets[i].rssi_thold,
7080 request->min_rssi_thold);
7081 } else {
7082 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
7083 }
7084
9900e484
JB
7085 if (ie_len) {
7086 request->ie_len = ie_len;
807f8a8c 7087 memcpy((void *)request->ie,
256da02d 7088 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
7089 request->ie_len);
7090 }
7091
256da02d 7092 if (attrs[NL80211_ATTR_SCAN_FLAGS]) {
ed473771 7093 request->flags = nla_get_u32(
256da02d 7094 attrs[NL80211_ATTR_SCAN_FLAGS]);
00c3a6ed
JB
7095 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
7096 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
46856bbf
SL
7097 err = -EOPNOTSUPP;
7098 goto out_free;
7099 }
ad2b26ab
JB
7100
7101 if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
7102 u32 flg = NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
7103
7104 if (!wdev) /* must be net-detect */
7105 flg = NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7106
7107 if (!(wiphy->features & flg)) {
7108 err = -EOPNOTSUPP;
7109 goto out_free;
7110 }
7111
7112 if (wdev && wdev->current_bss) {
7113 err = -EOPNOTSUPP;
7114 goto out_free;
7115 }
7116
7117 err = nl80211_parse_random_mac(attrs, request->mac_addr,
7118 request->mac_addr_mask);
7119 if (err)
7120 goto out_free;
7121 }
46856bbf 7122 }
ed473771 7123
9c748934
LC
7124 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
7125 request->delay =
7126 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
7127
3b06d277
AS
7128 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
7129 if (err)
7130 goto out_free;
7131
15d6030b 7132 request->scan_start = jiffies;
807f8a8c 7133
256da02d 7134 return request;
807f8a8c
LC
7135
7136out_free:
7137 kfree(request);
256da02d
LC
7138 return ERR_PTR(err);
7139}
7140
7141static int nl80211_start_sched_scan(struct sk_buff *skb,
7142 struct genl_info *info)
7143{
7144 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7145 struct net_device *dev = info->user_ptr[1];
ad2b26ab 7146 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 7147 struct cfg80211_sched_scan_request *sched_scan_req;
256da02d
LC
7148 int err;
7149
7150 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
7151 !rdev->ops->sched_scan_start)
7152 return -EOPNOTSUPP;
7153
7154 if (rdev->sched_scan_req)
7155 return -EINPROGRESS;
7156
31a60ed1
JR
7157 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
7158 info->attrs);
7159
7160 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
7161 if (err)
7162 goto out_err;
7163
31a60ed1 7164 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
7165 if (err)
7166 goto out_free;
7167
31a60ed1
JR
7168 sched_scan_req->dev = dev;
7169 sched_scan_req->wiphy = &rdev->wiphy;
7170
93a1e86c
JR
7171 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
7172 sched_scan_req->owner_nlportid = info->snd_portid;
7173
31a60ed1 7174 rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req);
256da02d
LC
7175
7176 nl80211_send_sched_scan(rdev, dev,
7177 NL80211_CMD_START_SCHED_SCAN);
7178 return 0;
7179
7180out_free:
31a60ed1 7181 kfree(sched_scan_req);
256da02d 7182out_err:
807f8a8c
LC
7183 return err;
7184}
7185
7186static int nl80211_stop_sched_scan(struct sk_buff *skb,
7187 struct genl_info *info)
7188{
7189 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7190
7191 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
7192 !rdev->ops->sched_scan_stop)
7193 return -EOPNOTSUPP;
7194
5fe231e8 7195 return __cfg80211_stop_sched_scan(rdev, false);
807f8a8c
LC
7196}
7197
04f39047
SW
7198static int nl80211_start_radar_detection(struct sk_buff *skb,
7199 struct genl_info *info)
7200{
7201 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7202 struct net_device *dev = info->user_ptr[1];
7203 struct wireless_dev *wdev = dev->ieee80211_ptr;
7204 struct cfg80211_chan_def chandef;
55f7435c 7205 enum nl80211_dfs_regions dfs_region;
31559f35 7206 unsigned int cac_time_ms;
04f39047
SW
7207 int err;
7208
55f7435c
LR
7209 dfs_region = reg_get_dfs_region(wdev->wiphy);
7210 if (dfs_region == NL80211_DFS_UNSET)
7211 return -EINVAL;
7212
04f39047
SW
7213 err = nl80211_parse_chandef(rdev, info, &chandef);
7214 if (err)
7215 return err;
7216
ff311bc1
SW
7217 if (netif_carrier_ok(dev))
7218 return -EBUSY;
7219
04f39047
SW
7220 if (wdev->cac_started)
7221 return -EBUSY;
7222
2beb6dab 7223 err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef,
00ec75fc 7224 wdev->iftype);
04f39047
SW
7225 if (err < 0)
7226 return err;
7227
7228 if (err == 0)
7229 return -EINVAL;
7230
fe7c3a1f 7231 if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef))
04f39047
SW
7232 return -EINVAL;
7233
7234 if (!rdev->ops->start_radar_detection)
7235 return -EOPNOTSUPP;
7236
31559f35
JD
7237 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
7238 if (WARN_ON(!cac_time_ms))
7239 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
7240
a1056b1b 7241 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 7242 if (!err) {
9e0e2961 7243 wdev->chandef = chandef;
04f39047
SW
7244 wdev->cac_started = true;
7245 wdev->cac_start_time = jiffies;
31559f35 7246 wdev->cac_time_ms = cac_time_ms;
04f39047 7247 }
04f39047
SW
7248 return err;
7249}
7250
16ef1fe2
SW
7251static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
7252{
7253 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7254 struct net_device *dev = info->user_ptr[1];
7255 struct wireless_dev *wdev = dev->ieee80211_ptr;
7256 struct cfg80211_csa_settings params;
7257 /* csa_attrs is defined static to avoid waste of stack size - this
7258 * function is called under RTNL lock, so this should not be a problem.
7259 */
7260 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
16ef1fe2 7261 int err;
ee4bc9e7 7262 bool need_new_beacon = false;
9a774c78 7263 int len, i;
252e07ca 7264 u32 cs_count;
16ef1fe2
SW
7265
7266 if (!rdev->ops->channel_switch ||
7267 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
7268 return -EOPNOTSUPP;
7269
ee4bc9e7
SW
7270 switch (dev->ieee80211_ptr->iftype) {
7271 case NL80211_IFTYPE_AP:
7272 case NL80211_IFTYPE_P2P_GO:
7273 need_new_beacon = true;
7274
7275 /* useless if AP is not running */
7276 if (!wdev->beacon_interval)
1ff79dfa 7277 return -ENOTCONN;
ee4bc9e7
SW
7278 break;
7279 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
7280 if (!wdev->ssid_len)
7281 return -ENOTCONN;
7282 break;
c6da674a 7283 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
7284 if (!wdev->mesh_id_len)
7285 return -ENOTCONN;
ee4bc9e7
SW
7286 break;
7287 default:
16ef1fe2 7288 return -EOPNOTSUPP;
ee4bc9e7 7289 }
16ef1fe2
SW
7290
7291 memset(&params, 0, sizeof(params));
7292
7293 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
7294 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
7295 return -EINVAL;
7296
7297 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 7298 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
7299 return -EINVAL;
7300
252e07ca
LC
7301 /* Even though the attribute is u32, the specification says
7302 * u8, so let's make sure we don't overflow.
7303 */
7304 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
7305 if (cs_count > 255)
7306 return -EINVAL;
7307
7308 params.count = cs_count;
16ef1fe2 7309
ee4bc9e7
SW
7310 if (!need_new_beacon)
7311 goto skip_beacons;
7312
16ef1fe2
SW
7313 err = nl80211_parse_beacon(info->attrs, &params.beacon_after);
7314 if (err)
7315 return err;
7316
7317 err = nla_parse_nested(csa_attrs, NL80211_ATTR_MAX,
7318 info->attrs[NL80211_ATTR_CSA_IES],
7319 nl80211_policy);
7320 if (err)
7321 return err;
7322
7323 err = nl80211_parse_beacon(csa_attrs, &params.beacon_csa);
7324 if (err)
7325 return err;
7326
7327 if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON])
7328 return -EINVAL;
7329
9a774c78
AO
7330 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
7331 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
7332 return -EINVAL;
7333
9a774c78
AO
7334 params.n_counter_offsets_beacon = len / sizeof(u16);
7335 if (rdev->wiphy.max_num_csa_counters &&
7336 (params.n_counter_offsets_beacon >
7337 rdev->wiphy.max_num_csa_counters))
16ef1fe2
SW
7338 return -EINVAL;
7339
9a774c78
AO
7340 params.counter_offsets_beacon =
7341 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
7342
7343 /* sanity checks - counters should fit and be the same */
7344 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
7345 u16 offset = params.counter_offsets_beacon[i];
7346
7347 if (offset >= params.beacon_csa.tail_len)
7348 return -EINVAL;
7349
7350 if (params.beacon_csa.tail[offset] != params.count)
7351 return -EINVAL;
7352 }
7353
16ef1fe2 7354 if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) {
9a774c78
AO
7355 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
7356 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
7357 return -EINVAL;
7358
9a774c78
AO
7359 params.n_counter_offsets_presp = len / sizeof(u16);
7360 if (rdev->wiphy.max_num_csa_counters &&
ad5987b4 7361 (params.n_counter_offsets_presp >
9a774c78 7362 rdev->wiphy.max_num_csa_counters))
16ef1fe2 7363 return -EINVAL;
9a774c78
AO
7364
7365 params.counter_offsets_presp =
7366 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
7367
7368 /* sanity checks - counters should fit and be the same */
7369 for (i = 0; i < params.n_counter_offsets_presp; i++) {
7370 u16 offset = params.counter_offsets_presp[i];
7371
7372 if (offset >= params.beacon_csa.probe_resp_len)
7373 return -EINVAL;
7374
7375 if (params.beacon_csa.probe_resp[offset] !=
7376 params.count)
7377 return -EINVAL;
7378 }
16ef1fe2
SW
7379 }
7380
ee4bc9e7 7381skip_beacons:
16ef1fe2
SW
7382 err = nl80211_parse_chandef(rdev, info, &params.chandef);
7383 if (err)
7384 return err;
7385
923b352f
AN
7386 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
7387 wdev->iftype))
16ef1fe2
SW
7388 return -EINVAL;
7389
2beb6dab
LC
7390 err = cfg80211_chandef_dfs_required(wdev->wiphy,
7391 &params.chandef,
7392 wdev->iftype);
7393 if (err < 0)
7394 return err;
7395
dcc6c2f5 7396 if (err > 0)
2beb6dab 7397 params.radar_required = true;
16ef1fe2 7398
16ef1fe2
SW
7399 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
7400 params.block_tx = true;
7401
c56589ed
SW
7402 wdev_lock(wdev);
7403 err = rdev_channel_switch(rdev, dev, &params);
7404 wdev_unlock(wdev);
7405
7406 return err;
16ef1fe2
SW
7407}
7408
9720bb3a
JB
7409static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
7410 u32 seq, int flags,
2a519311 7411 struct cfg80211_registered_device *rdev,
48ab905d
JB
7412 struct wireless_dev *wdev,
7413 struct cfg80211_internal_bss *intbss)
2a519311 7414{
48ab905d 7415 struct cfg80211_bss *res = &intbss->pub;
9caf0364 7416 const struct cfg80211_bss_ies *ies;
2a519311
JB
7417 void *hdr;
7418 struct nlattr *bss;
48ab905d
JB
7419
7420 ASSERT_WDEV_LOCK(wdev);
2a519311 7421
15e47304 7422 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
7423 NL80211_CMD_NEW_SCAN_RESULTS);
7424 if (!hdr)
7425 return -1;
7426
9720bb3a
JB
7427 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
7428
97990a06
JB
7429 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
7430 goto nla_put_failure;
7431 if (wdev->netdev &&
9360ffd1
DM
7432 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
7433 goto nla_put_failure;
2dad624e
ND
7434 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
7435 NL80211_ATTR_PAD))
97990a06 7436 goto nla_put_failure;
2a519311
JB
7437
7438 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
7439 if (!bss)
7440 goto nla_put_failure;
9360ffd1 7441 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 7442 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 7443 goto nla_put_failure;
9caf0364
JB
7444
7445 rcu_read_lock();
0e227084
JB
7446 /* indicate whether we have probe response data or not */
7447 if (rcu_access_pointer(res->proberesp_ies) &&
7448 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
7449 goto fail_unlock_rcu;
7450
7451 /* this pointer prefers to be pointed to probe response data
7452 * but is always valid
7453 */
9caf0364 7454 ies = rcu_dereference(res->ies);
8cef2c9d 7455 if (ies) {
2dad624e
ND
7456 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
7457 NL80211_BSS_PAD))
8cef2c9d 7458 goto fail_unlock_rcu;
8cef2c9d
JB
7459 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
7460 ies->len, ies->data))
7461 goto fail_unlock_rcu;
9caf0364 7462 }
0e227084
JB
7463
7464 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 7465 ies = rcu_dereference(res->beacon_ies);
0e227084 7466 if (ies && ies->from_beacon) {
2dad624e
ND
7467 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
7468 NL80211_BSS_PAD))
8cef2c9d
JB
7469 goto fail_unlock_rcu;
7470 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
7471 ies->len, ies->data))
7472 goto fail_unlock_rcu;
9caf0364
JB
7473 }
7474 rcu_read_unlock();
7475
9360ffd1
DM
7476 if (res->beacon_interval &&
7477 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
7478 goto nla_put_failure;
7479 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
7480 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
dcd6eac1 7481 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
7482 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
7483 jiffies_to_msecs(jiffies - intbss->ts)))
7484 goto nla_put_failure;
2a519311 7485
1d76250b
AS
7486 if (intbss->parent_tsf &&
7487 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
7488 intbss->parent_tsf, NL80211_BSS_PAD) ||
7489 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
7490 intbss->parent_bssid)))
7491 goto nla_put_failure;
7492
6e19bc4b 7493 if (intbss->ts_boottime &&
2dad624e
ND
7494 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
7495 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
7496 goto nla_put_failure;
7497
77965c97 7498 switch (rdev->wiphy.signal_type) {
2a519311 7499 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
7500 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
7501 goto nla_put_failure;
2a519311
JB
7502 break;
7503 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
7504 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
7505 goto nla_put_failure;
2a519311
JB
7506 break;
7507 default:
7508 break;
7509 }
7510
48ab905d 7511 switch (wdev->iftype) {
074ac8df 7512 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 7513 case NL80211_IFTYPE_STATION:
9360ffd1
DM
7514 if (intbss == wdev->current_bss &&
7515 nla_put_u32(msg, NL80211_BSS_STATUS,
7516 NL80211_BSS_STATUS_ASSOCIATED))
7517 goto nla_put_failure;
48ab905d
JB
7518 break;
7519 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
7520 if (intbss == wdev->current_bss &&
7521 nla_put_u32(msg, NL80211_BSS_STATUS,
7522 NL80211_BSS_STATUS_IBSS_JOINED))
7523 goto nla_put_failure;
48ab905d
JB
7524 break;
7525 default:
7526 break;
7527 }
7528
2a519311
JB
7529 nla_nest_end(msg, bss);
7530
053c095a
JB
7531 genlmsg_end(msg, hdr);
7532 return 0;
2a519311 7533
8cef2c9d
JB
7534 fail_unlock_rcu:
7535 rcu_read_unlock();
2a519311
JB
7536 nla_put_failure:
7537 genlmsg_cancel(msg, hdr);
7538 return -EMSGSIZE;
7539}
7540
97990a06 7541static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 7542{
48ab905d 7543 struct cfg80211_registered_device *rdev;
2a519311 7544 struct cfg80211_internal_bss *scan;
48ab905d 7545 struct wireless_dev *wdev;
97990a06 7546 int start = cb->args[2], idx = 0;
2a519311
JB
7547 int err;
7548
97990a06 7549 err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
7550 if (err)
7551 return err;
2a519311 7552
48ab905d
JB
7553 wdev_lock(wdev);
7554 spin_lock_bh(&rdev->bss_lock);
7555 cfg80211_bss_expire(rdev);
7556
9720bb3a
JB
7557 cb->seq = rdev->bss_generation;
7558
48ab905d 7559 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
7560 if (++idx <= start)
7561 continue;
9720bb3a 7562 if (nl80211_send_bss(skb, cb,
2a519311 7563 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 7564 rdev, wdev, scan) < 0) {
2a519311 7565 idx--;
67748893 7566 break;
2a519311
JB
7567 }
7568 }
7569
48ab905d
JB
7570 spin_unlock_bh(&rdev->bss_lock);
7571 wdev_unlock(wdev);
2a519311 7572
97990a06
JB
7573 cb->args[2] = idx;
7574 nl80211_finish_wdev_dump(rdev);
2a519311 7575
67748893 7576 return skb->len;
2a519311
JB
7577}
7578
15e47304 7579static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
7580 int flags, struct net_device *dev,
7581 bool allow_radio_stats,
7582 struct survey_info *survey)
61fa713c
HS
7583{
7584 void *hdr;
7585 struct nlattr *infoattr;
7586
11f78ac3
JB
7587 /* skip radio stats if userspace didn't request them */
7588 if (!survey->channel && !allow_radio_stats)
7589 return 0;
7590
15e47304 7591 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
7592 NL80211_CMD_NEW_SURVEY_RESULTS);
7593 if (!hdr)
7594 return -ENOMEM;
7595
9360ffd1
DM
7596 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
7597 goto nla_put_failure;
61fa713c
HS
7598
7599 infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
7600 if (!infoattr)
7601 goto nla_put_failure;
7602
11f78ac3
JB
7603 if (survey->channel &&
7604 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
7605 survey->channel->center_freq))
7606 goto nla_put_failure;
7607
7608 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
7609 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
7610 goto nla_put_failure;
7611 if ((survey->filled & SURVEY_INFO_IN_USE) &&
7612 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
7613 goto nla_put_failure;
4ed20beb 7614 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
7615 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
7616 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 7617 goto nla_put_failure;
4ed20beb 7618 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
7619 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
7620 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 7621 goto nla_put_failure;
4ed20beb 7622 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
7623 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
7624 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 7625 goto nla_put_failure;
4ed20beb 7626 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
7627 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
7628 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 7629 goto nla_put_failure;
4ed20beb 7630 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
7631 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
7632 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 7633 goto nla_put_failure;
052536ab 7634 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
7635 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
7636 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 7637 goto nla_put_failure;
61fa713c
HS
7638
7639 nla_nest_end(msg, infoattr);
7640
053c095a
JB
7641 genlmsg_end(msg, hdr);
7642 return 0;
61fa713c
HS
7643
7644 nla_put_failure:
7645 genlmsg_cancel(msg, hdr);
7646 return -EMSGSIZE;
7647}
7648
11f78ac3 7649static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c
HS
7650{
7651 struct survey_info survey;
1b8ec87a 7652 struct cfg80211_registered_device *rdev;
97990a06
JB
7653 struct wireless_dev *wdev;
7654 int survey_idx = cb->args[2];
61fa713c 7655 int res;
11f78ac3 7656 bool radio_stats;
61fa713c 7657
1b8ec87a 7658 res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
67748893
JB
7659 if (res)
7660 return res;
61fa713c 7661
11f78ac3
JB
7662 /* prepare_wdev_dump parsed the attributes */
7663 radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
7664
97990a06
JB
7665 if (!wdev->netdev) {
7666 res = -EINVAL;
7667 goto out_err;
7668 }
7669
1b8ec87a 7670 if (!rdev->ops->dump_survey) {
61fa713c
HS
7671 res = -EOPNOTSUPP;
7672 goto out_err;
7673 }
7674
7675 while (1) {
1b8ec87a 7676 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
7677 if (res == -ENOENT)
7678 break;
7679 if (res)
7680 goto out_err;
7681
11f78ac3
JB
7682 /* don't send disabled channels, but do send non-channel data */
7683 if (survey.channel &&
7684 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
7685 survey_idx++;
7686 continue;
7687 }
7688
61fa713c 7689 if (nl80211_send_survey(skb,
15e47304 7690 NETLINK_CB(cb->skb).portid,
61fa713c 7691 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 7692 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
7693 goto out;
7694 survey_idx++;
7695 }
7696
7697 out:
97990a06 7698 cb->args[2] = survey_idx;
61fa713c
HS
7699 res = skb->len;
7700 out_err:
1b8ec87a 7701 nl80211_finish_wdev_dump(rdev);
61fa713c
HS
7702 return res;
7703}
7704
b23aa676
SO
7705static bool nl80211_valid_wpa_versions(u32 wpa_versions)
7706{
7707 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
7708 NL80211_WPA_VERSION_2));
7709}
7710
636a5d36
JM
7711static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
7712{
4c476991
JB
7713 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7714 struct net_device *dev = info->user_ptr[1];
19957bb3 7715 struct ieee80211_channel *chan;
e39e5b5e
JM
7716 const u8 *bssid, *ssid, *ie = NULL, *sae_data = NULL;
7717 int err, ssid_len, ie_len = 0, sae_data_len = 0;
19957bb3 7718 enum nl80211_auth_type auth_type;
fffd0934 7719 struct key_parse key;
d5cdfacb 7720 bool local_state_change;
636a5d36 7721
f4a11bb0
JB
7722 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
7723 return -EINVAL;
7724
7725 if (!info->attrs[NL80211_ATTR_MAC])
7726 return -EINVAL;
7727
1778092e
JM
7728 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
7729 return -EINVAL;
7730
19957bb3
JB
7731 if (!info->attrs[NL80211_ATTR_SSID])
7732 return -EINVAL;
7733
7734 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
7735 return -EINVAL;
7736
fffd0934
JB
7737 err = nl80211_parse_key(info, &key);
7738 if (err)
7739 return err;
7740
7741 if (key.idx >= 0) {
e31b8213
JB
7742 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
7743 return -EINVAL;
fffd0934
JB
7744 if (!key.p.key || !key.p.key_len)
7745 return -EINVAL;
7746 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
7747 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
7748 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
7749 key.p.key_len != WLAN_KEY_LEN_WEP104))
7750 return -EINVAL;
b6b5555b 7751 if (key.idx > 3)
fffd0934
JB
7752 return -EINVAL;
7753 } else {
7754 key.p.key_len = 0;
7755 key.p.key = NULL;
7756 }
7757
afea0b7a
JB
7758 if (key.idx >= 0) {
7759 int i;
7760 bool ok = false;
7a087e74 7761
afea0b7a
JB
7762 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
7763 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
7764 ok = true;
7765 break;
7766 }
7767 }
4c476991
JB
7768 if (!ok)
7769 return -EINVAL;
afea0b7a
JB
7770 }
7771
4c476991
JB
7772 if (!rdev->ops->auth)
7773 return -EOPNOTSUPP;
636a5d36 7774
074ac8df 7775 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7776 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
7777 return -EOPNOTSUPP;
eec60b03 7778
19957bb3 7779 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
664834de
JM
7780 chan = nl80211_get_valid_chan(&rdev->wiphy,
7781 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
7782 if (!chan)
4c476991 7783 return -EINVAL;
636a5d36 7784
19957bb3
JB
7785 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
7786 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
7787
7788 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
7789 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
7790 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
7791 }
7792
19957bb3 7793 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 7794 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 7795 return -EINVAL;
636a5d36 7796
e39e5b5e
JM
7797 if (auth_type == NL80211_AUTHTYPE_SAE &&
7798 !info->attrs[NL80211_ATTR_SAE_DATA])
7799 return -EINVAL;
7800
7801 if (info->attrs[NL80211_ATTR_SAE_DATA]) {
7802 if (auth_type != NL80211_AUTHTYPE_SAE)
7803 return -EINVAL;
7804 sae_data = nla_data(info->attrs[NL80211_ATTR_SAE_DATA]);
7805 sae_data_len = nla_len(info->attrs[NL80211_ATTR_SAE_DATA]);
7806 /* need to include at least Auth Transaction and Status Code */
7807 if (sae_data_len < 4)
7808 return -EINVAL;
7809 }
7810
d5cdfacb
JM
7811 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
7812
95de817b
JB
7813 /*
7814 * Since we no longer track auth state, ignore
7815 * requests to only change local state.
7816 */
7817 if (local_state_change)
7818 return 0;
7819
91bf9b26
JB
7820 wdev_lock(dev->ieee80211_ptr);
7821 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
7822 ssid, ssid_len, ie, ie_len,
7823 key.p.key, key.p.key_len, key.idx,
7824 sae_data, sae_data_len);
7825 wdev_unlock(dev->ieee80211_ptr);
7826 return err;
636a5d36
JM
7827}
7828
c0692b8f
JB
7829static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
7830 struct genl_info *info,
3dc27d25
JB
7831 struct cfg80211_crypto_settings *settings,
7832 int cipher_limit)
b23aa676 7833{
c0b2bbd8
JB
7834 memset(settings, 0, sizeof(*settings));
7835
b23aa676
SO
7836 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
7837
c0692b8f
JB
7838 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
7839 u16 proto;
7a087e74 7840
c0692b8f
JB
7841 proto = nla_get_u16(
7842 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
7843 settings->control_port_ethertype = cpu_to_be16(proto);
7844 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
7845 proto != ETH_P_PAE)
7846 return -EINVAL;
7847 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
7848 settings->control_port_no_encrypt = true;
7849 } else
7850 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
7851
b23aa676
SO
7852 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
7853 void *data;
7854 int len, i;
7855
7856 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
7857 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
7858 settings->n_ciphers_pairwise = len / sizeof(u32);
7859
7860 if (len % sizeof(u32))
7861 return -EINVAL;
7862
3dc27d25 7863 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
7864 return -EINVAL;
7865
7866 memcpy(settings->ciphers_pairwise, data, len);
7867
7868 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
7869 if (!cfg80211_supported_cipher_suite(
7870 &rdev->wiphy,
b23aa676
SO
7871 settings->ciphers_pairwise[i]))
7872 return -EINVAL;
7873 }
7874
7875 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
7876 settings->cipher_group =
7877 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
7878 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
7879 settings->cipher_group))
b23aa676
SO
7880 return -EINVAL;
7881 }
7882
7883 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
7884 settings->wpa_versions =
7885 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
7886 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
7887 return -EINVAL;
7888 }
7889
7890 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
7891 void *data;
6d30240e 7892 int len;
b23aa676
SO
7893
7894 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
7895 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
7896 settings->n_akm_suites = len / sizeof(u32);
7897
7898 if (len % sizeof(u32))
7899 return -EINVAL;
7900
1b9ca027
JM
7901 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
7902 return -EINVAL;
7903
b23aa676 7904 memcpy(settings->akm_suites, data, len);
b23aa676
SO
7905 }
7906
7907 return 0;
7908}
7909
636a5d36
JM
7910static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
7911{
4c476991
JB
7912 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7913 struct net_device *dev = info->user_ptr[1];
f444de05 7914 struct ieee80211_channel *chan;
f62fab73
JB
7915 struct cfg80211_assoc_request req = {};
7916 const u8 *bssid, *ssid;
7917 int err, ssid_len = 0;
636a5d36 7918
f4a11bb0
JB
7919 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
7920 return -EINVAL;
7921
7922 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
7923 !info->attrs[NL80211_ATTR_SSID] ||
7924 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
7925 return -EINVAL;
7926
4c476991
JB
7927 if (!rdev->ops->assoc)
7928 return -EOPNOTSUPP;
636a5d36 7929
074ac8df 7930 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
7931 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
7932 return -EOPNOTSUPP;
eec60b03 7933
19957bb3 7934 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 7935
664834de
JM
7936 chan = nl80211_get_valid_chan(&rdev->wiphy,
7937 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
7938 if (!chan)
4c476991 7939 return -EINVAL;
636a5d36 7940
19957bb3
JB
7941 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
7942 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
7943
7944 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
7945 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
7946 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
7947 }
7948
dc6382ce 7949 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 7950 enum nl80211_mfp mfp =
dc6382ce 7951 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 7952 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 7953 req.use_mfp = true;
4c476991
JB
7954 else if (mfp != NL80211_MFP_NO)
7955 return -EINVAL;
dc6382ce
JM
7956 }
7957
3e5d7649 7958 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 7959 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 7960
7e7c8926 7961 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 7962 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
7963
7964 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
7965 memcpy(&req.ht_capa_mask,
7966 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
7967 sizeof(req.ht_capa_mask));
7e7c8926
BG
7968
7969 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 7970 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 7971 return -EINVAL;
f62fab73
JB
7972 memcpy(&req.ht_capa,
7973 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
7974 sizeof(req.ht_capa));
7e7c8926
BG
7975 }
7976
ee2aca34 7977 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 7978 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34
JB
7979
7980 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
7981 memcpy(&req.vht_capa_mask,
7982 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
7983 sizeof(req.vht_capa_mask));
ee2aca34
JB
7984
7985 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 7986 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 7987 return -EINVAL;
f62fab73
JB
7988 memcpy(&req.vht_capa,
7989 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
7990 sizeof(req.vht_capa));
ee2aca34
JB
7991 }
7992
bab5ab7d 7993 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
7994 if (!((rdev->wiphy.features &
7995 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
7996 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
7997 !wiphy_ext_feature_isset(&rdev->wiphy,
7998 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
7999 return -EINVAL;
8000 req.flags |= ASSOC_REQ_USE_RRM;
8001 }
8002
f62fab73 8003 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
8004 if (!err) {
8005 wdev_lock(dev->ieee80211_ptr);
f62fab73
JB
8006 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
8007 ssid, ssid_len, &req);
91bf9b26
JB
8008 wdev_unlock(dev->ieee80211_ptr);
8009 }
636a5d36 8010
636a5d36
JM
8011 return err;
8012}
8013
8014static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
8015{
4c476991
JB
8016 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8017 struct net_device *dev = info->user_ptr[1];
19957bb3 8018 const u8 *ie = NULL, *bssid;
91bf9b26 8019 int ie_len = 0, err;
19957bb3 8020 u16 reason_code;
d5cdfacb 8021 bool local_state_change;
636a5d36 8022
f4a11bb0
JB
8023 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8024 return -EINVAL;
8025
8026 if (!info->attrs[NL80211_ATTR_MAC])
8027 return -EINVAL;
8028
8029 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8030 return -EINVAL;
8031
4c476991
JB
8032 if (!rdev->ops->deauth)
8033 return -EOPNOTSUPP;
636a5d36 8034
074ac8df 8035 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8036 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8037 return -EOPNOTSUPP;
eec60b03 8038
19957bb3 8039 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8040
19957bb3
JB
8041 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8042 if (reason_code == 0) {
f4a11bb0 8043 /* Reason Code 0 is reserved */
4c476991 8044 return -EINVAL;
255e737e 8045 }
636a5d36
JM
8046
8047 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8048 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8049 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8050 }
8051
d5cdfacb
JM
8052 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8053
91bf9b26
JB
8054 wdev_lock(dev->ieee80211_ptr);
8055 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
8056 local_state_change);
8057 wdev_unlock(dev->ieee80211_ptr);
8058 return err;
636a5d36
JM
8059}
8060
8061static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
8062{
4c476991
JB
8063 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8064 struct net_device *dev = info->user_ptr[1];
19957bb3 8065 const u8 *ie = NULL, *bssid;
91bf9b26 8066 int ie_len = 0, err;
19957bb3 8067 u16 reason_code;
d5cdfacb 8068 bool local_state_change;
636a5d36 8069
f4a11bb0
JB
8070 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8071 return -EINVAL;
8072
8073 if (!info->attrs[NL80211_ATTR_MAC])
8074 return -EINVAL;
8075
8076 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8077 return -EINVAL;
8078
4c476991
JB
8079 if (!rdev->ops->disassoc)
8080 return -EOPNOTSUPP;
636a5d36 8081
074ac8df 8082 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8083 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8084 return -EOPNOTSUPP;
eec60b03 8085
19957bb3 8086 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8087
19957bb3
JB
8088 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8089 if (reason_code == 0) {
f4a11bb0 8090 /* Reason Code 0 is reserved */
4c476991 8091 return -EINVAL;
255e737e 8092 }
636a5d36
JM
8093
8094 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8095 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8096 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8097 }
8098
d5cdfacb
JM
8099 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8100
91bf9b26
JB
8101 wdev_lock(dev->ieee80211_ptr);
8102 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
8103 local_state_change);
8104 wdev_unlock(dev->ieee80211_ptr);
8105 return err;
636a5d36
JM
8106}
8107
dd5b4cc7
FF
8108static bool
8109nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 8110 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
8111 int rateval)
8112{
8113 struct wiphy *wiphy = &rdev->wiphy;
8114 bool found = false;
8115 int band, i;
8116
57fbcce3 8117 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
8118 struct ieee80211_supported_band *sband;
8119
8120 sband = wiphy->bands[band];
8121 if (!sband)
8122 continue;
8123
8124 for (i = 0; i < sband->n_bitrates; i++) {
8125 if (sband->bitrates[i].bitrate == rateval) {
8126 mcast_rate[band] = i + 1;
8127 found = true;
8128 break;
8129 }
8130 }
8131 }
8132
8133 return found;
8134}
8135
04a773ad
JB
8136static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
8137{
4c476991
JB
8138 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8139 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
8140 struct cfg80211_ibss_params ibss;
8141 struct wiphy *wiphy;
fffd0934 8142 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
8143 int err;
8144
8e30bc55
JB
8145 memset(&ibss, 0, sizeof(ibss));
8146
04a773ad
JB
8147 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8148 return -EINVAL;
8149
683b6d3b 8150 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
8151 !nla_len(info->attrs[NL80211_ATTR_SSID]))
8152 return -EINVAL;
8153
8e30bc55
JB
8154 ibss.beacon_interval = 100;
8155
12d20fc9 8156 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
8157 ibss.beacon_interval =
8158 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 8159
0c317a02
PK
8160 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
8161 ibss.beacon_interval);
12d20fc9
PK
8162 if (err)
8163 return err;
8e30bc55 8164
4c476991
JB
8165 if (!rdev->ops->join_ibss)
8166 return -EOPNOTSUPP;
04a773ad 8167
4c476991
JB
8168 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
8169 return -EOPNOTSUPP;
04a773ad 8170
79c97e97 8171 wiphy = &rdev->wiphy;
04a773ad 8172
39193498 8173 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 8174 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
8175
8176 if (!is_valid_ether_addr(ibss.bssid))
8177 return -EINVAL;
8178 }
04a773ad
JB
8179 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8180 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
8181
8182 if (info->attrs[NL80211_ATTR_IE]) {
8183 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8184 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8185 }
8186
683b6d3b
JB
8187 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
8188 if (err)
8189 return err;
04a773ad 8190
174e0cd2
IP
8191 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
8192 NL80211_IFTYPE_ADHOC))
54858ee5
AS
8193 return -EINVAL;
8194
2f301ab2 8195 switch (ibss.chandef.width) {
bf372645
SW
8196 case NL80211_CHAN_WIDTH_5:
8197 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
8198 case NL80211_CHAN_WIDTH_20_NOHT:
8199 break;
8200 case NL80211_CHAN_WIDTH_20:
8201 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
8202 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8203 return -EINVAL;
8204 break;
8205 case NL80211_CHAN_WIDTH_80:
8206 case NL80211_CHAN_WIDTH_80P80:
8207 case NL80211_CHAN_WIDTH_160:
8208 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
8209 return -EINVAL;
8210 if (!wiphy_ext_feature_isset(&rdev->wiphy,
8211 NL80211_EXT_FEATURE_VHT_IBSS))
8212 return -EINVAL;
8213 break;
2f301ab2 8214 default:
c04d6150 8215 return -EINVAL;
2f301ab2 8216 }
db9c64cf 8217
04a773ad 8218 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
8219 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
8220
fbd2c8dc
TP
8221 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
8222 u8 *rates =
8223 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8224 int n_rates =
8225 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8226 struct ieee80211_supported_band *sband =
683b6d3b 8227 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 8228
34850ab2
JB
8229 err = ieee80211_get_ratemask(sband, rates, n_rates,
8230 &ibss.basic_rates);
8231 if (err)
8232 return err;
fbd2c8dc 8233 }
dd5b4cc7 8234
803768f5
SW
8235 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8236 memcpy(&ibss.ht_capa_mask,
8237 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8238 sizeof(ibss.ht_capa_mask));
8239
8240 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
8241 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8242 return -EINVAL;
8243 memcpy(&ibss.ht_capa,
8244 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8245 sizeof(ibss.ht_capa));
8246 }
8247
dd5b4cc7
FF
8248 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
8249 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
8250 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
8251 return -EINVAL;
fbd2c8dc 8252
4c476991 8253 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
8254 bool no_ht = false;
8255
4c476991 8256 connkeys = nl80211_parse_connkeys(rdev,
de7044ee
SM
8257 info->attrs[NL80211_ATTR_KEYS],
8258 &no_ht);
4c476991
JB
8259 if (IS_ERR(connkeys))
8260 return PTR_ERR(connkeys);
de7044ee 8261
3d9d1d66
JB
8262 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
8263 no_ht) {
5e950a78 8264 kzfree(connkeys);
de7044ee
SM
8265 return -EINVAL;
8266 }
4c476991 8267 }
04a773ad 8268
267335d6
AQ
8269 ibss.control_port =
8270 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
8271
5336fa88
SW
8272 ibss.userspace_handles_dfs =
8273 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
8274
4c476991 8275 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 8276 if (err)
b47f610b 8277 kzfree(connkeys);
04a773ad
JB
8278 return err;
8279}
8280
8281static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
8282{
4c476991
JB
8283 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8284 struct net_device *dev = info->user_ptr[1];
04a773ad 8285
4c476991
JB
8286 if (!rdev->ops->leave_ibss)
8287 return -EOPNOTSUPP;
04a773ad 8288
4c476991
JB
8289 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
8290 return -EOPNOTSUPP;
04a773ad 8291
4c476991 8292 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
8293}
8294
f4e583c8
AQ
8295static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
8296{
8297 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8298 struct net_device *dev = info->user_ptr[1];
57fbcce3 8299 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
8300 u32 nla_rate;
8301 int err;
8302
8303 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
8304 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
8305 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
8306 return -EOPNOTSUPP;
8307
8308 if (!rdev->ops->set_mcast_rate)
8309 return -EOPNOTSUPP;
8310
8311 memset(mcast_rate, 0, sizeof(mcast_rate));
8312
8313 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
8314 return -EINVAL;
8315
8316 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
8317 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
8318 return -EINVAL;
8319
a1056b1b 8320 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
8321
8322 return err;
8323}
8324
ad7e718c
JB
8325static struct sk_buff *
8326__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
8327 struct wireless_dev *wdev, int approxlen,
8328 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
8329 enum nl80211_attrs attr,
8330 const struct nl80211_vendor_cmd_info *info,
8331 gfp_t gfp)
ad7e718c
JB
8332{
8333 struct sk_buff *skb;
8334 void *hdr;
8335 struct nlattr *data;
8336
8337 skb = nlmsg_new(approxlen + 100, gfp);
8338 if (!skb)
8339 return NULL;
8340
8341 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
8342 if (!hdr) {
8343 kfree_skb(skb);
8344 return NULL;
8345 }
8346
8347 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
8348 goto nla_put_failure;
567ffc35
JB
8349
8350 if (info) {
8351 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
8352 info->vendor_id))
8353 goto nla_put_failure;
8354 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
8355 info->subcmd))
8356 goto nla_put_failure;
8357 }
8358
6c09e791 8359 if (wdev) {
2dad624e
ND
8360 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
8361 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
8362 goto nla_put_failure;
8363 if (wdev->netdev &&
8364 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
8365 wdev->netdev->ifindex))
8366 goto nla_put_failure;
8367 }
8368
ad7e718c 8369 data = nla_nest_start(skb, attr);
76e1fb4b
JB
8370 if (!data)
8371 goto nla_put_failure;
ad7e718c
JB
8372
8373 ((void **)skb->cb)[0] = rdev;
8374 ((void **)skb->cb)[1] = hdr;
8375 ((void **)skb->cb)[2] = data;
8376
8377 return skb;
8378
8379 nla_put_failure:
8380 kfree_skb(skb);
8381 return NULL;
8382}
f4e583c8 8383
e03ad6ea 8384struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 8385 struct wireless_dev *wdev,
e03ad6ea
JB
8386 enum nl80211_commands cmd,
8387 enum nl80211_attrs attr,
8388 int vendor_event_idx,
8389 int approxlen, gfp_t gfp)
8390{
f26cbf40 8391 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
8392 const struct nl80211_vendor_cmd_info *info;
8393
8394 switch (cmd) {
8395 case NL80211_CMD_TESTMODE:
8396 if (WARN_ON(vendor_event_idx != -1))
8397 return NULL;
8398 info = NULL;
8399 break;
8400 case NL80211_CMD_VENDOR:
8401 if (WARN_ON(vendor_event_idx < 0 ||
8402 vendor_event_idx >= wiphy->n_vendor_events))
8403 return NULL;
8404 info = &wiphy->vendor_events[vendor_event_idx];
8405 break;
8406 default:
8407 WARN_ON(1);
8408 return NULL;
8409 }
8410
6c09e791 8411 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, 0, 0,
e03ad6ea
JB
8412 cmd, attr, info, gfp);
8413}
8414EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
8415
8416void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
8417{
8418 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
8419 void *hdr = ((void **)skb->cb)[1];
8420 struct nlattr *data = ((void **)skb->cb)[2];
8421 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
8422
bd8c78e7
JB
8423 /* clear CB data for netlink core to own from now on */
8424 memset(skb->cb, 0, sizeof(skb->cb));
8425
e03ad6ea
JB
8426 nla_nest_end(skb, data);
8427 genlmsg_end(skb, hdr);
8428
8429 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
8430 mcgrp = NL80211_MCGRP_VENDOR;
8431
8432 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0,
8433 mcgrp, gfp);
8434}
8435EXPORT_SYMBOL(__cfg80211_send_event_skb);
8436
aff89a9b 8437#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
8438static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
8439{
4c476991 8440 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fc73f11f
DS
8441 struct wireless_dev *wdev =
8442 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
aff89a9b
JB
8443 int err;
8444
fc73f11f
DS
8445 if (!rdev->ops->testmode_cmd)
8446 return -EOPNOTSUPP;
8447
8448 if (IS_ERR(wdev)) {
8449 err = PTR_ERR(wdev);
8450 if (err != -EINVAL)
8451 return err;
8452 wdev = NULL;
8453 } else if (wdev->wiphy != &rdev->wiphy) {
8454 return -EINVAL;
8455 }
8456
aff89a9b
JB
8457 if (!info->attrs[NL80211_ATTR_TESTDATA])
8458 return -EINVAL;
8459
ad7e718c 8460 rdev->cur_cmd_info = info;
fc73f11f 8461 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
8462 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
8463 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 8464 rdev->cur_cmd_info = NULL;
aff89a9b 8465
aff89a9b
JB
8466 return err;
8467}
8468
71063f0e
WYG
8469static int nl80211_testmode_dump(struct sk_buff *skb,
8470 struct netlink_callback *cb)
8471{
00918d33 8472 struct cfg80211_registered_device *rdev;
71063f0e
WYG
8473 int err;
8474 long phy_idx;
8475 void *data = NULL;
8476 int data_len = 0;
8477
5fe231e8
JB
8478 rtnl_lock();
8479
71063f0e
WYG
8480 if (cb->args[0]) {
8481 /*
8482 * 0 is a valid index, but not valid for args[0],
8483 * so we need to offset by 1.
8484 */
8485 phy_idx = cb->args[0] - 1;
8486 } else {
8487 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
8488 nl80211_fam.attrbuf, nl80211_fam.maxattr,
8489 nl80211_policy);
8490 if (err)
5fe231e8 8491 goto out_err;
00918d33 8492
2bd7e35d
JB
8493 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
8494 nl80211_fam.attrbuf);
8495 if (IS_ERR(rdev)) {
5fe231e8
JB
8496 err = PTR_ERR(rdev);
8497 goto out_err;
00918d33 8498 }
2bd7e35d
JB
8499 phy_idx = rdev->wiphy_idx;
8500 rdev = NULL;
2bd7e35d 8501
71063f0e
WYG
8502 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
8503 cb->args[1] =
8504 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
8505 }
8506
8507 if (cb->args[1]) {
8508 data = nla_data((void *)cb->args[1]);
8509 data_len = nla_len((void *)cb->args[1]);
8510 }
8511
00918d33
JB
8512 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
8513 if (!rdev) {
5fe231e8
JB
8514 err = -ENOENT;
8515 goto out_err;
71063f0e 8516 }
71063f0e 8517
00918d33 8518 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
8519 err = -EOPNOTSUPP;
8520 goto out_err;
8521 }
8522
8523 while (1) {
15e47304 8524 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
8525 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8526 NL80211_CMD_TESTMODE);
8527 struct nlattr *tmdata;
8528
cb35fba3
DC
8529 if (!hdr)
8530 break;
8531
9360ffd1 8532 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
8533 genlmsg_cancel(skb, hdr);
8534 break;
8535 }
8536
8537 tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
8538 if (!tmdata) {
8539 genlmsg_cancel(skb, hdr);
8540 break;
8541 }
e35e4d28 8542 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
8543 nla_nest_end(skb, tmdata);
8544
8545 if (err == -ENOBUFS || err == -ENOENT) {
8546 genlmsg_cancel(skb, hdr);
8547 break;
8548 } else if (err) {
8549 genlmsg_cancel(skb, hdr);
8550 goto out_err;
8551 }
8552
8553 genlmsg_end(skb, hdr);
8554 }
8555
8556 err = skb->len;
8557 /* see above */
8558 cb->args[0] = phy_idx + 1;
8559 out_err:
5fe231e8 8560 rtnl_unlock();
71063f0e
WYG
8561 return err;
8562}
aff89a9b
JB
8563#endif
8564
b23aa676
SO
8565static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
8566{
4c476991
JB
8567 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8568 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
8569 struct cfg80211_connect_params connect;
8570 struct wiphy *wiphy;
fffd0934 8571 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
8572 int err;
8573
8574 memset(&connect, 0, sizeof(connect));
8575
8576 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
8577 return -EINVAL;
8578
8579 if (!info->attrs[NL80211_ATTR_SSID] ||
8580 !nla_len(info->attrs[NL80211_ATTR_SSID]))
8581 return -EINVAL;
8582
8583 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
8584 connect.auth_type =
8585 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
8586 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
8587 NL80211_CMD_CONNECT))
b23aa676
SO
8588 return -EINVAL;
8589 } else
8590 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
8591
8592 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
8593
c0692b8f 8594 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 8595 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
8596 if (err)
8597 return err;
b23aa676 8598
074ac8df 8599 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8600 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8601 return -EOPNOTSUPP;
b23aa676 8602
79c97e97 8603 wiphy = &rdev->wiphy;
b23aa676 8604
4486ea98
BS
8605 connect.bg_scan_period = -1;
8606 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
8607 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
8608 connect.bg_scan_period =
8609 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
8610 }
8611
b23aa676
SO
8612 if (info->attrs[NL80211_ATTR_MAC])
8613 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
8614 else if (info->attrs[NL80211_ATTR_MAC_HINT])
8615 connect.bssid_hint =
8616 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
8617 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8618 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
8619
8620 if (info->attrs[NL80211_ATTR_IE]) {
8621 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8622 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8623 }
8624
cee00a95
JM
8625 if (info->attrs[NL80211_ATTR_USE_MFP]) {
8626 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
8627 if (connect.mfp != NL80211_MFP_REQUIRED &&
8628 connect.mfp != NL80211_MFP_NO)
8629 return -EINVAL;
8630 } else {
8631 connect.mfp = NL80211_MFP_NO;
8632 }
8633
ba6fbacf
JM
8634 if (info->attrs[NL80211_ATTR_PREV_BSSID])
8635 connect.prev_bssid =
8636 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
8637
b23aa676 8638 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
664834de
JM
8639 connect.channel = nl80211_get_valid_chan(
8640 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8641 if (!connect.channel)
1df4a510
JM
8642 return -EINVAL;
8643 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
664834de
JM
8644 connect.channel_hint = nl80211_get_valid_chan(
8645 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
8646 if (!connect.channel_hint)
4c476991 8647 return -EINVAL;
b23aa676
SO
8648 }
8649
fffd0934
JB
8650 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
8651 connkeys = nl80211_parse_connkeys(rdev,
de7044ee 8652 info->attrs[NL80211_ATTR_KEYS], NULL);
4c476991
JB
8653 if (IS_ERR(connkeys))
8654 return PTR_ERR(connkeys);
fffd0934
JB
8655 }
8656
7e7c8926
BG
8657 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
8658 connect.flags |= ASSOC_REQ_DISABLE_HT;
8659
8660 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
8661 memcpy(&connect.ht_capa_mask,
8662 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
8663 sizeof(connect.ht_capa_mask));
8664
8665 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 8666 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
b47f610b 8667 kzfree(connkeys);
7e7c8926 8668 return -EINVAL;
b4e4f47e 8669 }
7e7c8926
BG
8670 memcpy(&connect.ht_capa,
8671 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
8672 sizeof(connect.ht_capa));
8673 }
8674
ee2aca34
JB
8675 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
8676 connect.flags |= ASSOC_REQ_DISABLE_VHT;
8677
8678 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
8679 memcpy(&connect.vht_capa_mask,
8680 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
8681 sizeof(connect.vht_capa_mask));
8682
8683 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
8684 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
b47f610b 8685 kzfree(connkeys);
ee2aca34
JB
8686 return -EINVAL;
8687 }
8688 memcpy(&connect.vht_capa,
8689 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
8690 sizeof(connect.vht_capa));
8691 }
8692
bab5ab7d 8693 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
8694 if (!((rdev->wiphy.features &
8695 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
8696 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
8697 !wiphy_ext_feature_isset(&rdev->wiphy,
8698 NL80211_EXT_FEATURE_RRM)) {
707554b4 8699 kzfree(connkeys);
bab5ab7d 8700 return -EINVAL;
707554b4 8701 }
bab5ab7d
AK
8702 connect.flags |= ASSOC_REQ_USE_RRM;
8703 }
8704
34d50519 8705 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 8706 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
34d50519
LD
8707 kzfree(connkeys);
8708 return -EOPNOTSUPP;
8709 }
8710
38de03d2
AS
8711 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
8712 /* bss selection makes no sense if bssid is set */
8713 if (connect.bssid) {
8714 kzfree(connkeys);
8715 return -EINVAL;
8716 }
8717
8718 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
8719 wiphy, &connect.bss_select);
8720 if (err) {
8721 kzfree(connkeys);
8722 return err;
8723 }
8724 }
8725
83739b03 8726 wdev_lock(dev->ieee80211_ptr);
4ce2bd9c
JM
8727 err = cfg80211_connect(rdev, dev, &connect, connkeys,
8728 connect.prev_bssid);
83739b03 8729 wdev_unlock(dev->ieee80211_ptr);
fffd0934 8730 if (err)
b47f610b 8731 kzfree(connkeys);
b23aa676
SO
8732 return err;
8733}
8734
8735static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
8736{
4c476991
JB
8737 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8738 struct net_device *dev = info->user_ptr[1];
b23aa676 8739 u16 reason;
83739b03 8740 int ret;
b23aa676
SO
8741
8742 if (!info->attrs[NL80211_ATTR_REASON_CODE])
8743 reason = WLAN_REASON_DEAUTH_LEAVING;
8744 else
8745 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
8746
8747 if (reason == 0)
8748 return -EINVAL;
8749
074ac8df 8750 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8751 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8752 return -EOPNOTSUPP;
b23aa676 8753
83739b03
JB
8754 wdev_lock(dev->ieee80211_ptr);
8755 ret = cfg80211_disconnect(rdev, dev, reason, true);
8756 wdev_unlock(dev->ieee80211_ptr);
8757 return ret;
b23aa676
SO
8758}
8759
463d0183
JB
8760static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
8761{
4c476991 8762 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
8763 struct net *net;
8764 int err;
463d0183 8765
4b681c82
VK
8766 if (info->attrs[NL80211_ATTR_PID]) {
8767 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
8768
8769 net = get_net_ns_by_pid(pid);
8770 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
8771 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 8772
4b681c82
VK
8773 net = get_net_ns_by_fd(fd);
8774 } else {
8775 return -EINVAL;
8776 }
463d0183 8777
4c476991
JB
8778 if (IS_ERR(net))
8779 return PTR_ERR(net);
463d0183
JB
8780
8781 err = 0;
8782
8783 /* check if anything to do */
4c476991
JB
8784 if (!net_eq(wiphy_net(&rdev->wiphy), net))
8785 err = cfg80211_switch_netns(rdev, net);
463d0183 8786
463d0183 8787 put_net(net);
463d0183
JB
8788 return err;
8789}
8790
67fbb16b
SO
8791static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
8792{
4c476991 8793 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
8794 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
8795 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 8796 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
8797 struct cfg80211_pmksa pmksa;
8798
8799 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
8800
8801 if (!info->attrs[NL80211_ATTR_MAC])
8802 return -EINVAL;
8803
8804 if (!info->attrs[NL80211_ATTR_PMKID])
8805 return -EINVAL;
8806
67fbb16b
SO
8807 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
8808 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
8809
074ac8df 8810 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8811 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8812 return -EOPNOTSUPP;
67fbb16b
SO
8813
8814 switch (info->genlhdr->cmd) {
8815 case NL80211_CMD_SET_PMKSA:
8816 rdev_ops = rdev->ops->set_pmksa;
8817 break;
8818 case NL80211_CMD_DEL_PMKSA:
8819 rdev_ops = rdev->ops->del_pmksa;
8820 break;
8821 default:
8822 WARN_ON(1);
8823 break;
8824 }
8825
4c476991
JB
8826 if (!rdev_ops)
8827 return -EOPNOTSUPP;
67fbb16b 8828
4c476991 8829 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
8830}
8831
8832static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
8833{
4c476991
JB
8834 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8835 struct net_device *dev = info->user_ptr[1];
67fbb16b 8836
074ac8df 8837 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8838 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8839 return -EOPNOTSUPP;
67fbb16b 8840
4c476991
JB
8841 if (!rdev->ops->flush_pmksa)
8842 return -EOPNOTSUPP;
67fbb16b 8843
e35e4d28 8844 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
8845}
8846
109086ce
AN
8847static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
8848{
8849 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8850 struct net_device *dev = info->user_ptr[1];
8851 u8 action_code, dialog_token;
df942e7b 8852 u32 peer_capability = 0;
109086ce
AN
8853 u16 status_code;
8854 u8 *peer;
31fa97c5 8855 bool initiator;
109086ce
AN
8856
8857 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
8858 !rdev->ops->tdls_mgmt)
8859 return -EOPNOTSUPP;
8860
8861 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
8862 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
8863 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
8864 !info->attrs[NL80211_ATTR_IE] ||
8865 !info->attrs[NL80211_ATTR_MAC])
8866 return -EINVAL;
8867
8868 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
8869 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
8870 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
8871 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 8872 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
8873 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
8874 peer_capability =
8875 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 8876
e35e4d28 8877 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 8878 dialog_token, status_code, peer_capability,
31fa97c5 8879 initiator,
e35e4d28
HG
8880 nla_data(info->attrs[NL80211_ATTR_IE]),
8881 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
8882}
8883
8884static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
8885{
8886 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8887 struct net_device *dev = info->user_ptr[1];
8888 enum nl80211_tdls_operation operation;
8889 u8 *peer;
8890
8891 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
8892 !rdev->ops->tdls_oper)
8893 return -EOPNOTSUPP;
8894
8895 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
8896 !info->attrs[NL80211_ATTR_MAC])
8897 return -EINVAL;
8898
8899 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
8900 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
8901
e35e4d28 8902 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
8903}
8904
9588bbd5
JM
8905static int nl80211_remain_on_channel(struct sk_buff *skb,
8906 struct genl_info *info)
8907{
4c476991 8908 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 8909 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 8910 struct cfg80211_chan_def chandef;
9588bbd5
JM
8911 struct sk_buff *msg;
8912 void *hdr;
8913 u64 cookie;
683b6d3b 8914 u32 duration;
9588bbd5
JM
8915 int err;
8916
8917 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
8918 !info->attrs[NL80211_ATTR_DURATION])
8919 return -EINVAL;
8920
8921 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
8922
ebf348fc
JB
8923 if (!rdev->ops->remain_on_channel ||
8924 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
8925 return -EOPNOTSUPP;
8926
9588bbd5 8927 /*
ebf348fc
JB
8928 * We should be on that channel for at least a minimum amount of
8929 * time (10ms) but no longer than the driver supports.
9588bbd5 8930 */
ebf348fc 8931 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 8932 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
8933 return -EINVAL;
8934
683b6d3b
JB
8935 err = nl80211_parse_chandef(rdev, info, &chandef);
8936 if (err)
8937 return err;
9588bbd5
JM
8938
8939 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
8940 if (!msg)
8941 return -ENOMEM;
9588bbd5 8942
15e47304 8943 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 8944 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
8945 if (!hdr) {
8946 err = -ENOBUFS;
9588bbd5
JM
8947 goto free_msg;
8948 }
8949
683b6d3b
JB
8950 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
8951 duration, &cookie);
9588bbd5
JM
8952
8953 if (err)
8954 goto free_msg;
8955
2dad624e
ND
8956 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
8957 NL80211_ATTR_PAD))
9360ffd1 8958 goto nla_put_failure;
9588bbd5
JM
8959
8960 genlmsg_end(msg, hdr);
4c476991
JB
8961
8962 return genlmsg_reply(msg, info);
9588bbd5
JM
8963
8964 nla_put_failure:
8965 err = -ENOBUFS;
8966 free_msg:
8967 nlmsg_free(msg);
9588bbd5
JM
8968 return err;
8969}
8970
8971static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
8972 struct genl_info *info)
8973{
4c476991 8974 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 8975 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 8976 u64 cookie;
9588bbd5
JM
8977
8978 if (!info->attrs[NL80211_ATTR_COOKIE])
8979 return -EINVAL;
8980
4c476991
JB
8981 if (!rdev->ops->cancel_remain_on_channel)
8982 return -EOPNOTSUPP;
9588bbd5 8983
9588bbd5
JM
8984 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
8985
e35e4d28 8986 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
8987}
8988
13ae75b1
JM
8989static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
8990 struct genl_info *info)
8991{
13ae75b1 8992 struct cfg80211_bitrate_mask mask;
a7c7fbff 8993 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 8994 struct net_device *dev = info->user_ptr[1];
a7c7fbff 8995 int err;
13ae75b1 8996
4c476991
JB
8997 if (!rdev->ops->set_bitrate_mask)
8998 return -EOPNOTSUPP;
13ae75b1 8999
a7c7fbff
PK
9000 err = nl80211_parse_tx_bitrate_mask(info, &mask);
9001 if (err)
9002 return err;
13ae75b1 9003
e35e4d28 9004 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
9005}
9006
2e161f78 9007static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 9008{
4c476991 9009 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9010 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 9011 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
9012
9013 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
9014 return -EINVAL;
9015
2e161f78
JB
9016 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
9017 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 9018
71bbc994
JB
9019 switch (wdev->iftype) {
9020 case NL80211_IFTYPE_STATION:
9021 case NL80211_IFTYPE_ADHOC:
9022 case NL80211_IFTYPE_P2P_CLIENT:
9023 case NL80211_IFTYPE_AP:
9024 case NL80211_IFTYPE_AP_VLAN:
9025 case NL80211_IFTYPE_MESH_POINT:
9026 case NL80211_IFTYPE_P2P_GO:
98104fde 9027 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 9028 break;
cb3b7d87 9029 case NL80211_IFTYPE_NAN:
71bbc994 9030 default:
4c476991 9031 return -EOPNOTSUPP;
71bbc994 9032 }
026331c4
JM
9033
9034 /* not much point in registering if we can't reply */
4c476991
JB
9035 if (!rdev->ops->mgmt_tx)
9036 return -EOPNOTSUPP;
026331c4 9037
15e47304 9038 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
026331c4
JM
9039 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
9040 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
026331c4
JM
9041}
9042
2e161f78 9043static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 9044{
4c476991 9045 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9046 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 9047 struct cfg80211_chan_def chandef;
026331c4 9048 int err;
d64d373f 9049 void *hdr = NULL;
026331c4 9050 u64 cookie;
e247bd90 9051 struct sk_buff *msg = NULL;
b176e629
AO
9052 struct cfg80211_mgmt_tx_params params = {
9053 .dont_wait_for_ack =
9054 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
9055 };
026331c4 9056
683b6d3b 9057 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
9058 return -EINVAL;
9059
4c476991
JB
9060 if (!rdev->ops->mgmt_tx)
9061 return -EOPNOTSUPP;
026331c4 9062
71bbc994 9063 switch (wdev->iftype) {
ea141b75
AQ
9064 case NL80211_IFTYPE_P2P_DEVICE:
9065 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
9066 return -EINVAL;
71bbc994
JB
9067 case NL80211_IFTYPE_STATION:
9068 case NL80211_IFTYPE_ADHOC:
9069 case NL80211_IFTYPE_P2P_CLIENT:
9070 case NL80211_IFTYPE_AP:
9071 case NL80211_IFTYPE_AP_VLAN:
9072 case NL80211_IFTYPE_MESH_POINT:
9073 case NL80211_IFTYPE_P2P_GO:
9074 break;
cb3b7d87 9075 case NL80211_IFTYPE_NAN:
71bbc994 9076 default:
4c476991 9077 return -EOPNOTSUPP;
71bbc994 9078 }
026331c4 9079
f7ca38df 9080 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 9081 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 9082 return -EINVAL;
b176e629 9083 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
9084
9085 /*
9086 * We should wait on the channel for at least a minimum amount
9087 * of time (10ms) but no longer than the driver supports.
9088 */
b176e629
AO
9089 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
9090 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 9091 return -EINVAL;
f7ca38df
JB
9092 }
9093
b176e629 9094 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 9095
b176e629 9096 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
9097 return -EINVAL;
9098
b176e629 9099 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 9100
ea141b75
AQ
9101 /* get the channel if any has been specified, otherwise pass NULL to
9102 * the driver. The latter will use the current one
9103 */
9104 chandef.chan = NULL;
9105 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
9106 err = nl80211_parse_chandef(rdev, info, &chandef);
9107 if (err)
9108 return err;
9109 }
9110
b176e629 9111 if (!chandef.chan && params.offchan)
ea141b75 9112 return -EINVAL;
026331c4 9113
34d22ce2
AO
9114 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
9115 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
9116
9117 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
9118 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
9119 int i;
9120
9121 if (len % sizeof(u16))
9122 return -EINVAL;
9123
9124 params.n_csa_offsets = len / sizeof(u16);
9125 params.csa_offsets =
9126 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
9127
9128 /* check that all the offsets fit the frame */
9129 for (i = 0; i < params.n_csa_offsets; i++) {
9130 if (params.csa_offsets[i] >= params.len)
9131 return -EINVAL;
9132 }
9133 }
9134
b176e629 9135 if (!params.dont_wait_for_ack) {
e247bd90
JB
9136 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9137 if (!msg)
9138 return -ENOMEM;
026331c4 9139
15e47304 9140 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 9141 NL80211_CMD_FRAME);
cb35fba3
DC
9142 if (!hdr) {
9143 err = -ENOBUFS;
e247bd90
JB
9144 goto free_msg;
9145 }
026331c4 9146 }
e247bd90 9147
b176e629
AO
9148 params.chan = chandef.chan;
9149 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
9150 if (err)
9151 goto free_msg;
9152
e247bd90 9153 if (msg) {
2dad624e
ND
9154 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
9155 NL80211_ATTR_PAD))
9360ffd1 9156 goto nla_put_failure;
026331c4 9157
e247bd90
JB
9158 genlmsg_end(msg, hdr);
9159 return genlmsg_reply(msg, info);
9160 }
9161
9162 return 0;
026331c4
JM
9163
9164 nla_put_failure:
9165 err = -ENOBUFS;
9166 free_msg:
9167 nlmsg_free(msg);
026331c4
JM
9168 return err;
9169}
9170
f7ca38df
JB
9171static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
9172{
9173 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 9174 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
9175 u64 cookie;
9176
9177 if (!info->attrs[NL80211_ATTR_COOKIE])
9178 return -EINVAL;
9179
9180 if (!rdev->ops->mgmt_tx_cancel_wait)
9181 return -EOPNOTSUPP;
9182
71bbc994
JB
9183 switch (wdev->iftype) {
9184 case NL80211_IFTYPE_STATION:
9185 case NL80211_IFTYPE_ADHOC:
9186 case NL80211_IFTYPE_P2P_CLIENT:
9187 case NL80211_IFTYPE_AP:
9188 case NL80211_IFTYPE_AP_VLAN:
9189 case NL80211_IFTYPE_P2P_GO:
98104fde 9190 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 9191 break;
cb3b7d87 9192 case NL80211_IFTYPE_NAN:
71bbc994 9193 default:
f7ca38df 9194 return -EOPNOTSUPP;
71bbc994 9195 }
f7ca38df
JB
9196
9197 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9198
e35e4d28 9199 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
9200}
9201
ffb9eb3d
KV
9202static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
9203{
4c476991 9204 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 9205 struct wireless_dev *wdev;
4c476991 9206 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
9207 u8 ps_state;
9208 bool state;
9209 int err;
9210
4c476991
JB
9211 if (!info->attrs[NL80211_ATTR_PS_STATE])
9212 return -EINVAL;
ffb9eb3d
KV
9213
9214 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
9215
4c476991
JB
9216 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
9217 return -EINVAL;
ffb9eb3d
KV
9218
9219 wdev = dev->ieee80211_ptr;
9220
4c476991
JB
9221 if (!rdev->ops->set_power_mgmt)
9222 return -EOPNOTSUPP;
ffb9eb3d
KV
9223
9224 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
9225
9226 if (state == wdev->ps)
4c476991 9227 return 0;
ffb9eb3d 9228
e35e4d28 9229 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
9230 if (!err)
9231 wdev->ps = state;
ffb9eb3d
KV
9232 return err;
9233}
9234
9235static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
9236{
4c476991 9237 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
9238 enum nl80211_ps_state ps_state;
9239 struct wireless_dev *wdev;
4c476991 9240 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
9241 struct sk_buff *msg;
9242 void *hdr;
9243 int err;
9244
ffb9eb3d
KV
9245 wdev = dev->ieee80211_ptr;
9246
4c476991
JB
9247 if (!rdev->ops->set_power_mgmt)
9248 return -EOPNOTSUPP;
ffb9eb3d
KV
9249
9250 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
9251 if (!msg)
9252 return -ENOMEM;
ffb9eb3d 9253
15e47304 9254 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
9255 NL80211_CMD_GET_POWER_SAVE);
9256 if (!hdr) {
4c476991 9257 err = -ENOBUFS;
ffb9eb3d
KV
9258 goto free_msg;
9259 }
9260
9261 if (wdev->ps)
9262 ps_state = NL80211_PS_ENABLED;
9263 else
9264 ps_state = NL80211_PS_DISABLED;
9265
9360ffd1
DM
9266 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
9267 goto nla_put_failure;
ffb9eb3d
KV
9268
9269 genlmsg_end(msg, hdr);
4c476991 9270 return genlmsg_reply(msg, info);
ffb9eb3d 9271
4c476991 9272 nla_put_failure:
ffb9eb3d 9273 err = -ENOBUFS;
4c476991 9274 free_msg:
ffb9eb3d 9275 nlmsg_free(msg);
ffb9eb3d
KV
9276 return err;
9277}
9278
94e860f1
JB
9279static const struct nla_policy
9280nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
d6dc1a38
JO
9281 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
9282 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
9283 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
9284 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
9285 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
9286 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
d6dc1a38
JO
9287};
9288
84f10708 9289static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 9290 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
9291{
9292 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 9293 struct net_device *dev = info->user_ptr[1];
1da5fcc8 9294 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 9295
d9d8b019 9296 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
9297 return -EINVAL;
9298
84f10708
TP
9299 if (!rdev->ops->set_cqm_txe_config)
9300 return -EOPNOTSUPP;
9301
9302 if (wdev->iftype != NL80211_IFTYPE_STATION &&
9303 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
9304 return -EOPNOTSUPP;
9305
e35e4d28 9306 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
9307}
9308
d6dc1a38
JO
9309static int nl80211_set_cqm_rssi(struct genl_info *info,
9310 s32 threshold, u32 hysteresis)
9311{
4c476991 9312 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 9313 struct net_device *dev = info->user_ptr[1];
1da5fcc8 9314 struct wireless_dev *wdev = dev->ieee80211_ptr;
d6dc1a38
JO
9315
9316 if (threshold > 0)
9317 return -EINVAL;
9318
1da5fcc8
JB
9319 /* disabling - hysteresis should also be zero then */
9320 if (threshold == 0)
9321 hysteresis = 0;
d6dc1a38 9322
4c476991
JB
9323 if (!rdev->ops->set_cqm_rssi_config)
9324 return -EOPNOTSUPP;
d6dc1a38 9325
074ac8df 9326 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9327 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
9328 return -EOPNOTSUPP;
d6dc1a38 9329
e35e4d28 9330 return rdev_set_cqm_rssi_config(rdev, dev, threshold, hysteresis);
d6dc1a38
JO
9331}
9332
9333static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
9334{
9335 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
9336 struct nlattr *cqm;
9337 int err;
9338
9339 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
9340 if (!cqm)
9341 return -EINVAL;
d6dc1a38
JO
9342
9343 err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
9344 nl80211_attr_cqm_policy);
9345 if (err)
1da5fcc8 9346 return err;
d6dc1a38
JO
9347
9348 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
9349 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
1da5fcc8
JB
9350 s32 threshold = nla_get_s32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
9351 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 9352
1da5fcc8
JB
9353 return nl80211_set_cqm_rssi(info, threshold, hysteresis);
9354 }
9355
9356 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
9357 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
9358 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
9359 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
9360 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
9361 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
9362
9363 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
9364 }
9365
9366 return -EINVAL;
d6dc1a38
JO
9367}
9368
6e0bd6c3
RL
9369static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
9370{
9371 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9372 struct net_device *dev = info->user_ptr[1];
9373 struct ocb_setup setup = {};
9374 int err;
9375
9376 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
9377 if (err)
9378 return err;
9379
9380 return cfg80211_join_ocb(rdev, dev, &setup);
9381}
9382
9383static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
9384{
9385 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9386 struct net_device *dev = info->user_ptr[1];
9387
9388 return cfg80211_leave_ocb(rdev, dev);
9389}
9390
29cbe68c
JB
9391static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
9392{
9393 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9394 struct net_device *dev = info->user_ptr[1];
9395 struct mesh_config cfg;
c80d545d 9396 struct mesh_setup setup;
29cbe68c
JB
9397 int err;
9398
9399 /* start with default */
9400 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 9401 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 9402
24bdd9f4 9403 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 9404 /* and parse parameters if given */
24bdd9f4 9405 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
9406 if (err)
9407 return err;
9408 }
9409
9410 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
9411 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
9412 return -EINVAL;
9413
c80d545d
JC
9414 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
9415 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
9416
4bb62344
CYY
9417 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
9418 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
9419 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
9420 return -EINVAL;
9421
9bdbf04d
MP
9422 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
9423 setup.beacon_interval =
9424 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 9425
0c317a02
PK
9426 err = cfg80211_validate_beacon_int(rdev,
9427 NL80211_IFTYPE_MESH_POINT,
9428 setup.beacon_interval);
12d20fc9
PK
9429 if (err)
9430 return err;
9bdbf04d
MP
9431 }
9432
9433 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
9434 setup.dtim_period =
9435 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
9436 if (setup.dtim_period < 1 || setup.dtim_period > 100)
9437 return -EINVAL;
9438 }
9439
c80d545d
JC
9440 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
9441 /* parse additional setup parameters if given */
9442 err = nl80211_parse_mesh_setup(info, &setup);
9443 if (err)
9444 return err;
9445 }
9446
d37bb18a
TP
9447 if (setup.user_mpm)
9448 cfg.auto_open_plinks = false;
9449
cc1d2806 9450 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
9451 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
9452 if (err)
9453 return err;
cc1d2806
JB
9454 } else {
9455 /* cfg80211_join_mesh() will sort it out */
683b6d3b 9456 setup.chandef.chan = NULL;
cc1d2806
JB
9457 }
9458
ffb3cf30
AN
9459 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
9460 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9461 int n_rates =
9462 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9463 struct ieee80211_supported_band *sband;
9464
9465 if (!setup.chandef.chan)
9466 return -EINVAL;
9467
9468 sband = rdev->wiphy.bands[setup.chandef.chan->band];
9469
9470 err = ieee80211_get_ratemask(sband, rates, n_rates,
9471 &setup.basic_rates);
9472 if (err)
9473 return err;
9474 }
9475
8564e382
JB
9476 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9477 err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate);
9478 if (err)
9479 return err;
9480
9481 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
9482 &setup.beacon_rate);
9483 if (err)
9484 return err;
9485 }
9486
c80d545d 9487 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
29cbe68c
JB
9488}
9489
9490static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
9491{
9492 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9493 struct net_device *dev = info->user_ptr[1];
9494
9495 return cfg80211_leave_mesh(rdev, dev);
9496}
9497
dfb89c56 9498#ifdef CONFIG_PM
bb92d199
AK
9499static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
9500 struct cfg80211_registered_device *rdev)
9501{
6abb9cb9 9502 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
9503 struct nlattr *nl_pats, *nl_pat;
9504 int i, pat_len;
9505
6abb9cb9 9506 if (!wowlan->n_patterns)
bb92d199
AK
9507 return 0;
9508
9509 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
9510 if (!nl_pats)
9511 return -ENOBUFS;
9512
6abb9cb9 9513 for (i = 0; i < wowlan->n_patterns; i++) {
bb92d199
AK
9514 nl_pat = nla_nest_start(msg, i + 1);
9515 if (!nl_pat)
9516 return -ENOBUFS;
6abb9cb9 9517 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 9518 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 9519 wowlan->patterns[i].mask) ||
50ac6607
AK
9520 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
9521 wowlan->patterns[i].pattern) ||
9522 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 9523 wowlan->patterns[i].pkt_offset))
bb92d199
AK
9524 return -ENOBUFS;
9525 nla_nest_end(msg, nl_pat);
9526 }
9527 nla_nest_end(msg, nl_pats);
9528
9529 return 0;
9530}
9531
2a0e047e
JB
9532static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
9533 struct cfg80211_wowlan_tcp *tcp)
9534{
9535 struct nlattr *nl_tcp;
9536
9537 if (!tcp)
9538 return 0;
9539
9540 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
9541 if (!nl_tcp)
9542 return -ENOBUFS;
9543
930345ea
JB
9544 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
9545 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
9546 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
9547 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
9548 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
9549 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
9550 tcp->payload_len, tcp->payload) ||
9551 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
9552 tcp->data_interval) ||
9553 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
9554 tcp->wake_len, tcp->wake_data) ||
9555 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
9556 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
9557 return -ENOBUFS;
9558
9559 if (tcp->payload_seq.len &&
9560 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
9561 sizeof(tcp->payload_seq), &tcp->payload_seq))
9562 return -ENOBUFS;
9563
9564 if (tcp->payload_tok.len &&
9565 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
9566 sizeof(tcp->payload_tok) + tcp->tokens_size,
9567 &tcp->payload_tok))
9568 return -ENOBUFS;
9569
e248ad30
JB
9570 nla_nest_end(msg, nl_tcp);
9571
2a0e047e
JB
9572 return 0;
9573}
9574
75453ccb
LC
9575static int nl80211_send_wowlan_nd(struct sk_buff *msg,
9576 struct cfg80211_sched_scan_request *req)
9577{
3b06d277 9578 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
9579 int i;
9580
9581 if (!req)
9582 return 0;
9583
9584 nd = nla_nest_start(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
9585 if (!nd)
9586 return -ENOBUFS;
9587
3b06d277
AS
9588 if (req->n_scan_plans == 1 &&
9589 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
9590 req->scan_plans[0].interval * 1000))
75453ccb
LC
9591 return -ENOBUFS;
9592
21fea567
LC
9593 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
9594 return -ENOBUFS;
9595
75453ccb
LC
9596 freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
9597 if (!freqs)
9598 return -ENOBUFS;
9599
53b18980
JB
9600 for (i = 0; i < req->n_channels; i++) {
9601 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
9602 return -ENOBUFS;
9603 }
75453ccb
LC
9604
9605 nla_nest_end(msg, freqs);
9606
9607 if (req->n_match_sets) {
9608 matches = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
9609 if (!matches)
9610 return -ENOBUFS;
9611
75453ccb
LC
9612 for (i = 0; i < req->n_match_sets; i++) {
9613 match = nla_nest_start(msg, i);
76e1fb4b
JB
9614 if (!match)
9615 return -ENOBUFS;
9616
53b18980
JB
9617 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
9618 req->match_sets[i].ssid.ssid_len,
9619 req->match_sets[i].ssid.ssid))
9620 return -ENOBUFS;
75453ccb
LC
9621 nla_nest_end(msg, match);
9622 }
9623 nla_nest_end(msg, matches);
9624 }
9625
3b06d277
AS
9626 scan_plans = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
9627 if (!scan_plans)
9628 return -ENOBUFS;
9629
9630 for (i = 0; i < req->n_scan_plans; i++) {
9631 scan_plan = nla_nest_start(msg, i + 1);
76e1fb4b
JB
9632 if (!scan_plan)
9633 return -ENOBUFS;
9634
3b06d277
AS
9635 if (!scan_plan ||
9636 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
9637 req->scan_plans[i].interval) ||
9638 (req->scan_plans[i].iterations &&
9639 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
9640 req->scan_plans[i].iterations)))
9641 return -ENOBUFS;
9642 nla_nest_end(msg, scan_plan);
9643 }
9644 nla_nest_end(msg, scan_plans);
9645
75453ccb
LC
9646 nla_nest_end(msg, nd);
9647
9648 return 0;
9649}
9650
ff1b6e69
JB
9651static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
9652{
9653 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9654 struct sk_buff *msg;
9655 void *hdr;
2a0e047e 9656 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 9657
964dc9e2 9658 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
9659 return -EOPNOTSUPP;
9660
6abb9cb9 9661 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 9662 /* adjust size to have room for all the data */
6abb9cb9
JB
9663 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
9664 rdev->wiphy.wowlan_config->tcp->payload_len +
9665 rdev->wiphy.wowlan_config->tcp->wake_len +
9666 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
9667 }
9668
9669 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
9670 if (!msg)
9671 return -ENOMEM;
9672
15e47304 9673 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
9674 NL80211_CMD_GET_WOWLAN);
9675 if (!hdr)
9676 goto nla_put_failure;
9677
6abb9cb9 9678 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
9679 struct nlattr *nl_wowlan;
9680
9681 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
9682 if (!nl_wowlan)
9683 goto nla_put_failure;
9684
6abb9cb9 9685 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 9686 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 9687 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 9688 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 9689 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 9690 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 9691 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 9692 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 9693 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 9694 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 9695 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 9696 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 9697 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
9698 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
9699 goto nla_put_failure;
2a0e047e 9700
bb92d199
AK
9701 if (nl80211_send_wowlan_patterns(msg, rdev))
9702 goto nla_put_failure;
2a0e047e 9703
6abb9cb9
JB
9704 if (nl80211_send_wowlan_tcp(msg,
9705 rdev->wiphy.wowlan_config->tcp))
2a0e047e 9706 goto nla_put_failure;
75453ccb
LC
9707
9708 if (nl80211_send_wowlan_nd(
9709 msg,
9710 rdev->wiphy.wowlan_config->nd_config))
9711 goto nla_put_failure;
2a0e047e 9712
ff1b6e69
JB
9713 nla_nest_end(msg, nl_wowlan);
9714 }
9715
9716 genlmsg_end(msg, hdr);
9717 return genlmsg_reply(msg, info);
9718
9719nla_put_failure:
9720 nlmsg_free(msg);
9721 return -ENOBUFS;
9722}
9723
2a0e047e
JB
9724static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
9725 struct nlattr *attr,
9726 struct cfg80211_wowlan *trig)
9727{
9728 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
9729 struct cfg80211_wowlan_tcp *cfg;
9730 struct nl80211_wowlan_tcp_data_token *tok = NULL;
9731 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
9732 u32 size;
9733 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
9734 int err, port;
9735
964dc9e2 9736 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
9737 return -EINVAL;
9738
9739 err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP,
9740 nla_data(attr), nla_len(attr),
9741 nl80211_wowlan_tcp_policy);
9742 if (err)
9743 return err;
9744
9745 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
9746 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
9747 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
9748 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
9749 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
9750 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
9751 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
9752 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
9753 return -EINVAL;
9754
9755 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 9756 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
9757 return -EINVAL;
9758
9759 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 9760 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 9761 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
9762 return -EINVAL;
9763
9764 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 9765 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
9766 return -EINVAL;
9767
9768 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
9769 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
9770 return -EINVAL;
9771
9772 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
9773 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
9774
9775 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
9776 tokens_size = tokln - sizeof(*tok);
9777
9778 if (!tok->len || tokens_size % tok->len)
9779 return -EINVAL;
964dc9e2 9780 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 9781 return -EINVAL;
964dc9e2 9782 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 9783 return -EINVAL;
964dc9e2 9784 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 9785 return -EINVAL;
964dc9e2 9786 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
9787 return -EINVAL;
9788 if (tok->offset + tok->len > data_size)
9789 return -EINVAL;
9790 }
9791
9792 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
9793 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 9794 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
9795 return -EINVAL;
9796 if (seq->len == 0 || seq->len > 4)
9797 return -EINVAL;
9798 if (seq->len + seq->offset > data_size)
9799 return -EINVAL;
9800 }
9801
9802 size = sizeof(*cfg);
9803 size += data_size;
9804 size += wake_size + wake_mask_size;
9805 size += tokens_size;
9806
9807 cfg = kzalloc(size, GFP_KERNEL);
9808 if (!cfg)
9809 return -ENOMEM;
67b61f6c
JB
9810 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
9811 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
9812 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
9813 ETH_ALEN);
9814 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
9815 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
9816 else
9817 port = 0;
9818#ifdef CONFIG_INET
9819 /* allocate a socket and port for it and use it */
9820 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
9821 IPPROTO_TCP, &cfg->sock, 1);
9822 if (err) {
9823 kfree(cfg);
9824 return err;
9825 }
9826 if (inet_csk_get_port(cfg->sock->sk, port)) {
9827 sock_release(cfg->sock);
9828 kfree(cfg);
9829 return -EADDRINUSE;
9830 }
9831 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
9832#else
9833 if (!port) {
9834 kfree(cfg);
9835 return -EINVAL;
9836 }
9837 cfg->src_port = port;
9838#endif
9839
9840 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
9841 cfg->payload_len = data_size;
9842 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
9843 memcpy((void *)cfg->payload,
9844 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
9845 data_size);
9846 if (seq)
9847 cfg->payload_seq = *seq;
9848 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
9849 cfg->wake_len = wake_size;
9850 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
9851 memcpy((void *)cfg->wake_data,
9852 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
9853 wake_size);
9854 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
9855 data_size + wake_size;
9856 memcpy((void *)cfg->wake_mask,
9857 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
9858 wake_mask_size);
9859 if (tok) {
9860 cfg->tokens_size = tokens_size;
9861 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
9862 }
9863
9864 trig->tcp = cfg;
9865
9866 return 0;
9867}
9868
8cd4d456
LC
9869static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
9870 const struct wiphy_wowlan_support *wowlan,
9871 struct nlattr *attr,
9872 struct cfg80211_wowlan *trig)
9873{
9874 struct nlattr **tb;
9875 int err;
9876
9877 tb = kzalloc(NUM_NL80211_ATTR * sizeof(*tb), GFP_KERNEL);
9878 if (!tb)
9879 return -ENOMEM;
9880
9881 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
9882 err = -EOPNOTSUPP;
9883 goto out;
9884 }
9885
9886 err = nla_parse(tb, NL80211_ATTR_MAX,
9887 nla_data(attr), nla_len(attr),
9888 nl80211_policy);
9889 if (err)
9890 goto out;
9891
ad2b26ab 9892 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb);
8cd4d456
LC
9893 err = PTR_ERR_OR_ZERO(trig->nd_config);
9894 if (err)
9895 trig->nd_config = NULL;
9896
9897out:
9898 kfree(tb);
9899 return err;
9900}
9901
ff1b6e69
JB
9902static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
9903{
9904 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9905 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 9906 struct cfg80211_wowlan new_triggers = {};
ae33bd81 9907 struct cfg80211_wowlan *ntrig;
964dc9e2 9908 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 9909 int err, i;
6abb9cb9 9910 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 9911 bool regular = false;
ff1b6e69 9912
964dc9e2 9913 if (!wowlan)
ff1b6e69
JB
9914 return -EOPNOTSUPP;
9915
ae33bd81
JB
9916 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
9917 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 9918 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
9919 goto set_wakeup;
9920 }
ff1b6e69
JB
9921
9922 err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG,
9923 nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
9924 nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
9925 nl80211_wowlan_policy);
9926 if (err)
9927 return err;
9928
9929 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
9930 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
9931 return -EINVAL;
9932 new_triggers.any = true;
9933 }
9934
9935 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
9936 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
9937 return -EINVAL;
9938 new_triggers.disconnect = true;
98fc4386 9939 regular = true;
ff1b6e69
JB
9940 }
9941
9942 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
9943 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
9944 return -EINVAL;
9945 new_triggers.magic_pkt = true;
98fc4386 9946 regular = true;
ff1b6e69
JB
9947 }
9948
77dbbb13
JB
9949 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
9950 return -EINVAL;
9951
9952 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
9953 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
9954 return -EINVAL;
9955 new_triggers.gtk_rekey_failure = true;
98fc4386 9956 regular = true;
77dbbb13
JB
9957 }
9958
9959 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
9960 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
9961 return -EINVAL;
9962 new_triggers.eap_identity_req = true;
98fc4386 9963 regular = true;
77dbbb13
JB
9964 }
9965
9966 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
9967 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
9968 return -EINVAL;
9969 new_triggers.four_way_handshake = true;
98fc4386 9970 regular = true;
77dbbb13
JB
9971 }
9972
9973 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
9974 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
9975 return -EINVAL;
9976 new_triggers.rfkill_release = true;
98fc4386 9977 regular = true;
77dbbb13
JB
9978 }
9979
ff1b6e69
JB
9980 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
9981 struct nlattr *pat;
9982 int n_patterns = 0;
bb92d199 9983 int rem, pat_len, mask_len, pkt_offset;
50ac6607 9984 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 9985
98fc4386
JB
9986 regular = true;
9987
ff1b6e69
JB
9988 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
9989 rem)
9990 n_patterns++;
9991 if (n_patterns > wowlan->n_patterns)
9992 return -EINVAL;
9993
9994 new_triggers.patterns = kcalloc(n_patterns,
9995 sizeof(new_triggers.patterns[0]),
9996 GFP_KERNEL);
9997 if (!new_triggers.patterns)
9998 return -ENOMEM;
9999
10000 new_triggers.n_patterns = n_patterns;
10001 i = 0;
10002
10003 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
10004 rem) {
922bd80f
JB
10005 u8 *mask_pat;
10006
50ac6607
AK
10007 nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
10008 nla_len(pat), NULL);
ff1b6e69 10009 err = -EINVAL;
50ac6607
AK
10010 if (!pat_tb[NL80211_PKTPAT_MASK] ||
10011 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 10012 goto error;
50ac6607 10013 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 10014 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 10015 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
10016 goto error;
10017 if (pat_len > wowlan->pattern_max_len ||
10018 pat_len < wowlan->pattern_min_len)
10019 goto error;
10020
50ac6607 10021 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
10022 pkt_offset = 0;
10023 else
10024 pkt_offset = nla_get_u32(
50ac6607 10025 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
10026 if (pkt_offset > wowlan->max_pkt_offset)
10027 goto error;
10028 new_triggers.patterns[i].pkt_offset = pkt_offset;
10029
922bd80f
JB
10030 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
10031 if (!mask_pat) {
ff1b6e69
JB
10032 err = -ENOMEM;
10033 goto error;
10034 }
922bd80f
JB
10035 new_triggers.patterns[i].mask = mask_pat;
10036 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 10037 mask_len);
922bd80f
JB
10038 mask_pat += mask_len;
10039 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 10040 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 10041 memcpy(mask_pat,
50ac6607 10042 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
10043 pat_len);
10044 i++;
10045 }
10046 }
10047
2a0e047e 10048 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 10049 regular = true;
2a0e047e
JB
10050 err = nl80211_parse_wowlan_tcp(
10051 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
10052 &new_triggers);
10053 if (err)
10054 goto error;
10055 }
10056
8cd4d456 10057 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 10058 regular = true;
8cd4d456
LC
10059 err = nl80211_parse_wowlan_nd(
10060 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
10061 &new_triggers);
10062 if (err)
10063 goto error;
10064 }
10065
98fc4386
JB
10066 /* The 'any' trigger means the device continues operating more or less
10067 * as in its normal operation mode and wakes up the host on most of the
10068 * normal interrupts (like packet RX, ...)
10069 * It therefore makes little sense to combine with the more constrained
10070 * wakeup trigger modes.
10071 */
10072 if (new_triggers.any && regular) {
10073 err = -EINVAL;
10074 goto error;
10075 }
10076
ae33bd81
JB
10077 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
10078 if (!ntrig) {
10079 err = -ENOMEM;
10080 goto error;
ff1b6e69 10081 }
ae33bd81 10082 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 10083 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 10084
ae33bd81 10085 set_wakeup:
6abb9cb9
JB
10086 if (rdev->ops->set_wakeup &&
10087 prev_enabled != !!rdev->wiphy.wowlan_config)
10088 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 10089
ff1b6e69
JB
10090 return 0;
10091 error:
10092 for (i = 0; i < new_triggers.n_patterns; i++)
10093 kfree(new_triggers.patterns[i].mask);
10094 kfree(new_triggers.patterns);
2a0e047e
JB
10095 if (new_triggers.tcp && new_triggers.tcp->sock)
10096 sock_release(new_triggers.tcp->sock);
10097 kfree(new_triggers.tcp);
e5dbe070 10098 kfree(new_triggers.nd_config);
ff1b6e69
JB
10099 return err;
10100}
dfb89c56 10101#endif
ff1b6e69 10102
be29b99a
AK
10103static int nl80211_send_coalesce_rules(struct sk_buff *msg,
10104 struct cfg80211_registered_device *rdev)
10105{
10106 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
10107 int i, j, pat_len;
10108 struct cfg80211_coalesce_rules *rule;
10109
10110 if (!rdev->coalesce->n_rules)
10111 return 0;
10112
10113 nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
10114 if (!nl_rules)
10115 return -ENOBUFS;
10116
10117 for (i = 0; i < rdev->coalesce->n_rules; i++) {
10118 nl_rule = nla_nest_start(msg, i + 1);
10119 if (!nl_rule)
10120 return -ENOBUFS;
10121
10122 rule = &rdev->coalesce->rules[i];
10123 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
10124 rule->delay))
10125 return -ENOBUFS;
10126
10127 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
10128 rule->condition))
10129 return -ENOBUFS;
10130
10131 nl_pats = nla_nest_start(msg,
10132 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
10133 if (!nl_pats)
10134 return -ENOBUFS;
10135
10136 for (j = 0; j < rule->n_patterns; j++) {
10137 nl_pat = nla_nest_start(msg, j + 1);
10138 if (!nl_pat)
10139 return -ENOBUFS;
10140 pat_len = rule->patterns[j].pattern_len;
10141 if (nla_put(msg, NL80211_PKTPAT_MASK,
10142 DIV_ROUND_UP(pat_len, 8),
10143 rule->patterns[j].mask) ||
10144 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
10145 rule->patterns[j].pattern) ||
10146 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
10147 rule->patterns[j].pkt_offset))
10148 return -ENOBUFS;
10149 nla_nest_end(msg, nl_pat);
10150 }
10151 nla_nest_end(msg, nl_pats);
10152 nla_nest_end(msg, nl_rule);
10153 }
10154 nla_nest_end(msg, nl_rules);
10155
10156 return 0;
10157}
10158
10159static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
10160{
10161 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10162 struct sk_buff *msg;
10163 void *hdr;
10164
10165 if (!rdev->wiphy.coalesce)
10166 return -EOPNOTSUPP;
10167
10168 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10169 if (!msg)
10170 return -ENOMEM;
10171
10172 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
10173 NL80211_CMD_GET_COALESCE);
10174 if (!hdr)
10175 goto nla_put_failure;
10176
10177 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
10178 goto nla_put_failure;
10179
10180 genlmsg_end(msg, hdr);
10181 return genlmsg_reply(msg, info);
10182
10183nla_put_failure:
10184 nlmsg_free(msg);
10185 return -ENOBUFS;
10186}
10187
10188void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
10189{
10190 struct cfg80211_coalesce *coalesce = rdev->coalesce;
10191 int i, j;
10192 struct cfg80211_coalesce_rules *rule;
10193
10194 if (!coalesce)
10195 return;
10196
10197 for (i = 0; i < coalesce->n_rules; i++) {
10198 rule = &coalesce->rules[i];
10199 for (j = 0; j < rule->n_patterns; j++)
10200 kfree(rule->patterns[j].mask);
10201 kfree(rule->patterns);
10202 }
10203 kfree(coalesce->rules);
10204 kfree(coalesce);
10205 rdev->coalesce = NULL;
10206}
10207
10208static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
10209 struct nlattr *rule,
10210 struct cfg80211_coalesce_rules *new_rule)
10211{
10212 int err, i;
10213 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
10214 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
10215 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
10216 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
10217
10218 err = nla_parse(tb, NL80211_ATTR_COALESCE_RULE_MAX, nla_data(rule),
10219 nla_len(rule), nl80211_coalesce_policy);
10220 if (err)
10221 return err;
10222
10223 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
10224 new_rule->delay =
10225 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
10226 if (new_rule->delay > coalesce->max_delay)
10227 return -EINVAL;
10228
10229 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
10230 new_rule->condition =
10231 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
10232 if (new_rule->condition != NL80211_COALESCE_CONDITION_MATCH &&
10233 new_rule->condition != NL80211_COALESCE_CONDITION_NO_MATCH)
10234 return -EINVAL;
10235
10236 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
10237 return -EINVAL;
10238
10239 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
10240 rem)
10241 n_patterns++;
10242 if (n_patterns > coalesce->n_patterns)
10243 return -EINVAL;
10244
10245 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
10246 GFP_KERNEL);
10247 if (!new_rule->patterns)
10248 return -ENOMEM;
10249
10250 new_rule->n_patterns = n_patterns;
10251 i = 0;
10252
10253 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
10254 rem) {
922bd80f
JB
10255 u8 *mask_pat;
10256
be29b99a
AK
10257 nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
10258 nla_len(pat), NULL);
10259 if (!pat_tb[NL80211_PKTPAT_MASK] ||
10260 !pat_tb[NL80211_PKTPAT_PATTERN])
10261 return -EINVAL;
10262 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
10263 mask_len = DIV_ROUND_UP(pat_len, 8);
10264 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
10265 return -EINVAL;
10266 if (pat_len > coalesce->pattern_max_len ||
10267 pat_len < coalesce->pattern_min_len)
10268 return -EINVAL;
10269
10270 if (!pat_tb[NL80211_PKTPAT_OFFSET])
10271 pkt_offset = 0;
10272 else
10273 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
10274 if (pkt_offset > coalesce->max_pkt_offset)
10275 return -EINVAL;
10276 new_rule->patterns[i].pkt_offset = pkt_offset;
10277
922bd80f
JB
10278 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
10279 if (!mask_pat)
be29b99a 10280 return -ENOMEM;
922bd80f
JB
10281
10282 new_rule->patterns[i].mask = mask_pat;
10283 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
10284 mask_len);
10285
10286 mask_pat += mask_len;
10287 new_rule->patterns[i].pattern = mask_pat;
be29b99a 10288 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
10289 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
10290 pat_len);
be29b99a
AK
10291 i++;
10292 }
10293
10294 return 0;
10295}
10296
10297static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
10298{
10299 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10300 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
10301 struct cfg80211_coalesce new_coalesce = {};
10302 struct cfg80211_coalesce *n_coalesce;
10303 int err, rem_rule, n_rules = 0, i, j;
10304 struct nlattr *rule;
10305 struct cfg80211_coalesce_rules *tmp_rule;
10306
10307 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
10308 return -EOPNOTSUPP;
10309
10310 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
10311 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 10312 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
10313 return 0;
10314 }
10315
10316 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
10317 rem_rule)
10318 n_rules++;
10319 if (n_rules > coalesce->n_rules)
10320 return -EINVAL;
10321
10322 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
10323 GFP_KERNEL);
10324 if (!new_coalesce.rules)
10325 return -ENOMEM;
10326
10327 new_coalesce.n_rules = n_rules;
10328 i = 0;
10329
10330 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
10331 rem_rule) {
10332 err = nl80211_parse_coalesce_rule(rdev, rule,
10333 &new_coalesce.rules[i]);
10334 if (err)
10335 goto error;
10336
10337 i++;
10338 }
10339
a1056b1b 10340 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
10341 if (err)
10342 goto error;
10343
10344 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
10345 if (!n_coalesce) {
10346 err = -ENOMEM;
10347 goto error;
10348 }
10349 cfg80211_rdev_free_coalesce(rdev);
10350 rdev->coalesce = n_coalesce;
10351
10352 return 0;
10353error:
10354 for (i = 0; i < new_coalesce.n_rules; i++) {
10355 tmp_rule = &new_coalesce.rules[i];
10356 for (j = 0; j < tmp_rule->n_patterns; j++)
10357 kfree(tmp_rule->patterns[j].mask);
10358 kfree(tmp_rule->patterns);
10359 }
10360 kfree(new_coalesce.rules);
10361
10362 return err;
10363}
10364
e5497d76
JB
10365static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
10366{
10367 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10368 struct net_device *dev = info->user_ptr[1];
10369 struct wireless_dev *wdev = dev->ieee80211_ptr;
10370 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
10371 struct cfg80211_gtk_rekey_data rekey_data;
10372 int err;
10373
10374 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
10375 return -EINVAL;
10376
10377 err = nla_parse(tb, MAX_NL80211_REKEY_DATA,
10378 nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]),
10379 nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]),
10380 nl80211_rekey_policy);
10381 if (err)
10382 return err;
10383
10384 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
10385 return -ERANGE;
10386 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
10387 return -ERANGE;
10388 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
10389 return -ERANGE;
10390
78f686ca
JB
10391 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
10392 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
10393 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
e5497d76
JB
10394
10395 wdev_lock(wdev);
10396 if (!wdev->current_bss) {
10397 err = -ENOTCONN;
10398 goto out;
10399 }
10400
10401 if (!rdev->ops->set_rekey_data) {
10402 err = -EOPNOTSUPP;
10403 goto out;
10404 }
10405
e35e4d28 10406 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
10407 out:
10408 wdev_unlock(wdev);
10409 return err;
10410}
10411
28946da7
JB
10412static int nl80211_register_unexpected_frame(struct sk_buff *skb,
10413 struct genl_info *info)
10414{
10415 struct net_device *dev = info->user_ptr[1];
10416 struct wireless_dev *wdev = dev->ieee80211_ptr;
10417
10418 if (wdev->iftype != NL80211_IFTYPE_AP &&
10419 wdev->iftype != NL80211_IFTYPE_P2P_GO)
10420 return -EINVAL;
10421
15e47304 10422 if (wdev->ap_unexpected_nlportid)
28946da7
JB
10423 return -EBUSY;
10424
15e47304 10425 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
10426 return 0;
10427}
10428
7f6cf311
JB
10429static int nl80211_probe_client(struct sk_buff *skb,
10430 struct genl_info *info)
10431{
10432 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10433 struct net_device *dev = info->user_ptr[1];
10434 struct wireless_dev *wdev = dev->ieee80211_ptr;
10435 struct sk_buff *msg;
10436 void *hdr;
10437 const u8 *addr;
10438 u64 cookie;
10439 int err;
10440
10441 if (wdev->iftype != NL80211_IFTYPE_AP &&
10442 wdev->iftype != NL80211_IFTYPE_P2P_GO)
10443 return -EOPNOTSUPP;
10444
10445 if (!info->attrs[NL80211_ATTR_MAC])
10446 return -EINVAL;
10447
10448 if (!rdev->ops->probe_client)
10449 return -EOPNOTSUPP;
10450
10451 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10452 if (!msg)
10453 return -ENOMEM;
10454
15e47304 10455 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 10456 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
10457 if (!hdr) {
10458 err = -ENOBUFS;
7f6cf311
JB
10459 goto free_msg;
10460 }
10461
10462 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
10463
e35e4d28 10464 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
10465 if (err)
10466 goto free_msg;
10467
2dad624e
ND
10468 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
10469 NL80211_ATTR_PAD))
9360ffd1 10470 goto nla_put_failure;
7f6cf311
JB
10471
10472 genlmsg_end(msg, hdr);
10473
10474 return genlmsg_reply(msg, info);
10475
10476 nla_put_failure:
10477 err = -ENOBUFS;
10478 free_msg:
10479 nlmsg_free(msg);
10480 return err;
10481}
10482
5e760230
JB
10483static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
10484{
10485 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
10486 struct cfg80211_beacon_registration *reg, *nreg;
10487 int rv;
5e760230
JB
10488
10489 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
10490 return -EOPNOTSUPP;
10491
37c73b5f
BG
10492 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
10493 if (!nreg)
10494 return -ENOMEM;
10495
10496 /* First, check if already registered. */
10497 spin_lock_bh(&rdev->beacon_registrations_lock);
10498 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
10499 if (reg->nlportid == info->snd_portid) {
10500 rv = -EALREADY;
10501 goto out_err;
10502 }
10503 }
10504 /* Add it to the list */
10505 nreg->nlportid = info->snd_portid;
10506 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 10507
37c73b5f 10508 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
10509
10510 return 0;
37c73b5f
BG
10511out_err:
10512 spin_unlock_bh(&rdev->beacon_registrations_lock);
10513 kfree(nreg);
10514 return rv;
5e760230
JB
10515}
10516
98104fde
JB
10517static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
10518{
10519 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10520 struct wireless_dev *wdev = info->user_ptr[1];
10521 int err;
10522
10523 if (!rdev->ops->start_p2p_device)
10524 return -EOPNOTSUPP;
10525
10526 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
10527 return -EOPNOTSUPP;
10528
10529 if (wdev->p2p_started)
10530 return 0;
10531
b6a55015
LC
10532 if (rfkill_blocked(rdev->rfkill))
10533 return -ERFKILL;
98104fde 10534
eeb126e9 10535 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
10536 if (err)
10537 return err;
10538
10539 wdev->p2p_started = true;
98104fde 10540 rdev->opencount++;
98104fde
JB
10541
10542 return 0;
10543}
10544
10545static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
10546{
10547 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10548 struct wireless_dev *wdev = info->user_ptr[1];
10549
10550 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
10551 return -EOPNOTSUPP;
10552
10553 if (!rdev->ops->stop_p2p_device)
10554 return -EOPNOTSUPP;
10555
f9f47529 10556 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
10557
10558 return 0;
10559}
10560
cb3b7d87
AB
10561static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
10562{
10563 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10564 struct wireless_dev *wdev = info->user_ptr[1];
10565 struct cfg80211_nan_conf conf = {};
10566 int err;
10567
10568 if (wdev->iftype != NL80211_IFTYPE_NAN)
10569 return -EOPNOTSUPP;
10570
10571 if (wdev->nan_started)
10572 return -EEXIST;
10573
10574 if (rfkill_blocked(rdev->rfkill))
10575 return -ERFKILL;
10576
10577 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
10578 return -EINVAL;
10579
10580 if (!info->attrs[NL80211_ATTR_NAN_DUAL])
10581 return -EINVAL;
10582
10583 conf.master_pref =
10584 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
10585 if (!conf.master_pref)
10586 return -EINVAL;
10587
10588 conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]);
10589
10590 err = rdev_start_nan(rdev, wdev, &conf);
10591 if (err)
10592 return err;
10593
10594 wdev->nan_started = true;
10595 rdev->opencount++;
10596
10597 return 0;
10598}
10599
10600static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
10601{
10602 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10603 struct wireless_dev *wdev = info->user_ptr[1];
10604
10605 if (wdev->iftype != NL80211_IFTYPE_NAN)
10606 return -EOPNOTSUPP;
10607
10608 cfg80211_stop_nan(rdev, wdev);
10609
10610 return 0;
10611}
10612
a442b761
AB
10613static int validate_nan_filter(struct nlattr *filter_attr)
10614{
10615 struct nlattr *attr;
10616 int len = 0, n_entries = 0, rem;
10617
10618 nla_for_each_nested(attr, filter_attr, rem) {
10619 len += nla_len(attr);
10620 n_entries++;
10621 }
10622
10623 if (len >= U8_MAX)
10624 return -EINVAL;
10625
10626 return n_entries;
10627}
10628
10629static int handle_nan_filter(struct nlattr *attr_filter,
10630 struct cfg80211_nan_func *func,
10631 bool tx)
10632{
10633 struct nlattr *attr;
10634 int n_entries, rem, i;
10635 struct cfg80211_nan_func_filter *filter;
10636
10637 n_entries = validate_nan_filter(attr_filter);
10638 if (n_entries < 0)
10639 return n_entries;
10640
10641 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
10642
10643 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
10644 if (!filter)
10645 return -ENOMEM;
10646
10647 i = 0;
10648 nla_for_each_nested(attr, attr_filter, rem) {
10649 filter[i].filter = kmemdup(nla_data(attr), nla_len(attr),
10650 GFP_KERNEL);
10651 filter[i].len = nla_len(attr);
10652 i++;
10653 }
10654 if (tx) {
10655 func->num_tx_filters = n_entries;
10656 func->tx_filters = filter;
10657 } else {
10658 func->num_rx_filters = n_entries;
10659 func->rx_filters = filter;
10660 }
10661
10662 return 0;
10663}
10664
10665static int nl80211_nan_add_func(struct sk_buff *skb,
10666 struct genl_info *info)
10667{
10668 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10669 struct wireless_dev *wdev = info->user_ptr[1];
10670 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
10671 struct cfg80211_nan_func *func;
10672 struct sk_buff *msg = NULL;
10673 void *hdr = NULL;
10674 int err = 0;
10675
10676 if (wdev->iftype != NL80211_IFTYPE_NAN)
10677 return -EOPNOTSUPP;
10678
10679 if (!wdev->nan_started)
10680 return -ENOTCONN;
10681
10682 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
10683 return -EINVAL;
10684
10685 if (wdev->owner_nlportid &&
10686 wdev->owner_nlportid != info->snd_portid)
10687 return -ENOTCONN;
10688
10689 err = nla_parse(tb, NL80211_NAN_FUNC_ATTR_MAX,
10690 nla_data(info->attrs[NL80211_ATTR_NAN_FUNC]),
10691 nla_len(info->attrs[NL80211_ATTR_NAN_FUNC]),
10692 nl80211_nan_func_policy);
10693 if (err)
10694 return err;
10695
10696 func = kzalloc(sizeof(*func), GFP_KERNEL);
10697 if (!func)
10698 return -ENOMEM;
10699
10700 func->cookie = wdev->wiphy->cookie_counter++;
10701
10702 if (!tb[NL80211_NAN_FUNC_TYPE] ||
10703 nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
10704 err = -EINVAL;
10705 goto out;
10706 }
10707
10708
10709 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
10710
10711 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
10712 err = -EINVAL;
10713 goto out;
10714 }
10715
10716 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
10717 sizeof(func->service_id));
10718
10719 func->close_range =
10720 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
10721
10722 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
10723 func->serv_spec_info_len =
10724 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
10725 func->serv_spec_info =
10726 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
10727 func->serv_spec_info_len,
10728 GFP_KERNEL);
10729 if (!func->serv_spec_info) {
10730 err = -ENOMEM;
10731 goto out;
10732 }
10733 }
10734
10735 if (tb[NL80211_NAN_FUNC_TTL])
10736 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
10737
10738 switch (func->type) {
10739 case NL80211_NAN_FUNC_PUBLISH:
10740 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
10741 err = -EINVAL;
10742 goto out;
10743 }
10744
10745 func->publish_type =
10746 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
10747 func->publish_bcast =
10748 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
10749
10750 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
10751 func->publish_bcast) {
10752 err = -EINVAL;
10753 goto out;
10754 }
10755 break;
10756 case NL80211_NAN_FUNC_SUBSCRIBE:
10757 func->subscribe_active =
10758 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
10759 break;
10760 case NL80211_NAN_FUNC_FOLLOW_UP:
10761 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
10762 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]) {
10763 err = -EINVAL;
10764 goto out;
10765 }
10766
10767 func->followup_id =
10768 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
10769 func->followup_reqid =
10770 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
10771 memcpy(func->followup_dest.addr,
10772 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
10773 sizeof(func->followup_dest.addr));
10774 if (func->ttl) {
10775 err = -EINVAL;
10776 goto out;
10777 }
10778 break;
10779 default:
10780 err = -EINVAL;
10781 goto out;
10782 }
10783
10784 if (tb[NL80211_NAN_FUNC_SRF]) {
10785 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
10786
10787 err = nla_parse(srf_tb, NL80211_NAN_SRF_ATTR_MAX,
10788 nla_data(tb[NL80211_NAN_FUNC_SRF]),
10789 nla_len(tb[NL80211_NAN_FUNC_SRF]), NULL);
10790 if (err)
10791 goto out;
10792
10793 func->srf_include =
10794 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
10795
10796 if (srf_tb[NL80211_NAN_SRF_BF]) {
10797 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
10798 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
10799 err = -EINVAL;
10800 goto out;
10801 }
10802
10803 func->srf_bf_len =
10804 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
10805 func->srf_bf =
10806 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
10807 func->srf_bf_len, GFP_KERNEL);
10808 if (!func->srf_bf) {
10809 err = -ENOMEM;
10810 goto out;
10811 }
10812
10813 func->srf_bf_idx =
10814 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
10815 } else {
10816 struct nlattr *attr, *mac_attr =
10817 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
10818 int n_entries, rem, i = 0;
10819
10820 if (!mac_attr) {
10821 err = -EINVAL;
10822 goto out;
10823 }
10824
10825 n_entries = validate_acl_mac_addrs(mac_attr);
10826 if (n_entries <= 0) {
10827 err = -EINVAL;
10828 goto out;
10829 }
10830
10831 func->srf_num_macs = n_entries;
10832 func->srf_macs =
10833 kzalloc(sizeof(*func->srf_macs) * n_entries,
10834 GFP_KERNEL);
10835 if (!func->srf_macs) {
10836 err = -ENOMEM;
10837 goto out;
10838 }
10839
10840 nla_for_each_nested(attr, mac_attr, rem)
10841 memcpy(func->srf_macs[i++].addr, nla_data(attr),
10842 sizeof(*func->srf_macs));
10843 }
10844 }
10845
10846 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
10847 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
10848 func, true);
10849 if (err)
10850 goto out;
10851 }
10852
10853 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
10854 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
10855 func, false);
10856 if (err)
10857 goto out;
10858 }
10859
10860 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10861 if (!msg) {
10862 err = -ENOMEM;
10863 goto out;
10864 }
10865
10866 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
10867 NL80211_CMD_ADD_NAN_FUNCTION);
10868 /* This can't really happen - we just allocated 4KB */
10869 if (WARN_ON(!hdr)) {
10870 err = -ENOMEM;
10871 goto out;
10872 }
10873
10874 err = rdev_add_nan_func(rdev, wdev, func);
10875out:
10876 if (err < 0) {
10877 cfg80211_free_nan_func(func);
10878 nlmsg_free(msg);
10879 return err;
10880 }
10881
10882 /* propagate the instance id and cookie to userspace */
10883 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
10884 NL80211_ATTR_PAD))
10885 goto nla_put_failure;
10886
10887 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
10888 if (!func_attr)
10889 goto nla_put_failure;
10890
10891 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
10892 func->instance_id))
10893 goto nla_put_failure;
10894
10895 nla_nest_end(msg, func_attr);
10896
10897 genlmsg_end(msg, hdr);
10898 return genlmsg_reply(msg, info);
10899
10900nla_put_failure:
10901 nlmsg_free(msg);
10902 return -ENOBUFS;
10903}
10904
10905static int nl80211_nan_del_func(struct sk_buff *skb,
10906 struct genl_info *info)
10907{
10908 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10909 struct wireless_dev *wdev = info->user_ptr[1];
10910 u64 cookie;
10911
10912 if (wdev->iftype != NL80211_IFTYPE_NAN)
10913 return -EOPNOTSUPP;
10914
10915 if (!wdev->nan_started)
10916 return -ENOTCONN;
10917
10918 if (!info->attrs[NL80211_ATTR_COOKIE])
10919 return -EINVAL;
10920
10921 if (wdev->owner_nlportid &&
10922 wdev->owner_nlportid != info->snd_portid)
10923 return -ENOTCONN;
10924
10925 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
10926
10927 rdev_del_nan_func(rdev, wdev, cookie);
10928
10929 return 0;
10930}
10931
a5a9dcf2
AB
10932static int nl80211_nan_change_config(struct sk_buff *skb,
10933 struct genl_info *info)
10934{
10935 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10936 struct wireless_dev *wdev = info->user_ptr[1];
10937 struct cfg80211_nan_conf conf = {};
10938 u32 changed = 0;
10939
10940 if (wdev->iftype != NL80211_IFTYPE_NAN)
10941 return -EOPNOTSUPP;
10942
10943 if (!wdev->nan_started)
10944 return -ENOTCONN;
10945
10946 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
10947 conf.master_pref =
10948 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
10949 if (conf.master_pref <= 1 || conf.master_pref == 255)
10950 return -EINVAL;
10951
10952 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
10953 }
10954
10955 if (info->attrs[NL80211_ATTR_NAN_DUAL]) {
10956 conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]);
10957 changed |= CFG80211_NAN_CONF_CHANGED_DUAL;
10958 }
10959
10960 if (!changed)
10961 return -EINVAL;
10962
10963 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
10964}
10965
50bcd31d
AB
10966void cfg80211_nan_match(struct wireless_dev *wdev,
10967 struct cfg80211_nan_match_params *match, gfp_t gfp)
10968{
10969 struct wiphy *wiphy = wdev->wiphy;
10970 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
10971 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
10972 struct sk_buff *msg;
10973 void *hdr;
10974
10975 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
10976 return;
10977
10978 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
10979 if (!msg)
10980 return;
10981
10982 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
10983 if (!hdr) {
10984 nlmsg_free(msg);
10985 return;
10986 }
10987
10988 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
10989 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
10990 wdev->netdev->ifindex)) ||
10991 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
10992 NL80211_ATTR_PAD))
10993 goto nla_put_failure;
10994
10995 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
10996 NL80211_ATTR_PAD) ||
10997 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
10998 goto nla_put_failure;
10999
11000 match_attr = nla_nest_start(msg, NL80211_ATTR_NAN_MATCH);
11001 if (!match_attr)
11002 goto nla_put_failure;
11003
11004 local_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_LOCAL);
11005 if (!local_func_attr)
11006 goto nla_put_failure;
11007
11008 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
11009 goto nla_put_failure;
11010
11011 nla_nest_end(msg, local_func_attr);
11012
11013 peer_func_attr = nla_nest_start(msg, NL80211_NAN_MATCH_FUNC_PEER);
11014 if (!peer_func_attr)
11015 goto nla_put_failure;
11016
11017 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
11018 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
11019 goto nla_put_failure;
11020
11021 if (match->info && match->info_len &&
11022 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
11023 match->info))
11024 goto nla_put_failure;
11025
11026 nla_nest_end(msg, peer_func_attr);
11027 nla_nest_end(msg, match_attr);
11028 genlmsg_end(msg, hdr);
11029
11030 if (!wdev->owner_nlportid)
11031 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11032 msg, 0, NL80211_MCGRP_NAN, gfp);
11033 else
11034 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
11035 wdev->owner_nlportid);
11036
11037 return;
11038
11039nla_put_failure:
11040 nlmsg_free(msg);
11041}
11042EXPORT_SYMBOL(cfg80211_nan_match);
11043
368e5a7b
AB
11044void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
11045 u8 inst_id,
11046 enum nl80211_nan_func_term_reason reason,
11047 u64 cookie, gfp_t gfp)
11048{
11049 struct wiphy *wiphy = wdev->wiphy;
11050 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11051 struct sk_buff *msg;
11052 struct nlattr *func_attr;
11053 void *hdr;
11054
11055 if (WARN_ON(!inst_id))
11056 return;
11057
11058 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
11059 if (!msg)
11060 return;
11061
11062 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
11063 if (!hdr) {
11064 nlmsg_free(msg);
11065 return;
11066 }
11067
11068 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
11069 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
11070 wdev->netdev->ifindex)) ||
11071 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
11072 NL80211_ATTR_PAD))
11073 goto nla_put_failure;
11074
11075 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11076 NL80211_ATTR_PAD))
11077 goto nla_put_failure;
11078
11079 func_attr = nla_nest_start(msg, NL80211_ATTR_NAN_FUNC);
11080 if (!func_attr)
11081 goto nla_put_failure;
11082
11083 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
11084 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
11085 goto nla_put_failure;
11086
11087 nla_nest_end(msg, func_attr);
11088 genlmsg_end(msg, hdr);
11089
11090 if (!wdev->owner_nlportid)
11091 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11092 msg, 0, NL80211_MCGRP_NAN, gfp);
11093 else
11094 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
11095 wdev->owner_nlportid);
11096
11097 return;
11098
11099nla_put_failure:
11100 nlmsg_free(msg);
11101}
11102EXPORT_SYMBOL(cfg80211_nan_func_terminated);
11103
3713b4e3
JB
11104static int nl80211_get_protocol_features(struct sk_buff *skb,
11105 struct genl_info *info)
11106{
11107 void *hdr;
11108 struct sk_buff *msg;
11109
11110 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11111 if (!msg)
11112 return -ENOMEM;
11113
11114 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11115 NL80211_CMD_GET_PROTOCOL_FEATURES);
11116 if (!hdr)
11117 goto nla_put_failure;
11118
11119 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
11120 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
11121 goto nla_put_failure;
11122
11123 genlmsg_end(msg, hdr);
11124 return genlmsg_reply(msg, info);
11125
11126 nla_put_failure:
11127 kfree_skb(msg);
11128 return -ENOBUFS;
11129}
11130
355199e0
JM
11131static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
11132{
11133 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11134 struct cfg80211_update_ft_ies_params ft_params;
11135 struct net_device *dev = info->user_ptr[1];
11136
11137 if (!rdev->ops->update_ft_ies)
11138 return -EOPNOTSUPP;
11139
11140 if (!info->attrs[NL80211_ATTR_MDID] ||
11141 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
11142 return -EINVAL;
11143
11144 memset(&ft_params, 0, sizeof(ft_params));
11145 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
11146 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11147 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11148
11149 return rdev_update_ft_ies(rdev, dev, &ft_params);
11150}
11151
5de17984
AS
11152static int nl80211_crit_protocol_start(struct sk_buff *skb,
11153 struct genl_info *info)
11154{
11155 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11156 struct wireless_dev *wdev = info->user_ptr[1];
11157 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
11158 u16 duration;
11159 int ret;
11160
11161 if (!rdev->ops->crit_proto_start)
11162 return -EOPNOTSUPP;
11163
11164 if (WARN_ON(!rdev->ops->crit_proto_stop))
11165 return -EINVAL;
11166
11167 if (rdev->crit_proto_nlportid)
11168 return -EBUSY;
11169
11170 /* determine protocol if provided */
11171 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
11172 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
11173
11174 if (proto >= NUM_NL80211_CRIT_PROTO)
11175 return -EINVAL;
11176
11177 /* timeout must be provided */
11178 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
11179 return -EINVAL;
11180
11181 duration =
11182 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
11183
11184 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
11185 return -ERANGE;
11186
11187 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
11188 if (!ret)
11189 rdev->crit_proto_nlportid = info->snd_portid;
11190
11191 return ret;
11192}
11193
11194static int nl80211_crit_protocol_stop(struct sk_buff *skb,
11195 struct genl_info *info)
11196{
11197 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11198 struct wireless_dev *wdev = info->user_ptr[1];
11199
11200 if (!rdev->ops->crit_proto_stop)
11201 return -EOPNOTSUPP;
11202
11203 if (rdev->crit_proto_nlportid) {
11204 rdev->crit_proto_nlportid = 0;
11205 rdev_crit_proto_stop(rdev, wdev);
11206 }
11207 return 0;
11208}
11209
ad7e718c
JB
11210static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
11211{
11212 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11213 struct wireless_dev *wdev =
11214 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
11215 int i, err;
11216 u32 vid, subcmd;
11217
11218 if (!rdev->wiphy.vendor_commands)
11219 return -EOPNOTSUPP;
11220
11221 if (IS_ERR(wdev)) {
11222 err = PTR_ERR(wdev);
11223 if (err != -EINVAL)
11224 return err;
11225 wdev = NULL;
11226 } else if (wdev->wiphy != &rdev->wiphy) {
11227 return -EINVAL;
11228 }
11229
11230 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
11231 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
11232 return -EINVAL;
11233
11234 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
11235 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
11236 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
11237 const struct wiphy_vendor_command *vcmd;
11238 void *data = NULL;
11239 int len = 0;
11240
11241 vcmd = &rdev->wiphy.vendor_commands[i];
11242
11243 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11244 continue;
11245
11246 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11247 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11248 if (!wdev)
11249 return -EINVAL;
11250 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11251 !wdev->netdev)
11252 return -EINVAL;
11253
11254 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
11255 if (wdev->netdev &&
11256 !netif_running(wdev->netdev))
11257 return -ENETDOWN;
11258 if (!wdev->netdev && !wdev->p2p_started)
11259 return -ENETDOWN;
11260 }
7bdbe400
JB
11261
11262 if (!vcmd->doit)
11263 return -EOPNOTSUPP;
ad7e718c
JB
11264 } else {
11265 wdev = NULL;
11266 }
11267
11268 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
11269 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11270 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
11271 }
11272
11273 rdev->cur_cmd_info = info;
11274 err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
11275 data, len);
11276 rdev->cur_cmd_info = NULL;
11277 return err;
11278 }
11279
11280 return -EOPNOTSUPP;
11281}
11282
7bdbe400
JB
11283static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
11284 struct netlink_callback *cb,
11285 struct cfg80211_registered_device **rdev,
11286 struct wireless_dev **wdev)
11287{
11288 u32 vid, subcmd;
11289 unsigned int i;
11290 int vcmd_idx = -1;
11291 int err;
11292 void *data = NULL;
11293 unsigned int data_len = 0;
11294
11295 rtnl_lock();
11296
11297 if (cb->args[0]) {
11298 /* subtract the 1 again here */
11299 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
11300 struct wireless_dev *tmp;
11301
11302 if (!wiphy) {
11303 err = -ENODEV;
11304 goto out_unlock;
11305 }
11306 *rdev = wiphy_to_rdev(wiphy);
11307 *wdev = NULL;
11308
11309 if (cb->args[1]) {
53873f13 11310 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
11311 if (tmp->identifier == cb->args[1] - 1) {
11312 *wdev = tmp;
11313 break;
11314 }
11315 }
11316 }
11317
11318 /* keep rtnl locked in successful case */
11319 return 0;
11320 }
11321
11322 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
11323 nl80211_fam.attrbuf, nl80211_fam.maxattr,
11324 nl80211_policy);
11325 if (err)
11326 goto out_unlock;
11327
11328 if (!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID] ||
11329 !nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
11330 err = -EINVAL;
11331 goto out_unlock;
11332 }
11333
11334 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
11335 nl80211_fam.attrbuf);
11336 if (IS_ERR(*wdev))
11337 *wdev = NULL;
11338
11339 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
11340 nl80211_fam.attrbuf);
11341 if (IS_ERR(*rdev)) {
11342 err = PTR_ERR(*rdev);
11343 goto out_unlock;
11344 }
11345
11346 vid = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID]);
11347 subcmd = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
11348
11349 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
11350 const struct wiphy_vendor_command *vcmd;
11351
11352 vcmd = &(*rdev)->wiphy.vendor_commands[i];
11353
11354 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
11355 continue;
11356
11357 if (!vcmd->dumpit) {
11358 err = -EOPNOTSUPP;
11359 goto out_unlock;
11360 }
11361
11362 vcmd_idx = i;
11363 break;
11364 }
11365
11366 if (vcmd_idx < 0) {
11367 err = -EOPNOTSUPP;
11368 goto out_unlock;
11369 }
11370
11371 if (nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]) {
11372 data = nla_data(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
11373 data_len = nla_len(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
11374 }
11375
11376 /* 0 is the first index - add 1 to parse only once */
11377 cb->args[0] = (*rdev)->wiphy_idx + 1;
11378 /* add 1 to know if it was NULL */
11379 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
11380 cb->args[2] = vcmd_idx;
11381 cb->args[3] = (unsigned long)data;
11382 cb->args[4] = data_len;
11383
11384 /* keep rtnl locked in successful case */
11385 return 0;
11386 out_unlock:
11387 rtnl_unlock();
11388 return err;
11389}
11390
11391static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
11392 struct netlink_callback *cb)
11393{
11394 struct cfg80211_registered_device *rdev;
11395 struct wireless_dev *wdev;
11396 unsigned int vcmd_idx;
11397 const struct wiphy_vendor_command *vcmd;
11398 void *data;
11399 int data_len;
11400 int err;
11401 struct nlattr *vendor_data;
11402
11403 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
11404 if (err)
11405 return err;
11406
11407 vcmd_idx = cb->args[2];
11408 data = (void *)cb->args[3];
11409 data_len = cb->args[4];
11410 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
11411
11412 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
11413 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
11414 if (!wdev)
11415 return -EINVAL;
11416 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
11417 !wdev->netdev)
11418 return -EINVAL;
11419
11420 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
11421 if (wdev->netdev &&
11422 !netif_running(wdev->netdev))
11423 return -ENETDOWN;
11424 if (!wdev->netdev && !wdev->p2p_started)
11425 return -ENETDOWN;
11426 }
11427 }
11428
11429 while (1) {
11430 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
11431 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11432 NL80211_CMD_VENDOR);
11433 if (!hdr)
11434 break;
11435
11436 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
11437 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
11438 wdev_id(wdev),
11439 NL80211_ATTR_PAD))) {
7bdbe400
JB
11440 genlmsg_cancel(skb, hdr);
11441 break;
11442 }
11443
11444 vendor_data = nla_nest_start(skb, NL80211_ATTR_VENDOR_DATA);
11445 if (!vendor_data) {
11446 genlmsg_cancel(skb, hdr);
11447 break;
11448 }
11449
11450 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
11451 (unsigned long *)&cb->args[5]);
11452 nla_nest_end(skb, vendor_data);
11453
11454 if (err == -ENOBUFS || err == -ENOENT) {
11455 genlmsg_cancel(skb, hdr);
11456 break;
11457 } else if (err) {
11458 genlmsg_cancel(skb, hdr);
11459 goto out;
11460 }
11461
11462 genlmsg_end(skb, hdr);
11463 }
11464
11465 err = skb->len;
11466 out:
11467 rtnl_unlock();
11468 return err;
11469}
11470
ad7e718c
JB
11471struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
11472 enum nl80211_commands cmd,
11473 enum nl80211_attrs attr,
11474 int approxlen)
11475{
f26cbf40 11476 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
11477
11478 if (WARN_ON(!rdev->cur_cmd_info))
11479 return NULL;
11480
6c09e791 11481 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
11482 rdev->cur_cmd_info->snd_portid,
11483 rdev->cur_cmd_info->snd_seq,
567ffc35 11484 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
11485}
11486EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
11487
11488int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
11489{
11490 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
11491 void *hdr = ((void **)skb->cb)[1];
11492 struct nlattr *data = ((void **)skb->cb)[2];
11493
bd8c78e7
JB
11494 /* clear CB data for netlink core to own from now on */
11495 memset(skb->cb, 0, sizeof(skb->cb));
11496
ad7e718c
JB
11497 if (WARN_ON(!rdev->cur_cmd_info)) {
11498 kfree_skb(skb);
11499 return -EINVAL;
11500 }
11501
11502 nla_nest_end(skb, data);
11503 genlmsg_end(skb, hdr);
11504 return genlmsg_reply(skb, rdev->cur_cmd_info);
11505}
11506EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
11507
fa9ffc74
KP
11508static int nl80211_set_qos_map(struct sk_buff *skb,
11509 struct genl_info *info)
11510{
11511 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11512 struct cfg80211_qos_map *qos_map = NULL;
11513 struct net_device *dev = info->user_ptr[1];
11514 u8 *pos, len, num_des, des_len, des;
11515 int ret;
11516
11517 if (!rdev->ops->set_qos_map)
11518 return -EOPNOTSUPP;
11519
11520 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
11521 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
11522 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
11523
11524 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
11525 len > IEEE80211_QOS_MAP_LEN_MAX)
11526 return -EINVAL;
11527
11528 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
11529 if (!qos_map)
11530 return -ENOMEM;
11531
11532 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
11533 if (num_des) {
11534 des_len = num_des *
11535 sizeof(struct cfg80211_dscp_exception);
11536 memcpy(qos_map->dscp_exception, pos, des_len);
11537 qos_map->num_des = num_des;
11538 for (des = 0; des < num_des; des++) {
11539 if (qos_map->dscp_exception[des].up > 7) {
11540 kfree(qos_map);
11541 return -EINVAL;
11542 }
11543 }
11544 pos += des_len;
11545 }
11546 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
11547 }
11548
11549 wdev_lock(dev->ieee80211_ptr);
11550 ret = nl80211_key_allowed(dev->ieee80211_ptr);
11551 if (!ret)
11552 ret = rdev_set_qos_map(rdev, dev, qos_map);
11553 wdev_unlock(dev->ieee80211_ptr);
11554
11555 kfree(qos_map);
11556 return ret;
11557}
11558
960d01ac
JB
11559static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
11560{
11561 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11562 struct net_device *dev = info->user_ptr[1];
11563 struct wireless_dev *wdev = dev->ieee80211_ptr;
11564 const u8 *peer;
11565 u8 tsid, up;
11566 u16 admitted_time = 0;
11567 int err;
11568
723e73ac 11569 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
11570 return -EOPNOTSUPP;
11571
11572 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
11573 !info->attrs[NL80211_ATTR_USER_PRIO])
11574 return -EINVAL;
11575
11576 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
11577 if (tsid >= IEEE80211_NUM_TIDS)
11578 return -EINVAL;
11579
11580 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
11581 if (up >= IEEE80211_NUM_UPS)
11582 return -EINVAL;
11583
11584 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 11585 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 11586 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
11587 * need more attributes for that (e.g. BA session requirement);
11588 * change the WMM adminssion test above to allow both then
960d01ac
JB
11589 */
11590 return -EINVAL;
11591 }
11592
11593 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11594
11595 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
11596 admitted_time =
11597 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
11598 if (!admitted_time)
11599 return -EINVAL;
11600 }
11601
11602 wdev_lock(wdev);
11603 switch (wdev->iftype) {
11604 case NL80211_IFTYPE_STATION:
11605 case NL80211_IFTYPE_P2P_CLIENT:
11606 if (wdev->current_bss)
11607 break;
11608 err = -ENOTCONN;
11609 goto out;
11610 default:
11611 err = -EOPNOTSUPP;
11612 goto out;
11613 }
11614
11615 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
11616
11617 out:
11618 wdev_unlock(wdev);
11619 return err;
11620}
11621
11622static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
11623{
11624 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11625 struct net_device *dev = info->user_ptr[1];
11626 struct wireless_dev *wdev = dev->ieee80211_ptr;
11627 const u8 *peer;
11628 u8 tsid;
11629 int err;
11630
11631 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
11632 return -EINVAL;
11633
11634 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
11635 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11636
11637 wdev_lock(wdev);
11638 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
11639 wdev_unlock(wdev);
11640
11641 return err;
11642}
11643
1057d35e
AN
11644static int nl80211_tdls_channel_switch(struct sk_buff *skb,
11645 struct genl_info *info)
11646{
11647 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11648 struct net_device *dev = info->user_ptr[1];
11649 struct wireless_dev *wdev = dev->ieee80211_ptr;
11650 struct cfg80211_chan_def chandef = {};
11651 const u8 *addr;
11652 u8 oper_class;
11653 int err;
11654
11655 if (!rdev->ops->tdls_channel_switch ||
11656 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
11657 return -EOPNOTSUPP;
11658
11659 switch (dev->ieee80211_ptr->iftype) {
11660 case NL80211_IFTYPE_STATION:
11661 case NL80211_IFTYPE_P2P_CLIENT:
11662 break;
11663 default:
11664 return -EOPNOTSUPP;
11665 }
11666
11667 if (!info->attrs[NL80211_ATTR_MAC] ||
11668 !info->attrs[NL80211_ATTR_OPER_CLASS])
11669 return -EINVAL;
11670
11671 err = nl80211_parse_chandef(rdev, info, &chandef);
11672 if (err)
11673 return err;
11674
11675 /*
11676 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
11677 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
11678 * specification is not defined for them.
11679 */
57fbcce3 11680 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
11681 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
11682 chandef.width != NL80211_CHAN_WIDTH_20)
11683 return -EINVAL;
11684
11685 /* we will be active on the TDLS link */
923b352f
AN
11686 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
11687 wdev->iftype))
1057d35e
AN
11688 return -EINVAL;
11689
11690 /* don't allow switching to DFS channels */
11691 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
11692 return -EINVAL;
11693
11694 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11695 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
11696
11697 wdev_lock(wdev);
11698 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
11699 wdev_unlock(wdev);
11700
11701 return err;
11702}
11703
11704static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
11705 struct genl_info *info)
11706{
11707 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11708 struct net_device *dev = info->user_ptr[1];
11709 struct wireless_dev *wdev = dev->ieee80211_ptr;
11710 const u8 *addr;
11711
11712 if (!rdev->ops->tdls_channel_switch ||
11713 !rdev->ops->tdls_cancel_channel_switch ||
11714 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
11715 return -EOPNOTSUPP;
11716
11717 switch (dev->ieee80211_ptr->iftype) {
11718 case NL80211_IFTYPE_STATION:
11719 case NL80211_IFTYPE_P2P_CLIENT:
11720 break;
11721 default:
11722 return -EOPNOTSUPP;
11723 }
11724
11725 if (!info->attrs[NL80211_ATTR_MAC])
11726 return -EINVAL;
11727
11728 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11729
11730 wdev_lock(wdev);
11731 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
11732 wdev_unlock(wdev);
11733
11734 return 0;
11735}
11736
4c476991
JB
11737#define NL80211_FLAG_NEED_WIPHY 0x01
11738#define NL80211_FLAG_NEED_NETDEV 0x02
11739#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
11740#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
11741#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
11742 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 11743#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 11744/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
11745#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
11746 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 11747#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 11748
f84f771d 11749static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
11750 struct genl_info *info)
11751{
11752 struct cfg80211_registered_device *rdev;
89a54e48 11753 struct wireless_dev *wdev;
4c476991 11754 struct net_device *dev;
4c476991
JB
11755 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
11756
11757 if (rtnl)
11758 rtnl_lock();
11759
11760 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 11761 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
11762 if (IS_ERR(rdev)) {
11763 if (rtnl)
11764 rtnl_unlock();
11765 return PTR_ERR(rdev);
11766 }
11767 info->user_ptr[0] = rdev;
1bf614ef
JB
11768 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
11769 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
11770 ASSERT_RTNL();
11771
89a54e48
JB
11772 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
11773 info->attrs);
11774 if (IS_ERR(wdev)) {
4c476991
JB
11775 if (rtnl)
11776 rtnl_unlock();
89a54e48 11777 return PTR_ERR(wdev);
4c476991 11778 }
89a54e48 11779
89a54e48 11780 dev = wdev->netdev;
f26cbf40 11781 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 11782
1bf614ef
JB
11783 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
11784 if (!dev) {
1bf614ef
JB
11785 if (rtnl)
11786 rtnl_unlock();
11787 return -EINVAL;
11788 }
11789
11790 info->user_ptr[1] = dev;
11791 } else {
11792 info->user_ptr[1] = wdev;
41265714 11793 }
1bf614ef
JB
11794
11795 if (dev) {
11796 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
11797 !netif_running(dev)) {
1bf614ef
JB
11798 if (rtnl)
11799 rtnl_unlock();
11800 return -ENETDOWN;
11801 }
11802
11803 dev_hold(dev);
98104fde 11804 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) {
cb3b7d87
AB
11805 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
11806 !wdev->p2p_started) {
11807 if (rtnl)
11808 rtnl_unlock();
11809 return -ENETDOWN;
11810 }
11811 if (wdev->iftype == NL80211_IFTYPE_NAN &&
11812 !wdev->nan_started) {
98104fde
JB
11813 if (rtnl)
11814 rtnl_unlock();
11815 return -ENETDOWN;
11816 }
41265714 11817 }
89a54e48 11818
4c476991 11819 info->user_ptr[0] = rdev;
4c476991
JB
11820 }
11821
11822 return 0;
11823}
11824
f84f771d 11825static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
11826 struct genl_info *info)
11827{
1bf614ef
JB
11828 if (info->user_ptr[1]) {
11829 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
11830 struct wireless_dev *wdev = info->user_ptr[1];
11831
11832 if (wdev->netdev)
11833 dev_put(wdev->netdev);
11834 } else {
11835 dev_put(info->user_ptr[1]);
11836 }
11837 }
5393b917 11838
4c476991
JB
11839 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
11840 rtnl_unlock();
5393b917
JB
11841
11842 /* If needed, clear the netlink message payload from the SKB
11843 * as it might contain key data that shouldn't stick around on
11844 * the heap after the SKB is freed. The netlink message header
11845 * is still needed for further processing, so leave it intact.
11846 */
11847 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
11848 struct nlmsghdr *nlh = nlmsg_hdr(skb);
11849
11850 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
11851 }
4c476991
JB
11852}
11853
4534de83 11854static const struct genl_ops nl80211_ops[] = {
55682965
JB
11855 {
11856 .cmd = NL80211_CMD_GET_WIPHY,
11857 .doit = nl80211_get_wiphy,
11858 .dumpit = nl80211_dump_wiphy,
86e8cf98 11859 .done = nl80211_dump_wiphy_done,
55682965
JB
11860 .policy = nl80211_policy,
11861 /* can be retrieved by unprivileged users */
5fe231e8
JB
11862 .internal_flags = NL80211_FLAG_NEED_WIPHY |
11863 NL80211_FLAG_NEED_RTNL,
55682965
JB
11864 },
11865 {
11866 .cmd = NL80211_CMD_SET_WIPHY,
11867 .doit = nl80211_set_wiphy,
11868 .policy = nl80211_policy,
5617c6cd 11869 .flags = GENL_UNS_ADMIN_PERM,
4c476991 11870 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
11871 },
11872 {
11873 .cmd = NL80211_CMD_GET_INTERFACE,
11874 .doit = nl80211_get_interface,
11875 .dumpit = nl80211_dump_interface,
11876 .policy = nl80211_policy,
11877 /* can be retrieved by unprivileged users */
5fe231e8
JB
11878 .internal_flags = NL80211_FLAG_NEED_WDEV |
11879 NL80211_FLAG_NEED_RTNL,
55682965
JB
11880 },
11881 {
11882 .cmd = NL80211_CMD_SET_INTERFACE,
11883 .doit = nl80211_set_interface,
11884 .policy = nl80211_policy,
5617c6cd 11885 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
11886 .internal_flags = NL80211_FLAG_NEED_NETDEV |
11887 NL80211_FLAG_NEED_RTNL,
55682965
JB
11888 },
11889 {
11890 .cmd = NL80211_CMD_NEW_INTERFACE,
11891 .doit = nl80211_new_interface,
11892 .policy = nl80211_policy,
5617c6cd 11893 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
11894 .internal_flags = NL80211_FLAG_NEED_WIPHY |
11895 NL80211_FLAG_NEED_RTNL,
55682965
JB
11896 },
11897 {
11898 .cmd = NL80211_CMD_DEL_INTERFACE,
11899 .doit = nl80211_del_interface,
11900 .policy = nl80211_policy,
5617c6cd 11901 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 11902 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 11903 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
11904 },
11905 {
11906 .cmd = NL80211_CMD_GET_KEY,
11907 .doit = nl80211_get_key,
11908 .policy = nl80211_policy,
5617c6cd 11909 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11910 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11911 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
11912 },
11913 {
11914 .cmd = NL80211_CMD_SET_KEY,
11915 .doit = nl80211_set_key,
11916 .policy = nl80211_policy,
5617c6cd 11917 .flags = GENL_UNS_ADMIN_PERM,
41265714 11918 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
11919 NL80211_FLAG_NEED_RTNL |
11920 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
11921 },
11922 {
11923 .cmd = NL80211_CMD_NEW_KEY,
11924 .doit = nl80211_new_key,
11925 .policy = nl80211_policy,
5617c6cd 11926 .flags = GENL_UNS_ADMIN_PERM,
41265714 11927 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
11928 NL80211_FLAG_NEED_RTNL |
11929 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
11930 },
11931 {
11932 .cmd = NL80211_CMD_DEL_KEY,
11933 .doit = nl80211_del_key,
11934 .policy = nl80211_policy,
5617c6cd 11935 .flags = GENL_UNS_ADMIN_PERM,
41265714 11936 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11937 NL80211_FLAG_NEED_RTNL,
55682965 11938 },
ed1b6cc7
JB
11939 {
11940 .cmd = NL80211_CMD_SET_BEACON,
11941 .policy = nl80211_policy,
5617c6cd 11942 .flags = GENL_UNS_ADMIN_PERM,
8860020e 11943 .doit = nl80211_set_beacon,
2b5f8b0b 11944 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11945 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
11946 },
11947 {
8860020e 11948 .cmd = NL80211_CMD_START_AP,
ed1b6cc7 11949 .policy = nl80211_policy,
5617c6cd 11950 .flags = GENL_UNS_ADMIN_PERM,
8860020e 11951 .doit = nl80211_start_ap,
2b5f8b0b 11952 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11953 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
11954 },
11955 {
8860020e 11956 .cmd = NL80211_CMD_STOP_AP,
ed1b6cc7 11957 .policy = nl80211_policy,
5617c6cd 11958 .flags = GENL_UNS_ADMIN_PERM,
8860020e 11959 .doit = nl80211_stop_ap,
2b5f8b0b 11960 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11961 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 11962 },
5727ef1b
JB
11963 {
11964 .cmd = NL80211_CMD_GET_STATION,
11965 .doit = nl80211_get_station,
2ec600d6 11966 .dumpit = nl80211_dump_station,
5727ef1b 11967 .policy = nl80211_policy,
4c476991
JB
11968 .internal_flags = NL80211_FLAG_NEED_NETDEV |
11969 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
11970 },
11971 {
11972 .cmd = NL80211_CMD_SET_STATION,
11973 .doit = nl80211_set_station,
11974 .policy = nl80211_policy,
5617c6cd 11975 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11976 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11977 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
11978 },
11979 {
11980 .cmd = NL80211_CMD_NEW_STATION,
11981 .doit = nl80211_new_station,
11982 .policy = nl80211_policy,
5617c6cd 11983 .flags = GENL_UNS_ADMIN_PERM,
41265714 11984 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11985 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
11986 },
11987 {
11988 .cmd = NL80211_CMD_DEL_STATION,
11989 .doit = nl80211_del_station,
11990 .policy = nl80211_policy,
5617c6cd 11991 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 11992 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 11993 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
11994 },
11995 {
11996 .cmd = NL80211_CMD_GET_MPATH,
11997 .doit = nl80211_get_mpath,
11998 .dumpit = nl80211_dump_mpath,
11999 .policy = nl80211_policy,
5617c6cd 12000 .flags = GENL_UNS_ADMIN_PERM,
41265714 12001 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12002 NL80211_FLAG_NEED_RTNL,
2ec600d6 12003 },
66be7d2b
HR
12004 {
12005 .cmd = NL80211_CMD_GET_MPP,
12006 .doit = nl80211_get_mpp,
12007 .dumpit = nl80211_dump_mpp,
12008 .policy = nl80211_policy,
5617c6cd 12009 .flags = GENL_UNS_ADMIN_PERM,
66be7d2b
HR
12010 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12011 NL80211_FLAG_NEED_RTNL,
12012 },
2ec600d6
LCC
12013 {
12014 .cmd = NL80211_CMD_SET_MPATH,
12015 .doit = nl80211_set_mpath,
12016 .policy = nl80211_policy,
5617c6cd 12017 .flags = GENL_UNS_ADMIN_PERM,
41265714 12018 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12019 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12020 },
12021 {
12022 .cmd = NL80211_CMD_NEW_MPATH,
12023 .doit = nl80211_new_mpath,
12024 .policy = nl80211_policy,
5617c6cd 12025 .flags = GENL_UNS_ADMIN_PERM,
41265714 12026 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12027 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
12028 },
12029 {
12030 .cmd = NL80211_CMD_DEL_MPATH,
12031 .doit = nl80211_del_mpath,
12032 .policy = nl80211_policy,
5617c6cd 12033 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12034 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12035 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
12036 },
12037 {
12038 .cmd = NL80211_CMD_SET_BSS,
12039 .doit = nl80211_set_bss,
12040 .policy = nl80211_policy,
5617c6cd 12041 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12042 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12043 NL80211_FLAG_NEED_RTNL,
b2e1b302 12044 },
f130347c
LR
12045 {
12046 .cmd = NL80211_CMD_GET_REG,
ad30ca2c
AN
12047 .doit = nl80211_get_reg_do,
12048 .dumpit = nl80211_get_reg_dump,
f130347c 12049 .policy = nl80211_policy,
5fe231e8 12050 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
12051 /* can be retrieved by unprivileged users */
12052 },
b6863036 12053#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
12054 {
12055 .cmd = NL80211_CMD_SET_REG,
12056 .doit = nl80211_set_reg,
12057 .policy = nl80211_policy,
12058 .flags = GENL_ADMIN_PERM,
5fe231e8 12059 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302 12060 },
b6863036 12061#endif
b2e1b302
LR
12062 {
12063 .cmd = NL80211_CMD_REQ_SET_REG,
12064 .doit = nl80211_req_set_reg,
12065 .policy = nl80211_policy,
93da9cc1 12066 .flags = GENL_ADMIN_PERM,
12067 },
12068 {
24bdd9f4
JC
12069 .cmd = NL80211_CMD_GET_MESH_CONFIG,
12070 .doit = nl80211_get_mesh_config,
93da9cc1 12071 .policy = nl80211_policy,
12072 /* can be retrieved by unprivileged users */
2b5f8b0b 12073 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12074 NL80211_FLAG_NEED_RTNL,
93da9cc1 12075 },
12076 {
24bdd9f4
JC
12077 .cmd = NL80211_CMD_SET_MESH_CONFIG,
12078 .doit = nl80211_update_mesh_config,
93da9cc1 12079 .policy = nl80211_policy,
5617c6cd 12080 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c 12081 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12082 NL80211_FLAG_NEED_RTNL,
9aed3cc1 12083 },
2a519311
JB
12084 {
12085 .cmd = NL80211_CMD_TRIGGER_SCAN,
12086 .doit = nl80211_trigger_scan,
12087 .policy = nl80211_policy,
5617c6cd 12088 .flags = GENL_UNS_ADMIN_PERM,
fd014284 12089 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12090 NL80211_FLAG_NEED_RTNL,
2a519311 12091 },
91d3ab46
VK
12092 {
12093 .cmd = NL80211_CMD_ABORT_SCAN,
12094 .doit = nl80211_abort_scan,
12095 .policy = nl80211_policy,
5617c6cd 12096 .flags = GENL_UNS_ADMIN_PERM,
91d3ab46
VK
12097 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12098 NL80211_FLAG_NEED_RTNL,
12099 },
2a519311
JB
12100 {
12101 .cmd = NL80211_CMD_GET_SCAN,
12102 .policy = nl80211_policy,
12103 .dumpit = nl80211_dump_scan,
12104 },
807f8a8c
LC
12105 {
12106 .cmd = NL80211_CMD_START_SCHED_SCAN,
12107 .doit = nl80211_start_sched_scan,
12108 .policy = nl80211_policy,
5617c6cd 12109 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
12110 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12111 NL80211_FLAG_NEED_RTNL,
12112 },
12113 {
12114 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
12115 .doit = nl80211_stop_sched_scan,
12116 .policy = nl80211_policy,
5617c6cd 12117 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
12118 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12119 NL80211_FLAG_NEED_RTNL,
12120 },
636a5d36
JM
12121 {
12122 .cmd = NL80211_CMD_AUTHENTICATE,
12123 .doit = nl80211_authenticate,
12124 .policy = nl80211_policy,
5617c6cd 12125 .flags = GENL_UNS_ADMIN_PERM,
41265714 12126 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12127 NL80211_FLAG_NEED_RTNL |
12128 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
12129 },
12130 {
12131 .cmd = NL80211_CMD_ASSOCIATE,
12132 .doit = nl80211_associate,
12133 .policy = nl80211_policy,
5617c6cd 12134 .flags = GENL_UNS_ADMIN_PERM,
41265714 12135 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12136 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
12137 },
12138 {
12139 .cmd = NL80211_CMD_DEAUTHENTICATE,
12140 .doit = nl80211_deauthenticate,
12141 .policy = nl80211_policy,
5617c6cd 12142 .flags = GENL_UNS_ADMIN_PERM,
41265714 12143 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12144 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
12145 },
12146 {
12147 .cmd = NL80211_CMD_DISASSOCIATE,
12148 .doit = nl80211_disassociate,
12149 .policy = nl80211_policy,
5617c6cd 12150 .flags = GENL_UNS_ADMIN_PERM,
41265714 12151 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12152 NL80211_FLAG_NEED_RTNL,
636a5d36 12153 },
04a773ad
JB
12154 {
12155 .cmd = NL80211_CMD_JOIN_IBSS,
12156 .doit = nl80211_join_ibss,
12157 .policy = nl80211_policy,
5617c6cd 12158 .flags = GENL_UNS_ADMIN_PERM,
41265714 12159 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12160 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
12161 },
12162 {
12163 .cmd = NL80211_CMD_LEAVE_IBSS,
12164 .doit = nl80211_leave_ibss,
12165 .policy = nl80211_policy,
5617c6cd 12166 .flags = GENL_UNS_ADMIN_PERM,
41265714 12167 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12168 NL80211_FLAG_NEED_RTNL,
04a773ad 12169 },
aff89a9b
JB
12170#ifdef CONFIG_NL80211_TESTMODE
12171 {
12172 .cmd = NL80211_CMD_TESTMODE,
12173 .doit = nl80211_testmode_do,
71063f0e 12174 .dumpit = nl80211_testmode_dump,
aff89a9b 12175 .policy = nl80211_policy,
5617c6cd 12176 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12177 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12178 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
12179 },
12180#endif
b23aa676
SO
12181 {
12182 .cmd = NL80211_CMD_CONNECT,
12183 .doit = nl80211_connect,
12184 .policy = nl80211_policy,
5617c6cd 12185 .flags = GENL_UNS_ADMIN_PERM,
41265714 12186 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12187 NL80211_FLAG_NEED_RTNL,
b23aa676
SO
12188 },
12189 {
12190 .cmd = NL80211_CMD_DISCONNECT,
12191 .doit = nl80211_disconnect,
12192 .policy = nl80211_policy,
5617c6cd 12193 .flags = GENL_UNS_ADMIN_PERM,
41265714 12194 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12195 NL80211_FLAG_NEED_RTNL,
b23aa676 12196 },
463d0183
JB
12197 {
12198 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
12199 .doit = nl80211_wiphy_netns,
12200 .policy = nl80211_policy,
5617c6cd 12201 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12202 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12203 NL80211_FLAG_NEED_RTNL,
463d0183 12204 },
61fa713c
HS
12205 {
12206 .cmd = NL80211_CMD_GET_SURVEY,
12207 .policy = nl80211_policy,
12208 .dumpit = nl80211_dump_survey,
12209 },
67fbb16b
SO
12210 {
12211 .cmd = NL80211_CMD_SET_PMKSA,
12212 .doit = nl80211_setdel_pmksa,
12213 .policy = nl80211_policy,
5617c6cd 12214 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12215 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12216 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12217 },
12218 {
12219 .cmd = NL80211_CMD_DEL_PMKSA,
12220 .doit = nl80211_setdel_pmksa,
12221 .policy = nl80211_policy,
5617c6cd 12222 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12223 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12224 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
12225 },
12226 {
12227 .cmd = NL80211_CMD_FLUSH_PMKSA,
12228 .doit = nl80211_flush_pmksa,
12229 .policy = nl80211_policy,
5617c6cd 12230 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12231 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 12232 NL80211_FLAG_NEED_RTNL,
67fbb16b 12233 },
9588bbd5
JM
12234 {
12235 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
12236 .doit = nl80211_remain_on_channel,
12237 .policy = nl80211_policy,
5617c6cd 12238 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12239 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12240 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
12241 },
12242 {
12243 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
12244 .doit = nl80211_cancel_remain_on_channel,
12245 .policy = nl80211_policy,
5617c6cd 12246 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12247 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12248 NL80211_FLAG_NEED_RTNL,
9588bbd5 12249 },
13ae75b1
JM
12250 {
12251 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
12252 .doit = nl80211_set_tx_bitrate_mask,
12253 .policy = nl80211_policy,
5617c6cd 12254 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12255 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12256 NL80211_FLAG_NEED_RTNL,
13ae75b1 12257 },
026331c4 12258 {
2e161f78
JB
12259 .cmd = NL80211_CMD_REGISTER_FRAME,
12260 .doit = nl80211_register_mgmt,
026331c4 12261 .policy = nl80211_policy,
5617c6cd 12262 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12263 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 12264 NL80211_FLAG_NEED_RTNL,
026331c4
JM
12265 },
12266 {
2e161f78
JB
12267 .cmd = NL80211_CMD_FRAME,
12268 .doit = nl80211_tx_mgmt,
026331c4 12269 .policy = nl80211_policy,
5617c6cd 12270 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12271 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
12272 NL80211_FLAG_NEED_RTNL,
12273 },
12274 {
12275 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
12276 .doit = nl80211_tx_mgmt_cancel_wait,
12277 .policy = nl80211_policy,
5617c6cd 12278 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 12279 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 12280 NL80211_FLAG_NEED_RTNL,
026331c4 12281 },
ffb9eb3d
KV
12282 {
12283 .cmd = NL80211_CMD_SET_POWER_SAVE,
12284 .doit = nl80211_set_power_save,
12285 .policy = nl80211_policy,
5617c6cd 12286 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12287 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12288 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
12289 },
12290 {
12291 .cmd = NL80211_CMD_GET_POWER_SAVE,
12292 .doit = nl80211_get_power_save,
12293 .policy = nl80211_policy,
12294 /* can be retrieved by unprivileged users */
4c476991
JB
12295 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12296 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 12297 },
d6dc1a38
JO
12298 {
12299 .cmd = NL80211_CMD_SET_CQM,
12300 .doit = nl80211_set_cqm,
12301 .policy = nl80211_policy,
5617c6cd 12302 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12303 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12304 NL80211_FLAG_NEED_RTNL,
d6dc1a38 12305 },
f444de05
JB
12306 {
12307 .cmd = NL80211_CMD_SET_CHANNEL,
12308 .doit = nl80211_set_channel,
12309 .policy = nl80211_policy,
5617c6cd 12310 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
12311 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12312 NL80211_FLAG_NEED_RTNL,
f444de05 12313 },
e8347eba
BJ
12314 {
12315 .cmd = NL80211_CMD_SET_WDS_PEER,
12316 .doit = nl80211_set_wds_peer,
12317 .policy = nl80211_policy,
5617c6cd 12318 .flags = GENL_UNS_ADMIN_PERM,
43b19952
JB
12319 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12320 NL80211_FLAG_NEED_RTNL,
e8347eba 12321 },
29cbe68c
JB
12322 {
12323 .cmd = NL80211_CMD_JOIN_MESH,
12324 .doit = nl80211_join_mesh,
12325 .policy = nl80211_policy,
5617c6cd 12326 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
12327 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12328 NL80211_FLAG_NEED_RTNL,
12329 },
12330 {
12331 .cmd = NL80211_CMD_LEAVE_MESH,
12332 .doit = nl80211_leave_mesh,
12333 .policy = nl80211_policy,
5617c6cd 12334 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
12335 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12336 NL80211_FLAG_NEED_RTNL,
12337 },
6e0bd6c3
RL
12338 {
12339 .cmd = NL80211_CMD_JOIN_OCB,
12340 .doit = nl80211_join_ocb,
12341 .policy = nl80211_policy,
5617c6cd 12342 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
12343 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12344 NL80211_FLAG_NEED_RTNL,
12345 },
12346 {
12347 .cmd = NL80211_CMD_LEAVE_OCB,
12348 .doit = nl80211_leave_ocb,
12349 .policy = nl80211_policy,
5617c6cd 12350 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
12351 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12352 NL80211_FLAG_NEED_RTNL,
12353 },
dfb89c56 12354#ifdef CONFIG_PM
ff1b6e69
JB
12355 {
12356 .cmd = NL80211_CMD_GET_WOWLAN,
12357 .doit = nl80211_get_wowlan,
12358 .policy = nl80211_policy,
12359 /* can be retrieved by unprivileged users */
12360 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12361 NL80211_FLAG_NEED_RTNL,
12362 },
12363 {
12364 .cmd = NL80211_CMD_SET_WOWLAN,
12365 .doit = nl80211_set_wowlan,
12366 .policy = nl80211_policy,
5617c6cd 12367 .flags = GENL_UNS_ADMIN_PERM,
ff1b6e69
JB
12368 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12369 NL80211_FLAG_NEED_RTNL,
12370 },
dfb89c56 12371#endif
e5497d76
JB
12372 {
12373 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
12374 .doit = nl80211_set_rekey_data,
12375 .policy = nl80211_policy,
5617c6cd 12376 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 12377 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
12378 NL80211_FLAG_NEED_RTNL |
12379 NL80211_FLAG_CLEAR_SKB,
e5497d76 12380 },
109086ce
AN
12381 {
12382 .cmd = NL80211_CMD_TDLS_MGMT,
12383 .doit = nl80211_tdls_mgmt,
12384 .policy = nl80211_policy,
5617c6cd 12385 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
12386 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12387 NL80211_FLAG_NEED_RTNL,
12388 },
12389 {
12390 .cmd = NL80211_CMD_TDLS_OPER,
12391 .doit = nl80211_tdls_oper,
12392 .policy = nl80211_policy,
5617c6cd 12393 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
12394 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12395 NL80211_FLAG_NEED_RTNL,
12396 },
28946da7
JB
12397 {
12398 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
12399 .doit = nl80211_register_unexpected_frame,
12400 .policy = nl80211_policy,
5617c6cd 12401 .flags = GENL_UNS_ADMIN_PERM,
28946da7
JB
12402 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12403 NL80211_FLAG_NEED_RTNL,
12404 },
7f6cf311
JB
12405 {
12406 .cmd = NL80211_CMD_PROBE_CLIENT,
12407 .doit = nl80211_probe_client,
12408 .policy = nl80211_policy,
5617c6cd 12409 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 12410 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
12411 NL80211_FLAG_NEED_RTNL,
12412 },
5e760230
JB
12413 {
12414 .cmd = NL80211_CMD_REGISTER_BEACONS,
12415 .doit = nl80211_register_beacons,
12416 .policy = nl80211_policy,
5617c6cd 12417 .flags = GENL_UNS_ADMIN_PERM,
5e760230
JB
12418 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12419 NL80211_FLAG_NEED_RTNL,
12420 },
1d9d9213
SW
12421 {
12422 .cmd = NL80211_CMD_SET_NOACK_MAP,
12423 .doit = nl80211_set_noack_map,
12424 .policy = nl80211_policy,
5617c6cd 12425 .flags = GENL_UNS_ADMIN_PERM,
1d9d9213
SW
12426 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12427 NL80211_FLAG_NEED_RTNL,
12428 },
98104fde
JB
12429 {
12430 .cmd = NL80211_CMD_START_P2P_DEVICE,
12431 .doit = nl80211_start_p2p_device,
12432 .policy = nl80211_policy,
5617c6cd 12433 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
12434 .internal_flags = NL80211_FLAG_NEED_WDEV |
12435 NL80211_FLAG_NEED_RTNL,
12436 },
12437 {
12438 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
12439 .doit = nl80211_stop_p2p_device,
12440 .policy = nl80211_policy,
5617c6cd 12441 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
12442 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12443 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
12444 },
12445 {
12446 .cmd = NL80211_CMD_START_NAN,
12447 .doit = nl80211_start_nan,
12448 .policy = nl80211_policy,
12449 .flags = GENL_ADMIN_PERM,
12450 .internal_flags = NL80211_FLAG_NEED_WDEV |
12451 NL80211_FLAG_NEED_RTNL,
12452 },
12453 {
12454 .cmd = NL80211_CMD_STOP_NAN,
12455 .doit = nl80211_stop_nan,
12456 .policy = nl80211_policy,
12457 .flags = GENL_ADMIN_PERM,
12458 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12459 NL80211_FLAG_NEED_RTNL,
a442b761
AB
12460 },
12461 {
12462 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
12463 .doit = nl80211_nan_add_func,
12464 .policy = nl80211_policy,
12465 .flags = GENL_ADMIN_PERM,
12466 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12467 NL80211_FLAG_NEED_RTNL,
12468 },
12469 {
12470 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
12471 .doit = nl80211_nan_del_func,
12472 .policy = nl80211_policy,
12473 .flags = GENL_ADMIN_PERM,
12474 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12475 NL80211_FLAG_NEED_RTNL,
a5a9dcf2
AB
12476 },
12477 {
12478 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
12479 .doit = nl80211_nan_change_config,
12480 .policy = nl80211_policy,
12481 .flags = GENL_ADMIN_PERM,
12482 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12483 NL80211_FLAG_NEED_RTNL,
98104fde 12484 },
f4e583c8
AQ
12485 {
12486 .cmd = NL80211_CMD_SET_MCAST_RATE,
12487 .doit = nl80211_set_mcast_rate,
77765eaf 12488 .policy = nl80211_policy,
5617c6cd 12489 .flags = GENL_UNS_ADMIN_PERM,
77765eaf
VT
12490 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12491 NL80211_FLAG_NEED_RTNL,
12492 },
12493 {
12494 .cmd = NL80211_CMD_SET_MAC_ACL,
12495 .doit = nl80211_set_mac_acl,
f4e583c8 12496 .policy = nl80211_policy,
5617c6cd 12497 .flags = GENL_UNS_ADMIN_PERM,
f4e583c8
AQ
12498 .internal_flags = NL80211_FLAG_NEED_NETDEV |
12499 NL80211_FLAG_NEED_RTNL,
12500 },
04f39047
SW
12501 {
12502 .cmd = NL80211_CMD_RADAR_DETECT,
12503 .doit = nl80211_start_radar_detection,
12504 .policy = nl80211_policy,
5617c6cd 12505 .flags = GENL_UNS_ADMIN_PERM,
04f39047
SW
12506 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12507 NL80211_FLAG_NEED_RTNL,
12508 },
3713b4e3
JB
12509 {
12510 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
12511 .doit = nl80211_get_protocol_features,
12512 .policy = nl80211_policy,
12513 },
355199e0
JM
12514 {
12515 .cmd = NL80211_CMD_UPDATE_FT_IES,
12516 .doit = nl80211_update_ft_ies,
12517 .policy = nl80211_policy,
5617c6cd 12518 .flags = GENL_UNS_ADMIN_PERM,
355199e0
JM
12519 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12520 NL80211_FLAG_NEED_RTNL,
12521 },
5de17984
AS
12522 {
12523 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
12524 .doit = nl80211_crit_protocol_start,
12525 .policy = nl80211_policy,
5617c6cd 12526 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
12527 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12528 NL80211_FLAG_NEED_RTNL,
12529 },
12530 {
12531 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
12532 .doit = nl80211_crit_protocol_stop,
12533 .policy = nl80211_policy,
5617c6cd 12534 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
12535 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
12536 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
12537 },
12538 {
12539 .cmd = NL80211_CMD_GET_COALESCE,
12540 .doit = nl80211_get_coalesce,
12541 .policy = nl80211_policy,
12542 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12543 NL80211_FLAG_NEED_RTNL,
12544 },
12545 {
12546 .cmd = NL80211_CMD_SET_COALESCE,
12547 .doit = nl80211_set_coalesce,
12548 .policy = nl80211_policy,
5617c6cd 12549 .flags = GENL_UNS_ADMIN_PERM,
be29b99a
AK
12550 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12551 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
12552 },
12553 {
12554 .cmd = NL80211_CMD_CHANNEL_SWITCH,
12555 .doit = nl80211_channel_switch,
12556 .policy = nl80211_policy,
5617c6cd 12557 .flags = GENL_UNS_ADMIN_PERM,
16ef1fe2
SW
12558 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12559 NL80211_FLAG_NEED_RTNL,
12560 },
ad7e718c
JB
12561 {
12562 .cmd = NL80211_CMD_VENDOR,
12563 .doit = nl80211_vendor_cmd,
7bdbe400 12564 .dumpit = nl80211_vendor_cmd_dump,
ad7e718c 12565 .policy = nl80211_policy,
5617c6cd 12566 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c
JB
12567 .internal_flags = NL80211_FLAG_NEED_WIPHY |
12568 NL80211_FLAG_NEED_RTNL,
12569 },
fa9ffc74
KP
12570 {
12571 .cmd = NL80211_CMD_SET_QOS_MAP,
12572 .doit = nl80211_set_qos_map,
12573 .policy = nl80211_policy,
5617c6cd 12574 .flags = GENL_UNS_ADMIN_PERM,
fa9ffc74
KP
12575 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12576 NL80211_FLAG_NEED_RTNL,
12577 },
960d01ac
JB
12578 {
12579 .cmd = NL80211_CMD_ADD_TX_TS,
12580 .doit = nl80211_add_tx_ts,
12581 .policy = nl80211_policy,
5617c6cd 12582 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
12583 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12584 NL80211_FLAG_NEED_RTNL,
12585 },
12586 {
12587 .cmd = NL80211_CMD_DEL_TX_TS,
12588 .doit = nl80211_del_tx_ts,
12589 .policy = nl80211_policy,
5617c6cd 12590 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
12591 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12592 NL80211_FLAG_NEED_RTNL,
12593 },
1057d35e
AN
12594 {
12595 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
12596 .doit = nl80211_tdls_channel_switch,
12597 .policy = nl80211_policy,
5617c6cd 12598 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
12599 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12600 NL80211_FLAG_NEED_RTNL,
12601 },
12602 {
12603 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
12604 .doit = nl80211_tdls_cancel_channel_switch,
12605 .policy = nl80211_policy,
5617c6cd 12606 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
12607 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
12608 NL80211_FLAG_NEED_RTNL,
12609 },
55682965 12610};
9588bbd5 12611
55682965
JB
12612/* notification functions */
12613
3bb20556
JB
12614void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
12615 enum nl80211_commands cmd)
55682965
JB
12616{
12617 struct sk_buff *msg;
86e8cf98 12618 struct nl80211_dump_wiphy_state state = {};
55682965 12619
3bb20556
JB
12620 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
12621 cmd != NL80211_CMD_DEL_WIPHY);
12622
fd2120ca 12623 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
12624 if (!msg)
12625 return;
12626
3bb20556 12627 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
12628 nlmsg_free(msg);
12629 return;
12630 }
12631
68eb5503 12632 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12633 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
12634}
12635
896ff063
DK
12636void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
12637 struct wireless_dev *wdev,
12638 enum nl80211_commands cmd)
12639{
12640 struct sk_buff *msg;
12641
12642 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
12643 cmd != NL80211_CMD_DEL_INTERFACE);
12644
12645 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12646 if (!msg)
12647 return;
12648
12649 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev,
12650 cmd == NL80211_CMD_DEL_INTERFACE) < 0) {
12651 nlmsg_free(msg);
12652 return;
12653 }
12654
12655 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
12656 NL80211_MCGRP_CONFIG, GFP_KERNEL);
12657}
12658
362a415d
JB
12659static int nl80211_add_scan_req(struct sk_buff *msg,
12660 struct cfg80211_registered_device *rdev)
12661{
12662 struct cfg80211_scan_request *req = rdev->scan_req;
12663 struct nlattr *nest;
12664 int i;
12665
12666 if (WARN_ON(!req))
12667 return 0;
12668
12669 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
12670 if (!nest)
12671 goto nla_put_failure;
9360ffd1
DM
12672 for (i = 0; i < req->n_ssids; i++) {
12673 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
12674 goto nla_put_failure;
12675 }
362a415d
JB
12676 nla_nest_end(msg, nest);
12677
12678 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
12679 if (!nest)
12680 goto nla_put_failure;
9360ffd1
DM
12681 for (i = 0; i < req->n_channels; i++) {
12682 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
12683 goto nla_put_failure;
12684 }
362a415d
JB
12685 nla_nest_end(msg, nest);
12686
9360ffd1
DM
12687 if (req->ie &&
12688 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
12689 goto nla_put_failure;
362a415d 12690
ae917c9f
JB
12691 if (req->flags &&
12692 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
12693 goto nla_put_failure;
ed473771 12694
1d76250b
AS
12695 if (req->info.scan_start_tsf &&
12696 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
12697 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
12698 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
12699 req->info.tsf_bssid)))
12700 goto nla_put_failure;
12701
362a415d
JB
12702 return 0;
12703 nla_put_failure:
12704 return -ENOBUFS;
12705}
12706
a538e2d5
JB
12707static int nl80211_send_scan_msg(struct sk_buff *msg,
12708 struct cfg80211_registered_device *rdev,
fd014284 12709 struct wireless_dev *wdev,
15e47304 12710 u32 portid, u32 seq, int flags,
a538e2d5 12711 u32 cmd)
2a519311
JB
12712{
12713 void *hdr;
12714
15e47304 12715 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
12716 if (!hdr)
12717 return -1;
12718
9360ffd1 12719 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
12720 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12721 wdev->netdev->ifindex)) ||
2dad624e
ND
12722 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12723 NL80211_ATTR_PAD))
9360ffd1 12724 goto nla_put_failure;
2a519311 12725
362a415d
JB
12726 /* ignore errors and send incomplete event anyway */
12727 nl80211_add_scan_req(msg, rdev);
2a519311 12728
053c095a
JB
12729 genlmsg_end(msg, hdr);
12730 return 0;
2a519311
JB
12731
12732 nla_put_failure:
12733 genlmsg_cancel(msg, hdr);
12734 return -EMSGSIZE;
12735}
12736
807f8a8c
LC
12737static int
12738nl80211_send_sched_scan_msg(struct sk_buff *msg,
12739 struct cfg80211_registered_device *rdev,
12740 struct net_device *netdev,
15e47304 12741 u32 portid, u32 seq, int flags, u32 cmd)
807f8a8c
LC
12742{
12743 void *hdr;
12744
15e47304 12745 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
807f8a8c
LC
12746 if (!hdr)
12747 return -1;
12748
9360ffd1
DM
12749 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12750 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
12751 goto nla_put_failure;
807f8a8c 12752
053c095a
JB
12753 genlmsg_end(msg, hdr);
12754 return 0;
807f8a8c
LC
12755
12756 nla_put_failure:
12757 genlmsg_cancel(msg, hdr);
12758 return -EMSGSIZE;
12759}
12760
a538e2d5 12761void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 12762 struct wireless_dev *wdev)
a538e2d5
JB
12763{
12764 struct sk_buff *msg;
12765
58050fce 12766 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
12767 if (!msg)
12768 return;
12769
fd014284 12770 if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
12771 NL80211_CMD_TRIGGER_SCAN) < 0) {
12772 nlmsg_free(msg);
12773 return;
12774 }
12775
68eb5503 12776 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12777 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
12778}
12779
f9d15d16
JB
12780struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
12781 struct wireless_dev *wdev, bool aborted)
2a519311
JB
12782{
12783 struct sk_buff *msg;
12784
fd2120ca 12785 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 12786 if (!msg)
f9d15d16 12787 return NULL;
2a519311 12788
fd014284 12789 if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
12790 aborted ? NL80211_CMD_SCAN_ABORTED :
12791 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 12792 nlmsg_free(msg);
f9d15d16 12793 return NULL;
2a519311
JB
12794 }
12795
f9d15d16 12796 return msg;
2a519311
JB
12797}
12798
f9d15d16
JB
12799void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
12800 struct sk_buff *msg)
2a519311 12801{
2a519311
JB
12802 if (!msg)
12803 return;
12804
68eb5503 12805 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12806 NL80211_MCGRP_SCAN, GFP_KERNEL);
2a519311
JB
12807}
12808
807f8a8c
LC
12809void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
12810 struct net_device *netdev)
12811{
12812 struct sk_buff *msg;
12813
12814 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12815 if (!msg)
12816 return;
12817
12818 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0,
12819 NL80211_CMD_SCHED_SCAN_RESULTS) < 0) {
12820 nlmsg_free(msg);
12821 return;
12822 }
12823
68eb5503 12824 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12825 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
12826}
12827
12828void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
12829 struct net_device *netdev, u32 cmd)
12830{
12831 struct sk_buff *msg;
12832
58050fce 12833 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
12834 if (!msg)
12835 return;
12836
12837 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
12838 nlmsg_free(msg);
12839 return;
12840 }
12841
68eb5503 12842 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12843 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
12844}
12845
b0d7aa59
JD
12846static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
12847 struct regulatory_request *request)
73d54c9e 12848{
73d54c9e 12849 /* Userspace can always count this one always being set */
9360ffd1
DM
12850 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
12851 goto nla_put_failure;
12852
12853 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
12854 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12855 NL80211_REGDOM_TYPE_WORLD))
12856 goto nla_put_failure;
12857 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
12858 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12859 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
12860 goto nla_put_failure;
12861 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
12862 request->intersect) {
12863 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12864 NL80211_REGDOM_TYPE_INTERSECTION))
12865 goto nla_put_failure;
12866 } else {
12867 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
12868 NL80211_REGDOM_TYPE_COUNTRY) ||
12869 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
12870 request->alpha2))
12871 goto nla_put_failure;
12872 }
12873
ad30ca2c
AN
12874 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
12875 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
12876
12877 if (wiphy &&
12878 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
12879 goto nla_put_failure;
1bdd716c
AN
12880
12881 if (wiphy &&
12882 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
12883 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
12884 goto nla_put_failure;
ad30ca2c 12885 }
73d54c9e 12886
b0d7aa59
JD
12887 return true;
12888
12889nla_put_failure:
12890 return false;
12891}
12892
12893/*
12894 * This can happen on global regulatory changes or device specific settings
12895 * based on custom regulatory domains.
12896 */
12897void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
12898 struct regulatory_request *request)
12899{
12900 struct sk_buff *msg;
12901 void *hdr;
12902
12903 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12904 if (!msg)
12905 return;
12906
12907 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
12908 if (!hdr) {
12909 nlmsg_free(msg);
12910 return;
12911 }
12912
12913 if (nl80211_reg_change_event_fill(msg, request) == false)
12914 goto nla_put_failure;
12915
3b7b72ee 12916 genlmsg_end(msg, hdr);
73d54c9e 12917
bc43b28c 12918 rcu_read_lock();
68eb5503 12919 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 12920 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 12921 rcu_read_unlock();
73d54c9e
LR
12922
12923 return;
12924
12925nla_put_failure:
12926 genlmsg_cancel(msg, hdr);
12927 nlmsg_free(msg);
12928}
12929
6039f6d2
JM
12930static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
12931 struct net_device *netdev,
12932 const u8 *buf, size_t len,
b0b6aa2c
EP
12933 enum nl80211_commands cmd, gfp_t gfp,
12934 int uapsd_queues)
6039f6d2
JM
12935{
12936 struct sk_buff *msg;
12937 void *hdr;
12938
e6d6e342 12939 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
6039f6d2
JM
12940 if (!msg)
12941 return;
12942
12943 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
12944 if (!hdr) {
12945 nlmsg_free(msg);
12946 return;
12947 }
12948
9360ffd1
DM
12949 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12950 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
12951 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
12952 goto nla_put_failure;
6039f6d2 12953
b0b6aa2c
EP
12954 if (uapsd_queues >= 0) {
12955 struct nlattr *nla_wmm =
12956 nla_nest_start(msg, NL80211_ATTR_STA_WME);
12957 if (!nla_wmm)
12958 goto nla_put_failure;
12959
12960 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
12961 uapsd_queues))
12962 goto nla_put_failure;
12963
12964 nla_nest_end(msg, nla_wmm);
12965 }
12966
3b7b72ee 12967 genlmsg_end(msg, hdr);
6039f6d2 12968
68eb5503 12969 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 12970 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
12971 return;
12972
12973 nla_put_failure:
12974 genlmsg_cancel(msg, hdr);
12975 nlmsg_free(msg);
12976}
12977
12978void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12979 struct net_device *netdev, const u8 *buf,
12980 size_t len, gfp_t gfp)
6039f6d2
JM
12981{
12982 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12983 NL80211_CMD_AUTHENTICATE, gfp, -1);
6039f6d2
JM
12984}
12985
12986void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
12987 struct net_device *netdev, const u8 *buf,
b0b6aa2c 12988 size_t len, gfp_t gfp, int uapsd_queues)
6039f6d2 12989{
e6d6e342 12990 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12991 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues);
6039f6d2
JM
12992}
12993
53b46b84 12994void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
12995 struct net_device *netdev, const u8 *buf,
12996 size_t len, gfp_t gfp)
6039f6d2
JM
12997{
12998 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 12999 NL80211_CMD_DEAUTHENTICATE, gfp, -1);
6039f6d2
JM
13000}
13001
53b46b84
JM
13002void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
13003 struct net_device *netdev, const u8 *buf,
e6d6e342 13004 size_t len, gfp_t gfp)
6039f6d2
JM
13005{
13006 nl80211_send_mlme_event(rdev, netdev, buf, len,
b0b6aa2c 13007 NL80211_CMD_DISASSOCIATE, gfp, -1);
6039f6d2
JM
13008}
13009
6ff57cf8
JB
13010void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
13011 size_t len)
cf4e594e 13012{
947add36
JB
13013 struct wireless_dev *wdev = dev->ieee80211_ptr;
13014 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13015 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
13016 const struct ieee80211_mgmt *mgmt = (void *)buf;
13017 u32 cmd;
947add36 13018
6ff57cf8
JB
13019 if (WARN_ON(len < 2))
13020 return;
cf4e594e 13021
6ff57cf8
JB
13022 if (ieee80211_is_deauth(mgmt->frame_control))
13023 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
13024 else
13025 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 13026
6ff57cf8 13027 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
b0b6aa2c 13028 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1);
cf4e594e 13029}
6ff57cf8 13030EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 13031
1b06bb40
LR
13032static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
13033 struct net_device *netdev, int cmd,
e6d6e342 13034 const u8 *addr, gfp_t gfp)
1965c853
JM
13035{
13036 struct sk_buff *msg;
13037 void *hdr;
13038
e6d6e342 13039 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
13040 if (!msg)
13041 return;
13042
13043 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13044 if (!hdr) {
13045 nlmsg_free(msg);
13046 return;
13047 }
13048
9360ffd1
DM
13049 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13050 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13051 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
13052 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
13053 goto nla_put_failure;
1965c853 13054
3b7b72ee 13055 genlmsg_end(msg, hdr);
1965c853 13056
68eb5503 13057 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13058 NL80211_MCGRP_MLME, gfp);
1965c853
JM
13059 return;
13060
13061 nla_put_failure:
13062 genlmsg_cancel(msg, hdr);
13063 nlmsg_free(msg);
13064}
13065
13066void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13067 struct net_device *netdev, const u8 *addr,
13068 gfp_t gfp)
1965c853
JM
13069{
13070 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 13071 addr, gfp);
1965c853
JM
13072}
13073
13074void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
13075 struct net_device *netdev, const u8 *addr,
13076 gfp_t gfp)
1965c853 13077{
e6d6e342
JB
13078 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
13079 addr, gfp);
1965c853
JM
13080}
13081
b23aa676
SO
13082void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
13083 struct net_device *netdev, const u8 *bssid,
13084 const u8 *req_ie, size_t req_ie_len,
13085 const u8 *resp_ie, size_t resp_ie_len,
bf1ecd21 13086 int status, gfp_t gfp)
b23aa676
SO
13087{
13088 struct sk_buff *msg;
13089 void *hdr;
13090
58050fce 13091 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
b23aa676
SO
13092 if (!msg)
13093 return;
13094
13095 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
13096 if (!hdr) {
13097 nlmsg_free(msg);
13098 return;
13099 }
13100
9360ffd1
DM
13101 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13102 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13103 (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) ||
bf1ecd21
JM
13104 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
13105 status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
13106 status) ||
13107 (status < 0 && nla_put_flag(msg, NL80211_ATTR_TIMED_OUT)) ||
9360ffd1
DM
13108 (req_ie &&
13109 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
13110 (resp_ie &&
13111 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
13112 goto nla_put_failure;
b23aa676 13113
3b7b72ee 13114 genlmsg_end(msg, hdr);
b23aa676 13115
68eb5503 13116 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13117 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
13118 return;
13119
13120 nla_put_failure:
13121 genlmsg_cancel(msg, hdr);
13122 nlmsg_free(msg);
b23aa676
SO
13123}
13124
13125void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
13126 struct net_device *netdev, const u8 *bssid,
13127 const u8 *req_ie, size_t req_ie_len,
13128 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
13129{
13130 struct sk_buff *msg;
13131 void *hdr;
13132
58050fce 13133 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
b23aa676
SO
13134 if (!msg)
13135 return;
13136
13137 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
13138 if (!hdr) {
13139 nlmsg_free(msg);
13140 return;
13141 }
13142
9360ffd1
DM
13143 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13144 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13145 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
13146 (req_ie &&
13147 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
13148 (resp_ie &&
13149 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
13150 goto nla_put_failure;
b23aa676 13151
3b7b72ee 13152 genlmsg_end(msg, hdr);
b23aa676 13153
68eb5503 13154 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13155 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
13156 return;
13157
13158 nla_put_failure:
13159 genlmsg_cancel(msg, hdr);
13160 nlmsg_free(msg);
b23aa676
SO
13161}
13162
13163void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
13164 struct net_device *netdev, u16 reason,
667503dd 13165 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
13166{
13167 struct sk_buff *msg;
13168 void *hdr;
13169
58050fce 13170 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
b23aa676
SO
13171 if (!msg)
13172 return;
13173
13174 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
13175 if (!hdr) {
13176 nlmsg_free(msg);
13177 return;
13178 }
13179
9360ffd1
DM
13180 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13181 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13182 (from_ap && reason &&
13183 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
13184 (from_ap &&
13185 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
13186 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
13187 goto nla_put_failure;
b23aa676 13188
3b7b72ee 13189 genlmsg_end(msg, hdr);
b23aa676 13190
68eb5503 13191 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13192 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
13193 return;
13194
13195 nla_put_failure:
13196 genlmsg_cancel(msg, hdr);
13197 nlmsg_free(msg);
b23aa676
SO
13198}
13199
04a773ad
JB
13200void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
13201 struct net_device *netdev, const u8 *bssid,
13202 gfp_t gfp)
13203{
13204 struct sk_buff *msg;
13205 void *hdr;
13206
fd2120ca 13207 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
13208 if (!msg)
13209 return;
13210
13211 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
13212 if (!hdr) {
13213 nlmsg_free(msg);
13214 return;
13215 }
13216
9360ffd1
DM
13217 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13218 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13219 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13220 goto nla_put_failure;
04a773ad 13221
3b7b72ee 13222 genlmsg_end(msg, hdr);
04a773ad 13223
68eb5503 13224 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13225 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
13226 return;
13227
13228 nla_put_failure:
13229 genlmsg_cancel(msg, hdr);
13230 nlmsg_free(msg);
13231}
13232
947add36
JB
13233void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
13234 const u8* ie, u8 ie_len, gfp_t gfp)
c93b5e71 13235{
947add36 13236 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13237 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
13238 struct sk_buff *msg;
13239 void *hdr;
13240
947add36
JB
13241 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
13242 return;
13243
13244 trace_cfg80211_notify_new_peer_candidate(dev, addr);
13245
c93b5e71
JC
13246 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13247 if (!msg)
13248 return;
13249
13250 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
13251 if (!hdr) {
13252 nlmsg_free(msg);
13253 return;
13254 }
13255
9360ffd1 13256 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
13257 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13258 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1
DM
13259 (ie_len && ie &&
13260 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
13261 goto nla_put_failure;
c93b5e71 13262
3b7b72ee 13263 genlmsg_end(msg, hdr);
c93b5e71 13264
68eb5503 13265 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13266 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
13267 return;
13268
13269 nla_put_failure:
13270 genlmsg_cancel(msg, hdr);
13271 nlmsg_free(msg);
13272}
947add36 13273EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 13274
a3b8b056
JM
13275void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
13276 struct net_device *netdev, const u8 *addr,
13277 enum nl80211_key_type key_type, int key_id,
e6d6e342 13278 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
13279{
13280 struct sk_buff *msg;
13281 void *hdr;
13282
e6d6e342 13283 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
13284 if (!msg)
13285 return;
13286
13287 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
13288 if (!hdr) {
13289 nlmsg_free(msg);
13290 return;
13291 }
13292
9360ffd1
DM
13293 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13294 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13295 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
13296 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
13297 (key_id != -1 &&
13298 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
13299 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
13300 goto nla_put_failure;
a3b8b056 13301
3b7b72ee 13302 genlmsg_end(msg, hdr);
a3b8b056 13303
68eb5503 13304 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13305 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
13306 return;
13307
13308 nla_put_failure:
13309 genlmsg_cancel(msg, hdr);
13310 nlmsg_free(msg);
13311}
13312
6bad8766
LR
13313void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
13314 struct ieee80211_channel *channel_before,
13315 struct ieee80211_channel *channel_after)
13316{
13317 struct sk_buff *msg;
13318 void *hdr;
13319 struct nlattr *nl_freq;
13320
fd2120ca 13321 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
13322 if (!msg)
13323 return;
13324
13325 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
13326 if (!hdr) {
13327 nlmsg_free(msg);
13328 return;
13329 }
13330
13331 /*
13332 * Since we are applying the beacon hint to a wiphy we know its
13333 * wiphy_idx is valid
13334 */
9360ffd1
DM
13335 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
13336 goto nla_put_failure;
6bad8766
LR
13337
13338 /* Before */
13339 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
13340 if (!nl_freq)
13341 goto nla_put_failure;
cdc89b97 13342 if (nl80211_msg_put_channel(msg, channel_before, false))
6bad8766
LR
13343 goto nla_put_failure;
13344 nla_nest_end(msg, nl_freq);
13345
13346 /* After */
13347 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
13348 if (!nl_freq)
13349 goto nla_put_failure;
cdc89b97 13350 if (nl80211_msg_put_channel(msg, channel_after, false))
6bad8766
LR
13351 goto nla_put_failure;
13352 nla_nest_end(msg, nl_freq);
13353
3b7b72ee 13354 genlmsg_end(msg, hdr);
6bad8766 13355
463d0183 13356 rcu_read_lock();
68eb5503 13357 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 13358 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 13359 rcu_read_unlock();
6bad8766
LR
13360
13361 return;
13362
13363nla_put_failure:
13364 genlmsg_cancel(msg, hdr);
13365 nlmsg_free(msg);
13366}
13367
9588bbd5
JM
13368static void nl80211_send_remain_on_chan_event(
13369 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 13370 struct wireless_dev *wdev, u64 cookie,
9588bbd5 13371 struct ieee80211_channel *chan,
9588bbd5
JM
13372 unsigned int duration, gfp_t gfp)
13373{
13374 struct sk_buff *msg;
13375 void *hdr;
13376
13377 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13378 if (!msg)
13379 return;
13380
13381 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
13382 if (!hdr) {
13383 nlmsg_free(msg);
13384 return;
13385 }
13386
9360ffd1 13387 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13388 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13389 wdev->netdev->ifindex)) ||
2dad624e
ND
13390 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13391 NL80211_ATTR_PAD) ||
9360ffd1 13392 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
13393 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
13394 NL80211_CHAN_NO_HT) ||
2dad624e
ND
13395 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13396 NL80211_ATTR_PAD))
9360ffd1 13397 goto nla_put_failure;
9588bbd5 13398
9360ffd1
DM
13399 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
13400 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
13401 goto nla_put_failure;
9588bbd5 13402
3b7b72ee 13403 genlmsg_end(msg, hdr);
9588bbd5 13404
68eb5503 13405 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13406 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
13407 return;
13408
13409 nla_put_failure:
13410 genlmsg_cancel(msg, hdr);
13411 nlmsg_free(msg);
13412}
13413
947add36
JB
13414void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
13415 struct ieee80211_channel *chan,
13416 unsigned int duration, gfp_t gfp)
9588bbd5 13417{
947add36 13418 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13419 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13420
13421 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 13422 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 13423 rdev, wdev, cookie, chan,
42d97a59 13424 duration, gfp);
9588bbd5 13425}
947add36 13426EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 13427
947add36
JB
13428void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
13429 struct ieee80211_channel *chan,
13430 gfp_t gfp)
9588bbd5 13431{
947add36 13432 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13433 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13434
13435 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 13436 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 13437 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 13438}
947add36 13439EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 13440
947add36
JB
13441void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
13442 struct station_info *sinfo, gfp_t gfp)
98b62183 13443{
947add36 13444 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13445 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
13446 struct sk_buff *msg;
13447
947add36
JB
13448 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
13449
58050fce 13450 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
13451 if (!msg)
13452 return;
13453
cf5ead82 13454 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 13455 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
13456 nlmsg_free(msg);
13457 return;
13458 }
13459
68eb5503 13460 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13461 NL80211_MCGRP_MLME, gfp);
98b62183 13462}
947add36 13463EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 13464
cf5ead82
JB
13465void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
13466 struct station_info *sinfo, gfp_t gfp)
ec15e68b 13467{
947add36 13468 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13469 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 13470 struct sk_buff *msg;
cf5ead82
JB
13471 struct station_info empty_sinfo = {};
13472
13473 if (!sinfo)
13474 sinfo = &empty_sinfo;
ec15e68b 13475
947add36
JB
13476 trace_cfg80211_del_sta(dev, mac_addr);
13477
58050fce 13478 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
ec15e68b
JM
13479 if (!msg)
13480 return;
13481
cf5ead82 13482 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 13483 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b
JM
13484 nlmsg_free(msg);
13485 return;
13486 }
13487
68eb5503 13488 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13489 NL80211_MCGRP_MLME, gfp);
ec15e68b 13490}
cf5ead82 13491EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 13492
947add36
JB
13493void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
13494 enum nl80211_connect_failed_reason reason,
13495 gfp_t gfp)
ed44a951 13496{
947add36 13497 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 13498 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
13499 struct sk_buff *msg;
13500 void *hdr;
13501
13502 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
13503 if (!msg)
13504 return;
13505
13506 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
13507 if (!hdr) {
13508 nlmsg_free(msg);
13509 return;
13510 }
13511
13512 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13513 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
13514 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
13515 goto nla_put_failure;
13516
13517 genlmsg_end(msg, hdr);
13518
68eb5503 13519 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13520 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
13521 return;
13522
13523 nla_put_failure:
13524 genlmsg_cancel(msg, hdr);
13525 nlmsg_free(msg);
13526}
947add36 13527EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 13528
b92ab5d8
JB
13529static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
13530 const u8 *addr, gfp_t gfp)
28946da7
JB
13531{
13532 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 13533 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
13534 struct sk_buff *msg;
13535 void *hdr;
15e47304 13536 u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid);
28946da7 13537
15e47304 13538 if (!nlportid)
28946da7
JB
13539 return false;
13540
13541 msg = nlmsg_new(100, gfp);
13542 if (!msg)
13543 return true;
13544
b92ab5d8 13545 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
13546 if (!hdr) {
13547 nlmsg_free(msg);
13548 return true;
13549 }
13550
9360ffd1
DM
13551 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13552 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
13553 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
13554 goto nla_put_failure;
28946da7 13555
9c90a9f6 13556 genlmsg_end(msg, hdr);
15e47304 13557 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
13558 return true;
13559
13560 nla_put_failure:
13561 genlmsg_cancel(msg, hdr);
13562 nlmsg_free(msg);
13563 return true;
13564}
13565
947add36
JB
13566bool cfg80211_rx_spurious_frame(struct net_device *dev,
13567 const u8 *addr, gfp_t gfp)
b92ab5d8 13568{
947add36
JB
13569 struct wireless_dev *wdev = dev->ieee80211_ptr;
13570 bool ret;
13571
13572 trace_cfg80211_rx_spurious_frame(dev, addr);
13573
13574 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
13575 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
13576 trace_cfg80211_return_bool(false);
13577 return false;
13578 }
13579 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
13580 addr, gfp);
13581 trace_cfg80211_return_bool(ret);
13582 return ret;
b92ab5d8 13583}
947add36 13584EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 13585
947add36
JB
13586bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
13587 const u8 *addr, gfp_t gfp)
b92ab5d8 13588{
947add36
JB
13589 struct wireless_dev *wdev = dev->ieee80211_ptr;
13590 bool ret;
13591
13592 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
13593
13594 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
13595 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
13596 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
13597 trace_cfg80211_return_bool(false);
13598 return false;
13599 }
13600 ret = __nl80211_unexpected_frame(dev,
13601 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
13602 addr, gfp);
13603 trace_cfg80211_return_bool(ret);
13604 return ret;
b92ab5d8 13605}
947add36 13606EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 13607
2e161f78 13608int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 13609 struct wireless_dev *wdev, u32 nlportid,
804483e9 13610 int freq, int sig_dbm,
19504cf5 13611 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 13612{
71bbc994 13613 struct net_device *netdev = wdev->netdev;
026331c4
JM
13614 struct sk_buff *msg;
13615 void *hdr;
026331c4
JM
13616
13617 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13618 if (!msg)
13619 return -ENOMEM;
13620
2e161f78 13621 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
13622 if (!hdr) {
13623 nlmsg_free(msg);
13624 return -ENOMEM;
13625 }
13626
9360ffd1 13627 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13628 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13629 netdev->ifindex)) ||
2dad624e
ND
13630 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13631 NL80211_ATTR_PAD) ||
9360ffd1
DM
13632 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
13633 (sig_dbm &&
13634 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
13635 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
13636 (flags &&
13637 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 13638 goto nla_put_failure;
026331c4 13639
3b7b72ee 13640 genlmsg_end(msg, hdr);
026331c4 13641
15e47304 13642 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
13643
13644 nla_put_failure:
13645 genlmsg_cancel(msg, hdr);
13646 nlmsg_free(msg);
13647 return -ENOBUFS;
13648}
13649
947add36
JB
13650void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
13651 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 13652{
947add36 13653 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13654 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 13655 struct net_device *netdev = wdev->netdev;
026331c4
JM
13656 struct sk_buff *msg;
13657 void *hdr;
13658
947add36
JB
13659 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
13660
026331c4
JM
13661 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13662 if (!msg)
13663 return;
13664
2e161f78 13665 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
13666 if (!hdr) {
13667 nlmsg_free(msg);
13668 return;
13669 }
13670
9360ffd1 13671 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
13672 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13673 netdev->ifindex)) ||
2dad624e
ND
13674 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13675 NL80211_ATTR_PAD) ||
9360ffd1 13676 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
13677 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13678 NL80211_ATTR_PAD) ||
9360ffd1
DM
13679 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
13680 goto nla_put_failure;
026331c4 13681
3b7b72ee 13682 genlmsg_end(msg, hdr);
026331c4 13683
68eb5503 13684 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13685 NL80211_MCGRP_MLME, gfp);
026331c4
JM
13686 return;
13687
13688 nla_put_failure:
13689 genlmsg_cancel(msg, hdr);
13690 nlmsg_free(msg);
13691}
947add36 13692EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 13693
5b97f49d
JB
13694static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
13695 const char *mac, gfp_t gfp)
d6dc1a38 13696{
947add36 13697 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
13698 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
13699 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13700 void **cb;
947add36 13701
d6dc1a38 13702 if (!msg)
5b97f49d 13703 return NULL;
d6dc1a38 13704
5b97f49d
JB
13705 cb = (void **)msg->cb;
13706
13707 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
13708 if (!cb[0]) {
d6dc1a38 13709 nlmsg_free(msg);
5b97f49d 13710 return NULL;
d6dc1a38
JO
13711 }
13712
9360ffd1 13713 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 13714 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 13715 goto nla_put_failure;
d6dc1a38 13716
5b97f49d 13717 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
13718 goto nla_put_failure;
13719
5b97f49d
JB
13720 cb[1] = nla_nest_start(msg, NL80211_ATTR_CQM);
13721 if (!cb[1])
9360ffd1 13722 goto nla_put_failure;
d6dc1a38 13723
5b97f49d 13724 cb[2] = rdev;
d6dc1a38 13725
5b97f49d
JB
13726 return msg;
13727 nla_put_failure:
13728 nlmsg_free(msg);
13729 return NULL;
13730}
13731
13732static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
13733{
13734 void **cb = (void **)msg->cb;
13735 struct cfg80211_registered_device *rdev = cb[2];
13736
13737 nla_nest_end(msg, cb[1]);
13738 genlmsg_end(msg, cb[0]);
13739
13740 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 13741
68eb5503 13742 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13743 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
13744}
13745
13746void cfg80211_cqm_rssi_notify(struct net_device *dev,
13747 enum nl80211_cqm_rssi_threshold_event rssi_event,
13748 gfp_t gfp)
13749{
13750 struct sk_buff *msg;
13751
13752 trace_cfg80211_cqm_rssi_notify(dev, rssi_event);
13753
98f03342
JB
13754 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
13755 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
13756 return;
13757
5b97f49d
JB
13758 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
13759 if (!msg)
13760 return;
13761
13762 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
13763 rssi_event))
13764 goto nla_put_failure;
13765
13766 cfg80211_send_cqm(msg, gfp);
13767
d6dc1a38
JO
13768 return;
13769
13770 nla_put_failure:
d6dc1a38
JO
13771 nlmsg_free(msg);
13772}
947add36 13773EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 13774
5b97f49d
JB
13775void cfg80211_cqm_txe_notify(struct net_device *dev,
13776 const u8 *peer, u32 num_packets,
13777 u32 rate, u32 intvl, gfp_t gfp)
13778{
13779 struct sk_buff *msg;
13780
13781 msg = cfg80211_prepare_cqm(dev, peer, gfp);
13782 if (!msg)
13783 return;
13784
13785 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
13786 goto nla_put_failure;
13787
13788 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
13789 goto nla_put_failure;
13790
13791 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
13792 goto nla_put_failure;
13793
13794 cfg80211_send_cqm(msg, gfp);
13795 return;
13796
13797 nla_put_failure:
13798 nlmsg_free(msg);
13799}
13800EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
13801
13802void cfg80211_cqm_pktloss_notify(struct net_device *dev,
13803 const u8 *peer, u32 num_packets, gfp_t gfp)
13804{
13805 struct sk_buff *msg;
13806
13807 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
13808
13809 msg = cfg80211_prepare_cqm(dev, peer, gfp);
13810 if (!msg)
13811 return;
13812
13813 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
13814 goto nla_put_failure;
13815
13816 cfg80211_send_cqm(msg, gfp);
13817 return;
13818
13819 nla_put_failure:
13820 nlmsg_free(msg);
13821}
13822EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
13823
98f03342
JB
13824void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
13825{
13826 struct sk_buff *msg;
13827
13828 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
13829 if (!msg)
13830 return;
13831
13832 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
13833 goto nla_put_failure;
13834
13835 cfg80211_send_cqm(msg, gfp);
13836 return;
13837
13838 nla_put_failure:
13839 nlmsg_free(msg);
13840}
13841EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
13842
947add36
JB
13843static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
13844 struct net_device *netdev, const u8 *bssid,
13845 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
13846{
13847 struct sk_buff *msg;
13848 struct nlattr *rekey_attr;
13849 void *hdr;
13850
58050fce 13851 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
13852 if (!msg)
13853 return;
13854
13855 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
13856 if (!hdr) {
13857 nlmsg_free(msg);
13858 return;
13859 }
13860
9360ffd1
DM
13861 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13862 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
13863 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13864 goto nla_put_failure;
e5497d76
JB
13865
13866 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
13867 if (!rekey_attr)
13868 goto nla_put_failure;
13869
9360ffd1
DM
13870 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
13871 NL80211_REPLAY_CTR_LEN, replay_ctr))
13872 goto nla_put_failure;
e5497d76
JB
13873
13874 nla_nest_end(msg, rekey_attr);
13875
3b7b72ee 13876 genlmsg_end(msg, hdr);
e5497d76 13877
68eb5503 13878 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13879 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
13880 return;
13881
13882 nla_put_failure:
13883 genlmsg_cancel(msg, hdr);
13884 nlmsg_free(msg);
13885}
13886
947add36
JB
13887void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
13888 const u8 *replay_ctr, gfp_t gfp)
13889{
13890 struct wireless_dev *wdev = dev->ieee80211_ptr;
13891 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13892 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13893
13894 trace_cfg80211_gtk_rekey_notify(dev, bssid);
13895 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
13896}
13897EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
13898
13899static void
13900nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
13901 struct net_device *netdev, int index,
13902 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
13903{
13904 struct sk_buff *msg;
13905 struct nlattr *attr;
13906 void *hdr;
13907
58050fce 13908 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
13909 if (!msg)
13910 return;
13911
13912 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
13913 if (!hdr) {
13914 nlmsg_free(msg);
13915 return;
13916 }
13917
9360ffd1
DM
13918 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13919 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
13920 goto nla_put_failure;
c9df56b4
JM
13921
13922 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
13923 if (!attr)
13924 goto nla_put_failure;
13925
9360ffd1
DM
13926 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
13927 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
13928 (preauth &&
13929 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
13930 goto nla_put_failure;
c9df56b4
JM
13931
13932 nla_nest_end(msg, attr);
13933
3b7b72ee 13934 genlmsg_end(msg, hdr);
c9df56b4 13935
68eb5503 13936 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13937 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
13938 return;
13939
13940 nla_put_failure:
13941 genlmsg_cancel(msg, hdr);
13942 nlmsg_free(msg);
13943}
13944
947add36
JB
13945void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
13946 const u8 *bssid, bool preauth, gfp_t gfp)
13947{
13948 struct wireless_dev *wdev = dev->ieee80211_ptr;
13949 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 13950 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
13951
13952 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
13953 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
13954}
13955EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
13956
13957static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
13958 struct net_device *netdev,
13959 struct cfg80211_chan_def *chandef,
f8d7552e
LC
13960 gfp_t gfp,
13961 enum nl80211_commands notif,
13962 u8 count)
5314526b
TP
13963{
13964 struct sk_buff *msg;
13965 void *hdr;
13966
58050fce 13967 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
13968 if (!msg)
13969 return;
13970
f8d7552e 13971 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
13972 if (!hdr) {
13973 nlmsg_free(msg);
13974 return;
13975 }
13976
683b6d3b
JB
13977 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
13978 goto nla_put_failure;
13979
13980 if (nl80211_send_chandef(msg, chandef))
7eab0f64 13981 goto nla_put_failure;
5314526b 13982
f8d7552e
LC
13983 if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
13984 (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
13985 goto nla_put_failure;
13986
5314526b
TP
13987 genlmsg_end(msg, hdr);
13988
68eb5503 13989 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 13990 NL80211_MCGRP_MLME, gfp);
5314526b
TP
13991 return;
13992
13993 nla_put_failure:
13994 genlmsg_cancel(msg, hdr);
13995 nlmsg_free(msg);
13996}
13997
947add36
JB
13998void cfg80211_ch_switch_notify(struct net_device *dev,
13999 struct cfg80211_chan_def *chandef)
84f10708 14000{
947add36
JB
14001 struct wireless_dev *wdev = dev->ieee80211_ptr;
14002 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14003 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 14004
e487eaeb 14005 ASSERT_WDEV_LOCK(wdev);
947add36 14006
e487eaeb 14007 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 14008
9e0e2961 14009 wdev->chandef = *chandef;
96f55f12 14010 wdev->preset_chandef = *chandef;
f8d7552e
LC
14011 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
14012 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
947add36
JB
14013}
14014EXPORT_SYMBOL(cfg80211_ch_switch_notify);
14015
f8d7552e
LC
14016void cfg80211_ch_switch_started_notify(struct net_device *dev,
14017 struct cfg80211_chan_def *chandef,
14018 u8 count)
14019{
14020 struct wireless_dev *wdev = dev->ieee80211_ptr;
14021 struct wiphy *wiphy = wdev->wiphy;
14022 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14023
14024 trace_cfg80211_ch_switch_started_notify(dev, chandef);
14025
14026 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
14027 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
14028}
14029EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
14030
04f39047
SW
14031void
14032nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 14033 const struct cfg80211_chan_def *chandef,
04f39047
SW
14034 enum nl80211_radar_event event,
14035 struct net_device *netdev, gfp_t gfp)
14036{
14037 struct sk_buff *msg;
14038 void *hdr;
14039
14040 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14041 if (!msg)
14042 return;
14043
14044 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
14045 if (!hdr) {
14046 nlmsg_free(msg);
14047 return;
14048 }
14049
14050 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
14051 goto nla_put_failure;
14052
14053 /* NOP and radar events don't need a netdev parameter */
14054 if (netdev) {
14055 struct wireless_dev *wdev = netdev->ieee80211_ptr;
14056
14057 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
14058 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14059 NL80211_ATTR_PAD))
04f39047
SW
14060 goto nla_put_failure;
14061 }
14062
14063 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
14064 goto nla_put_failure;
14065
14066 if (nl80211_send_chandef(msg, chandef))
14067 goto nla_put_failure;
14068
9c90a9f6 14069 genlmsg_end(msg, hdr);
04f39047 14070
68eb5503 14071 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14072 NL80211_MCGRP_MLME, gfp);
04f39047
SW
14073 return;
14074
14075 nla_put_failure:
14076 genlmsg_cancel(msg, hdr);
14077 nlmsg_free(msg);
14078}
14079
7f6cf311
JB
14080void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
14081 u64 cookie, bool acked, gfp_t gfp)
14082{
14083 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14084 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
14085 struct sk_buff *msg;
14086 void *hdr;
7f6cf311 14087
4ee3e063
BL
14088 trace_cfg80211_probe_status(dev, addr, cookie, acked);
14089
58050fce 14090 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 14091
7f6cf311
JB
14092 if (!msg)
14093 return;
14094
14095 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
14096 if (!hdr) {
14097 nlmsg_free(msg);
14098 return;
14099 }
14100
9360ffd1
DM
14101 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14102 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14103 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
14104 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14105 NL80211_ATTR_PAD) ||
9360ffd1
DM
14106 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
14107 goto nla_put_failure;
7f6cf311 14108
9c90a9f6 14109 genlmsg_end(msg, hdr);
7f6cf311 14110
68eb5503 14111 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14112 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
14113 return;
14114
14115 nla_put_failure:
14116 genlmsg_cancel(msg, hdr);
14117 nlmsg_free(msg);
14118}
14119EXPORT_SYMBOL(cfg80211_probe_status);
14120
5e760230
JB
14121void cfg80211_report_obss_beacon(struct wiphy *wiphy,
14122 const u8 *frame, size_t len,
37c73b5f 14123 int freq, int sig_dbm)
5e760230 14124{
f26cbf40 14125 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
14126 struct sk_buff *msg;
14127 void *hdr;
37c73b5f 14128 struct cfg80211_beacon_registration *reg;
5e760230 14129
4ee3e063
BL
14130 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
14131
37c73b5f
BG
14132 spin_lock_bh(&rdev->beacon_registrations_lock);
14133 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
14134 msg = nlmsg_new(len + 100, GFP_ATOMIC);
14135 if (!msg) {
14136 spin_unlock_bh(&rdev->beacon_registrations_lock);
14137 return;
14138 }
5e760230 14139
37c73b5f
BG
14140 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
14141 if (!hdr)
14142 goto nla_put_failure;
5e760230 14143
37c73b5f
BG
14144 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14145 (freq &&
14146 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
14147 (sig_dbm &&
14148 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
14149 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
14150 goto nla_put_failure;
5e760230 14151
37c73b5f 14152 genlmsg_end(msg, hdr);
5e760230 14153
37c73b5f
BG
14154 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
14155 }
14156 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
14157 return;
14158
14159 nla_put_failure:
37c73b5f
BG
14160 spin_unlock_bh(&rdev->beacon_registrations_lock);
14161 if (hdr)
14162 genlmsg_cancel(msg, hdr);
5e760230
JB
14163 nlmsg_free(msg);
14164}
14165EXPORT_SYMBOL(cfg80211_report_obss_beacon);
14166
cd8f7cb4 14167#ifdef CONFIG_PM
8cd4d456
LC
14168static int cfg80211_net_detect_results(struct sk_buff *msg,
14169 struct cfg80211_wowlan_wakeup *wakeup)
14170{
14171 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
14172 struct nlattr *nl_results, *nl_match, *nl_freqs;
14173 int i, j;
14174
14175 nl_results = nla_nest_start(
14176 msg, NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
14177 if (!nl_results)
14178 return -EMSGSIZE;
14179
14180 for (i = 0; i < nd->n_matches; i++) {
14181 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
14182
14183 nl_match = nla_nest_start(msg, i);
14184 if (!nl_match)
14185 break;
14186
14187 /* The SSID attribute is optional in nl80211, but for
14188 * simplicity reasons it's always present in the
14189 * cfg80211 structure. If a driver can't pass the
14190 * SSID, that needs to be changed. A zero length SSID
14191 * is still a valid SSID (wildcard), so it cannot be
14192 * used for this purpose.
14193 */
14194 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
14195 match->ssid.ssid)) {
14196 nla_nest_cancel(msg, nl_match);
14197 goto out;
14198 }
14199
14200 if (match->n_channels) {
14201 nl_freqs = nla_nest_start(
14202 msg, NL80211_ATTR_SCAN_FREQUENCIES);
14203 if (!nl_freqs) {
14204 nla_nest_cancel(msg, nl_match);
14205 goto out;
14206 }
14207
14208 for (j = 0; j < match->n_channels; j++) {
5528fae8 14209 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
14210 nla_nest_cancel(msg, nl_freqs);
14211 nla_nest_cancel(msg, nl_match);
14212 goto out;
14213 }
14214 }
14215
14216 nla_nest_end(msg, nl_freqs);
14217 }
14218
14219 nla_nest_end(msg, nl_match);
14220 }
14221
14222out:
14223 nla_nest_end(msg, nl_results);
14224 return 0;
14225}
14226
cd8f7cb4
JB
14227void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
14228 struct cfg80211_wowlan_wakeup *wakeup,
14229 gfp_t gfp)
14230{
f26cbf40 14231 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
14232 struct sk_buff *msg;
14233 void *hdr;
9c90a9f6 14234 int size = 200;
cd8f7cb4
JB
14235
14236 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
14237
14238 if (wakeup)
14239 size += wakeup->packet_present_len;
14240
14241 msg = nlmsg_new(size, gfp);
14242 if (!msg)
14243 return;
14244
14245 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
14246 if (!hdr)
14247 goto free_msg;
14248
14249 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
14250 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14251 NL80211_ATTR_PAD))
cd8f7cb4
JB
14252 goto free_msg;
14253
14254 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14255 wdev->netdev->ifindex))
14256 goto free_msg;
14257
14258 if (wakeup) {
14259 struct nlattr *reasons;
14260
14261 reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
14262 if (!reasons)
14263 goto free_msg;
cd8f7cb4
JB
14264
14265 if (wakeup->disconnect &&
14266 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
14267 goto free_msg;
14268 if (wakeup->magic_pkt &&
14269 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
14270 goto free_msg;
14271 if (wakeup->gtk_rekey_failure &&
14272 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
14273 goto free_msg;
14274 if (wakeup->eap_identity_req &&
14275 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
14276 goto free_msg;
14277 if (wakeup->four_way_handshake &&
14278 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
14279 goto free_msg;
14280 if (wakeup->rfkill_release &&
14281 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
14282 goto free_msg;
14283
14284 if (wakeup->pattern_idx >= 0 &&
14285 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
14286 wakeup->pattern_idx))
14287 goto free_msg;
14288
ae917c9f
JB
14289 if (wakeup->tcp_match &&
14290 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
14291 goto free_msg;
2a0e047e 14292
ae917c9f
JB
14293 if (wakeup->tcp_connlost &&
14294 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
14295 goto free_msg;
2a0e047e 14296
ae917c9f
JB
14297 if (wakeup->tcp_nomoretokens &&
14298 nla_put_flag(msg,
14299 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
14300 goto free_msg;
2a0e047e 14301
cd8f7cb4
JB
14302 if (wakeup->packet) {
14303 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
14304 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
14305
14306 if (!wakeup->packet_80211) {
14307 pkt_attr =
14308 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
14309 len_attr =
14310 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
14311 }
14312
14313 if (wakeup->packet_len &&
14314 nla_put_u32(msg, len_attr, wakeup->packet_len))
14315 goto free_msg;
14316
14317 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
14318 wakeup->packet))
14319 goto free_msg;
14320 }
14321
8cd4d456
LC
14322 if (wakeup->net_detect &&
14323 cfg80211_net_detect_results(msg, wakeup))
14324 goto free_msg;
14325
cd8f7cb4
JB
14326 nla_nest_end(msg, reasons);
14327 }
14328
9c90a9f6 14329 genlmsg_end(msg, hdr);
cd8f7cb4 14330
68eb5503 14331 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14332 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
14333 return;
14334
14335 free_msg:
14336 nlmsg_free(msg);
14337}
14338EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
14339#endif
14340
3475b094
JM
14341void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
14342 enum nl80211_tdls_operation oper,
14343 u16 reason_code, gfp_t gfp)
14344{
14345 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 14346 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
14347 struct sk_buff *msg;
14348 void *hdr;
3475b094
JM
14349
14350 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
14351 reason_code);
14352
14353 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14354 if (!msg)
14355 return;
14356
14357 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
14358 if (!hdr) {
14359 nlmsg_free(msg);
14360 return;
14361 }
14362
14363 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14364 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
14365 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
14366 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
14367 (reason_code > 0 &&
14368 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
14369 goto nla_put_failure;
14370
9c90a9f6 14371 genlmsg_end(msg, hdr);
3475b094 14372
68eb5503 14373 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14374 NL80211_MCGRP_MLME, gfp);
3475b094
JM
14375 return;
14376
14377 nla_put_failure:
14378 genlmsg_cancel(msg, hdr);
14379 nlmsg_free(msg);
14380}
14381EXPORT_SYMBOL(cfg80211_tdls_oper_request);
14382
026331c4
JM
14383static int nl80211_netlink_notify(struct notifier_block * nb,
14384 unsigned long state,
14385 void *_notify)
14386{
14387 struct netlink_notify *notify = _notify;
14388 struct cfg80211_registered_device *rdev;
14389 struct wireless_dev *wdev;
37c73b5f 14390 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 14391
8f815cdd 14392 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
14393 return NOTIFY_DONE;
14394
14395 rcu_read_lock();
14396
5e760230 14397 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
78f22b6a 14398 bool schedule_destroy_work = false;
93a1e86c
JR
14399 bool schedule_scan_stop = false;
14400 struct cfg80211_sched_scan_request *sched_scan_req =
14401 rcu_dereference(rdev->sched_scan_req);
14402
14403 if (sched_scan_req && notify->portid &&
14404 sched_scan_req->owner_nlportid == notify->portid)
14405 schedule_scan_stop = true;
78f22b6a 14406
53873f13 14407 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 14408 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 14409
78f22b6a
JB
14410 if (wdev->owner_nlportid == notify->portid)
14411 schedule_destroy_work = true;
14412 }
14413
37c73b5f
BG
14414 spin_lock_bh(&rdev->beacon_registrations_lock);
14415 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
14416 list) {
14417 if (reg->nlportid == notify->portid) {
14418 list_del(&reg->list);
14419 kfree(reg);
14420 break;
14421 }
14422 }
14423 spin_unlock_bh(&rdev->beacon_registrations_lock);
78f22b6a
JB
14424
14425 if (schedule_destroy_work) {
14426 struct cfg80211_iface_destroy *destroy;
14427
14428 destroy = kzalloc(sizeof(*destroy), GFP_ATOMIC);
14429 if (destroy) {
14430 destroy->nlportid = notify->portid;
14431 spin_lock(&rdev->destroy_list_lock);
14432 list_add(&destroy->list, &rdev->destroy_list);
14433 spin_unlock(&rdev->destroy_list_lock);
14434 schedule_work(&rdev->destroy_work);
14435 }
93a1e86c
JR
14436 } else if (schedule_scan_stop) {
14437 sched_scan_req->owner_nlportid = 0;
14438
14439 if (rdev->ops->sched_scan_stop &&
14440 rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
14441 schedule_work(&rdev->sched_scan_stop_wk);
78f22b6a 14442 }
5e760230 14443 }
026331c4
JM
14444
14445 rcu_read_unlock();
14446
05050753
I
14447 /*
14448 * It is possible that the user space process that is controlling the
14449 * indoor setting disappeared, so notify the regulatory core.
14450 */
14451 regulatory_netlink_notify(notify->portid);
6784c7db 14452 return NOTIFY_OK;
026331c4
JM
14453}
14454
14455static struct notifier_block nl80211_netlink_notifier = {
14456 .notifier_call = nl80211_netlink_notify,
14457};
14458
355199e0
JM
14459void cfg80211_ft_event(struct net_device *netdev,
14460 struct cfg80211_ft_event_params *ft_event)
14461{
14462 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 14463 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
14464 struct sk_buff *msg;
14465 void *hdr;
355199e0
JM
14466
14467 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
14468
14469 if (!ft_event->target_ap)
14470 return;
14471
14472 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14473 if (!msg)
14474 return;
14475
14476 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
14477 if (!hdr)
14478 goto out;
355199e0 14479
ae917c9f
JB
14480 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14481 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14482 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
14483 goto out;
355199e0 14484
ae917c9f
JB
14485 if (ft_event->ies &&
14486 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
14487 goto out;
14488 if (ft_event->ric_ies &&
14489 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
14490 ft_event->ric_ies))
14491 goto out;
355199e0 14492
9c90a9f6 14493 genlmsg_end(msg, hdr);
355199e0 14494
68eb5503 14495 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14496 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
14497 return;
14498 out:
14499 nlmsg_free(msg);
355199e0
JM
14500}
14501EXPORT_SYMBOL(cfg80211_ft_event);
14502
5de17984
AS
14503void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
14504{
14505 struct cfg80211_registered_device *rdev;
14506 struct sk_buff *msg;
14507 void *hdr;
14508 u32 nlportid;
14509
f26cbf40 14510 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
14511 if (!rdev->crit_proto_nlportid)
14512 return;
14513
14514 nlportid = rdev->crit_proto_nlportid;
14515 rdev->crit_proto_nlportid = 0;
14516
14517 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14518 if (!msg)
14519 return;
14520
14521 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
14522 if (!hdr)
14523 goto nla_put_failure;
14524
14525 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
14526 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14527 NL80211_ATTR_PAD))
5de17984
AS
14528 goto nla_put_failure;
14529
14530 genlmsg_end(msg, hdr);
14531
14532 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
14533 return;
14534
14535 nla_put_failure:
14536 if (hdr)
14537 genlmsg_cancel(msg, hdr);
14538 nlmsg_free(msg);
5de17984
AS
14539}
14540EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
14541
348baf0e
JB
14542void nl80211_send_ap_stopped(struct wireless_dev *wdev)
14543{
14544 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14545 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
14546 struct sk_buff *msg;
14547 void *hdr;
14548
14549 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14550 if (!msg)
14551 return;
14552
14553 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
14554 if (!hdr)
14555 goto out;
14556
14557 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14558 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
14559 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14560 NL80211_ATTR_PAD))
348baf0e
JB
14561 goto out;
14562
14563 genlmsg_end(msg, hdr);
14564
14565 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
14566 NL80211_MCGRP_MLME, GFP_KERNEL);
14567 return;
14568 out:
14569 nlmsg_free(msg);
14570}
14571
55682965
JB
14572/* initialisation/exit functions */
14573
14574int nl80211_init(void)
14575{
0d63cbb5 14576 int err;
55682965 14577
2a94fe48
JB
14578 err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops,
14579 nl80211_mcgrps);
55682965
JB
14580 if (err)
14581 return err;
14582
026331c4
JM
14583 err = netlink_register_notifier(&nl80211_netlink_notifier);
14584 if (err)
14585 goto err_out;
14586
55682965
JB
14587 return 0;
14588 err_out:
14589 genl_unregister_family(&nl80211_fam);
14590 return err;
14591}
14592
14593void nl80211_exit(void)
14594{
026331c4 14595 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
14596 genl_unregister_family(&nl80211_fam);
14597}