xref: /linux/net/wireless/nl80211.c (revision 0c93ea4064a209cdc36de8a9a3003d43d08f46f7)
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 #include "reg.h"
22 
23 /* the netlink family */
24 static struct genl_family nl80211_fam = {
25 	.id = GENL_ID_GENERATE,	/* don't bother with a hardcoded ID */
26 	.name = "nl80211",	/* have users key off the name instead */
27 	.hdrsize = 0,		/* no private header */
28 	.version = 1,		/* no particular meaning now */
29 	.maxattr = NL80211_ATTR_MAX,
30 };
31 
32 /* internal helper: get drv and dev */
33 static int get_drv_dev_by_info_ifindex(struct nlattr **attrs,
34 				       struct cfg80211_registered_device **drv,
35 				       struct net_device **dev)
36 {
37 	int ifindex;
38 
39 	if (!attrs[NL80211_ATTR_IFINDEX])
40 		return -EINVAL;
41 
42 	ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
43 	*dev = dev_get_by_index(&init_net, ifindex);
44 	if (!*dev)
45 		return -ENODEV;
46 
47 	*drv = cfg80211_get_dev_from_ifindex(ifindex);
48 	if (IS_ERR(*drv)) {
49 		dev_put(*dev);
50 		return PTR_ERR(*drv);
51 	}
52 
53 	return 0;
54 }
55 
56 /* policy for the attributes */
57 static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
58 	[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
59 	[NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
60 				      .len = BUS_ID_SIZE-1 },
61 	[NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
62 	[NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
63 	[NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
64 
65 	[NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
66 	[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
67 	[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
68 
69 	[NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
70 
71 	[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
72 				    .len = WLAN_MAX_KEY_LEN },
73 	[NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
74 	[NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
75 	[NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
76 
77 	[NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
78 	[NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
79 	[NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
80 				       .len = IEEE80211_MAX_DATA_LEN },
81 	[NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
82 				       .len = IEEE80211_MAX_DATA_LEN },
83 	[NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
84 	[NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
85 	[NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
86 	[NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
87 					       .len = NL80211_MAX_SUPP_RATES },
88 	[NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
89 	[NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
90 	[NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
91 	[NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
92 				.len = IEEE80211_MAX_MESH_ID_LEN },
93 	[NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
94 
95 	[NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
96 	[NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
97 
98 	[NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
99 	[NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
100 	[NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
101 	[NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
102 					   .len = NL80211_MAX_SUPP_RATES },
103 
104 	[NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED },
105 
106 	[NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
107 					 .len = NL80211_HT_CAPABILITY_LEN },
108 };
109 
110 /* message building helper */
111 static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
112 				   int flags, u8 cmd)
113 {
114 	/* since there is no private header just add the generic one */
115 	return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
116 }
117 
118 /* netlink command implementations */
119 
120 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
121 			      struct cfg80211_registered_device *dev)
122 {
123 	void *hdr;
124 	struct nlattr *nl_bands, *nl_band;
125 	struct nlattr *nl_freqs, *nl_freq;
126 	struct nlattr *nl_rates, *nl_rate;
127 	struct nlattr *nl_modes;
128 	enum ieee80211_band band;
129 	struct ieee80211_channel *chan;
130 	struct ieee80211_rate *rate;
131 	int i;
132 	u16 ifmodes = dev->wiphy.interface_modes;
133 
134 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
135 	if (!hdr)
136 		return -1;
137 
138 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
139 	NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
140 
141 	nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
142 	if (!nl_modes)
143 		goto nla_put_failure;
144 
145 	i = 0;
146 	while (ifmodes) {
147 		if (ifmodes & 1)
148 			NLA_PUT_FLAG(msg, i);
149 		ifmodes >>= 1;
150 		i++;
151 	}
152 
153 	nla_nest_end(msg, nl_modes);
154 
155 	nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
156 	if (!nl_bands)
157 		goto nla_put_failure;
158 
159 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
160 		if (!dev->wiphy.bands[band])
161 			continue;
162 
163 		nl_band = nla_nest_start(msg, band);
164 		if (!nl_band)
165 			goto nla_put_failure;
166 
167 		/* add HT info */
168 		if (dev->wiphy.bands[band]->ht_cap.ht_supported) {
169 			NLA_PUT(msg, NL80211_BAND_ATTR_HT_MCS_SET,
170 				sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
171 				&dev->wiphy.bands[band]->ht_cap.mcs);
172 			NLA_PUT_U16(msg, NL80211_BAND_ATTR_HT_CAPA,
173 				dev->wiphy.bands[band]->ht_cap.cap);
174 			NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
175 				dev->wiphy.bands[band]->ht_cap.ampdu_factor);
176 			NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
177 				dev->wiphy.bands[band]->ht_cap.ampdu_density);
178 		}
179 
180 		/* add frequencies */
181 		nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
182 		if (!nl_freqs)
183 			goto nla_put_failure;
184 
185 		for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
186 			nl_freq = nla_nest_start(msg, i);
187 			if (!nl_freq)
188 				goto nla_put_failure;
189 
190 			chan = &dev->wiphy.bands[band]->channels[i];
191 			NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
192 				    chan->center_freq);
193 
194 			if (chan->flags & IEEE80211_CHAN_DISABLED)
195 				NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
196 			if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
197 				NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
198 			if (chan->flags & IEEE80211_CHAN_NO_IBSS)
199 				NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
200 			if (chan->flags & IEEE80211_CHAN_RADAR)
201 				NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
202 
203 			NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
204 				    DBM_TO_MBM(chan->max_power));
205 
206 			nla_nest_end(msg, nl_freq);
207 		}
208 
209 		nla_nest_end(msg, nl_freqs);
210 
211 		/* add bitrates */
212 		nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
213 		if (!nl_rates)
214 			goto nla_put_failure;
215 
216 		for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
217 			nl_rate = nla_nest_start(msg, i);
218 			if (!nl_rate)
219 				goto nla_put_failure;
220 
221 			rate = &dev->wiphy.bands[band]->bitrates[i];
222 			NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
223 				    rate->bitrate);
224 			if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
225 				NLA_PUT_FLAG(msg,
226 					NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
227 
228 			nla_nest_end(msg, nl_rate);
229 		}
230 
231 		nla_nest_end(msg, nl_rates);
232 
233 		nla_nest_end(msg, nl_band);
234 	}
235 	nla_nest_end(msg, nl_bands);
236 
237 	return genlmsg_end(msg, hdr);
238 
239  nla_put_failure:
240 	genlmsg_cancel(msg, hdr);
241 	return -EMSGSIZE;
242 }
243 
244 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
245 {
246 	int idx = 0;
247 	int start = cb->args[0];
248 	struct cfg80211_registered_device *dev;
249 
250 	mutex_lock(&cfg80211_drv_mutex);
251 	list_for_each_entry(dev, &cfg80211_drv_list, list) {
252 		if (++idx <= start)
253 			continue;
254 		if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
255 				       cb->nlh->nlmsg_seq, NLM_F_MULTI,
256 				       dev) < 0) {
257 			idx--;
258 			break;
259 		}
260 	}
261 	mutex_unlock(&cfg80211_drv_mutex);
262 
263 	cb->args[0] = idx;
264 
265 	return skb->len;
266 }
267 
268 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
269 {
270 	struct sk_buff *msg;
271 	struct cfg80211_registered_device *dev;
272 
273 	dev = cfg80211_get_dev_from_info(info);
274 	if (IS_ERR(dev))
275 		return PTR_ERR(dev);
276 
277 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
278 	if (!msg)
279 		goto out_err;
280 
281 	if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
282 		goto out_free;
283 
284 	cfg80211_put_dev(dev);
285 
286 	return genlmsg_unicast(msg, info->snd_pid);
287 
288  out_free:
289 	nlmsg_free(msg);
290  out_err:
291 	cfg80211_put_dev(dev);
292 	return -ENOBUFS;
293 }
294 
295 static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
296 	[NL80211_TXQ_ATTR_QUEUE]		= { .type = NLA_U8 },
297 	[NL80211_TXQ_ATTR_TXOP]			= { .type = NLA_U16 },
298 	[NL80211_TXQ_ATTR_CWMIN]		= { .type = NLA_U16 },
299 	[NL80211_TXQ_ATTR_CWMAX]		= { .type = NLA_U16 },
300 	[NL80211_TXQ_ATTR_AIFS]			= { .type = NLA_U8 },
301 };
302 
303 static int parse_txq_params(struct nlattr *tb[],
304 			    struct ieee80211_txq_params *txq_params)
305 {
306 	if (!tb[NL80211_TXQ_ATTR_QUEUE] || !tb[NL80211_TXQ_ATTR_TXOP] ||
307 	    !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
308 	    !tb[NL80211_TXQ_ATTR_AIFS])
309 		return -EINVAL;
310 
311 	txq_params->queue = nla_get_u8(tb[NL80211_TXQ_ATTR_QUEUE]);
312 	txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
313 	txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
314 	txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
315 	txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
316 
317 	return 0;
318 }
319 
320 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
321 {
322 	struct cfg80211_registered_device *rdev;
323 	int result = 0, rem_txq_params = 0;
324 	struct nlattr *nl_txq_params;
325 
326 	rdev = cfg80211_get_dev_from_info(info);
327 	if (IS_ERR(rdev))
328 		return PTR_ERR(rdev);
329 
330 	if (info->attrs[NL80211_ATTR_WIPHY_NAME]) {
331 		result = cfg80211_dev_rename(
332 			rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
333 		if (result)
334 			goto bad_res;
335 	}
336 
337 	if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
338 		struct ieee80211_txq_params txq_params;
339 		struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
340 
341 		if (!rdev->ops->set_txq_params) {
342 			result = -EOPNOTSUPP;
343 			goto bad_res;
344 		}
345 
346 		nla_for_each_nested(nl_txq_params,
347 				    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
348 				    rem_txq_params) {
349 			nla_parse(tb, NL80211_TXQ_ATTR_MAX,
350 				  nla_data(nl_txq_params),
351 				  nla_len(nl_txq_params),
352 				  txq_params_policy);
353 			result = parse_txq_params(tb, &txq_params);
354 			if (result)
355 				goto bad_res;
356 
357 			result = rdev->ops->set_txq_params(&rdev->wiphy,
358 							   &txq_params);
359 			if (result)
360 				goto bad_res;
361 		}
362 	}
363 
364 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
365 		enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
366 		struct ieee80211_channel *chan;
367 		struct ieee80211_sta_ht_cap *ht_cap;
368 		u32 freq, sec_freq;
369 
370 		if (!rdev->ops->set_channel) {
371 			result = -EOPNOTSUPP;
372 			goto bad_res;
373 		}
374 
375 		result = -EINVAL;
376 
377 		if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
378 			channel_type = nla_get_u32(info->attrs[
379 					   NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
380 			if (channel_type != NL80211_CHAN_NO_HT &&
381 			    channel_type != NL80211_CHAN_HT20 &&
382 			    channel_type != NL80211_CHAN_HT40PLUS &&
383 			    channel_type != NL80211_CHAN_HT40MINUS)
384 				goto bad_res;
385 		}
386 
387 		freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
388 		chan = ieee80211_get_channel(&rdev->wiphy, freq);
389 
390 		/* Primary channel not allowed */
391 		if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
392 			goto bad_res;
393 
394 		if (channel_type == NL80211_CHAN_HT40MINUS)
395 			sec_freq = freq - 20;
396 		else if (channel_type == NL80211_CHAN_HT40PLUS)
397 			sec_freq = freq + 20;
398 		else
399 			sec_freq = 0;
400 
401 		ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
402 
403 		/* no HT capabilities */
404 		if (channel_type != NL80211_CHAN_NO_HT &&
405 		    !ht_cap->ht_supported)
406 			goto bad_res;
407 
408 		if (sec_freq) {
409 			struct ieee80211_channel *schan;
410 
411 			/* no 40 MHz capabilities */
412 			if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
413 			    (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
414 				goto bad_res;
415 
416 			schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
417 
418 			/* Secondary channel not allowed */
419 			if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
420 				goto bad_res;
421 		}
422 
423 		result = rdev->ops->set_channel(&rdev->wiphy, chan,
424 						channel_type);
425 		if (result)
426 			goto bad_res;
427 	}
428 
429 
430  bad_res:
431 	cfg80211_put_dev(rdev);
432 	return result;
433 }
434 
435 
436 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
437 			      struct net_device *dev)
438 {
439 	void *hdr;
440 
441 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
442 	if (!hdr)
443 		return -1;
444 
445 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
446 	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
447 	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
448 	return genlmsg_end(msg, hdr);
449 
450  nla_put_failure:
451 	genlmsg_cancel(msg, hdr);
452 	return -EMSGSIZE;
453 }
454 
455 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
456 {
457 	int wp_idx = 0;
458 	int if_idx = 0;
459 	int wp_start = cb->args[0];
460 	int if_start = cb->args[1];
461 	struct cfg80211_registered_device *dev;
462 	struct wireless_dev *wdev;
463 
464 	mutex_lock(&cfg80211_drv_mutex);
465 	list_for_each_entry(dev, &cfg80211_drv_list, list) {
466 		if (wp_idx < wp_start) {
467 			wp_idx++;
468 			continue;
469 		}
470 		if_idx = 0;
471 
472 		mutex_lock(&dev->devlist_mtx);
473 		list_for_each_entry(wdev, &dev->netdev_list, list) {
474 			if (if_idx < if_start) {
475 				if_idx++;
476 				continue;
477 			}
478 			if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
479 					       cb->nlh->nlmsg_seq, NLM_F_MULTI,
480 					       wdev->netdev) < 0) {
481 				mutex_unlock(&dev->devlist_mtx);
482 				goto out;
483 			}
484 			if_idx++;
485 		}
486 		mutex_unlock(&dev->devlist_mtx);
487 
488 		wp_idx++;
489 	}
490  out:
491 	mutex_unlock(&cfg80211_drv_mutex);
492 
493 	cb->args[0] = wp_idx;
494 	cb->args[1] = if_idx;
495 
496 	return skb->len;
497 }
498 
499 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
500 {
501 	struct sk_buff *msg;
502 	struct cfg80211_registered_device *dev;
503 	struct net_device *netdev;
504 	int err;
505 
506 	err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev);
507 	if (err)
508 		return err;
509 
510 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
511 	if (!msg)
512 		goto out_err;
513 
514 	if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0)
515 		goto out_free;
516 
517 	dev_put(netdev);
518 	cfg80211_put_dev(dev);
519 
520 	return genlmsg_unicast(msg, info->snd_pid);
521 
522  out_free:
523 	nlmsg_free(msg);
524  out_err:
525 	dev_put(netdev);
526 	cfg80211_put_dev(dev);
527 	return -ENOBUFS;
528 }
529 
530 static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
531 	[NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
532 	[NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
533 	[NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
534 	[NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
535 	[NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
536 };
537 
538 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
539 {
540 	struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
541 	int flag;
542 
543 	*mntrflags = 0;
544 
545 	if (!nla)
546 		return -EINVAL;
547 
548 	if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
549 			     nla, mntr_flags_policy))
550 		return -EINVAL;
551 
552 	for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
553 		if (flags[flag])
554 			*mntrflags |= (1<<flag);
555 
556 	return 0;
557 }
558 
559 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
560 {
561 	struct cfg80211_registered_device *drv;
562 	struct vif_params params;
563 	int err, ifindex;
564 	enum nl80211_iftype type;
565 	struct net_device *dev;
566 	u32 _flags, *flags = NULL;
567 
568 	memset(&params, 0, sizeof(params));
569 
570 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
571 	if (err)
572 		return err;
573 	ifindex = dev->ifindex;
574 	type = dev->ieee80211_ptr->iftype;
575 	dev_put(dev);
576 
577 	err = -EINVAL;
578 	if (info->attrs[NL80211_ATTR_IFTYPE]) {
579 		type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
580 		if (type > NL80211_IFTYPE_MAX)
581 			goto unlock;
582 	}
583 
584 	if (!drv->ops->change_virtual_intf ||
585 	    !(drv->wiphy.interface_modes & (1 << type))) {
586 		err = -EOPNOTSUPP;
587 		goto unlock;
588 	}
589 
590 	if (info->attrs[NL80211_ATTR_MESH_ID]) {
591 		if (type != NL80211_IFTYPE_MESH_POINT) {
592 			err = -EINVAL;
593 			goto unlock;
594 		}
595 		params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
596 		params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
597 	}
598 
599 	if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
600 		if (type != NL80211_IFTYPE_MONITOR) {
601 			err = -EINVAL;
602 			goto unlock;
603 		}
604 		err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
605 					  &_flags);
606 		if (!err)
607 			flags = &_flags;
608 	}
609 	rtnl_lock();
610 	err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
611 					    type, flags, &params);
612 
613 	dev = __dev_get_by_index(&init_net, ifindex);
614 	WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
615 
616 	rtnl_unlock();
617 
618  unlock:
619 	cfg80211_put_dev(drv);
620 	return err;
621 }
622 
623 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
624 {
625 	struct cfg80211_registered_device *drv;
626 	struct vif_params params;
627 	int err;
628 	enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
629 	u32 flags;
630 
631 	memset(&params, 0, sizeof(params));
632 
633 	if (!info->attrs[NL80211_ATTR_IFNAME])
634 		return -EINVAL;
635 
636 	if (info->attrs[NL80211_ATTR_IFTYPE]) {
637 		type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
638 		if (type > NL80211_IFTYPE_MAX)
639 			return -EINVAL;
640 	}
641 
642 	drv = cfg80211_get_dev_from_info(info);
643 	if (IS_ERR(drv))
644 		return PTR_ERR(drv);
645 
646 	if (!drv->ops->add_virtual_intf ||
647 	    !(drv->wiphy.interface_modes & (1 << type))) {
648 		err = -EOPNOTSUPP;
649 		goto unlock;
650 	}
651 
652 	if (type == NL80211_IFTYPE_MESH_POINT &&
653 	    info->attrs[NL80211_ATTR_MESH_ID]) {
654 		params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
655 		params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
656 	}
657 
658 	rtnl_lock();
659 	err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
660 				  info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
661 				  &flags);
662 	err = drv->ops->add_virtual_intf(&drv->wiphy,
663 		nla_data(info->attrs[NL80211_ATTR_IFNAME]),
664 		type, err ? NULL : &flags, &params);
665 	rtnl_unlock();
666 
667 
668  unlock:
669 	cfg80211_put_dev(drv);
670 	return err;
671 }
672 
673 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
674 {
675 	struct cfg80211_registered_device *drv;
676 	int ifindex, err;
677 	struct net_device *dev;
678 
679 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
680 	if (err)
681 		return err;
682 	ifindex = dev->ifindex;
683 	dev_put(dev);
684 
685 	if (!drv->ops->del_virtual_intf) {
686 		err = -EOPNOTSUPP;
687 		goto out;
688 	}
689 
690 	rtnl_lock();
691 	err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
692 	rtnl_unlock();
693 
694  out:
695 	cfg80211_put_dev(drv);
696 	return err;
697 }
698 
699 struct get_key_cookie {
700 	struct sk_buff *msg;
701 	int error;
702 };
703 
704 static void get_key_callback(void *c, struct key_params *params)
705 {
706 	struct get_key_cookie *cookie = c;
707 
708 	if (params->key)
709 		NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
710 			params->key_len, params->key);
711 
712 	if (params->seq)
713 		NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
714 			params->seq_len, params->seq);
715 
716 	if (params->cipher)
717 		NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
718 			    params->cipher);
719 
720 	return;
721  nla_put_failure:
722 	cookie->error = 1;
723 }
724 
725 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
726 {
727 	struct cfg80211_registered_device *drv;
728 	int err;
729 	struct net_device *dev;
730 	u8 key_idx = 0;
731 	u8 *mac_addr = NULL;
732 	struct get_key_cookie cookie = {
733 		.error = 0,
734 	};
735 	void *hdr;
736 	struct sk_buff *msg;
737 
738 	if (info->attrs[NL80211_ATTR_KEY_IDX])
739 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
740 
741 	if (key_idx > 3)
742 		return -EINVAL;
743 
744 	if (info->attrs[NL80211_ATTR_MAC])
745 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
746 
747 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
748 	if (err)
749 		return err;
750 
751 	if (!drv->ops->get_key) {
752 		err = -EOPNOTSUPP;
753 		goto out;
754 	}
755 
756 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
757 	if (!msg) {
758 		err = -ENOMEM;
759 		goto out;
760 	}
761 
762 	hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
763 			     NL80211_CMD_NEW_KEY);
764 
765 	if (IS_ERR(hdr)) {
766 		err = PTR_ERR(hdr);
767 		goto out;
768 	}
769 
770 	cookie.msg = msg;
771 
772 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
773 	NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
774 	if (mac_addr)
775 		NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
776 
777 	rtnl_lock();
778 	err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
779 				&cookie, get_key_callback);
780 	rtnl_unlock();
781 
782 	if (err)
783 		goto out;
784 
785 	if (cookie.error)
786 		goto nla_put_failure;
787 
788 	genlmsg_end(msg, hdr);
789 	err = genlmsg_unicast(msg, info->snd_pid);
790 	goto out;
791 
792  nla_put_failure:
793 	err = -ENOBUFS;
794 	nlmsg_free(msg);
795  out:
796 	cfg80211_put_dev(drv);
797 	dev_put(dev);
798 	return err;
799 }
800 
801 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
802 {
803 	struct cfg80211_registered_device *drv;
804 	int err;
805 	struct net_device *dev;
806 	u8 key_idx;
807 
808 	if (!info->attrs[NL80211_ATTR_KEY_IDX])
809 		return -EINVAL;
810 
811 	key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
812 
813 	if (key_idx > 3)
814 		return -EINVAL;
815 
816 	/* currently only support setting default key */
817 	if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
818 		return -EINVAL;
819 
820 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
821 	if (err)
822 		return err;
823 
824 	if (!drv->ops->set_default_key) {
825 		err = -EOPNOTSUPP;
826 		goto out;
827 	}
828 
829 	rtnl_lock();
830 	err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
831 	rtnl_unlock();
832 
833  out:
834 	cfg80211_put_dev(drv);
835 	dev_put(dev);
836 	return err;
837 }
838 
839 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
840 {
841 	struct cfg80211_registered_device *drv;
842 	int err;
843 	struct net_device *dev;
844 	struct key_params params;
845 	u8 key_idx = 0;
846 	u8 *mac_addr = NULL;
847 
848 	memset(&params, 0, sizeof(params));
849 
850 	if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
851 		return -EINVAL;
852 
853 	if (info->attrs[NL80211_ATTR_KEY_DATA]) {
854 		params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
855 		params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
856 	}
857 
858 	if (info->attrs[NL80211_ATTR_KEY_IDX])
859 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
860 
861 	params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
862 
863 	if (info->attrs[NL80211_ATTR_MAC])
864 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
865 
866 	if (key_idx > 3)
867 		return -EINVAL;
868 
869 	/*
870 	 * Disallow pairwise keys with non-zero index unless it's WEP
871 	 * (because current deployments use pairwise WEP keys with
872 	 * non-zero indizes but 802.11i clearly specifies to use zero)
873 	 */
874 	if (mac_addr && key_idx &&
875 	    params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
876 	    params.cipher != WLAN_CIPHER_SUITE_WEP104)
877 		return -EINVAL;
878 
879 	/* TODO: add definitions for the lengths to linux/ieee80211.h */
880 	switch (params.cipher) {
881 	case WLAN_CIPHER_SUITE_WEP40:
882 		if (params.key_len != 5)
883 			return -EINVAL;
884 		break;
885 	case WLAN_CIPHER_SUITE_TKIP:
886 		if (params.key_len != 32)
887 			return -EINVAL;
888 		break;
889 	case WLAN_CIPHER_SUITE_CCMP:
890 		if (params.key_len != 16)
891 			return -EINVAL;
892 		break;
893 	case WLAN_CIPHER_SUITE_WEP104:
894 		if (params.key_len != 13)
895 			return -EINVAL;
896 		break;
897 	default:
898 		return -EINVAL;
899 	}
900 
901 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
902 	if (err)
903 		return err;
904 
905 	if (!drv->ops->add_key) {
906 		err = -EOPNOTSUPP;
907 		goto out;
908 	}
909 
910 	rtnl_lock();
911 	err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
912 	rtnl_unlock();
913 
914  out:
915 	cfg80211_put_dev(drv);
916 	dev_put(dev);
917 	return err;
918 }
919 
920 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
921 {
922 	struct cfg80211_registered_device *drv;
923 	int err;
924 	struct net_device *dev;
925 	u8 key_idx = 0;
926 	u8 *mac_addr = NULL;
927 
928 	if (info->attrs[NL80211_ATTR_KEY_IDX])
929 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
930 
931 	if (key_idx > 3)
932 		return -EINVAL;
933 
934 	if (info->attrs[NL80211_ATTR_MAC])
935 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
936 
937 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
938 	if (err)
939 		return err;
940 
941 	if (!drv->ops->del_key) {
942 		err = -EOPNOTSUPP;
943 		goto out;
944 	}
945 
946 	rtnl_lock();
947 	err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
948 	rtnl_unlock();
949 
950  out:
951 	cfg80211_put_dev(drv);
952 	dev_put(dev);
953 	return err;
954 }
955 
956 static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
957 {
958         int (*call)(struct wiphy *wiphy, struct net_device *dev,
959 		    struct beacon_parameters *info);
960 	struct cfg80211_registered_device *drv;
961 	int err;
962 	struct net_device *dev;
963 	struct beacon_parameters params;
964 	int haveinfo = 0;
965 
966 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
967 	if (err)
968 		return err;
969 
970 	switch (info->genlhdr->cmd) {
971 	case NL80211_CMD_NEW_BEACON:
972 		/* these are required for NEW_BEACON */
973 		if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
974 		    !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
975 		    !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
976 			err = -EINVAL;
977 			goto out;
978 		}
979 
980 		call = drv->ops->add_beacon;
981 		break;
982 	case NL80211_CMD_SET_BEACON:
983 		call = drv->ops->set_beacon;
984 		break;
985 	default:
986 		WARN_ON(1);
987 		err = -EOPNOTSUPP;
988 		goto out;
989 	}
990 
991 	if (!call) {
992 		err = -EOPNOTSUPP;
993 		goto out;
994 	}
995 
996 	memset(&params, 0, sizeof(params));
997 
998 	if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
999 		params.interval =
1000 		    nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1001 		haveinfo = 1;
1002 	}
1003 
1004 	if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
1005 		params.dtim_period =
1006 		    nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1007 		haveinfo = 1;
1008 	}
1009 
1010 	if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
1011 		params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1012 		params.head_len =
1013 		    nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1014 		haveinfo = 1;
1015 	}
1016 
1017 	if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
1018 		params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
1019 		params.tail_len =
1020 		    nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
1021 		haveinfo = 1;
1022 	}
1023 
1024 	if (!haveinfo) {
1025 		err = -EINVAL;
1026 		goto out;
1027 	}
1028 
1029 	rtnl_lock();
1030 	err = call(&drv->wiphy, dev, &params);
1031 	rtnl_unlock();
1032 
1033  out:
1034 	cfg80211_put_dev(drv);
1035 	dev_put(dev);
1036 	return err;
1037 }
1038 
1039 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1040 {
1041 	struct cfg80211_registered_device *drv;
1042 	int err;
1043 	struct net_device *dev;
1044 
1045 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1046 	if (err)
1047 		return err;
1048 
1049 	if (!drv->ops->del_beacon) {
1050 		err = -EOPNOTSUPP;
1051 		goto out;
1052 	}
1053 
1054 	rtnl_lock();
1055 	err = drv->ops->del_beacon(&drv->wiphy, dev);
1056 	rtnl_unlock();
1057 
1058  out:
1059 	cfg80211_put_dev(drv);
1060 	dev_put(dev);
1061 	return err;
1062 }
1063 
1064 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
1065 	[NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
1066 	[NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
1067 	[NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
1068 };
1069 
1070 static int parse_station_flags(struct nlattr *nla, u32 *staflags)
1071 {
1072 	struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
1073 	int flag;
1074 
1075 	*staflags = 0;
1076 
1077 	if (!nla)
1078 		return 0;
1079 
1080 	if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
1081 			     nla, sta_flags_policy))
1082 		return -EINVAL;
1083 
1084 	*staflags = STATION_FLAG_CHANGED;
1085 
1086 	for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
1087 		if (flags[flag])
1088 			*staflags |= (1<<flag);
1089 
1090 	return 0;
1091 }
1092 
1093 static u16 nl80211_calculate_bitrate(struct rate_info *rate)
1094 {
1095 	int modulation, streams, bitrate;
1096 
1097 	if (!(rate->flags & RATE_INFO_FLAGS_MCS))
1098 		return rate->legacy;
1099 
1100 	/* the formula below does only work for MCS values smaller than 32 */
1101 	if (rate->mcs >= 32)
1102 		return 0;
1103 
1104 	modulation = rate->mcs & 7;
1105 	streams = (rate->mcs >> 3) + 1;
1106 
1107 	bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
1108 			13500000 : 6500000;
1109 
1110 	if (modulation < 4)
1111 		bitrate *= (modulation + 1);
1112 	else if (modulation == 4)
1113 		bitrate *= (modulation + 2);
1114 	else
1115 		bitrate *= (modulation + 3);
1116 
1117 	bitrate *= streams;
1118 
1119 	if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
1120 		bitrate = (bitrate / 9) * 10;
1121 
1122 	/* do NOT round down here */
1123 	return (bitrate + 50000) / 100000;
1124 }
1125 
1126 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1127 				int flags, struct net_device *dev,
1128 				u8 *mac_addr, struct station_info *sinfo)
1129 {
1130 	void *hdr;
1131 	struct nlattr *sinfoattr, *txrate;
1132 	u16 bitrate;
1133 
1134 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1135 	if (!hdr)
1136 		return -1;
1137 
1138 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1139 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
1140 
1141 	sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
1142 	if (!sinfoattr)
1143 		goto nla_put_failure;
1144 	if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
1145 		NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
1146 			    sinfo->inactive_time);
1147 	if (sinfo->filled & STATION_INFO_RX_BYTES)
1148 		NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES,
1149 			    sinfo->rx_bytes);
1150 	if (sinfo->filled & STATION_INFO_TX_BYTES)
1151 		NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES,
1152 			    sinfo->tx_bytes);
1153 	if (sinfo->filled & STATION_INFO_LLID)
1154 		NLA_PUT_U16(msg, NL80211_STA_INFO_LLID,
1155 			    sinfo->llid);
1156 	if (sinfo->filled & STATION_INFO_PLID)
1157 		NLA_PUT_U16(msg, NL80211_STA_INFO_PLID,
1158 			    sinfo->plid);
1159 	if (sinfo->filled & STATION_INFO_PLINK_STATE)
1160 		NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
1161 			    sinfo->plink_state);
1162 	if (sinfo->filled & STATION_INFO_SIGNAL)
1163 		NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
1164 			   sinfo->signal);
1165 	if (sinfo->filled & STATION_INFO_TX_BITRATE) {
1166 		txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
1167 		if (!txrate)
1168 			goto nla_put_failure;
1169 
1170 		/* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
1171 		bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
1172 		if (bitrate > 0)
1173 			NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
1174 
1175 		if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
1176 			NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
1177 				    sinfo->txrate.mcs);
1178 		if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
1179 			NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
1180 		if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
1181 			NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
1182 
1183 		nla_nest_end(msg, txrate);
1184 	}
1185 	nla_nest_end(msg, sinfoattr);
1186 
1187 	return genlmsg_end(msg, hdr);
1188 
1189  nla_put_failure:
1190 	genlmsg_cancel(msg, hdr);
1191 	return -EMSGSIZE;
1192 }
1193 
1194 static int nl80211_dump_station(struct sk_buff *skb,
1195 				struct netlink_callback *cb)
1196 {
1197 	struct station_info sinfo;
1198 	struct cfg80211_registered_device *dev;
1199 	struct net_device *netdev;
1200 	u8 mac_addr[ETH_ALEN];
1201 	int ifidx = cb->args[0];
1202 	int sta_idx = cb->args[1];
1203 	int err;
1204 
1205 	if (!ifidx) {
1206 		err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1207 				  nl80211_fam.attrbuf, nl80211_fam.maxattr,
1208 				  nl80211_policy);
1209 		if (err)
1210 			return err;
1211 
1212 		if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
1213 			return -EINVAL;
1214 
1215 		ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1216 		if (!ifidx)
1217 			return -EINVAL;
1218 	}
1219 
1220 	netdev = dev_get_by_index(&init_net, ifidx);
1221 	if (!netdev)
1222 		return -ENODEV;
1223 
1224 	dev = cfg80211_get_dev_from_ifindex(ifidx);
1225 	if (IS_ERR(dev)) {
1226 		err = PTR_ERR(dev);
1227 		goto out_put_netdev;
1228 	}
1229 
1230 	if (!dev->ops->dump_station) {
1231 		err = -ENOSYS;
1232 		goto out_err;
1233 	}
1234 
1235 	rtnl_lock();
1236 
1237 	while (1) {
1238 		err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
1239 					     mac_addr, &sinfo);
1240 		if (err == -ENOENT)
1241 			break;
1242 		if (err)
1243 			goto out_err_rtnl;
1244 
1245 		if (nl80211_send_station(skb,
1246 				NETLINK_CB(cb->skb).pid,
1247 				cb->nlh->nlmsg_seq, NLM_F_MULTI,
1248 				netdev, mac_addr,
1249 				&sinfo) < 0)
1250 			goto out;
1251 
1252 		sta_idx++;
1253 	}
1254 
1255 
1256  out:
1257 	cb->args[1] = sta_idx;
1258 	err = skb->len;
1259  out_err_rtnl:
1260 	rtnl_unlock();
1261  out_err:
1262 	cfg80211_put_dev(dev);
1263  out_put_netdev:
1264 	dev_put(netdev);
1265 
1266 	return err;
1267 }
1268 
1269 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1270 {
1271 	struct cfg80211_registered_device *drv;
1272 	int err;
1273 	struct net_device *dev;
1274 	struct station_info sinfo;
1275 	struct sk_buff *msg;
1276 	u8 *mac_addr = NULL;
1277 
1278 	memset(&sinfo, 0, sizeof(sinfo));
1279 
1280 	if (!info->attrs[NL80211_ATTR_MAC])
1281 		return -EINVAL;
1282 
1283 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1284 
1285 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1286 	if (err)
1287 		return err;
1288 
1289 	if (!drv->ops->get_station) {
1290 		err = -EOPNOTSUPP;
1291 		goto out;
1292 	}
1293 
1294 	rtnl_lock();
1295 	err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
1296 	rtnl_unlock();
1297 
1298 	if (err)
1299 		goto out;
1300 
1301 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1302 	if (!msg)
1303 		goto out;
1304 
1305 	if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
1306 				 dev, mac_addr, &sinfo) < 0)
1307 		goto out_free;
1308 
1309 	err = genlmsg_unicast(msg, info->snd_pid);
1310 	goto out;
1311 
1312  out_free:
1313 	nlmsg_free(msg);
1314 
1315  out:
1316 	cfg80211_put_dev(drv);
1317 	dev_put(dev);
1318 	return err;
1319 }
1320 
1321 /*
1322  * Get vlan interface making sure it is on the right wiphy.
1323  */
1324 static int get_vlan(struct nlattr *vlanattr,
1325 		    struct cfg80211_registered_device *rdev,
1326 		    struct net_device **vlan)
1327 {
1328 	*vlan = NULL;
1329 
1330 	if (vlanattr) {
1331 		*vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
1332 		if (!*vlan)
1333 			return -ENODEV;
1334 		if (!(*vlan)->ieee80211_ptr)
1335 			return -EINVAL;
1336 		if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
1337 			return -EINVAL;
1338 	}
1339 	return 0;
1340 }
1341 
1342 static int nl80211_set_station(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 station_parameters params;
1348 	u8 *mac_addr = NULL;
1349 
1350 	memset(&params, 0, sizeof(params));
1351 
1352 	params.listen_interval = -1;
1353 
1354 	if (info->attrs[NL80211_ATTR_STA_AID])
1355 		return -EINVAL;
1356 
1357 	if (!info->attrs[NL80211_ATTR_MAC])
1358 		return -EINVAL;
1359 
1360 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1361 
1362 	if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
1363 		params.supported_rates =
1364 			nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1365 		params.supported_rates_len =
1366 			nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1367 	}
1368 
1369 	if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1370 		params.listen_interval =
1371 		    nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1372 
1373 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1374 		params.ht_capa =
1375 			nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1376 
1377 	if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1378 				&params.station_flags))
1379 		return -EINVAL;
1380 
1381 	if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
1382 		params.plink_action =
1383 		    nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
1384 
1385 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1386 	if (err)
1387 		return err;
1388 
1389 	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1390 	if (err)
1391 		goto out;
1392 
1393 	if (!drv->ops->change_station) {
1394 		err = -EOPNOTSUPP;
1395 		goto out;
1396 	}
1397 
1398 	rtnl_lock();
1399 	err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params);
1400 	rtnl_unlock();
1401 
1402  out:
1403 	if (params.vlan)
1404 		dev_put(params.vlan);
1405 	cfg80211_put_dev(drv);
1406 	dev_put(dev);
1407 	return err;
1408 }
1409 
1410 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1411 {
1412 	struct cfg80211_registered_device *drv;
1413 	int err;
1414 	struct net_device *dev;
1415 	struct station_parameters params;
1416 	u8 *mac_addr = NULL;
1417 
1418 	memset(&params, 0, sizeof(params));
1419 
1420 	if (!info->attrs[NL80211_ATTR_MAC])
1421 		return -EINVAL;
1422 
1423 	if (!info->attrs[NL80211_ATTR_STA_AID])
1424 		return -EINVAL;
1425 
1426 	if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1427 		return -EINVAL;
1428 
1429 	if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
1430 		return -EINVAL;
1431 
1432 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1433 	params.supported_rates =
1434 		nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1435 	params.supported_rates_len =
1436 		nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1437 	params.listen_interval =
1438 		nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1439 	params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1440 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1441 		params.ht_capa =
1442 			nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1443 
1444 	if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1445 				&params.station_flags))
1446 		return -EINVAL;
1447 
1448 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1449 	if (err)
1450 		return err;
1451 
1452 	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1453 	if (err)
1454 		goto out;
1455 
1456 	if (!drv->ops->add_station) {
1457 		err = -EOPNOTSUPP;
1458 		goto out;
1459 	}
1460 
1461 	rtnl_lock();
1462 	err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params);
1463 	rtnl_unlock();
1464 
1465  out:
1466 	if (params.vlan)
1467 		dev_put(params.vlan);
1468 	cfg80211_put_dev(drv);
1469 	dev_put(dev);
1470 	return err;
1471 }
1472 
1473 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1474 {
1475 	struct cfg80211_registered_device *drv;
1476 	int err;
1477 	struct net_device *dev;
1478 	u8 *mac_addr = NULL;
1479 
1480 	if (info->attrs[NL80211_ATTR_MAC])
1481 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1482 
1483 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1484 	if (err)
1485 		return err;
1486 
1487 	if (!drv->ops->del_station) {
1488 		err = -EOPNOTSUPP;
1489 		goto out;
1490 	}
1491 
1492 	rtnl_lock();
1493 	err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
1494 	rtnl_unlock();
1495 
1496  out:
1497 	cfg80211_put_dev(drv);
1498 	dev_put(dev);
1499 	return err;
1500 }
1501 
1502 static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
1503 				int flags, struct net_device *dev,
1504 				u8 *dst, u8 *next_hop,
1505 				struct mpath_info *pinfo)
1506 {
1507 	void *hdr;
1508 	struct nlattr *pinfoattr;
1509 
1510 	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1511 	if (!hdr)
1512 		return -1;
1513 
1514 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1515 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
1516 	NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
1517 
1518 	pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
1519 	if (!pinfoattr)
1520 		goto nla_put_failure;
1521 	if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
1522 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
1523 			    pinfo->frame_qlen);
1524 	if (pinfo->filled & MPATH_INFO_DSN)
1525 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_DSN,
1526 			    pinfo->dsn);
1527 	if (pinfo->filled & MPATH_INFO_METRIC)
1528 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
1529 			    pinfo->metric);
1530 	if (pinfo->filled & MPATH_INFO_EXPTIME)
1531 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME,
1532 			    pinfo->exptime);
1533 	if (pinfo->filled & MPATH_INFO_FLAGS)
1534 		NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS,
1535 			    pinfo->flags);
1536 	if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT)
1537 		NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
1538 			    pinfo->discovery_timeout);
1539 	if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES)
1540 		NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
1541 			    pinfo->discovery_retries);
1542 
1543 	nla_nest_end(msg, pinfoattr);
1544 
1545 	return genlmsg_end(msg, hdr);
1546 
1547  nla_put_failure:
1548 	genlmsg_cancel(msg, hdr);
1549 	return -EMSGSIZE;
1550 }
1551 
1552 static int nl80211_dump_mpath(struct sk_buff *skb,
1553 			      struct netlink_callback *cb)
1554 {
1555 	struct mpath_info pinfo;
1556 	struct cfg80211_registered_device *dev;
1557 	struct net_device *netdev;
1558 	u8 dst[ETH_ALEN];
1559 	u8 next_hop[ETH_ALEN];
1560 	int ifidx = cb->args[0];
1561 	int path_idx = cb->args[1];
1562 	int err;
1563 
1564 	if (!ifidx) {
1565 		err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1566 				  nl80211_fam.attrbuf, nl80211_fam.maxattr,
1567 				  nl80211_policy);
1568 		if (err)
1569 			return err;
1570 
1571 		if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
1572 			return -EINVAL;
1573 
1574 		ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1575 		if (!ifidx)
1576 			return -EINVAL;
1577 	}
1578 
1579 	netdev = dev_get_by_index(&init_net, ifidx);
1580 	if (!netdev)
1581 		return -ENODEV;
1582 
1583 	dev = cfg80211_get_dev_from_ifindex(ifidx);
1584 	if (IS_ERR(dev)) {
1585 		err = PTR_ERR(dev);
1586 		goto out_put_netdev;
1587 	}
1588 
1589 	if (!dev->ops->dump_mpath) {
1590 		err = -ENOSYS;
1591 		goto out_err;
1592 	}
1593 
1594 	rtnl_lock();
1595 
1596 	while (1) {
1597 		err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,
1598 					   dst, next_hop, &pinfo);
1599 		if (err == -ENOENT)
1600 			break;
1601 		if (err)
1602 			goto out_err_rtnl;
1603 
1604 		if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
1605 				       cb->nlh->nlmsg_seq, NLM_F_MULTI,
1606 				       netdev, dst, next_hop,
1607 				       &pinfo) < 0)
1608 			goto out;
1609 
1610 		path_idx++;
1611 	}
1612 
1613 
1614  out:
1615 	cb->args[1] = path_idx;
1616 	err = skb->len;
1617  out_err_rtnl:
1618 	rtnl_unlock();
1619  out_err:
1620 	cfg80211_put_dev(dev);
1621  out_put_netdev:
1622 	dev_put(netdev);
1623 
1624 	return err;
1625 }
1626 
1627 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1628 {
1629 	struct cfg80211_registered_device *drv;
1630 	int err;
1631 	struct net_device *dev;
1632 	struct mpath_info pinfo;
1633 	struct sk_buff *msg;
1634 	u8 *dst = NULL;
1635 	u8 next_hop[ETH_ALEN];
1636 
1637 	memset(&pinfo, 0, sizeof(pinfo));
1638 
1639 	if (!info->attrs[NL80211_ATTR_MAC])
1640 		return -EINVAL;
1641 
1642 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1643 
1644 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1645 	if (err)
1646 		return err;
1647 
1648 	if (!drv->ops->get_mpath) {
1649 		err = -EOPNOTSUPP;
1650 		goto out;
1651 	}
1652 
1653 	rtnl_lock();
1654 	err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
1655 	rtnl_unlock();
1656 
1657 	if (err)
1658 		goto out;
1659 
1660 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1661 	if (!msg)
1662 		goto out;
1663 
1664 	if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
1665 				 dev, dst, next_hop, &pinfo) < 0)
1666 		goto out_free;
1667 
1668 	err = genlmsg_unicast(msg, info->snd_pid);
1669 	goto out;
1670 
1671  out_free:
1672 	nlmsg_free(msg);
1673 
1674  out:
1675 	cfg80211_put_dev(drv);
1676 	dev_put(dev);
1677 	return err;
1678 }
1679 
1680 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
1681 {
1682 	struct cfg80211_registered_device *drv;
1683 	int err;
1684 	struct net_device *dev;
1685 	u8 *dst = NULL;
1686 	u8 *next_hop = NULL;
1687 
1688 	if (!info->attrs[NL80211_ATTR_MAC])
1689 		return -EINVAL;
1690 
1691 	if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1692 		return -EINVAL;
1693 
1694 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1695 	next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1696 
1697 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1698 	if (err)
1699 		return err;
1700 
1701 	if (!drv->ops->change_mpath) {
1702 		err = -EOPNOTSUPP;
1703 		goto out;
1704 	}
1705 
1706 	rtnl_lock();
1707 	err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
1708 	rtnl_unlock();
1709 
1710  out:
1711 	cfg80211_put_dev(drv);
1712 	dev_put(dev);
1713 	return err;
1714 }
1715 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
1716 {
1717 	struct cfg80211_registered_device *drv;
1718 	int err;
1719 	struct net_device *dev;
1720 	u8 *dst = NULL;
1721 	u8 *next_hop = NULL;
1722 
1723 	if (!info->attrs[NL80211_ATTR_MAC])
1724 		return -EINVAL;
1725 
1726 	if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1727 		return -EINVAL;
1728 
1729 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1730 	next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1731 
1732 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1733 	if (err)
1734 		return err;
1735 
1736 	if (!drv->ops->add_mpath) {
1737 		err = -EOPNOTSUPP;
1738 		goto out;
1739 	}
1740 
1741 	rtnl_lock();
1742 	err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
1743 	rtnl_unlock();
1744 
1745  out:
1746 	cfg80211_put_dev(drv);
1747 	dev_put(dev);
1748 	return err;
1749 }
1750 
1751 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1752 {
1753 	struct cfg80211_registered_device *drv;
1754 	int err;
1755 	struct net_device *dev;
1756 	u8 *dst = NULL;
1757 
1758 	if (info->attrs[NL80211_ATTR_MAC])
1759 		dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1760 
1761 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1762 	if (err)
1763 		return err;
1764 
1765 	if (!drv->ops->del_mpath) {
1766 		err = -EOPNOTSUPP;
1767 		goto out;
1768 	}
1769 
1770 	rtnl_lock();
1771 	err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
1772 	rtnl_unlock();
1773 
1774  out:
1775 	cfg80211_put_dev(drv);
1776 	dev_put(dev);
1777 	return err;
1778 }
1779 
1780 static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
1781 {
1782 	struct cfg80211_registered_device *drv;
1783 	int err;
1784 	struct net_device *dev;
1785 	struct bss_parameters params;
1786 
1787 	memset(&params, 0, sizeof(params));
1788 	/* default to not changing parameters */
1789 	params.use_cts_prot = -1;
1790 	params.use_short_preamble = -1;
1791 	params.use_short_slot_time = -1;
1792 
1793 	if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
1794 		params.use_cts_prot =
1795 		    nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
1796 	if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
1797 		params.use_short_preamble =
1798 		    nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
1799 	if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
1800 		params.use_short_slot_time =
1801 		    nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
1802 	if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
1803 		params.basic_rates =
1804 			nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
1805 		params.basic_rates_len =
1806 			nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
1807 	}
1808 
1809 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1810 	if (err)
1811 		return err;
1812 
1813 	if (!drv->ops->change_bss) {
1814 		err = -EOPNOTSUPP;
1815 		goto out;
1816 	}
1817 
1818 	rtnl_lock();
1819 	err = drv->ops->change_bss(&drv->wiphy, dev, &params);
1820 	rtnl_unlock();
1821 
1822  out:
1823 	cfg80211_put_dev(drv);
1824 	dev_put(dev);
1825 	return err;
1826 }
1827 
1828 static const struct nla_policy
1829 	reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
1830 	[NL80211_ATTR_REG_RULE_FLAGS]		= { .type = NLA_U32 },
1831 	[NL80211_ATTR_FREQ_RANGE_START]		= { .type = NLA_U32 },
1832 	[NL80211_ATTR_FREQ_RANGE_END]		= { .type = NLA_U32 },
1833 	[NL80211_ATTR_FREQ_RANGE_MAX_BW]	= { .type = NLA_U32 },
1834 	[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]	= { .type = NLA_U32 },
1835 	[NL80211_ATTR_POWER_RULE_MAX_EIRP]	= { .type = NLA_U32 },
1836 };
1837 
1838 static int parse_reg_rule(struct nlattr *tb[],
1839 	struct ieee80211_reg_rule *reg_rule)
1840 {
1841 	struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
1842 	struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
1843 
1844 	if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
1845 		return -EINVAL;
1846 	if (!tb[NL80211_ATTR_FREQ_RANGE_START])
1847 		return -EINVAL;
1848 	if (!tb[NL80211_ATTR_FREQ_RANGE_END])
1849 		return -EINVAL;
1850 	if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
1851 		return -EINVAL;
1852 	if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
1853 		return -EINVAL;
1854 
1855 	reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
1856 
1857 	freq_range->start_freq_khz =
1858 		nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
1859 	freq_range->end_freq_khz =
1860 		nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
1861 	freq_range->max_bandwidth_khz =
1862 		nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
1863 
1864 	power_rule->max_eirp =
1865 		nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
1866 
1867 	if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
1868 		power_rule->max_antenna_gain =
1869 			nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
1870 
1871 	return 0;
1872 }
1873 
1874 static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
1875 {
1876 	int r;
1877 	char *data = NULL;
1878 
1879 	if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
1880 		return -EINVAL;
1881 
1882 	data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
1883 
1884 #ifdef CONFIG_WIRELESS_OLD_REGULATORY
1885 	/* We ignore world regdom requests with the old regdom setup */
1886 	if (is_world_regdom(data))
1887 		return -EINVAL;
1888 #endif
1889 	mutex_lock(&cfg80211_drv_mutex);
1890 	r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY);
1891 	mutex_unlock(&cfg80211_drv_mutex);
1892 	return r;
1893 }
1894 
1895 static int nl80211_get_mesh_params(struct sk_buff *skb,
1896 	struct genl_info *info)
1897 {
1898 	struct cfg80211_registered_device *drv;
1899 	struct mesh_config cur_params;
1900 	int err;
1901 	struct net_device *dev;
1902 	void *hdr;
1903 	struct nlattr *pinfoattr;
1904 	struct sk_buff *msg;
1905 
1906 	/* Look up our device */
1907 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1908 	if (err)
1909 		return err;
1910 
1911 	if (!drv->ops->get_mesh_params) {
1912 		err = -EOPNOTSUPP;
1913 		goto out;
1914 	}
1915 
1916 	/* Get the mesh params */
1917 	rtnl_lock();
1918 	err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params);
1919 	rtnl_unlock();
1920 	if (err)
1921 		goto out;
1922 
1923 	/* Draw up a netlink message to send back */
1924 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1925 	if (!msg) {
1926 		err = -ENOBUFS;
1927 		goto out;
1928 	}
1929 	hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
1930 			     NL80211_CMD_GET_MESH_PARAMS);
1931 	if (!hdr)
1932 		goto nla_put_failure;
1933 	pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS);
1934 	if (!pinfoattr)
1935 		goto nla_put_failure;
1936 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1937 	NLA_PUT_U16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
1938 			cur_params.dot11MeshRetryTimeout);
1939 	NLA_PUT_U16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
1940 			cur_params.dot11MeshConfirmTimeout);
1941 	NLA_PUT_U16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
1942 			cur_params.dot11MeshHoldingTimeout);
1943 	NLA_PUT_U16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
1944 			cur_params.dot11MeshMaxPeerLinks);
1945 	NLA_PUT_U8(msg, NL80211_MESHCONF_MAX_RETRIES,
1946 			cur_params.dot11MeshMaxRetries);
1947 	NLA_PUT_U8(msg, NL80211_MESHCONF_TTL,
1948 			cur_params.dot11MeshTTL);
1949 	NLA_PUT_U8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
1950 			cur_params.auto_open_plinks);
1951 	NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
1952 			cur_params.dot11MeshHWMPmaxPREQretries);
1953 	NLA_PUT_U32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
1954 			cur_params.path_refresh_time);
1955 	NLA_PUT_U16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
1956 			cur_params.min_discovery_timeout);
1957 	NLA_PUT_U32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
1958 			cur_params.dot11MeshHWMPactivePathTimeout);
1959 	NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
1960 			cur_params.dot11MeshHWMPpreqMinInterval);
1961 	NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
1962 			cur_params.dot11MeshHWMPnetDiameterTraversalTime);
1963 	nla_nest_end(msg, pinfoattr);
1964 	genlmsg_end(msg, hdr);
1965 	err = genlmsg_unicast(msg, info->snd_pid);
1966 	goto out;
1967 
1968 nla_put_failure:
1969 	genlmsg_cancel(msg, hdr);
1970 	err = -EMSGSIZE;
1971 out:
1972 	/* Cleanup */
1973 	cfg80211_put_dev(drv);
1974 	dev_put(dev);
1975 	return err;
1976 }
1977 
1978 #define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
1979 do {\
1980 	if (table[attr_num]) {\
1981 		cfg.param = nla_fn(table[attr_num]); \
1982 		mask |= (1 << (attr_num - 1)); \
1983 	} \
1984 } while (0);\
1985 
1986 static struct nla_policy
1987 nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] __read_mostly = {
1988 	[NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
1989 	[NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
1990 	[NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
1991 	[NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
1992 	[NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
1993 	[NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
1994 	[NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
1995 
1996 	[NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
1997 	[NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
1998 	[NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
1999 	[NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
2000 	[NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
2001 	[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
2002 };
2003 
2004 static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2005 {
2006 	int err;
2007 	u32 mask;
2008 	struct cfg80211_registered_device *drv;
2009 	struct net_device *dev;
2010 	struct mesh_config cfg;
2011 	struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
2012 	struct nlattr *parent_attr;
2013 
2014 	parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS];
2015 	if (!parent_attr)
2016 		return -EINVAL;
2017 	if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
2018 			parent_attr, nl80211_meshconf_params_policy))
2019 		return -EINVAL;
2020 
2021 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2022 	if (err)
2023 		return err;
2024 
2025 	if (!drv->ops->set_mesh_params) {
2026 		err = -EOPNOTSUPP;
2027 		goto out;
2028 	}
2029 
2030 	/* This makes sure that there aren't more than 32 mesh config
2031 	 * parameters (otherwise our bitfield scheme would not work.) */
2032 	BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
2033 
2034 	/* Fill in the params struct */
2035 	mask = 0;
2036 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
2037 			mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
2038 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
2039 			mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16);
2040 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
2041 			mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16);
2042 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
2043 			mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16);
2044 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
2045 			mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
2046 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
2047 			mask, NL80211_MESHCONF_TTL, nla_get_u8);
2048 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
2049 			mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
2050 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
2051 			mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
2052 			nla_get_u8);
2053 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
2054 			mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32);
2055 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
2056 			mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
2057 			nla_get_u16);
2058 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
2059 			mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
2060 			nla_get_u32);
2061 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
2062 			mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
2063 			nla_get_u16);
2064 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
2065 			dot11MeshHWMPnetDiameterTraversalTime,
2066 			mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
2067 			nla_get_u16);
2068 
2069 	/* Apply changes */
2070 	rtnl_lock();
2071 	err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask);
2072 	rtnl_unlock();
2073 
2074  out:
2075 	/* cleanup */
2076 	cfg80211_put_dev(drv);
2077 	dev_put(dev);
2078 	return err;
2079 }
2080 
2081 #undef FILL_IN_MESH_PARAM_IF_SET
2082 
2083 static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2084 {
2085 	struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
2086 	struct nlattr *nl_reg_rule;
2087 	char *alpha2 = NULL;
2088 	int rem_reg_rules = 0, r = 0;
2089 	u32 num_rules = 0, rule_idx = 0, size_of_regd;
2090 	struct ieee80211_regdomain *rd = NULL;
2091 
2092 	if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
2093 		return -EINVAL;
2094 
2095 	if (!info->attrs[NL80211_ATTR_REG_RULES])
2096 		return -EINVAL;
2097 
2098 	alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
2099 
2100 	nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
2101 			rem_reg_rules) {
2102 		num_rules++;
2103 		if (num_rules > NL80211_MAX_SUPP_REG_RULES)
2104 			goto bad_reg;
2105 	}
2106 
2107 	if (!reg_is_valid_request(alpha2))
2108 		return -EINVAL;
2109 
2110 	size_of_regd = sizeof(struct ieee80211_regdomain) +
2111 		(num_rules * sizeof(struct ieee80211_reg_rule));
2112 
2113 	rd = kzalloc(size_of_regd, GFP_KERNEL);
2114 	if (!rd)
2115 		return -ENOMEM;
2116 
2117 	rd->n_reg_rules = num_rules;
2118 	rd->alpha2[0] = alpha2[0];
2119 	rd->alpha2[1] = alpha2[1];
2120 
2121 	nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
2122 			rem_reg_rules) {
2123 		nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
2124 			nla_data(nl_reg_rule), nla_len(nl_reg_rule),
2125 			reg_rule_policy);
2126 		r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
2127 		if (r)
2128 			goto bad_reg;
2129 
2130 		rule_idx++;
2131 
2132 		if (rule_idx > NL80211_MAX_SUPP_REG_RULES)
2133 			goto bad_reg;
2134 	}
2135 
2136 	BUG_ON(rule_idx != num_rules);
2137 
2138 	mutex_lock(&cfg80211_drv_mutex);
2139 	r = set_regdom(rd);
2140 	mutex_unlock(&cfg80211_drv_mutex);
2141 	return r;
2142 
2143  bad_reg:
2144 	kfree(rd);
2145 	return -EINVAL;
2146 }
2147 
2148 static struct genl_ops nl80211_ops[] = {
2149 	{
2150 		.cmd = NL80211_CMD_GET_WIPHY,
2151 		.doit = nl80211_get_wiphy,
2152 		.dumpit = nl80211_dump_wiphy,
2153 		.policy = nl80211_policy,
2154 		/* can be retrieved by unprivileged users */
2155 	},
2156 	{
2157 		.cmd = NL80211_CMD_SET_WIPHY,
2158 		.doit = nl80211_set_wiphy,
2159 		.policy = nl80211_policy,
2160 		.flags = GENL_ADMIN_PERM,
2161 	},
2162 	{
2163 		.cmd = NL80211_CMD_GET_INTERFACE,
2164 		.doit = nl80211_get_interface,
2165 		.dumpit = nl80211_dump_interface,
2166 		.policy = nl80211_policy,
2167 		/* can be retrieved by unprivileged users */
2168 	},
2169 	{
2170 		.cmd = NL80211_CMD_SET_INTERFACE,
2171 		.doit = nl80211_set_interface,
2172 		.policy = nl80211_policy,
2173 		.flags = GENL_ADMIN_PERM,
2174 	},
2175 	{
2176 		.cmd = NL80211_CMD_NEW_INTERFACE,
2177 		.doit = nl80211_new_interface,
2178 		.policy = nl80211_policy,
2179 		.flags = GENL_ADMIN_PERM,
2180 	},
2181 	{
2182 		.cmd = NL80211_CMD_DEL_INTERFACE,
2183 		.doit = nl80211_del_interface,
2184 		.policy = nl80211_policy,
2185 		.flags = GENL_ADMIN_PERM,
2186 	},
2187 	{
2188 		.cmd = NL80211_CMD_GET_KEY,
2189 		.doit = nl80211_get_key,
2190 		.policy = nl80211_policy,
2191 		.flags = GENL_ADMIN_PERM,
2192 	},
2193 	{
2194 		.cmd = NL80211_CMD_SET_KEY,
2195 		.doit = nl80211_set_key,
2196 		.policy = nl80211_policy,
2197 		.flags = GENL_ADMIN_PERM,
2198 	},
2199 	{
2200 		.cmd = NL80211_CMD_NEW_KEY,
2201 		.doit = nl80211_new_key,
2202 		.policy = nl80211_policy,
2203 		.flags = GENL_ADMIN_PERM,
2204 	},
2205 	{
2206 		.cmd = NL80211_CMD_DEL_KEY,
2207 		.doit = nl80211_del_key,
2208 		.policy = nl80211_policy,
2209 		.flags = GENL_ADMIN_PERM,
2210 	},
2211 	{
2212 		.cmd = NL80211_CMD_SET_BEACON,
2213 		.policy = nl80211_policy,
2214 		.flags = GENL_ADMIN_PERM,
2215 		.doit = nl80211_addset_beacon,
2216 	},
2217 	{
2218 		.cmd = NL80211_CMD_NEW_BEACON,
2219 		.policy = nl80211_policy,
2220 		.flags = GENL_ADMIN_PERM,
2221 		.doit = nl80211_addset_beacon,
2222 	},
2223 	{
2224 		.cmd = NL80211_CMD_DEL_BEACON,
2225 		.policy = nl80211_policy,
2226 		.flags = GENL_ADMIN_PERM,
2227 		.doit = nl80211_del_beacon,
2228 	},
2229 	{
2230 		.cmd = NL80211_CMD_GET_STATION,
2231 		.doit = nl80211_get_station,
2232 		.dumpit = nl80211_dump_station,
2233 		.policy = nl80211_policy,
2234 		.flags = GENL_ADMIN_PERM,
2235 	},
2236 	{
2237 		.cmd = NL80211_CMD_SET_STATION,
2238 		.doit = nl80211_set_station,
2239 		.policy = nl80211_policy,
2240 		.flags = GENL_ADMIN_PERM,
2241 	},
2242 	{
2243 		.cmd = NL80211_CMD_NEW_STATION,
2244 		.doit = nl80211_new_station,
2245 		.policy = nl80211_policy,
2246 		.flags = GENL_ADMIN_PERM,
2247 	},
2248 	{
2249 		.cmd = NL80211_CMD_DEL_STATION,
2250 		.doit = nl80211_del_station,
2251 		.policy = nl80211_policy,
2252 		.flags = GENL_ADMIN_PERM,
2253 	},
2254 	{
2255 		.cmd = NL80211_CMD_GET_MPATH,
2256 		.doit = nl80211_get_mpath,
2257 		.dumpit = nl80211_dump_mpath,
2258 		.policy = nl80211_policy,
2259 		.flags = GENL_ADMIN_PERM,
2260 	},
2261 	{
2262 		.cmd = NL80211_CMD_SET_MPATH,
2263 		.doit = nl80211_set_mpath,
2264 		.policy = nl80211_policy,
2265 		.flags = GENL_ADMIN_PERM,
2266 	},
2267 	{
2268 		.cmd = NL80211_CMD_NEW_MPATH,
2269 		.doit = nl80211_new_mpath,
2270 		.policy = nl80211_policy,
2271 		.flags = GENL_ADMIN_PERM,
2272 	},
2273 	{
2274 		.cmd = NL80211_CMD_DEL_MPATH,
2275 		.doit = nl80211_del_mpath,
2276 		.policy = nl80211_policy,
2277 		.flags = GENL_ADMIN_PERM,
2278 	},
2279 	{
2280 		.cmd = NL80211_CMD_SET_BSS,
2281 		.doit = nl80211_set_bss,
2282 		.policy = nl80211_policy,
2283 		.flags = GENL_ADMIN_PERM,
2284 	},
2285 	{
2286 		.cmd = NL80211_CMD_SET_REG,
2287 		.doit = nl80211_set_reg,
2288 		.policy = nl80211_policy,
2289 		.flags = GENL_ADMIN_PERM,
2290 	},
2291 	{
2292 		.cmd = NL80211_CMD_REQ_SET_REG,
2293 		.doit = nl80211_req_set_reg,
2294 		.policy = nl80211_policy,
2295 		.flags = GENL_ADMIN_PERM,
2296 	},
2297 	{
2298 		.cmd = NL80211_CMD_GET_MESH_PARAMS,
2299 		.doit = nl80211_get_mesh_params,
2300 		.policy = nl80211_policy,
2301 		/* can be retrieved by unprivileged users */
2302 	},
2303 	{
2304 		.cmd = NL80211_CMD_SET_MESH_PARAMS,
2305 		.doit = nl80211_set_mesh_params,
2306 		.policy = nl80211_policy,
2307 		.flags = GENL_ADMIN_PERM,
2308 	},
2309 };
2310 
2311 /* multicast groups */
2312 static struct genl_multicast_group nl80211_config_mcgrp = {
2313 	.name = "config",
2314 };
2315 
2316 /* notification functions */
2317 
2318 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
2319 {
2320 	struct sk_buff *msg;
2321 
2322 	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2323 	if (!msg)
2324 		return;
2325 
2326 	if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
2327 		nlmsg_free(msg);
2328 		return;
2329 	}
2330 
2331 	genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
2332 }
2333 
2334 /* initialisation/exit functions */
2335 
2336 int nl80211_init(void)
2337 {
2338 	int err, i;
2339 
2340 	err = genl_register_family(&nl80211_fam);
2341 	if (err)
2342 		return err;
2343 
2344 	for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
2345 		err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
2346 		if (err)
2347 			goto err_out;
2348 	}
2349 
2350 	err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
2351 	if (err)
2352 		goto err_out;
2353 
2354 	return 0;
2355  err_out:
2356 	genl_unregister_family(&nl80211_fam);
2357 	return err;
2358 }
2359 
2360 void nl80211_exit(void)
2361 {
2362 	genl_unregister_family(&nl80211_fam);
2363 }
2364