WEXT: add mesh interface type
[deliverable/linux.git] / net / mac80211 / cfg.c
CommitLineData
f0706e82
JB
1/*
2 * mac80211 configuration hooks for cfg80211
3 *
62da92fb 4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
f0706e82
JB
5 *
6 * This file is GPLv2 as found in COPYING.
7 */
8
e8cbb4cb 9#include <linux/ieee80211.h>
f0706e82
JB
10#include <linux/nl80211.h>
11#include <linux/rtnetlink.h>
881d966b 12#include <net/net_namespace.h>
5dfdaf58 13#include <linux/rcupdate.h>
f0706e82
JB
14#include <net/cfg80211.h>
15#include "ieee80211_i.h"
e0eb6859 16#include "cfg.h"
4fd6931e 17#include "ieee80211_rate.h"
f0706e82 18
42613db7
JB
19static enum ieee80211_if_types
20nl80211_type_to_mac80211_type(enum nl80211_iftype type)
21{
22 switch (type) {
23 case NL80211_IFTYPE_UNSPECIFIED:
24 return IEEE80211_IF_TYPE_STA;
25 case NL80211_IFTYPE_ADHOC:
26 return IEEE80211_IF_TYPE_IBSS;
27 case NL80211_IFTYPE_STATION:
28 return IEEE80211_IF_TYPE_STA;
29 case NL80211_IFTYPE_MONITOR:
30 return IEEE80211_IF_TYPE_MNTR;
31 default:
32 return IEEE80211_IF_TYPE_INVALID;
33 }
34}
35
f0706e82 36static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
66f7ac50 37 enum nl80211_iftype type, u32 *flags)
f0706e82
JB
38{
39 struct ieee80211_local *local = wiphy_priv(wiphy);
42613db7 40 enum ieee80211_if_types itype;
8cc9a739
MW
41 struct net_device *dev;
42 struct ieee80211_sub_if_data *sdata;
43 int err;
f0706e82
JB
44
45 if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
46 return -ENODEV;
47
42613db7
JB
48 itype = nl80211_type_to_mac80211_type(type);
49 if (itype == IEEE80211_IF_TYPE_INVALID)
f0706e82 50 return -EINVAL;
f0706e82 51
8cc9a739
MW
52 err = ieee80211_if_add(local->mdev, name, &dev, itype);
53 if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags)
54 return err;
55
56 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
57 sdata->u.mntr_flags = *flags;
58 return 0;
f0706e82
JB
59}
60
61static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
62{
63 struct ieee80211_local *local = wiphy_priv(wiphy);
64 struct net_device *dev;
65 char *name;
66
67 if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
68 return -ENODEV;
69
42613db7
JB
70 /* we're under RTNL */
71 dev = __dev_get_by_index(&init_net, ifindex);
f0706e82
JB
72 if (!dev)
73 return 0;
74
75 name = dev->name;
f0706e82
JB
76
77 return ieee80211_if_remove(local->mdev, name, -1);
78}
79
42613db7 80static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
66f7ac50 81 enum nl80211_iftype type, u32 *flags)
42613db7
JB
82{
83 struct ieee80211_local *local = wiphy_priv(wiphy);
84 struct net_device *dev;
85 enum ieee80211_if_types itype;
86 struct ieee80211_sub_if_data *sdata;
87
88 if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
89 return -ENODEV;
90
91 /* we're under RTNL */
92 dev = __dev_get_by_index(&init_net, ifindex);
93 if (!dev)
94 return -ENODEV;
95
96 if (netif_running(dev))
97 return -EBUSY;
98
99 itype = nl80211_type_to_mac80211_type(type);
100 if (itype == IEEE80211_IF_TYPE_INVALID)
101 return -EINVAL;
102
103 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
104
51fb61e7 105 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
42613db7
JB
106 return -EOPNOTSUPP;
107
108 ieee80211_if_reinit(dev);
109 ieee80211_if_set_type(dev, itype);
110
8cc9a739
MW
111 if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags)
112 return 0;
113
114 sdata->u.mntr_flags = *flags;
42613db7
JB
115 return 0;
116}
117
e8cbb4cb
JB
118static 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 int ret;
db4d1169 126 struct ieee80211_key *key;
e8cbb4cb
JB
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
db4d1169
JB
145 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);
146 if (!key)
147 return -ENOMEM;
148
e8cbb4cb
JB
149 if (mac_addr) {
150 sta = sta_info_get(sdata->local, mac_addr);
db4d1169
JB
151 if (!sta) {
152 ieee80211_key_free(key);
e8cbb4cb 153 return -ENOENT;
db4d1169 154 }
e8cbb4cb
JB
155 }
156
db4d1169
JB
157 ieee80211_key_link(key, sdata, sta);
158
e8cbb4cb 159 ret = 0;
e8cbb4cb
JB
160
161 if (sta)
162 sta_info_put(sta);
163
164 return ret;
165}
166
167static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
168 u8 key_idx, u8 *mac_addr)
169{
170 struct ieee80211_sub_if_data *sdata;
171 struct sta_info *sta;
172 int ret;
db4d1169 173 struct ieee80211_key *key;
e8cbb4cb
JB
174
175 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
176
177 if (mac_addr) {
178 sta = sta_info_get(sdata->local, mac_addr);
179 if (!sta)
180 return -ENOENT;
181
182 ret = 0;
db4d1169
JB
183 if (sta->key) {
184 key = sta->key;
185 ieee80211_key_free(key);
186 WARN_ON(sta->key);
187 } else
e8cbb4cb
JB
188 ret = -ENOENT;
189
190 sta_info_put(sta);
191 return ret;
192 }
193
194 if (!sdata->keys[key_idx])
195 return -ENOENT;
196
db4d1169
JB
197 key = sdata->keys[key_idx];
198 ieee80211_key_free(key);
199 WARN_ON(sdata->keys[key_idx]);
e8cbb4cb
JB
200
201 return 0;
202}
203
62da92fb
JB
204static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
205 u8 key_idx, u8 *mac_addr, void *cookie,
206 void (*callback)(void *cookie,
207 struct key_params *params))
208{
209 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
210 struct sta_info *sta = NULL;
211 u8 seq[6] = {0};
212 struct key_params params;
213 struct ieee80211_key *key;
214 u32 iv32;
215 u16 iv16;
216 int err = -ENOENT;
217
218 if (mac_addr) {
219 sta = sta_info_get(sdata->local, mac_addr);
220 if (!sta)
221 goto out;
222
223 key = sta->key;
224 } else
225 key = sdata->keys[key_idx];
226
227 if (!key)
228 goto out;
229
230 memset(&params, 0, sizeof(params));
231
232 switch (key->conf.alg) {
233 case ALG_TKIP:
234 params.cipher = WLAN_CIPHER_SUITE_TKIP;
235
236 iv32 = key->u.tkip.iv32;
237 iv16 = key->u.tkip.iv16;
238
239 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
240 sdata->local->ops->get_tkip_seq)
241 sdata->local->ops->get_tkip_seq(
242 local_to_hw(sdata->local),
243 key->conf.hw_key_idx,
244 &iv32, &iv16);
245
246 seq[0] = iv16 & 0xff;
247 seq[1] = (iv16 >> 8) & 0xff;
248 seq[2] = iv32 & 0xff;
249 seq[3] = (iv32 >> 8) & 0xff;
250 seq[4] = (iv32 >> 16) & 0xff;
251 seq[5] = (iv32 >> 24) & 0xff;
252 params.seq = seq;
253 params.seq_len = 6;
254 break;
255 case ALG_CCMP:
256 params.cipher = WLAN_CIPHER_SUITE_CCMP;
257 seq[0] = key->u.ccmp.tx_pn[5];
258 seq[1] = key->u.ccmp.tx_pn[4];
259 seq[2] = key->u.ccmp.tx_pn[3];
260 seq[3] = key->u.ccmp.tx_pn[2];
261 seq[4] = key->u.ccmp.tx_pn[1];
262 seq[5] = key->u.ccmp.tx_pn[0];
263 params.seq = seq;
264 params.seq_len = 6;
265 break;
266 case ALG_WEP:
267 if (key->conf.keylen == 5)
268 params.cipher = WLAN_CIPHER_SUITE_WEP40;
269 else
270 params.cipher = WLAN_CIPHER_SUITE_WEP104;
271 break;
272 }
273
274 params.key = key->conf.key;
275 params.key_len = key->conf.keylen;
276
277 callback(cookie, &params);
278 err = 0;
279
280 out:
281 if (sta)
282 sta_info_put(sta);
283 return err;
284}
285
e8cbb4cb
JB
286static int ieee80211_config_default_key(struct wiphy *wiphy,
287 struct net_device *dev,
288 u8 key_idx)
289{
290 struct ieee80211_sub_if_data *sdata;
291
292 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
293 ieee80211_set_default_key(sdata, key_idx);
294
295 return 0;
296}
297
7bbdd2d9
JB
298static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
299 u8 *mac, struct station_stats *stats)
300{
301 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
302 struct sta_info *sta;
303
304 sta = sta_info_get(local, mac);
305 if (!sta)
306 return -ENOENT;
307
308 /* XXX: verify sta->dev == dev */
309
310 stats->filled = STATION_STAT_INACTIVE_TIME |
311 STATION_STAT_RX_BYTES |
312 STATION_STAT_TX_BYTES;
313
314 stats->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
315 stats->rx_bytes = sta->rx_bytes;
316 stats->tx_bytes = sta->tx_bytes;
317
318 sta_info_put(sta);
319
320 return 0;
321}
322
5dfdaf58
JB
323/*
324 * This handles both adding a beacon and setting new beacon info
325 */
326static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
327 struct beacon_parameters *params)
328{
329 struct beacon_data *new, *old;
330 int new_head_len, new_tail_len;
331 int size;
332 int err = -EINVAL;
333
334 old = sdata->u.ap.beacon;
335
336 /* head must not be zero-length */
337 if (params->head && !params->head_len)
338 return -EINVAL;
339
340 /*
341 * This is a kludge. beacon interval should really be part
342 * of the beacon information.
343 */
344 if (params->interval) {
345 sdata->local->hw.conf.beacon_int = params->interval;
346 if (ieee80211_hw_config(sdata->local))
347 return -EINVAL;
348 /*
349 * We updated some parameter so if below bails out
350 * it's not an error.
351 */
352 err = 0;
353 }
354
355 /* Need to have a beacon head if we don't have one yet */
356 if (!params->head && !old)
357 return err;
358
359 /* sorry, no way to start beaconing without dtim period */
360 if (!params->dtim_period && !old)
361 return err;
362
363 /* new or old head? */
364 if (params->head)
365 new_head_len = params->head_len;
366 else
367 new_head_len = old->head_len;
368
369 /* new or old tail? */
370 if (params->tail || !old)
371 /* params->tail_len will be zero for !params->tail */
372 new_tail_len = params->tail_len;
373 else
374 new_tail_len = old->tail_len;
375
376 size = sizeof(*new) + new_head_len + new_tail_len;
377
378 new = kzalloc(size, GFP_KERNEL);
379 if (!new)
380 return -ENOMEM;
381
382 /* start filling the new info now */
383
384 /* new or old dtim period? */
385 if (params->dtim_period)
386 new->dtim_period = params->dtim_period;
387 else
388 new->dtim_period = old->dtim_period;
389
390 /*
391 * pointers go into the block we allocated,
392 * memory is | beacon_data | head | tail |
393 */
394 new->head = ((u8 *) new) + sizeof(*new);
395 new->tail = new->head + new_head_len;
396 new->head_len = new_head_len;
397 new->tail_len = new_tail_len;
398
399 /* copy in head */
400 if (params->head)
401 memcpy(new->head, params->head, new_head_len);
402 else
403 memcpy(new->head, old->head, new_head_len);
404
405 /* copy in optional tail */
406 if (params->tail)
407 memcpy(new->tail, params->tail, new_tail_len);
408 else
409 if (old)
410 memcpy(new->tail, old->tail, new_tail_len);
411
412 rcu_assign_pointer(sdata->u.ap.beacon, new);
413
414 synchronize_rcu();
415
416 kfree(old);
417
418 return ieee80211_if_config_beacon(sdata->dev);
419}
420
421static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
422 struct beacon_parameters *params)
423{
424 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
425 struct beacon_data *old;
426
427 if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
428 return -EINVAL;
429
430 old = sdata->u.ap.beacon;
431
432 if (old)
433 return -EALREADY;
434
435 return ieee80211_config_beacon(sdata, params);
436}
437
438static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
439 struct beacon_parameters *params)
440{
441 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
442 struct beacon_data *old;
443
444 if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
445 return -EINVAL;
446
447 old = sdata->u.ap.beacon;
448
449 if (!old)
450 return -ENOENT;
451
452 return ieee80211_config_beacon(sdata, params);
453}
454
455static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
456{
457 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
458 struct beacon_data *old;
459
460 if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
461 return -EINVAL;
462
463 old = sdata->u.ap.beacon;
464
465 if (!old)
466 return -ENOENT;
467
468 rcu_assign_pointer(sdata->u.ap.beacon, NULL);
469 synchronize_rcu();
470 kfree(old);
471
472 return ieee80211_if_config_beacon(dev);
473}
474
4fd6931e
JB
475/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
476struct iapp_layer2_update {
477 u8 da[ETH_ALEN]; /* broadcast */
478 u8 sa[ETH_ALEN]; /* STA addr */
479 __be16 len; /* 6 */
480 u8 dsap; /* 0 */
481 u8 ssap; /* 0 */
482 u8 control;
483 u8 xid_info[3];
484} __attribute__ ((packed));
485
486static void ieee80211_send_layer2_update(struct sta_info *sta)
487{
488 struct iapp_layer2_update *msg;
489 struct sk_buff *skb;
490
491 /* Send Level 2 Update Frame to update forwarding tables in layer 2
492 * bridge devices */
493
494 skb = dev_alloc_skb(sizeof(*msg));
495 if (!skb)
496 return;
497 msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
498
499 /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
500 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
501
502 memset(msg->da, 0xff, ETH_ALEN);
503 memcpy(msg->sa, sta->addr, ETH_ALEN);
504 msg->len = htons(6);
505 msg->dsap = 0;
506 msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
507 msg->control = 0xaf; /* XID response lsb.1111F101.
508 * F=0 (no poll command; unsolicited frame) */
509 msg->xid_info[0] = 0x81; /* XID format identifier */
510 msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
511 msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */
512
513 skb->dev = sta->dev;
514 skb->protocol = eth_type_trans(skb, sta->dev);
515 memset(skb->cb, 0, sizeof(skb->cb));
516 netif_rx(skb);
517}
518
519static void sta_apply_parameters(struct ieee80211_local *local,
520 struct sta_info *sta,
521 struct station_parameters *params)
522{
523 u32 rates;
524 int i, j;
8318d78a 525 struct ieee80211_supported_band *sband;
4fd6931e
JB
526
527 if (params->station_flags & STATION_FLAG_CHANGED) {
528 sta->flags &= ~WLAN_STA_AUTHORIZED;
529 if (params->station_flags & STATION_FLAG_AUTHORIZED)
530 sta->flags |= WLAN_STA_AUTHORIZED;
531
532 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
533 if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
534 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
535
536 sta->flags &= ~WLAN_STA_WME;
537 if (params->station_flags & STATION_FLAG_WME)
538 sta->flags |= WLAN_STA_WME;
539 }
540
541 if (params->aid) {
542 sta->aid = params->aid;
543 if (sta->aid > IEEE80211_MAX_AID)
544 sta->aid = 0; /* XXX: should this be an error? */
545 }
546
547 if (params->listen_interval >= 0)
548 sta->listen_interval = params->listen_interval;
549
550 if (params->supported_rates) {
551 rates = 0;
8318d78a
JB
552 sband = local->hw.wiphy->bands[local->oper_channel->band];
553
4fd6931e
JB
554 for (i = 0; i < params->supported_rates_len; i++) {
555 int rate = (params->supported_rates[i] & 0x7f) * 5;
8318d78a
JB
556 for (j = 0; j < sband->n_bitrates; j++) {
557 if (sband->bitrates[j].bitrate == rate)
4fd6931e
JB
558 rates |= BIT(j);
559 }
560 }
8318d78a 561 sta->supp_rates[local->oper_channel->band] = rates;
4fd6931e
JB
562 }
563}
564
565static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
566 u8 *mac, struct station_parameters *params)
567{
568 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
569 struct sta_info *sta;
570 struct ieee80211_sub_if_data *sdata;
571
572 /* Prevent a race with changing the rate control algorithm */
573 if (!netif_running(dev))
574 return -ENETDOWN;
575
4fd6931e
JB
576 if (params->vlan) {
577 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
578
579 if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
580 sdata->vif.type != IEEE80211_IF_TYPE_AP)
581 return -EINVAL;
582 } else
583 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
584
585 sta = sta_info_add(local, dev, mac, GFP_KERNEL);
43ba7e95
JB
586 if (IS_ERR(sta))
587 return PTR_ERR(sta);
4fd6931e
JB
588
589 sta->dev = sdata->dev;
590 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN ||
591 sdata->vif.type == IEEE80211_IF_TYPE_AP)
592 ieee80211_send_layer2_update(sta);
593
594 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
595
596 sta_apply_parameters(local, sta, params);
597
598 rate_control_rate_init(sta, local);
599
600 sta_info_put(sta);
601
602 return 0;
603}
604
605static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
606 u8 *mac)
607{
608 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
609 struct sta_info *sta;
610
611 if (mac) {
612 /* XXX: get sta belonging to dev */
613 sta = sta_info_get(local, mac);
614 if (!sta)
615 return -ENOENT;
616
617 sta_info_free(sta);
618 sta_info_put(sta);
619 } else
620 sta_info_flush(local, dev);
621
622 return 0;
623}
624
625static int ieee80211_change_station(struct wiphy *wiphy,
626 struct net_device *dev,
627 u8 *mac,
628 struct station_parameters *params)
629{
630 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
631 struct sta_info *sta;
632 struct ieee80211_sub_if_data *vlansdata;
633
634 /* XXX: get sta belonging to dev */
635 sta = sta_info_get(local, mac);
636 if (!sta)
637 return -ENOENT;
638
639 if (params->vlan && params->vlan != sta->dev) {
640 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
641
642 if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
643 vlansdata->vif.type != IEEE80211_IF_TYPE_AP)
644 return -EINVAL;
645
646 sta->dev = params->vlan;
647 ieee80211_send_layer2_update(sta);
648 }
649
650 sta_apply_parameters(local, sta, params);
651
652 sta_info_put(sta);
653
654 return 0;
655}
656
f0706e82
JB
657struct cfg80211_ops mac80211_config_ops = {
658 .add_virtual_intf = ieee80211_add_iface,
659 .del_virtual_intf = ieee80211_del_iface,
42613db7 660 .change_virtual_intf = ieee80211_change_iface,
e8cbb4cb
JB
661 .add_key = ieee80211_add_key,
662 .del_key = ieee80211_del_key,
62da92fb 663 .get_key = ieee80211_get_key,
e8cbb4cb 664 .set_default_key = ieee80211_config_default_key,
5dfdaf58
JB
665 .add_beacon = ieee80211_add_beacon,
666 .set_beacon = ieee80211_set_beacon,
667 .del_beacon = ieee80211_del_beacon,
4fd6931e
JB
668 .add_station = ieee80211_add_station,
669 .del_station = ieee80211_del_station,
670 .change_station = ieee80211_change_station,
7bbdd2d9 671 .get_station = ieee80211_get_station,
f0706e82 672};
This page took 0.214648 seconds and 5 git commands to generate.