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