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