xref: /linux/net/mac80211/cfg.c (revision 367b8112fe2ea5c39a7bb4d263dcdd9b612fae18)
1 /*
2  * mac80211 configuration hooks for cfg80211
3  *
4  * Copyright 2006, 2007	Johannes Berg <johannes@sipsolutions.net>
5  *
6  * This file is GPLv2 as found in COPYING.
7  */
8 
9 #include <linux/ieee80211.h>
10 #include <linux/nl80211.h>
11 #include <linux/rtnetlink.h>
12 #include <net/net_namespace.h>
13 #include <linux/rcupdate.h>
14 #include <net/cfg80211.h>
15 #include "ieee80211_i.h"
16 #include "cfg.h"
17 #include "rate.h"
18 #include "mesh.h"
19 
20 struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy)
21 {
22 	struct ieee80211_local *local = wiphy_priv(wiphy);
23 	return &local->hw;
24 }
25 EXPORT_SYMBOL(wiphy_to_hw);
26 
27 static bool nl80211_type_check(enum nl80211_iftype type)
28 {
29 	switch (type) {
30 	case NL80211_IFTYPE_ADHOC:
31 	case NL80211_IFTYPE_STATION:
32 	case NL80211_IFTYPE_MONITOR:
33 #ifdef CONFIG_MAC80211_MESH
34 	case NL80211_IFTYPE_MESH_POINT:
35 #endif
36 	case NL80211_IFTYPE_WDS:
37 		return true;
38 	default:
39 		return false;
40 	}
41 }
42 
43 static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
44 			       enum nl80211_iftype type, u32 *flags,
45 			       struct vif_params *params)
46 {
47 	struct ieee80211_local *local = wiphy_priv(wiphy);
48 	struct net_device *dev;
49 	struct ieee80211_sub_if_data *sdata;
50 	int err;
51 
52 	if (!nl80211_type_check(type))
53 		return -EINVAL;
54 
55 	err = ieee80211_if_add(local, name, &dev, type, params);
56 	if (err || type != NL80211_IFTYPE_MONITOR || !flags)
57 		return err;
58 
59 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
60 	sdata->u.mntr_flags = *flags;
61 	return 0;
62 }
63 
64 static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
65 {
66 	struct net_device *dev;
67 	struct ieee80211_sub_if_data *sdata;
68 
69 	/* we're under RTNL */
70 	dev = __dev_get_by_index(&init_net, ifindex);
71 	if (!dev)
72 		return -ENODEV;
73 
74 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
75 
76 	ieee80211_if_remove(sdata);
77 
78 	return 0;
79 }
80 
81 static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
82 				  enum nl80211_iftype type, u32 *flags,
83 				  struct vif_params *params)
84 {
85 	struct net_device *dev;
86 	struct ieee80211_sub_if_data *sdata;
87 	int ret;
88 
89 	/* we're under RTNL */
90 	dev = __dev_get_by_index(&init_net, ifindex);
91 	if (!dev)
92 		return -ENODEV;
93 
94 	if (!nl80211_type_check(type))
95 		return -EINVAL;
96 
97 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
98 
99 	ret = ieee80211_if_change_type(sdata, type);
100 	if (ret)
101 		return ret;
102 
103 	if (netif_running(sdata->dev))
104 		return -EBUSY;
105 
106 	if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
107 		ieee80211_sdata_set_mesh_id(sdata,
108 					    params->mesh_id_len,
109 					    params->mesh_id);
110 
111 	if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
112 		return 0;
113 
114 	sdata->u.mntr_flags = *flags;
115 	return 0;
116 }
117 
118 static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
119 			     u8 key_idx, u8 *mac_addr,
120 			     struct key_params *params)
121 {
122 	struct ieee80211_sub_if_data *sdata;
123 	struct sta_info *sta = NULL;
124 	enum ieee80211_key_alg alg;
125 	struct ieee80211_key *key;
126 	int err;
127 
128 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
129 
130 	switch (params->cipher) {
131 	case WLAN_CIPHER_SUITE_WEP40:
132 	case WLAN_CIPHER_SUITE_WEP104:
133 		alg = ALG_WEP;
134 		break;
135 	case WLAN_CIPHER_SUITE_TKIP:
136 		alg = ALG_TKIP;
137 		break;
138 	case WLAN_CIPHER_SUITE_CCMP:
139 		alg = ALG_CCMP;
140 		break;
141 	default:
142 		return -EINVAL;
143 	}
144 
145 	key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);
146 	if (!key)
147 		return -ENOMEM;
148 
149 	rcu_read_lock();
150 
151 	if (mac_addr) {
152 		sta = sta_info_get(sdata->local, mac_addr);
153 		if (!sta) {
154 			ieee80211_key_free(key);
155 			err = -ENOENT;
156 			goto out_unlock;
157 		}
158 	}
159 
160 	ieee80211_key_link(key, sdata, sta);
161 
162 	err = 0;
163  out_unlock:
164 	rcu_read_unlock();
165 
166 	return err;
167 }
168 
169 static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
170 			     u8 key_idx, u8 *mac_addr)
171 {
172 	struct ieee80211_sub_if_data *sdata;
173 	struct sta_info *sta;
174 	int ret;
175 
176 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
177 
178 	rcu_read_lock();
179 
180 	if (mac_addr) {
181 		ret = -ENOENT;
182 
183 		sta = sta_info_get(sdata->local, mac_addr);
184 		if (!sta)
185 			goto out_unlock;
186 
187 		if (sta->key) {
188 			ieee80211_key_free(sta->key);
189 			WARN_ON(sta->key);
190 			ret = 0;
191 		}
192 
193 		goto out_unlock;
194 	}
195 
196 	if (!sdata->keys[key_idx]) {
197 		ret = -ENOENT;
198 		goto out_unlock;
199 	}
200 
201 	ieee80211_key_free(sdata->keys[key_idx]);
202 	WARN_ON(sdata->keys[key_idx]);
203 
204 	ret = 0;
205  out_unlock:
206 	rcu_read_unlock();
207 
208 	return ret;
209 }
210 
211 static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
212 			     u8 key_idx, u8 *mac_addr, void *cookie,
213 			     void (*callback)(void *cookie,
214 					      struct key_params *params))
215 {
216 	struct ieee80211_sub_if_data *sdata;
217 	struct sta_info *sta = NULL;
218 	u8 seq[6] = {0};
219 	struct key_params params;
220 	struct ieee80211_key *key;
221 	u32 iv32;
222 	u16 iv16;
223 	int err = -ENOENT;
224 
225 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
226 
227 	rcu_read_lock();
228 
229 	if (mac_addr) {
230 		sta = sta_info_get(sdata->local, mac_addr);
231 		if (!sta)
232 			goto out;
233 
234 		key = sta->key;
235 	} else
236 		key = sdata->keys[key_idx];
237 
238 	if (!key)
239 		goto out;
240 
241 	memset(&params, 0, sizeof(params));
242 
243 	switch (key->conf.alg) {
244 	case ALG_TKIP:
245 		params.cipher = WLAN_CIPHER_SUITE_TKIP;
246 
247 		iv32 = key->u.tkip.tx.iv32;
248 		iv16 = key->u.tkip.tx.iv16;
249 
250 		if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
251 		    sdata->local->ops->get_tkip_seq)
252 			sdata->local->ops->get_tkip_seq(
253 				local_to_hw(sdata->local),
254 				key->conf.hw_key_idx,
255 				&iv32, &iv16);
256 
257 		seq[0] = iv16 & 0xff;
258 		seq[1] = (iv16 >> 8) & 0xff;
259 		seq[2] = iv32 & 0xff;
260 		seq[3] = (iv32 >> 8) & 0xff;
261 		seq[4] = (iv32 >> 16) & 0xff;
262 		seq[5] = (iv32 >> 24) & 0xff;
263 		params.seq = seq;
264 		params.seq_len = 6;
265 		break;
266 	case ALG_CCMP:
267 		params.cipher = WLAN_CIPHER_SUITE_CCMP;
268 		seq[0] = key->u.ccmp.tx_pn[5];
269 		seq[1] = key->u.ccmp.tx_pn[4];
270 		seq[2] = key->u.ccmp.tx_pn[3];
271 		seq[3] = key->u.ccmp.tx_pn[2];
272 		seq[4] = key->u.ccmp.tx_pn[1];
273 		seq[5] = key->u.ccmp.tx_pn[0];
274 		params.seq = seq;
275 		params.seq_len = 6;
276 		break;
277 	case ALG_WEP:
278 		if (key->conf.keylen == 5)
279 			params.cipher = WLAN_CIPHER_SUITE_WEP40;
280 		else
281 			params.cipher = WLAN_CIPHER_SUITE_WEP104;
282 		break;
283 	}
284 
285 	params.key = key->conf.key;
286 	params.key_len = key->conf.keylen;
287 
288 	callback(cookie, &params);
289 	err = 0;
290 
291  out:
292 	rcu_read_unlock();
293 	return err;
294 }
295 
296 static int ieee80211_config_default_key(struct wiphy *wiphy,
297 					struct net_device *dev,
298 					u8 key_idx)
299 {
300 	struct ieee80211_sub_if_data *sdata;
301 
302 	rcu_read_lock();
303 
304 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
305 	ieee80211_set_default_key(sdata, key_idx);
306 
307 	rcu_read_unlock();
308 
309 	return 0;
310 }
311 
312 static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
313 {
314 	struct ieee80211_sub_if_data *sdata = sta->sdata;
315 
316 	sinfo->filled = STATION_INFO_INACTIVE_TIME |
317 			STATION_INFO_RX_BYTES |
318 			STATION_INFO_TX_BYTES;
319 
320 	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
321 	sinfo->rx_bytes = sta->rx_bytes;
322 	sinfo->tx_bytes = sta->tx_bytes;
323 
324 	if (ieee80211_vif_is_mesh(&sdata->vif)) {
325 #ifdef CONFIG_MAC80211_MESH
326 		sinfo->filled |= STATION_INFO_LLID |
327 				 STATION_INFO_PLID |
328 				 STATION_INFO_PLINK_STATE;
329 
330 		sinfo->llid = le16_to_cpu(sta->llid);
331 		sinfo->plid = le16_to_cpu(sta->plid);
332 		sinfo->plink_state = sta->plink_state;
333 #endif
334 	}
335 }
336 
337 
338 static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
339 				 int idx, u8 *mac, struct station_info *sinfo)
340 {
341 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
342 	struct sta_info *sta;
343 	int ret = -ENOENT;
344 
345 	rcu_read_lock();
346 
347 	sta = sta_info_get_by_idx(local, idx, dev);
348 	if (sta) {
349 		ret = 0;
350 		memcpy(mac, sta->sta.addr, ETH_ALEN);
351 		sta_set_sinfo(sta, sinfo);
352 	}
353 
354 	rcu_read_unlock();
355 
356 	return ret;
357 }
358 
359 static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
360 				 u8 *mac, struct station_info *sinfo)
361 {
362 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
363 	struct sta_info *sta;
364 	int ret = -ENOENT;
365 
366 	rcu_read_lock();
367 
368 	/* XXX: verify sta->dev == dev */
369 
370 	sta = sta_info_get(local, mac);
371 	if (sta) {
372 		ret = 0;
373 		sta_set_sinfo(sta, sinfo);
374 	}
375 
376 	rcu_read_unlock();
377 
378 	return ret;
379 }
380 
381 /*
382  * This handles both adding a beacon and setting new beacon info
383  */
384 static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
385 				   struct beacon_parameters *params)
386 {
387 	struct beacon_data *new, *old;
388 	int new_head_len, new_tail_len;
389 	int size;
390 	int err = -EINVAL;
391 
392 	old = sdata->u.ap.beacon;
393 
394 	/* head must not be zero-length */
395 	if (params->head && !params->head_len)
396 		return -EINVAL;
397 
398 	/*
399 	 * This is a kludge. beacon interval should really be part
400 	 * of the beacon information.
401 	 */
402 	if (params->interval) {
403 		sdata->local->hw.conf.beacon_int = params->interval;
404 		if (ieee80211_hw_config(sdata->local))
405 			return -EINVAL;
406 		/*
407 		 * We updated some parameter so if below bails out
408 		 * it's not an error.
409 		 */
410 		err = 0;
411 	}
412 
413 	/* Need to have a beacon head if we don't have one yet */
414 	if (!params->head && !old)
415 		return err;
416 
417 	/* sorry, no way to start beaconing without dtim period */
418 	if (!params->dtim_period && !old)
419 		return err;
420 
421 	/* new or old head? */
422 	if (params->head)
423 		new_head_len = params->head_len;
424 	else
425 		new_head_len = old->head_len;
426 
427 	/* new or old tail? */
428 	if (params->tail || !old)
429 		/* params->tail_len will be zero for !params->tail */
430 		new_tail_len = params->tail_len;
431 	else
432 		new_tail_len = old->tail_len;
433 
434 	size = sizeof(*new) + new_head_len + new_tail_len;
435 
436 	new = kzalloc(size, GFP_KERNEL);
437 	if (!new)
438 		return -ENOMEM;
439 
440 	/* start filling the new info now */
441 
442 	/* new or old dtim period? */
443 	if (params->dtim_period)
444 		new->dtim_period = params->dtim_period;
445 	else
446 		new->dtim_period = old->dtim_period;
447 
448 	/*
449 	 * pointers go into the block we allocated,
450 	 * memory is | beacon_data | head | tail |
451 	 */
452 	new->head = ((u8 *) new) + sizeof(*new);
453 	new->tail = new->head + new_head_len;
454 	new->head_len = new_head_len;
455 	new->tail_len = new_tail_len;
456 
457 	/* copy in head */
458 	if (params->head)
459 		memcpy(new->head, params->head, new_head_len);
460 	else
461 		memcpy(new->head, old->head, new_head_len);
462 
463 	/* copy in optional tail */
464 	if (params->tail)
465 		memcpy(new->tail, params->tail, new_tail_len);
466 	else
467 		if (old)
468 			memcpy(new->tail, old->tail, new_tail_len);
469 
470 	rcu_assign_pointer(sdata->u.ap.beacon, new);
471 
472 	synchronize_rcu();
473 
474 	kfree(old);
475 
476 	return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
477 }
478 
479 static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
480 				struct beacon_parameters *params)
481 {
482 	struct ieee80211_sub_if_data *sdata;
483 	struct beacon_data *old;
484 
485 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
486 
487 	if (sdata->vif.type != NL80211_IFTYPE_AP)
488 		return -EINVAL;
489 
490 	old = sdata->u.ap.beacon;
491 
492 	if (old)
493 		return -EALREADY;
494 
495 	return ieee80211_config_beacon(sdata, params);
496 }
497 
498 static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
499 				struct beacon_parameters *params)
500 {
501 	struct ieee80211_sub_if_data *sdata;
502 	struct beacon_data *old;
503 
504 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
505 
506 	if (sdata->vif.type != NL80211_IFTYPE_AP)
507 		return -EINVAL;
508 
509 	old = sdata->u.ap.beacon;
510 
511 	if (!old)
512 		return -ENOENT;
513 
514 	return ieee80211_config_beacon(sdata, params);
515 }
516 
517 static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
518 {
519 	struct ieee80211_sub_if_data *sdata;
520 	struct beacon_data *old;
521 
522 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
523 
524 	if (sdata->vif.type != NL80211_IFTYPE_AP)
525 		return -EINVAL;
526 
527 	old = sdata->u.ap.beacon;
528 
529 	if (!old)
530 		return -ENOENT;
531 
532 	rcu_assign_pointer(sdata->u.ap.beacon, NULL);
533 	synchronize_rcu();
534 	kfree(old);
535 
536 	return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
537 }
538 
539 /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
540 struct iapp_layer2_update {
541 	u8 da[ETH_ALEN];	/* broadcast */
542 	u8 sa[ETH_ALEN];	/* STA addr */
543 	__be16 len;		/* 6 */
544 	u8 dsap;		/* 0 */
545 	u8 ssap;		/* 0 */
546 	u8 control;
547 	u8 xid_info[3];
548 } __attribute__ ((packed));
549 
550 static void ieee80211_send_layer2_update(struct sta_info *sta)
551 {
552 	struct iapp_layer2_update *msg;
553 	struct sk_buff *skb;
554 
555 	/* Send Level 2 Update Frame to update forwarding tables in layer 2
556 	 * bridge devices */
557 
558 	skb = dev_alloc_skb(sizeof(*msg));
559 	if (!skb)
560 		return;
561 	msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
562 
563 	/* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
564 	 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
565 
566 	memset(msg->da, 0xff, ETH_ALEN);
567 	memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
568 	msg->len = htons(6);
569 	msg->dsap = 0;
570 	msg->ssap = 0x01;	/* NULL LSAP, CR Bit: Response */
571 	msg->control = 0xaf;	/* XID response lsb.1111F101.
572 				 * F=0 (no poll command; unsolicited frame) */
573 	msg->xid_info[0] = 0x81;	/* XID format identifier */
574 	msg->xid_info[1] = 1;	/* LLC types/classes: Type 1 LLC */
575 	msg->xid_info[2] = 0;	/* XID sender's receive window size (RW) */
576 
577 	skb->dev = sta->sdata->dev;
578 	skb->protocol = eth_type_trans(skb, sta->sdata->dev);
579 	memset(skb->cb, 0, sizeof(skb->cb));
580 	netif_rx(skb);
581 }
582 
583 static void sta_apply_parameters(struct ieee80211_local *local,
584 				 struct sta_info *sta,
585 				 struct station_parameters *params)
586 {
587 	u32 rates;
588 	int i, j;
589 	struct ieee80211_supported_band *sband;
590 	struct ieee80211_sub_if_data *sdata = sta->sdata;
591 
592 	/*
593 	 * FIXME: updating the flags is racy when this function is
594 	 *	  called from ieee80211_change_station(), this will
595 	 *	  be resolved in a future patch.
596 	 */
597 
598 	if (params->station_flags & STATION_FLAG_CHANGED) {
599 		spin_lock_bh(&sta->lock);
600 		sta->flags &= ~WLAN_STA_AUTHORIZED;
601 		if (params->station_flags & STATION_FLAG_AUTHORIZED)
602 			sta->flags |= WLAN_STA_AUTHORIZED;
603 
604 		sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
605 		if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
606 			sta->flags |= WLAN_STA_SHORT_PREAMBLE;
607 
608 		sta->flags &= ~WLAN_STA_WME;
609 		if (params->station_flags & STATION_FLAG_WME)
610 			sta->flags |= WLAN_STA_WME;
611 		spin_unlock_bh(&sta->lock);
612 	}
613 
614 	/*
615 	 * FIXME: updating the following information is racy when this
616 	 *	  function is called from ieee80211_change_station().
617 	 *	  However, all this information should be static so
618 	 *	  maybe we should just reject attemps to change it.
619 	 */
620 
621 	if (params->aid) {
622 		sta->sta.aid = params->aid;
623 		if (sta->sta.aid > IEEE80211_MAX_AID)
624 			sta->sta.aid = 0; /* XXX: should this be an error? */
625 	}
626 
627 	if (params->listen_interval >= 0)
628 		sta->listen_interval = params->listen_interval;
629 
630 	if (params->supported_rates) {
631 		rates = 0;
632 		sband = local->hw.wiphy->bands[local->oper_channel->band];
633 
634 		for (i = 0; i < params->supported_rates_len; i++) {
635 			int rate = (params->supported_rates[i] & 0x7f) * 5;
636 			for (j = 0; j < sband->n_bitrates; j++) {
637 				if (sband->bitrates[j].bitrate == rate)
638 					rates |= BIT(j);
639 			}
640 		}
641 		sta->sta.supp_rates[local->oper_channel->band] = rates;
642 	}
643 
644 	if (params->ht_capa) {
645 		ieee80211_ht_cap_ie_to_ht_info(params->ht_capa,
646 					       &sta->sta.ht_info);
647 	}
648 
649 	if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
650 		switch (params->plink_action) {
651 		case PLINK_ACTION_OPEN:
652 			mesh_plink_open(sta);
653 			break;
654 		case PLINK_ACTION_BLOCK:
655 			mesh_plink_block(sta);
656 			break;
657 		}
658 	}
659 }
660 
661 static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
662 				 u8 *mac, struct station_parameters *params)
663 {
664 	struct ieee80211_local *local = wiphy_priv(wiphy);
665 	struct sta_info *sta;
666 	struct ieee80211_sub_if_data *sdata;
667 	int err;
668 
669 	/* Prevent a race with changing the rate control algorithm */
670 	if (!netif_running(dev))
671 		return -ENETDOWN;
672 
673 	if (params->vlan) {
674 		sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
675 
676 		if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
677 		    sdata->vif.type != NL80211_IFTYPE_AP)
678 			return -EINVAL;
679 	} else
680 		sdata = IEEE80211_DEV_TO_SUB_IF(dev);
681 
682 	if (compare_ether_addr(mac, dev->dev_addr) == 0)
683 		return -EINVAL;
684 
685 	if (is_multicast_ether_addr(mac))
686 		return -EINVAL;
687 
688 	sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
689 	if (!sta)
690 		return -ENOMEM;
691 
692 	sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
693 
694 	sta_apply_parameters(local, sta, params);
695 
696 	rate_control_rate_init(sta);
697 
698 	rcu_read_lock();
699 
700 	err = sta_info_insert(sta);
701 	if (err) {
702 		/* STA has been freed */
703 		rcu_read_unlock();
704 		return err;
705 	}
706 
707 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
708 	    sdata->vif.type == NL80211_IFTYPE_AP)
709 		ieee80211_send_layer2_update(sta);
710 
711 	rcu_read_unlock();
712 
713 	return 0;
714 }
715 
716 static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
717 				 u8 *mac)
718 {
719 	struct ieee80211_local *local = wiphy_priv(wiphy);
720 	struct ieee80211_sub_if_data *sdata;
721 	struct sta_info *sta;
722 
723 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
724 
725 	if (mac) {
726 		rcu_read_lock();
727 
728 		/* XXX: get sta belonging to dev */
729 		sta = sta_info_get(local, mac);
730 		if (!sta) {
731 			rcu_read_unlock();
732 			return -ENOENT;
733 		}
734 
735 		sta_info_unlink(&sta);
736 		rcu_read_unlock();
737 
738 		sta_info_destroy(sta);
739 	} else
740 		sta_info_flush(local, sdata);
741 
742 	return 0;
743 }
744 
745 static int ieee80211_change_station(struct wiphy *wiphy,
746 				    struct net_device *dev,
747 				    u8 *mac,
748 				    struct station_parameters *params)
749 {
750 	struct ieee80211_local *local = wiphy_priv(wiphy);
751 	struct sta_info *sta;
752 	struct ieee80211_sub_if_data *vlansdata;
753 
754 	rcu_read_lock();
755 
756 	/* XXX: get sta belonging to dev */
757 	sta = sta_info_get(local, mac);
758 	if (!sta) {
759 		rcu_read_unlock();
760 		return -ENOENT;
761 	}
762 
763 	if (params->vlan && params->vlan != sta->sdata->dev) {
764 		vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
765 
766 		if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
767 		    vlansdata->vif.type != NL80211_IFTYPE_AP) {
768 			rcu_read_unlock();
769 			return -EINVAL;
770 		}
771 
772 		sta->sdata = vlansdata;
773 		ieee80211_send_layer2_update(sta);
774 	}
775 
776 	sta_apply_parameters(local, sta, params);
777 
778 	rcu_read_unlock();
779 
780 	return 0;
781 }
782 
783 #ifdef CONFIG_MAC80211_MESH
784 static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
785 				 u8 *dst, u8 *next_hop)
786 {
787 	struct ieee80211_local *local = wiphy_priv(wiphy);
788 	struct ieee80211_sub_if_data *sdata;
789 	struct mesh_path *mpath;
790 	struct sta_info *sta;
791 	int err;
792 
793 	if (!netif_running(dev))
794 		return -ENETDOWN;
795 
796 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
797 
798 	if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
799 		return -ENOTSUPP;
800 
801 	rcu_read_lock();
802 	sta = sta_info_get(local, next_hop);
803 	if (!sta) {
804 		rcu_read_unlock();
805 		return -ENOENT;
806 	}
807 
808 	err = mesh_path_add(dst, sdata);
809 	if (err) {
810 		rcu_read_unlock();
811 		return err;
812 	}
813 
814 	mpath = mesh_path_lookup(dst, sdata);
815 	if (!mpath) {
816 		rcu_read_unlock();
817 		return -ENXIO;
818 	}
819 	mesh_path_fix_nexthop(mpath, sta);
820 
821 	rcu_read_unlock();
822 	return 0;
823 }
824 
825 static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
826 				 u8 *dst)
827 {
828 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
829 
830 	if (dst)
831 		return mesh_path_del(dst, sdata);
832 
833 	mesh_path_flush(sdata);
834 	return 0;
835 }
836 
837 static int ieee80211_change_mpath(struct wiphy *wiphy,
838 				    struct net_device *dev,
839 				    u8 *dst, u8 *next_hop)
840 {
841 	struct ieee80211_local *local = wiphy_priv(wiphy);
842 	struct ieee80211_sub_if_data *sdata;
843 	struct mesh_path *mpath;
844 	struct sta_info *sta;
845 
846 	if (!netif_running(dev))
847 		return -ENETDOWN;
848 
849 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
850 
851 	if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
852 		return -ENOTSUPP;
853 
854 	rcu_read_lock();
855 
856 	sta = sta_info_get(local, next_hop);
857 	if (!sta) {
858 		rcu_read_unlock();
859 		return -ENOENT;
860 	}
861 
862 	mpath = mesh_path_lookup(dst, sdata);
863 	if (!mpath) {
864 		rcu_read_unlock();
865 		return -ENOENT;
866 	}
867 
868 	mesh_path_fix_nexthop(mpath, sta);
869 
870 	rcu_read_unlock();
871 	return 0;
872 }
873 
874 static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
875 			    struct mpath_info *pinfo)
876 {
877 	if (mpath->next_hop)
878 		memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
879 	else
880 		memset(next_hop, 0, ETH_ALEN);
881 
882 	pinfo->filled = MPATH_INFO_FRAME_QLEN |
883 			MPATH_INFO_DSN |
884 			MPATH_INFO_METRIC |
885 			MPATH_INFO_EXPTIME |
886 			MPATH_INFO_DISCOVERY_TIMEOUT |
887 			MPATH_INFO_DISCOVERY_RETRIES |
888 			MPATH_INFO_FLAGS;
889 
890 	pinfo->frame_qlen = mpath->frame_queue.qlen;
891 	pinfo->dsn = mpath->dsn;
892 	pinfo->metric = mpath->metric;
893 	if (time_before(jiffies, mpath->exp_time))
894 		pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
895 	pinfo->discovery_timeout =
896 			jiffies_to_msecs(mpath->discovery_timeout);
897 	pinfo->discovery_retries = mpath->discovery_retries;
898 	pinfo->flags = 0;
899 	if (mpath->flags & MESH_PATH_ACTIVE)
900 		pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
901 	if (mpath->flags & MESH_PATH_RESOLVING)
902 		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
903 	if (mpath->flags & MESH_PATH_DSN_VALID)
904 		pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID;
905 	if (mpath->flags & MESH_PATH_FIXED)
906 		pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
907 	if (mpath->flags & MESH_PATH_RESOLVING)
908 		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
909 
910 	pinfo->flags = mpath->flags;
911 }
912 
913 static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
914 			       u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
915 
916 {
917 	struct ieee80211_sub_if_data *sdata;
918 	struct mesh_path *mpath;
919 
920 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
921 
922 	if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
923 		return -ENOTSUPP;
924 
925 	rcu_read_lock();
926 	mpath = mesh_path_lookup(dst, sdata);
927 	if (!mpath) {
928 		rcu_read_unlock();
929 		return -ENOENT;
930 	}
931 	memcpy(dst, mpath->dst, ETH_ALEN);
932 	mpath_set_pinfo(mpath, next_hop, pinfo);
933 	rcu_read_unlock();
934 	return 0;
935 }
936 
937 static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
938 				 int idx, u8 *dst, u8 *next_hop,
939 				 struct mpath_info *pinfo)
940 {
941 	struct ieee80211_sub_if_data *sdata;
942 	struct mesh_path *mpath;
943 
944 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
945 
946 	if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
947 		return -ENOTSUPP;
948 
949 	rcu_read_lock();
950 	mpath = mesh_path_lookup_by_idx(idx, sdata);
951 	if (!mpath) {
952 		rcu_read_unlock();
953 		return -ENOENT;
954 	}
955 	memcpy(dst, mpath->dst, ETH_ALEN);
956 	mpath_set_pinfo(mpath, next_hop, pinfo);
957 	rcu_read_unlock();
958 	return 0;
959 }
960 #endif
961 
962 static int ieee80211_change_bss(struct wiphy *wiphy,
963 				struct net_device *dev,
964 				struct bss_parameters *params)
965 {
966 	struct ieee80211_sub_if_data *sdata;
967 	u32 changed = 0;
968 
969 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
970 
971 	if (sdata->vif.type != NL80211_IFTYPE_AP)
972 		return -EINVAL;
973 
974 	if (params->use_cts_prot >= 0) {
975 		sdata->bss_conf.use_cts_prot = params->use_cts_prot;
976 		changed |= BSS_CHANGED_ERP_CTS_PROT;
977 	}
978 	if (params->use_short_preamble >= 0) {
979 		sdata->bss_conf.use_short_preamble =
980 			params->use_short_preamble;
981 		changed |= BSS_CHANGED_ERP_PREAMBLE;
982 	}
983 	if (params->use_short_slot_time >= 0) {
984 		sdata->bss_conf.use_short_slot =
985 			params->use_short_slot_time;
986 		changed |= BSS_CHANGED_ERP_SLOT;
987 	}
988 
989 	ieee80211_bss_info_change_notify(sdata, changed);
990 
991 	return 0;
992 }
993 
994 struct cfg80211_ops mac80211_config_ops = {
995 	.add_virtual_intf = ieee80211_add_iface,
996 	.del_virtual_intf = ieee80211_del_iface,
997 	.change_virtual_intf = ieee80211_change_iface,
998 	.add_key = ieee80211_add_key,
999 	.del_key = ieee80211_del_key,
1000 	.get_key = ieee80211_get_key,
1001 	.set_default_key = ieee80211_config_default_key,
1002 	.add_beacon = ieee80211_add_beacon,
1003 	.set_beacon = ieee80211_set_beacon,
1004 	.del_beacon = ieee80211_del_beacon,
1005 	.add_station = ieee80211_add_station,
1006 	.del_station = ieee80211_del_station,
1007 	.change_station = ieee80211_change_station,
1008 	.get_station = ieee80211_get_station,
1009 	.dump_station = ieee80211_dump_station,
1010 #ifdef CONFIG_MAC80211_MESH
1011 	.add_mpath = ieee80211_add_mpath,
1012 	.del_mpath = ieee80211_del_mpath,
1013 	.change_mpath = ieee80211_change_mpath,
1014 	.get_mpath = ieee80211_get_mpath,
1015 	.dump_mpath = ieee80211_dump_mpath,
1016 #endif
1017 	.change_bss = ieee80211_change_bss,
1018 };
1019