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