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