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