xref: /openbmc/linux/net/wireless/nl80211.c (revision 732a675a)
1 /*
2  * This is the new netlink-based wireless configuration interface.
3  *
4  * Copyright 2006, 2007	Johannes Berg <johannes@sipsolutions.net>
5  */
6 
7 #include <linux/if.h>
8 #include <linux/module.h>
9 #include <linux/err.h>
10 #include <linux/mutex.h>
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>
17 #include <net/genetlink.h>
18 #include <net/cfg80211.h>
19 #include "core.h"
20 #include "nl80211.h"
21 
22 /* the netlink family */
23 static struct genl_family nl80211_fam = {
24 	.id = GENL_ID_GENERATE,	/* don't bother with a hardcoded ID */
25 	.name = "nl80211",	/* have users key off the name instead */
26 	.hdrsize = 0,		/* no private header */
27 	.version = 1,		/* no particular meaning now */
28 	.maxattr = NL80211_ATTR_MAX,
29 };
30 
31 /* internal helper: get drv and dev */
32 static int get_drv_dev_by_info_ifindex(struct genl_info *info,
33 				       struct cfg80211_registered_device **drv,
34 				       struct net_device **dev)
35 {
36 	int ifindex;
37 
38 	if (!info->attrs[NL80211_ATTR_IFINDEX])
39 		return -EINVAL;
40 
41 	ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
42 	*dev = dev_get_by_index(&init_net, ifindex);
43 	if (!*dev)
44 		return -ENODEV;
45 
46 	*drv = cfg80211_get_dev_from_ifindex(ifindex);
47 	if (IS_ERR(*drv)) {
48 		dev_put(*dev);
49 		return PTR_ERR(*drv);
50 	}
51 
52 	return 0;
53 }
54 
55 /* policy for the attributes */
56 static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
57 	[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
58 	[NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
59 				      .len = BUS_ID_SIZE-1 },
60 
61 	[NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
62 	[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
63 	[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
64 
65 	[NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
66 
67 	[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
68 				    .len = WLAN_MAX_KEY_LEN },
69 	[NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
70 	[NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
71 	[NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
72 
73 	[NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
74 	[NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
75 	[NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
76 				       .len = IEEE80211_MAX_DATA_LEN },
77 	[NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
78 				       .len = IEEE80211_MAX_DATA_LEN },
79 	[NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
80 	[NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
81 	[NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
82 	[NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
83 					       .len = NL80211_MAX_SUPP_RATES },
84 	[NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
85 	[NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
86 	[NL80211_ATTR_MNTR_FLAGS] = { .type = NLA_NESTED },
87 	[NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
88 				.len = IEEE80211_MAX_MESH_ID_LEN },
89 	[NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
90 };
91 
92 /* message building helper */
93 static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
94 				   int flags, u8 cmd)
95 {
96 	/* since there is no private header just add the generic one */
97 	return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
98 }
99 
100 /* netlink command implementations */
101 
102 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
103 			      struct cfg80211_registered_device *dev)
104 {
105 	void *hdr;
106 	struct nlattr *nl_bands, *nl_band;
107 	struct nlattr *nl_freqs, *nl_freq;
108 	struct nlattr *nl_rates, *nl_rate;
109 	enum ieee80211_band band;
110 	struct ieee80211_channel *chan;
111 	struct ieee80211_rate *rate;
112 	int i;
113 
114 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
115 	if (!hdr)
116 		return -1;
117 
118 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
119 	NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
120 
121 	nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
122 	if (!nl_bands)
123 		goto nla_put_failure;
124 
125 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
126 		if (!dev->wiphy.bands[band])
127 			continue;
128 
129 		nl_band = nla_nest_start(msg, band);
130 		if (!nl_band)
131 			goto nla_put_failure;
132 
133 		/* add frequencies */
134 		nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
135 		if (!nl_freqs)
136 			goto nla_put_failure;
137 
138 		for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
139 			nl_freq = nla_nest_start(msg, i);
140 			if (!nl_freq)
141 				goto nla_put_failure;
142 
143 			chan = &dev->wiphy.bands[band]->channels[i];
144 			NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
145 				    chan->center_freq);
146 
147 			if (chan->flags & IEEE80211_CHAN_DISABLED)
148 				NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
149 			if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
150 				NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
151 			if (chan->flags & IEEE80211_CHAN_NO_IBSS)
152 				NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
153 			if (chan->flags & IEEE80211_CHAN_RADAR)
154 				NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
155 
156 			nla_nest_end(msg, nl_freq);
157 		}
158 
159 		nla_nest_end(msg, nl_freqs);
160 
161 		/* add bitrates */
162 		nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
163 		if (!nl_rates)
164 			goto nla_put_failure;
165 
166 		for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
167 			nl_rate = nla_nest_start(msg, i);
168 			if (!nl_rate)
169 				goto nla_put_failure;
170 
171 			rate = &dev->wiphy.bands[band]->bitrates[i];
172 			NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
173 				    rate->bitrate);
174 			if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
175 				NLA_PUT_FLAG(msg,
176 					NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
177 
178 			nla_nest_end(msg, nl_rate);
179 		}
180 
181 		nla_nest_end(msg, nl_rates);
182 
183 		nla_nest_end(msg, nl_band);
184 	}
185 	nla_nest_end(msg, nl_bands);
186 
187 	return genlmsg_end(msg, hdr);
188 
189  nla_put_failure:
190 	genlmsg_cancel(msg, hdr);
191 	return -EMSGSIZE;
192 }
193 
194 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
195 {
196 	int idx = 0;
197 	int start = cb->args[0];
198 	struct cfg80211_registered_device *dev;
199 
200 	mutex_lock(&cfg80211_drv_mutex);
201 	list_for_each_entry(dev, &cfg80211_drv_list, list) {
202 		if (++idx < start)
203 			continue;
204 		if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
205 				       cb->nlh->nlmsg_seq, NLM_F_MULTI,
206 				       dev) < 0)
207 			break;
208 	}
209 	mutex_unlock(&cfg80211_drv_mutex);
210 
211 	cb->args[0] = idx;
212 
213 	return skb->len;
214 }
215 
216 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
217 {
218 	struct sk_buff *msg;
219 	struct cfg80211_registered_device *dev;
220 
221 	dev = cfg80211_get_dev_from_info(info);
222 	if (IS_ERR(dev))
223 		return PTR_ERR(dev);
224 
225 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
226 	if (!msg)
227 		goto out_err;
228 
229 	if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
230 		goto out_free;
231 
232 	cfg80211_put_dev(dev);
233 
234 	return genlmsg_unicast(msg, info->snd_pid);
235 
236  out_free:
237 	nlmsg_free(msg);
238  out_err:
239 	cfg80211_put_dev(dev);
240 	return -ENOBUFS;
241 }
242 
243 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
244 {
245 	struct cfg80211_registered_device *rdev;
246 	int result;
247 
248 	if (!info->attrs[NL80211_ATTR_WIPHY_NAME])
249 		return -EINVAL;
250 
251 	rdev = cfg80211_get_dev_from_info(info);
252 	if (IS_ERR(rdev))
253 		return PTR_ERR(rdev);
254 
255 	result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
256 
257 	cfg80211_put_dev(rdev);
258 	return result;
259 }
260 
261 
262 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
263 			      struct net_device *dev)
264 {
265 	void *hdr;
266 
267 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
268 	if (!hdr)
269 		return -1;
270 
271 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
272 	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
273 	/* TODO: interface type */
274 	return genlmsg_end(msg, hdr);
275 
276  nla_put_failure:
277 	genlmsg_cancel(msg, hdr);
278 	return -EMSGSIZE;
279 }
280 
281 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
282 {
283 	int wp_idx = 0;
284 	int if_idx = 0;
285 	int wp_start = cb->args[0];
286 	int if_start = cb->args[1];
287 	struct cfg80211_registered_device *dev;
288 	struct wireless_dev *wdev;
289 
290 	mutex_lock(&cfg80211_drv_mutex);
291 	list_for_each_entry(dev, &cfg80211_drv_list, list) {
292 		if (++wp_idx < wp_start)
293 			continue;
294 		if_idx = 0;
295 
296 		mutex_lock(&dev->devlist_mtx);
297 		list_for_each_entry(wdev, &dev->netdev_list, list) {
298 			if (++if_idx < if_start)
299 				continue;
300 			if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
301 					       cb->nlh->nlmsg_seq, NLM_F_MULTI,
302 					       wdev->netdev) < 0)
303 				break;
304 		}
305 		mutex_unlock(&dev->devlist_mtx);
306 	}
307 	mutex_unlock(&cfg80211_drv_mutex);
308 
309 	cb->args[0] = wp_idx;
310 	cb->args[1] = if_idx;
311 
312 	return skb->len;
313 }
314 
315 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
316 {
317 	struct sk_buff *msg;
318 	struct cfg80211_registered_device *dev;
319 	struct net_device *netdev;
320 	int err;
321 
322 	err = get_drv_dev_by_info_ifindex(info, &dev, &netdev);
323 	if (err)
324 		return err;
325 
326 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
327 	if (!msg)
328 		goto out_err;
329 
330 	if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0)
331 		goto out_free;
332 
333 	dev_put(netdev);
334 	cfg80211_put_dev(dev);
335 
336 	return genlmsg_unicast(msg, info->snd_pid);
337 
338  out_free:
339 	nlmsg_free(msg);
340  out_err:
341 	dev_put(netdev);
342 	cfg80211_put_dev(dev);
343 	return -ENOBUFS;
344 }
345 
346 static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
347 	[NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
348 	[NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
349 	[NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
350 	[NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
351 	[NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
352 };
353 
354 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
355 {
356 	struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
357 	int flag;
358 
359 	*mntrflags = 0;
360 
361 	if (!nla)
362 		return -EINVAL;
363 
364 	if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
365 			     nla, mntr_flags_policy))
366 		return -EINVAL;
367 
368 	for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
369 		if (flags[flag])
370 			*mntrflags |= (1<<flag);
371 
372 	return 0;
373 }
374 
375 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
376 {
377 	struct cfg80211_registered_device *drv;
378 	struct vif_params params;
379 	int err, ifindex;
380 	enum nl80211_iftype type;
381 	struct net_device *dev;
382 	u32 flags;
383 
384 	memset(&params, 0, sizeof(params));
385 
386 	if (info->attrs[NL80211_ATTR_IFTYPE]) {
387 		type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
388 		if (type > NL80211_IFTYPE_MAX)
389 			return -EINVAL;
390 	} else
391 		return -EINVAL;
392 
393 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
394 	if (err)
395 		return err;
396 	ifindex = dev->ifindex;
397 	dev_put(dev);
398 
399 	if (!drv->ops->change_virtual_intf) {
400 		err = -EOPNOTSUPP;
401 		goto unlock;
402 	}
403 
404 	if (type == NL80211_IFTYPE_MESH_POINT &&
405 	    info->attrs[NL80211_ATTR_MESH_ID]) {
406 		params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
407 		params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
408 	}
409 
410 	rtnl_lock();
411 	err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
412 				  info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
413 				  &flags);
414 	err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
415 					    type, err ? NULL : &flags, &params);
416 	rtnl_unlock();
417 
418  unlock:
419 	cfg80211_put_dev(drv);
420 	return err;
421 }
422 
423 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
424 {
425 	struct cfg80211_registered_device *drv;
426 	struct vif_params params;
427 	int err;
428 	enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
429 	u32 flags;
430 
431 	memset(&params, 0, sizeof(params));
432 
433 	if (!info->attrs[NL80211_ATTR_IFNAME])
434 		return -EINVAL;
435 
436 	if (info->attrs[NL80211_ATTR_IFTYPE]) {
437 		type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
438 		if (type > NL80211_IFTYPE_MAX)
439 			return -EINVAL;
440 	}
441 
442 	drv = cfg80211_get_dev_from_info(info);
443 	if (IS_ERR(drv))
444 		return PTR_ERR(drv);
445 
446 	if (!drv->ops->add_virtual_intf) {
447 		err = -EOPNOTSUPP;
448 		goto unlock;
449 	}
450 
451 	if (type == NL80211_IFTYPE_MESH_POINT &&
452 	    info->attrs[NL80211_ATTR_MESH_ID]) {
453 		params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
454 		params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
455 	}
456 
457 	rtnl_lock();
458 	err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
459 				  info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
460 				  &flags);
461 	err = drv->ops->add_virtual_intf(&drv->wiphy,
462 		nla_data(info->attrs[NL80211_ATTR_IFNAME]),
463 		type, err ? NULL : &flags, &params);
464 	rtnl_unlock();
465 
466 
467  unlock:
468 	cfg80211_put_dev(drv);
469 	return err;
470 }
471 
472 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
473 {
474 	struct cfg80211_registered_device *drv;
475 	int ifindex, err;
476 	struct net_device *dev;
477 
478 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
479 	if (err)
480 		return err;
481 	ifindex = dev->ifindex;
482 	dev_put(dev);
483 
484 	if (!drv->ops->del_virtual_intf) {
485 		err = -EOPNOTSUPP;
486 		goto out;
487 	}
488 
489 	rtnl_lock();
490 	err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
491 	rtnl_unlock();
492 
493  out:
494 	cfg80211_put_dev(drv);
495 	return err;
496 }
497 
498 struct get_key_cookie {
499 	struct sk_buff *msg;
500 	int error;
501 };
502 
503 static void get_key_callback(void *c, struct key_params *params)
504 {
505 	struct get_key_cookie *cookie = c;
506 
507 	if (params->key)
508 		NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
509 			params->key_len, params->key);
510 
511 	if (params->seq)
512 		NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
513 			params->seq_len, params->seq);
514 
515 	if (params->cipher)
516 		NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
517 			    params->cipher);
518 
519 	return;
520  nla_put_failure:
521 	cookie->error = 1;
522 }
523 
524 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
525 {
526 	struct cfg80211_registered_device *drv;
527 	int err;
528 	struct net_device *dev;
529 	u8 key_idx = 0;
530 	u8 *mac_addr = NULL;
531 	struct get_key_cookie cookie = {
532 		.error = 0,
533 	};
534 	void *hdr;
535 	struct sk_buff *msg;
536 
537 	if (info->attrs[NL80211_ATTR_KEY_IDX])
538 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
539 
540 	if (key_idx > 3)
541 		return -EINVAL;
542 
543 	if (info->attrs[NL80211_ATTR_MAC])
544 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
545 
546 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
547 	if (err)
548 		return err;
549 
550 	if (!drv->ops->get_key) {
551 		err = -EOPNOTSUPP;
552 		goto out;
553 	}
554 
555 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
556 	if (!msg) {
557 		err = -ENOMEM;
558 		goto out;
559 	}
560 
561 	hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
562 			     NL80211_CMD_NEW_KEY);
563 
564 	if (IS_ERR(hdr)) {
565 		err = PTR_ERR(hdr);
566 		goto out;
567 	}
568 
569 	cookie.msg = msg;
570 
571 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
572 	NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
573 	if (mac_addr)
574 		NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
575 
576 	rtnl_lock();
577 	err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
578 				&cookie, get_key_callback);
579 	rtnl_unlock();
580 
581 	if (err)
582 		goto out;
583 
584 	if (cookie.error)
585 		goto nla_put_failure;
586 
587 	genlmsg_end(msg, hdr);
588 	err = genlmsg_unicast(msg, info->snd_pid);
589 	goto out;
590 
591  nla_put_failure:
592 	err = -ENOBUFS;
593 	nlmsg_free(msg);
594  out:
595 	cfg80211_put_dev(drv);
596 	dev_put(dev);
597 	return err;
598 }
599 
600 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
601 {
602 	struct cfg80211_registered_device *drv;
603 	int err;
604 	struct net_device *dev;
605 	u8 key_idx;
606 
607 	if (!info->attrs[NL80211_ATTR_KEY_IDX])
608 		return -EINVAL;
609 
610 	key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
611 
612 	if (key_idx > 3)
613 		return -EINVAL;
614 
615 	/* currently only support setting default key */
616 	if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
617 		return -EINVAL;
618 
619 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
620 	if (err)
621 		return err;
622 
623 	if (!drv->ops->set_default_key) {
624 		err = -EOPNOTSUPP;
625 		goto out;
626 	}
627 
628 	rtnl_lock();
629 	err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
630 	rtnl_unlock();
631 
632  out:
633 	cfg80211_put_dev(drv);
634 	dev_put(dev);
635 	return err;
636 }
637 
638 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
639 {
640 	struct cfg80211_registered_device *drv;
641 	int err;
642 	struct net_device *dev;
643 	struct key_params params;
644 	u8 key_idx = 0;
645 	u8 *mac_addr = NULL;
646 
647 	memset(&params, 0, sizeof(params));
648 
649 	if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
650 		return -EINVAL;
651 
652 	if (info->attrs[NL80211_ATTR_KEY_DATA]) {
653 		params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
654 		params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
655 	}
656 
657 	if (info->attrs[NL80211_ATTR_KEY_IDX])
658 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
659 
660 	params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
661 
662 	if (info->attrs[NL80211_ATTR_MAC])
663 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
664 
665 	if (key_idx > 3)
666 		return -EINVAL;
667 
668 	/*
669 	 * Disallow pairwise keys with non-zero index unless it's WEP
670 	 * (because current deployments use pairwise WEP keys with
671 	 * non-zero indizes but 802.11i clearly specifies to use zero)
672 	 */
673 	if (mac_addr && key_idx &&
674 	    params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
675 	    params.cipher != WLAN_CIPHER_SUITE_WEP104)
676 		return -EINVAL;
677 
678 	/* TODO: add definitions for the lengths to linux/ieee80211.h */
679 	switch (params.cipher) {
680 	case WLAN_CIPHER_SUITE_WEP40:
681 		if (params.key_len != 5)
682 			return -EINVAL;
683 		break;
684 	case WLAN_CIPHER_SUITE_TKIP:
685 		if (params.key_len != 32)
686 			return -EINVAL;
687 		break;
688 	case WLAN_CIPHER_SUITE_CCMP:
689 		if (params.key_len != 16)
690 			return -EINVAL;
691 		break;
692 	case WLAN_CIPHER_SUITE_WEP104:
693 		if (params.key_len != 13)
694 			return -EINVAL;
695 		break;
696 	default:
697 		return -EINVAL;
698 	}
699 
700 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
701 	if (err)
702 		return err;
703 
704 	if (!drv->ops->add_key) {
705 		err = -EOPNOTSUPP;
706 		goto out;
707 	}
708 
709 	rtnl_lock();
710 	err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
711 	rtnl_unlock();
712 
713  out:
714 	cfg80211_put_dev(drv);
715 	dev_put(dev);
716 	return err;
717 }
718 
719 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
720 {
721 	struct cfg80211_registered_device *drv;
722 	int err;
723 	struct net_device *dev;
724 	u8 key_idx = 0;
725 	u8 *mac_addr = NULL;
726 
727 	if (info->attrs[NL80211_ATTR_KEY_IDX])
728 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
729 
730 	if (key_idx > 3)
731 		return -EINVAL;
732 
733 	if (info->attrs[NL80211_ATTR_MAC])
734 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
735 
736 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
737 	if (err)
738 		return err;
739 
740 	if (!drv->ops->del_key) {
741 		err = -EOPNOTSUPP;
742 		goto out;
743 	}
744 
745 	rtnl_lock();
746 	err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
747 	rtnl_unlock();
748 
749  out:
750 	cfg80211_put_dev(drv);
751 	dev_put(dev);
752 	return err;
753 }
754 
755 static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
756 {
757         int (*call)(struct wiphy *wiphy, struct net_device *dev,
758 		    struct beacon_parameters *info);
759 	struct cfg80211_registered_device *drv;
760 	int err;
761 	struct net_device *dev;
762 	struct beacon_parameters params;
763 	int haveinfo = 0;
764 
765 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
766 	if (err)
767 		return err;
768 
769 	switch (info->genlhdr->cmd) {
770 	case NL80211_CMD_NEW_BEACON:
771 		/* these are required for NEW_BEACON */
772 		if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
773 		    !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
774 		    !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
775 			err = -EINVAL;
776 			goto out;
777 		}
778 
779 		call = drv->ops->add_beacon;
780 		break;
781 	case NL80211_CMD_SET_BEACON:
782 		call = drv->ops->set_beacon;
783 		break;
784 	default:
785 		WARN_ON(1);
786 		err = -EOPNOTSUPP;
787 		goto out;
788 	}
789 
790 	if (!call) {
791 		err = -EOPNOTSUPP;
792 		goto out;
793 	}
794 
795 	memset(&params, 0, sizeof(params));
796 
797 	if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
798 		params.interval =
799 		    nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
800 		haveinfo = 1;
801 	}
802 
803 	if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
804 		params.dtim_period =
805 		    nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
806 		haveinfo = 1;
807 	}
808 
809 	if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
810 		params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
811 		params.head_len =
812 		    nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
813 		haveinfo = 1;
814 	}
815 
816 	if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
817 		params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
818 		params.tail_len =
819 		    nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
820 		haveinfo = 1;
821 	}
822 
823 	if (!haveinfo) {
824 		err = -EINVAL;
825 		goto out;
826 	}
827 
828 	rtnl_lock();
829 	err = call(&drv->wiphy, dev, &params);
830 	rtnl_unlock();
831 
832  out:
833 	cfg80211_put_dev(drv);
834 	dev_put(dev);
835 	return err;
836 }
837 
838 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
839 {
840 	struct cfg80211_registered_device *drv;
841 	int err;
842 	struct net_device *dev;
843 
844 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
845 	if (err)
846 		return err;
847 
848 	if (!drv->ops->del_beacon) {
849 		err = -EOPNOTSUPP;
850 		goto out;
851 	}
852 
853 	rtnl_lock();
854 	err = drv->ops->del_beacon(&drv->wiphy, dev);
855 	rtnl_unlock();
856 
857  out:
858 	cfg80211_put_dev(drv);
859 	dev_put(dev);
860 	return err;
861 }
862 
863 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
864 	[NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
865 	[NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
866 	[NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
867 };
868 
869 static int parse_station_flags(struct nlattr *nla, u32 *staflags)
870 {
871 	struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
872 	int flag;
873 
874 	*staflags = 0;
875 
876 	if (!nla)
877 		return 0;
878 
879 	if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
880 			     nla, sta_flags_policy))
881 		return -EINVAL;
882 
883 	*staflags = STATION_FLAG_CHANGED;
884 
885 	for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
886 		if (flags[flag])
887 			*staflags |= (1<<flag);
888 
889 	return 0;
890 }
891 
892 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
893 				int flags, struct net_device *dev,
894 				u8 *mac_addr, struct station_info *sinfo)
895 {
896 	void *hdr;
897 	struct nlattr *sinfoattr;
898 
899 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
900 	if (!hdr)
901 		return -1;
902 
903 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
904 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
905 
906 	sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
907 	if (!sinfoattr)
908 		goto nla_put_failure;
909 	if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
910 		NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
911 			    sinfo->inactive_time);
912 	if (sinfo->filled & STATION_INFO_RX_BYTES)
913 		NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES,
914 			    sinfo->rx_bytes);
915 	if (sinfo->filled & STATION_INFO_TX_BYTES)
916 		NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES,
917 			    sinfo->tx_bytes);
918 	if (sinfo->filled & STATION_INFO_LLID)
919 		NLA_PUT_U16(msg, NL80211_STA_INFO_LLID,
920 			    sinfo->llid);
921 	if (sinfo->filled & STATION_INFO_PLID)
922 		NLA_PUT_U16(msg, NL80211_STA_INFO_PLID,
923 			    sinfo->plid);
924 	if (sinfo->filled & STATION_INFO_PLINK_STATE)
925 		NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
926 			    sinfo->plink_state);
927 
928 	nla_nest_end(msg, sinfoattr);
929 
930 	return genlmsg_end(msg, hdr);
931 
932  nla_put_failure:
933 	genlmsg_cancel(msg, hdr);
934 	return -EMSGSIZE;
935 }
936 
937 static int nl80211_dump_station(struct sk_buff *skb,
938 		struct netlink_callback *cb)
939 {
940 	int wp_idx = 0;
941 	int if_idx = 0;
942 	int sta_idx = cb->args[2];
943 	int wp_start = cb->args[0];
944 	int if_start = cb->args[1];
945 	struct station_info sinfo;
946 	struct cfg80211_registered_device *dev;
947 	struct wireless_dev *wdev;
948 	u8 mac_addr[ETH_ALEN];
949 	int err;
950 	int exit = 0;
951 
952 	/* TODO: filter by device */
953 	mutex_lock(&cfg80211_drv_mutex);
954 	list_for_each_entry(dev, &cfg80211_drv_list, list) {
955 		if (exit)
956 			break;
957 		if (++wp_idx < wp_start)
958 			continue;
959 		if_idx = 0;
960 
961 		mutex_lock(&dev->devlist_mtx);
962 		list_for_each_entry(wdev, &dev->netdev_list, list) {
963 			if (exit)
964 				break;
965 			if (++if_idx < if_start)
966 				continue;
967 			if (!dev->ops->dump_station)
968 				continue;
969 
970 			for (;; ++sta_idx) {
971 				rtnl_lock();
972 				err = dev->ops->dump_station(&dev->wiphy,
973 						wdev->netdev, sta_idx, mac_addr,
974 						&sinfo);
975 				rtnl_unlock();
976 				if (err) {
977 					sta_idx = 0;
978 					break;
979 				}
980 				if (nl80211_send_station(skb,
981 						NETLINK_CB(cb->skb).pid,
982 						cb->nlh->nlmsg_seq, NLM_F_MULTI,
983 						wdev->netdev, mac_addr,
984 						&sinfo) < 0) {
985 					exit = 1;
986 					break;
987 				}
988 			}
989 		}
990 		mutex_unlock(&dev->devlist_mtx);
991 	}
992 	mutex_unlock(&cfg80211_drv_mutex);
993 
994 	cb->args[0] = wp_idx;
995 	cb->args[1] = if_idx;
996 	cb->args[2] = sta_idx;
997 
998 	return skb->len;
999 }
1000 
1001 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1002 {
1003 	struct cfg80211_registered_device *drv;
1004 	int err;
1005 	struct net_device *dev;
1006 	struct station_info sinfo;
1007 	struct sk_buff *msg;
1008 	u8 *mac_addr = NULL;
1009 
1010 	memset(&sinfo, 0, sizeof(sinfo));
1011 
1012 	if (!info->attrs[NL80211_ATTR_MAC])
1013 		return -EINVAL;
1014 
1015 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1016 
1017 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1018 	if (err)
1019 		return err;
1020 
1021 	if (!drv->ops->get_station) {
1022 		err = -EOPNOTSUPP;
1023 		goto out;
1024 	}
1025 
1026 	rtnl_lock();
1027 	err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
1028 	rtnl_unlock();
1029 
1030 	if (err)
1031 		goto out;
1032 
1033 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1034 	if (!msg)
1035 		goto out;
1036 
1037 	if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
1038 				 dev, mac_addr, &sinfo) < 0)
1039 		goto out_free;
1040 
1041 	err = genlmsg_unicast(msg, info->snd_pid);
1042 	goto out;
1043 
1044  out_free:
1045 	nlmsg_free(msg);
1046 
1047  out:
1048 	cfg80211_put_dev(drv);
1049 	dev_put(dev);
1050 	return err;
1051 }
1052 
1053 /*
1054  * Get vlan interface making sure it is on the right wiphy.
1055  */
1056 static int get_vlan(struct nlattr *vlanattr,
1057 		    struct cfg80211_registered_device *rdev,
1058 		    struct net_device **vlan)
1059 {
1060 	*vlan = NULL;
1061 
1062 	if (vlanattr) {
1063 		*vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
1064 		if (!*vlan)
1065 			return -ENODEV;
1066 		if (!(*vlan)->ieee80211_ptr)
1067 			return -EINVAL;
1068 		if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
1069 			return -EINVAL;
1070 	}
1071 	return 0;
1072 }
1073 
1074 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1075 {
1076 	struct cfg80211_registered_device *drv;
1077 	int err;
1078 	struct net_device *dev;
1079 	struct station_parameters params;
1080 	u8 *mac_addr = NULL;
1081 
1082 	memset(&params, 0, sizeof(params));
1083 
1084 	params.listen_interval = -1;
1085 
1086 	if (info->attrs[NL80211_ATTR_STA_AID])
1087 		return -EINVAL;
1088 
1089 	if (!info->attrs[NL80211_ATTR_MAC])
1090 		return -EINVAL;
1091 
1092 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1093 
1094 	if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
1095 		params.supported_rates =
1096 			nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1097 		params.supported_rates_len =
1098 			nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1099 	}
1100 
1101 	if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1102 		params.listen_interval =
1103 		    nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1104 
1105 	if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1106 				&params.station_flags))
1107 		return -EINVAL;
1108 
1109 	if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
1110 		params.plink_action =
1111 		    nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
1112 
1113 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1114 	if (err)
1115 		return err;
1116 
1117 	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1118 	if (err)
1119 		goto out;
1120 
1121 	if (!drv->ops->change_station) {
1122 		err = -EOPNOTSUPP;
1123 		goto out;
1124 	}
1125 
1126 	rtnl_lock();
1127 	err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params);
1128 	rtnl_unlock();
1129 
1130  out:
1131 	if (params.vlan)
1132 		dev_put(params.vlan);
1133 	cfg80211_put_dev(drv);
1134 	dev_put(dev);
1135 	return err;
1136 }
1137 
1138 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1139 {
1140 	struct cfg80211_registered_device *drv;
1141 	int err;
1142 	struct net_device *dev;
1143 	struct station_parameters params;
1144 	u8 *mac_addr = NULL;
1145 
1146 	memset(&params, 0, sizeof(params));
1147 
1148 	if (!info->attrs[NL80211_ATTR_MAC])
1149 		return -EINVAL;
1150 
1151 	if (!info->attrs[NL80211_ATTR_STA_AID])
1152 		return -EINVAL;
1153 
1154 	if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1155 		return -EINVAL;
1156 
1157 	if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
1158 		return -EINVAL;
1159 
1160 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1161 	params.supported_rates =
1162 		nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1163 	params.supported_rates_len =
1164 		nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1165 	params.listen_interval =
1166 		nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1167 	params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1168 
1169 	if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1170 				&params.station_flags))
1171 		return -EINVAL;
1172 
1173 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1174 	if (err)
1175 		return err;
1176 
1177 	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1178 	if (err)
1179 		goto out;
1180 
1181 	if (!drv->ops->add_station) {
1182 		err = -EOPNOTSUPP;
1183 		goto out;
1184 	}
1185 
1186 	rtnl_lock();
1187 	err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params);
1188 	rtnl_unlock();
1189 
1190  out:
1191 	if (params.vlan)
1192 		dev_put(params.vlan);
1193 	cfg80211_put_dev(drv);
1194 	dev_put(dev);
1195 	return err;
1196 }
1197 
1198 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1199 {
1200 	struct cfg80211_registered_device *drv;
1201 	int err;
1202 	struct net_device *dev;
1203 	u8 *mac_addr = NULL;
1204 
1205 	if (info->attrs[NL80211_ATTR_MAC])
1206 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1207 
1208 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1209 	if (err)
1210 		return err;
1211 
1212 	if (!drv->ops->del_station) {
1213 		err = -EOPNOTSUPP;
1214 		goto out;
1215 	}
1216 
1217 	rtnl_lock();
1218 	err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
1219 	rtnl_unlock();
1220 
1221  out:
1222 	cfg80211_put_dev(drv);
1223 	dev_put(dev);
1224 	return err;
1225 }
1226 
1227 static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
1228 				int flags, struct net_device *dev,
1229 				u8 *dst, u8 *next_hop,
1230 				struct mpath_info *pinfo)
1231 {
1232 	void *hdr;
1233 	struct nlattr *pinfoattr;
1234 
1235 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1236 	if (!hdr)
1237 		return -1;
1238 
1239 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1240 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
1241 	NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
1242 
1243 	pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
1244 	if (!pinfoattr)
1245 		goto nla_put_failure;
1246 	if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
1247 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
1248 			    pinfo->frame_qlen);
1249 	if (pinfo->filled & MPATH_INFO_DSN)
1250 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_DSN,
1251 			    pinfo->dsn);
1252 	if (pinfo->filled & MPATH_INFO_METRIC)
1253 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
1254 			    pinfo->metric);
1255 	if (pinfo->filled & MPATH_INFO_EXPTIME)
1256 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME,
1257 			    pinfo->exptime);
1258 	if (pinfo->filled & MPATH_INFO_FLAGS)
1259 		NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS,
1260 			    pinfo->flags);
1261 	if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT)
1262 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
1263 			    pinfo->discovery_timeout);
1264 	if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES)
1265 		NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
1266 			    pinfo->discovery_retries);
1267 
1268 	nla_nest_end(msg, pinfoattr);
1269 
1270 	return genlmsg_end(msg, hdr);
1271 
1272  nla_put_failure:
1273 	genlmsg_cancel(msg, hdr);
1274 	return -EMSGSIZE;
1275 }
1276 
1277 static int nl80211_dump_mpath(struct sk_buff *skb,
1278 		struct netlink_callback *cb)
1279 {
1280 	int wp_idx = 0;
1281 	int if_idx = 0;
1282 	int sta_idx = cb->args[2];
1283 	int wp_start = cb->args[0];
1284 	int if_start = cb->args[1];
1285 	struct mpath_info pinfo;
1286 	struct cfg80211_registered_device *dev;
1287 	struct wireless_dev *wdev;
1288 	u8 dst[ETH_ALEN];
1289 	u8 next_hop[ETH_ALEN];
1290 	int err;
1291 	int exit = 0;
1292 
1293 	/* TODO: filter by device */
1294 	mutex_lock(&cfg80211_drv_mutex);
1295 	list_for_each_entry(dev, &cfg80211_drv_list, list) {
1296 		if (exit)
1297 			break;
1298 		if (++wp_idx < wp_start)
1299 			continue;
1300 		if_idx = 0;
1301 
1302 		mutex_lock(&dev->devlist_mtx);
1303 		list_for_each_entry(wdev, &dev->netdev_list, list) {
1304 			if (exit)
1305 				break;
1306 			if (++if_idx < if_start)
1307 				continue;
1308 			if (!dev->ops->dump_mpath)
1309 				continue;
1310 
1311 			for (;; ++sta_idx) {
1312 				rtnl_lock();
1313 				err = dev->ops->dump_mpath(&dev->wiphy,
1314 						wdev->netdev, sta_idx, dst,
1315 						next_hop, &pinfo);
1316 				rtnl_unlock();
1317 				if (err) {
1318 					sta_idx = 0;
1319 					break;
1320 				}
1321 				if (nl80211_send_mpath(skb,
1322 						NETLINK_CB(cb->skb).pid,
1323 						cb->nlh->nlmsg_seq, NLM_F_MULTI,
1324 						wdev->netdev, dst, next_hop,
1325 						&pinfo) < 0) {
1326 					exit = 1;
1327 					break;
1328 				}
1329 			}
1330 		}
1331 		mutex_unlock(&dev->devlist_mtx);
1332 	}
1333 	mutex_unlock(&cfg80211_drv_mutex);
1334 
1335 	cb->args[0] = wp_idx;
1336 	cb->args[1] = if_idx;
1337 	cb->args[2] = sta_idx;
1338 
1339 	return skb->len;
1340 }
1341 
1342 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1343 {
1344 	struct cfg80211_registered_device *drv;
1345 	int err;
1346 	struct net_device *dev;
1347 	struct mpath_info pinfo;
1348 	struct sk_buff *msg;
1349 	u8 *dst = NULL;
1350 	u8 next_hop[ETH_ALEN];
1351 
1352 	memset(&pinfo, 0, sizeof(pinfo));
1353 
1354 	if (!info->attrs[NL80211_ATTR_MAC])
1355 		return -EINVAL;
1356 
1357 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1358 
1359 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1360 	if (err)
1361 		return err;
1362 
1363 	if (!drv->ops->get_mpath) {
1364 		err = -EOPNOTSUPP;
1365 		goto out;
1366 	}
1367 
1368 	rtnl_lock();
1369 	err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
1370 	rtnl_unlock();
1371 
1372 	if (err)
1373 		goto out;
1374 
1375 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1376 	if (!msg)
1377 		goto out;
1378 
1379 	if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
1380 				 dev, dst, next_hop, &pinfo) < 0)
1381 		goto out_free;
1382 
1383 	err = genlmsg_unicast(msg, info->snd_pid);
1384 	goto out;
1385 
1386  out_free:
1387 	nlmsg_free(msg);
1388 
1389  out:
1390 	cfg80211_put_dev(drv);
1391 	dev_put(dev);
1392 	return err;
1393 }
1394 
1395 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
1396 {
1397 	struct cfg80211_registered_device *drv;
1398 	int err;
1399 	struct net_device *dev;
1400 	u8 *dst = NULL;
1401 	u8 *next_hop = NULL;
1402 
1403 	if (!info->attrs[NL80211_ATTR_MAC])
1404 		return -EINVAL;
1405 
1406 	if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1407 		return -EINVAL;
1408 
1409 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1410 	next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1411 
1412 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1413 	if (err)
1414 		return err;
1415 
1416 	if (!drv->ops->change_mpath) {
1417 		err = -EOPNOTSUPP;
1418 		goto out;
1419 	}
1420 
1421 	rtnl_lock();
1422 	err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
1423 	rtnl_unlock();
1424 
1425  out:
1426 	cfg80211_put_dev(drv);
1427 	dev_put(dev);
1428 	return err;
1429 }
1430 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
1431 {
1432 	struct cfg80211_registered_device *drv;
1433 	int err;
1434 	struct net_device *dev;
1435 	u8 *dst = NULL;
1436 	u8 *next_hop = NULL;
1437 
1438 	if (!info->attrs[NL80211_ATTR_MAC])
1439 		return -EINVAL;
1440 
1441 	if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1442 		return -EINVAL;
1443 
1444 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1445 	next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1446 
1447 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1448 	if (err)
1449 		return err;
1450 
1451 	if (!drv->ops->add_mpath) {
1452 		err = -EOPNOTSUPP;
1453 		goto out;
1454 	}
1455 
1456 	rtnl_lock();
1457 	err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
1458 	rtnl_unlock();
1459 
1460  out:
1461 	cfg80211_put_dev(drv);
1462 	dev_put(dev);
1463 	return err;
1464 }
1465 
1466 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1467 {
1468 	struct cfg80211_registered_device *drv;
1469 	int err;
1470 	struct net_device *dev;
1471 	u8 *dst = NULL;
1472 
1473 	if (info->attrs[NL80211_ATTR_MAC])
1474 		dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1475 
1476 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1477 	if (err)
1478 		return err;
1479 
1480 	if (!drv->ops->del_mpath) {
1481 		err = -EOPNOTSUPP;
1482 		goto out;
1483 	}
1484 
1485 	rtnl_lock();
1486 	err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
1487 	rtnl_unlock();
1488 
1489  out:
1490 	cfg80211_put_dev(drv);
1491 	dev_put(dev);
1492 	return err;
1493 }
1494 
1495 static struct genl_ops nl80211_ops[] = {
1496 	{
1497 		.cmd = NL80211_CMD_GET_WIPHY,
1498 		.doit = nl80211_get_wiphy,
1499 		.dumpit = nl80211_dump_wiphy,
1500 		.policy = nl80211_policy,
1501 		/* can be retrieved by unprivileged users */
1502 	},
1503 	{
1504 		.cmd = NL80211_CMD_SET_WIPHY,
1505 		.doit = nl80211_set_wiphy,
1506 		.policy = nl80211_policy,
1507 		.flags = GENL_ADMIN_PERM,
1508 	},
1509 	{
1510 		.cmd = NL80211_CMD_GET_INTERFACE,
1511 		.doit = nl80211_get_interface,
1512 		.dumpit = nl80211_dump_interface,
1513 		.policy = nl80211_policy,
1514 		/* can be retrieved by unprivileged users */
1515 	},
1516 	{
1517 		.cmd = NL80211_CMD_SET_INTERFACE,
1518 		.doit = nl80211_set_interface,
1519 		.policy = nl80211_policy,
1520 		.flags = GENL_ADMIN_PERM,
1521 	},
1522 	{
1523 		.cmd = NL80211_CMD_NEW_INTERFACE,
1524 		.doit = nl80211_new_interface,
1525 		.policy = nl80211_policy,
1526 		.flags = GENL_ADMIN_PERM,
1527 	},
1528 	{
1529 		.cmd = NL80211_CMD_DEL_INTERFACE,
1530 		.doit = nl80211_del_interface,
1531 		.policy = nl80211_policy,
1532 		.flags = GENL_ADMIN_PERM,
1533 	},
1534 	{
1535 		.cmd = NL80211_CMD_GET_KEY,
1536 		.doit = nl80211_get_key,
1537 		.policy = nl80211_policy,
1538 		.flags = GENL_ADMIN_PERM,
1539 	},
1540 	{
1541 		.cmd = NL80211_CMD_SET_KEY,
1542 		.doit = nl80211_set_key,
1543 		.policy = nl80211_policy,
1544 		.flags = GENL_ADMIN_PERM,
1545 	},
1546 	{
1547 		.cmd = NL80211_CMD_NEW_KEY,
1548 		.doit = nl80211_new_key,
1549 		.policy = nl80211_policy,
1550 		.flags = GENL_ADMIN_PERM,
1551 	},
1552 	{
1553 		.cmd = NL80211_CMD_DEL_KEY,
1554 		.doit = nl80211_del_key,
1555 		.policy = nl80211_policy,
1556 		.flags = GENL_ADMIN_PERM,
1557 	},
1558 	{
1559 		.cmd = NL80211_CMD_SET_BEACON,
1560 		.policy = nl80211_policy,
1561 		.flags = GENL_ADMIN_PERM,
1562 		.doit = nl80211_addset_beacon,
1563 	},
1564 	{
1565 		.cmd = NL80211_CMD_NEW_BEACON,
1566 		.policy = nl80211_policy,
1567 		.flags = GENL_ADMIN_PERM,
1568 		.doit = nl80211_addset_beacon,
1569 	},
1570 	{
1571 		.cmd = NL80211_CMD_DEL_BEACON,
1572 		.policy = nl80211_policy,
1573 		.flags = GENL_ADMIN_PERM,
1574 		.doit = nl80211_del_beacon,
1575 	},
1576 	{
1577 		.cmd = NL80211_CMD_GET_STATION,
1578 		.doit = nl80211_get_station,
1579 		.dumpit = nl80211_dump_station,
1580 		.policy = nl80211_policy,
1581 		.flags = GENL_ADMIN_PERM,
1582 	},
1583 	{
1584 		.cmd = NL80211_CMD_SET_STATION,
1585 		.doit = nl80211_set_station,
1586 		.policy = nl80211_policy,
1587 		.flags = GENL_ADMIN_PERM,
1588 	},
1589 	{
1590 		.cmd = NL80211_CMD_NEW_STATION,
1591 		.doit = nl80211_new_station,
1592 		.policy = nl80211_policy,
1593 		.flags = GENL_ADMIN_PERM,
1594 	},
1595 	{
1596 		.cmd = NL80211_CMD_DEL_STATION,
1597 		.doit = nl80211_del_station,
1598 		.policy = nl80211_policy,
1599 		.flags = GENL_ADMIN_PERM,
1600 	},
1601 	{
1602 		.cmd = NL80211_CMD_GET_MPATH,
1603 		.doit = nl80211_get_mpath,
1604 		.dumpit = nl80211_dump_mpath,
1605 		.policy = nl80211_policy,
1606 		.flags = GENL_ADMIN_PERM,
1607 	},
1608 	{
1609 		.cmd = NL80211_CMD_SET_MPATH,
1610 		.doit = nl80211_set_mpath,
1611 		.policy = nl80211_policy,
1612 		.flags = GENL_ADMIN_PERM,
1613 	},
1614 	{
1615 		.cmd = NL80211_CMD_NEW_MPATH,
1616 		.doit = nl80211_new_mpath,
1617 		.policy = nl80211_policy,
1618 		.flags = GENL_ADMIN_PERM,
1619 	},
1620 	{
1621 		.cmd = NL80211_CMD_DEL_MPATH,
1622 		.doit = nl80211_del_mpath,
1623 		.policy = nl80211_policy,
1624 		.flags = GENL_ADMIN_PERM,
1625 	},
1626 };
1627 
1628 /* multicast groups */
1629 static struct genl_multicast_group nl80211_config_mcgrp = {
1630 	.name = "config",
1631 };
1632 
1633 /* notification functions */
1634 
1635 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
1636 {
1637 	struct sk_buff *msg;
1638 
1639 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1640 	if (!msg)
1641 		return;
1642 
1643 	if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
1644 		nlmsg_free(msg);
1645 		return;
1646 	}
1647 
1648 	genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
1649 }
1650 
1651 /* initialisation/exit functions */
1652 
1653 int nl80211_init(void)
1654 {
1655 	int err, i;
1656 
1657 	err = genl_register_family(&nl80211_fam);
1658 	if (err)
1659 		return err;
1660 
1661 	for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
1662 		err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
1663 		if (err)
1664 			goto err_out;
1665 	}
1666 
1667 	err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
1668 	if (err)
1669 		goto err_out;
1670 
1671 	return 0;
1672  err_out:
1673 	genl_unregister_family(&nl80211_fam);
1674 	return err;
1675 }
1676 
1677 void nl80211_exit(void)
1678 {
1679 	genl_unregister_family(&nl80211_fam);
1680 }
1681