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