Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
[pandora-kernel.git] / net / wireless / nl80211.c
1 /*
2  * This is the new netlink-based wireless configuration interface.
3  *
4  * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
5  */
6
7 #include <linux/if.h>
8 #include <linux/module.h>
9 #include <linux/err.h>
10 #include <linux/mutex.h>
11 #include <linux/list.h>
12 #include <linux/if_ether.h>
13 #include <linux/ieee80211.h>
14 #include <linux/nl80211.h>
15 #include <linux/rtnetlink.h>
16 #include <linux/netlink.h>
17 #include <net/genetlink.h>
18 #include <net/cfg80211.h>
19 #include "core.h"
20 #include "nl80211.h"
21
22 /* the netlink family */
23 static struct genl_family nl80211_fam = {
24         .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
25         .name = "nl80211",      /* have users key off the name instead */
26         .hdrsize = 0,           /* no private header */
27         .version = 1,           /* no particular meaning now */
28         .maxattr = NL80211_ATTR_MAX,
29 };
30
31 /* internal helper: get drv and dev */
32 static int get_drv_dev_by_info_ifindex(struct genl_info *info,
33                                        struct cfg80211_registered_device **drv,
34                                        struct net_device **dev)
35 {
36         int ifindex;
37
38         if (!info->attrs[NL80211_ATTR_IFINDEX])
39                 return -EINVAL;
40
41         ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
42         *dev = dev_get_by_index(&init_net, ifindex);
43         if (!*dev)
44                 return -ENODEV;
45
46         *drv = cfg80211_get_dev_from_ifindex(ifindex);
47         if (IS_ERR(*drv)) {
48                 dev_put(*dev);
49                 return PTR_ERR(*drv);
50         }
51
52         return 0;
53 }
54
55 /* policy for the attributes */
56 static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
57         [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
58         [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
59                                       .len = BUS_ID_SIZE-1 },
60
61         [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
62         [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
63         [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
64
65         [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
66
67         [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
68                                     .len = WLAN_MAX_KEY_LEN },
69         [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
70         [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
71         [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
72
73         [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
74         [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
75         [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
76                                        .len = IEEE80211_MAX_DATA_LEN },
77         [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
78                                        .len = IEEE80211_MAX_DATA_LEN },
79         [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
80         [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
81         [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
82         [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
83                                                .len = NL80211_MAX_SUPP_RATES },
84         [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
85         [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
86         [NL80211_ATTR_MNTR_FLAGS] = { .type = NLA_NESTED },
87         [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
88                                 .len = IEEE80211_MAX_MESH_ID_LEN },
89         [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
90 };
91
92 /* message building helper */
93 static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
94                                    int flags, u8 cmd)
95 {
96         /* since there is no private header just add the generic one */
97         return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
98 }
99
100 /* netlink command implementations */
101
102 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
103                               struct cfg80211_registered_device *dev)
104 {
105         void *hdr;
106         struct nlattr *nl_bands, *nl_band;
107         struct nlattr *nl_freqs, *nl_freq;
108         struct nlattr *nl_rates, *nl_rate;
109         enum ieee80211_band band;
110         struct ieee80211_channel *chan;
111         struct ieee80211_rate *rate;
112         int i;
113
114         hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
115         if (!hdr)
116                 return -1;
117
118         NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
119         NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
120
121         nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
122         if (!nl_bands)
123                 goto nla_put_failure;
124
125         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
126                 if (!dev->wiphy.bands[band])
127                         continue;
128
129                 nl_band = nla_nest_start(msg, band);
130                 if (!nl_band)
131                         goto nla_put_failure;
132
133                 /* add frequencies */
134                 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
135                 if (!nl_freqs)
136                         goto nla_put_failure;
137
138                 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
139                         nl_freq = nla_nest_start(msg, i);
140                         if (!nl_freq)
141                                 goto nla_put_failure;
142
143                         chan = &dev->wiphy.bands[band]->channels[i];
144                         NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
145                                     chan->center_freq);
146
147                         if (chan->flags & IEEE80211_CHAN_DISABLED)
148                                 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
149                         if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
150                                 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
151                         if (chan->flags & IEEE80211_CHAN_NO_IBSS)
152                                 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
153                         if (chan->flags & IEEE80211_CHAN_RADAR)
154                                 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
155
156                         nla_nest_end(msg, nl_freq);
157                 }
158
159                 nla_nest_end(msg, nl_freqs);
160
161                 /* add bitrates */
162                 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
163                 if (!nl_rates)
164                         goto nla_put_failure;
165
166                 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
167                         nl_rate = nla_nest_start(msg, i);
168                         if (!nl_rate)
169                                 goto nla_put_failure;
170
171                         rate = &dev->wiphy.bands[band]->bitrates[i];
172                         NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
173                                     rate->bitrate);
174                         if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
175                                 NLA_PUT_FLAG(msg,
176                                         NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
177
178                         nla_nest_end(msg, nl_rate);
179                 }
180
181                 nla_nest_end(msg, nl_rates);
182
183                 nla_nest_end(msg, nl_band);
184         }
185         nla_nest_end(msg, nl_bands);
186
187         return genlmsg_end(msg, hdr);
188
189  nla_put_failure:
190         genlmsg_cancel(msg, hdr);
191         return -EMSGSIZE;
192 }
193
194 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
195 {
196         int idx = 0;
197         int start = cb->args[0];
198         struct cfg80211_registered_device *dev;
199
200         mutex_lock(&cfg80211_drv_mutex);
201         list_for_each_entry(dev, &cfg80211_drv_list, list) {
202                 if (++idx <= start)
203                         continue;
204                 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
205                                        cb->nlh->nlmsg_seq, NLM_F_MULTI,
206                                        dev) < 0) {
207                         idx--;
208                         break;
209                 }
210         }
211         mutex_unlock(&cfg80211_drv_mutex);
212
213         cb->args[0] = idx;
214
215         return skb->len;
216 }
217
218 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
219 {
220         struct sk_buff *msg;
221         struct cfg80211_registered_device *dev;
222
223         dev = cfg80211_get_dev_from_info(info);
224         if (IS_ERR(dev))
225                 return PTR_ERR(dev);
226
227         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
228         if (!msg)
229                 goto out_err;
230
231         if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
232                 goto out_free;
233
234         cfg80211_put_dev(dev);
235
236         return genlmsg_unicast(msg, info->snd_pid);
237
238  out_free:
239         nlmsg_free(msg);
240  out_err:
241         cfg80211_put_dev(dev);
242         return -ENOBUFS;
243 }
244
245 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
246 {
247         struct cfg80211_registered_device *rdev;
248         int result;
249
250         if (!info->attrs[NL80211_ATTR_WIPHY_NAME])
251                 return -EINVAL;
252
253         rdev = cfg80211_get_dev_from_info(info);
254         if (IS_ERR(rdev))
255                 return PTR_ERR(rdev);
256
257         result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
258
259         cfg80211_put_dev(rdev);
260         return result;
261 }
262
263
264 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
265                               struct net_device *dev)
266 {
267         void *hdr;
268
269         hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
270         if (!hdr)
271                 return -1;
272
273         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
274         NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
275         /* TODO: interface type */
276         return genlmsg_end(msg, hdr);
277
278  nla_put_failure:
279         genlmsg_cancel(msg, hdr);
280         return -EMSGSIZE;
281 }
282
283 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
284 {
285         int wp_idx = 0;
286         int if_idx = 0;
287         int wp_start = cb->args[0];
288         int if_start = cb->args[1];
289         struct cfg80211_registered_device *dev;
290         struct wireless_dev *wdev;
291
292         mutex_lock(&cfg80211_drv_mutex);
293         list_for_each_entry(dev, &cfg80211_drv_list, list) {
294                 if (++wp_idx < wp_start)
295                         continue;
296                 if_idx = 0;
297
298                 mutex_lock(&dev->devlist_mtx);
299                 list_for_each_entry(wdev, &dev->netdev_list, list) {
300                         if (++if_idx < if_start)
301                                 continue;
302                         if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
303                                                cb->nlh->nlmsg_seq, NLM_F_MULTI,
304                                                wdev->netdev) < 0)
305                                 break;
306                 }
307                 mutex_unlock(&dev->devlist_mtx);
308         }
309         mutex_unlock(&cfg80211_drv_mutex);
310
311         cb->args[0] = wp_idx;
312         cb->args[1] = if_idx;
313
314         return skb->len;
315 }
316
317 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
318 {
319         struct sk_buff *msg;
320         struct cfg80211_registered_device *dev;
321         struct net_device *netdev;
322         int err;
323
324         err = get_drv_dev_by_info_ifindex(info, &dev, &netdev);
325         if (err)
326                 return err;
327
328         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
329         if (!msg)
330                 goto out_err;
331
332         if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0)
333                 goto out_free;
334
335         dev_put(netdev);
336         cfg80211_put_dev(dev);
337
338         return genlmsg_unicast(msg, info->snd_pid);
339
340  out_free:
341         nlmsg_free(msg);
342  out_err:
343         dev_put(netdev);
344         cfg80211_put_dev(dev);
345         return -ENOBUFS;
346 }
347
348 static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
349         [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
350         [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
351         [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
352         [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
353         [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
354 };
355
356 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
357 {
358         struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
359         int flag;
360
361         *mntrflags = 0;
362
363         if (!nla)
364                 return -EINVAL;
365
366         if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
367                              nla, mntr_flags_policy))
368                 return -EINVAL;
369
370         for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
371                 if (flags[flag])
372                         *mntrflags |= (1<<flag);
373
374         return 0;
375 }
376
377 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
378 {
379         struct cfg80211_registered_device *drv;
380         struct vif_params params;
381         int err, ifindex;
382         enum nl80211_iftype type;
383         struct net_device *dev;
384         u32 flags;
385
386         memset(&params, 0, sizeof(params));
387
388         if (info->attrs[NL80211_ATTR_IFTYPE]) {
389                 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
390                 if (type > NL80211_IFTYPE_MAX)
391                         return -EINVAL;
392         } else
393                 return -EINVAL;
394
395         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
396         if (err)
397                 return err;
398         ifindex = dev->ifindex;
399         dev_put(dev);
400
401         if (!drv->ops->change_virtual_intf) {
402                 err = -EOPNOTSUPP;
403                 goto unlock;
404         }
405
406         if (type == NL80211_IFTYPE_MESH_POINT &&
407             info->attrs[NL80211_ATTR_MESH_ID]) {
408                 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
409                 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
410         }
411
412         rtnl_lock();
413         err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
414                                   info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
415                                   &flags);
416         err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
417                                             type, err ? NULL : &flags, &params);
418         rtnl_unlock();
419
420  unlock:
421         cfg80211_put_dev(drv);
422         return err;
423 }
424
425 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
426 {
427         struct cfg80211_registered_device *drv;
428         struct vif_params params;
429         int err;
430         enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
431         u32 flags;
432
433         memset(&params, 0, sizeof(params));
434
435         if (!info->attrs[NL80211_ATTR_IFNAME])
436                 return -EINVAL;
437
438         if (info->attrs[NL80211_ATTR_IFTYPE]) {
439                 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
440                 if (type > NL80211_IFTYPE_MAX)
441                         return -EINVAL;
442         }
443
444         drv = cfg80211_get_dev_from_info(info);
445         if (IS_ERR(drv))
446                 return PTR_ERR(drv);
447
448         if (!drv->ops->add_virtual_intf) {
449                 err = -EOPNOTSUPP;
450                 goto unlock;
451         }
452
453         if (type == NL80211_IFTYPE_MESH_POINT &&
454             info->attrs[NL80211_ATTR_MESH_ID]) {
455                 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
456                 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
457         }
458
459         rtnl_lock();
460         err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
461                                   info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
462                                   &flags);
463         err = drv->ops->add_virtual_intf(&drv->wiphy,
464                 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
465                 type, err ? NULL : &flags, &params);
466         rtnl_unlock();
467
468
469  unlock:
470         cfg80211_put_dev(drv);
471         return err;
472 }
473
474 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
475 {
476         struct cfg80211_registered_device *drv;
477         int ifindex, err;
478         struct net_device *dev;
479
480         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
481         if (err)
482                 return err;
483         ifindex = dev->ifindex;
484         dev_put(dev);
485
486         if (!drv->ops->del_virtual_intf) {
487                 err = -EOPNOTSUPP;
488                 goto out;
489         }
490
491         rtnl_lock();
492         err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
493         rtnl_unlock();
494
495  out:
496         cfg80211_put_dev(drv);
497         return err;
498 }
499
500 struct get_key_cookie {
501         struct sk_buff *msg;
502         int error;
503 };
504
505 static void get_key_callback(void *c, struct key_params *params)
506 {
507         struct get_key_cookie *cookie = c;
508
509         if (params->key)
510                 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
511                         params->key_len, params->key);
512
513         if (params->seq)
514                 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
515                         params->seq_len, params->seq);
516
517         if (params->cipher)
518                 NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
519                             params->cipher);
520
521         return;
522  nla_put_failure:
523         cookie->error = 1;
524 }
525
526 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
527 {
528         struct cfg80211_registered_device *drv;
529         int err;
530         struct net_device *dev;
531         u8 key_idx = 0;
532         u8 *mac_addr = NULL;
533         struct get_key_cookie cookie = {
534                 .error = 0,
535         };
536         void *hdr;
537         struct sk_buff *msg;
538
539         if (info->attrs[NL80211_ATTR_KEY_IDX])
540                 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
541
542         if (key_idx > 3)
543                 return -EINVAL;
544
545         if (info->attrs[NL80211_ATTR_MAC])
546                 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
547
548         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
549         if (err)
550                 return err;
551
552         if (!drv->ops->get_key) {
553                 err = -EOPNOTSUPP;
554                 goto out;
555         }
556
557         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
558         if (!msg) {
559                 err = -ENOMEM;
560                 goto out;
561         }
562
563         hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
564                              NL80211_CMD_NEW_KEY);
565
566         if (IS_ERR(hdr)) {
567                 err = PTR_ERR(hdr);
568                 goto out;
569         }
570
571         cookie.msg = msg;
572
573         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
574         NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
575         if (mac_addr)
576                 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
577
578         rtnl_lock();
579         err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
580                                 &cookie, get_key_callback);
581         rtnl_unlock();
582
583         if (err)
584                 goto out;
585
586         if (cookie.error)
587                 goto nla_put_failure;
588
589         genlmsg_end(msg, hdr);
590         err = genlmsg_unicast(msg, info->snd_pid);
591         goto out;
592
593  nla_put_failure:
594         err = -ENOBUFS;
595         nlmsg_free(msg);
596  out:
597         cfg80211_put_dev(drv);
598         dev_put(dev);
599         return err;
600 }
601
602 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
603 {
604         struct cfg80211_registered_device *drv;
605         int err;
606         struct net_device *dev;
607         u8 key_idx;
608
609         if (!info->attrs[NL80211_ATTR_KEY_IDX])
610                 return -EINVAL;
611
612         key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
613
614         if (key_idx > 3)
615                 return -EINVAL;
616
617         /* currently only support setting default key */
618         if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
619                 return -EINVAL;
620
621         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
622         if (err)
623                 return err;
624
625         if (!drv->ops->set_default_key) {
626                 err = -EOPNOTSUPP;
627                 goto out;
628         }
629
630         rtnl_lock();
631         err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
632         rtnl_unlock();
633
634  out:
635         cfg80211_put_dev(drv);
636         dev_put(dev);
637         return err;
638 }
639
640 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
641 {
642         struct cfg80211_registered_device *drv;
643         int err;
644         struct net_device *dev;
645         struct key_params params;
646         u8 key_idx = 0;
647         u8 *mac_addr = NULL;
648
649         memset(&params, 0, sizeof(params));
650
651         if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
652                 return -EINVAL;
653
654         if (info->attrs[NL80211_ATTR_KEY_DATA]) {
655                 params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
656                 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
657         }
658
659         if (info->attrs[NL80211_ATTR_KEY_IDX])
660                 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
661
662         params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
663
664         if (info->attrs[NL80211_ATTR_MAC])
665                 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
666
667         if (key_idx > 3)
668                 return -EINVAL;
669
670         /*
671          * Disallow pairwise keys with non-zero index unless it's WEP
672          * (because current deployments use pairwise WEP keys with
673          * non-zero indizes but 802.11i clearly specifies to use zero)
674          */
675         if (mac_addr && key_idx &&
676             params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
677             params.cipher != WLAN_CIPHER_SUITE_WEP104)
678                 return -EINVAL;
679
680         /* TODO: add definitions for the lengths to linux/ieee80211.h */
681         switch (params.cipher) {
682         case WLAN_CIPHER_SUITE_WEP40:
683                 if (params.key_len != 5)
684                         return -EINVAL;
685                 break;
686         case WLAN_CIPHER_SUITE_TKIP:
687                 if (params.key_len != 32)
688                         return -EINVAL;
689                 break;
690         case WLAN_CIPHER_SUITE_CCMP:
691                 if (params.key_len != 16)
692                         return -EINVAL;
693                 break;
694         case WLAN_CIPHER_SUITE_WEP104:
695                 if (params.key_len != 13)
696                         return -EINVAL;
697                 break;
698         default:
699                 return -EINVAL;
700         }
701
702         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
703         if (err)
704                 return err;
705
706         if (!drv->ops->add_key) {
707                 err = -EOPNOTSUPP;
708                 goto out;
709         }
710
711         rtnl_lock();
712         err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
713         rtnl_unlock();
714
715  out:
716         cfg80211_put_dev(drv);
717         dev_put(dev);
718         return err;
719 }
720
721 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
722 {
723         struct cfg80211_registered_device *drv;
724         int err;
725         struct net_device *dev;
726         u8 key_idx = 0;
727         u8 *mac_addr = NULL;
728
729         if (info->attrs[NL80211_ATTR_KEY_IDX])
730                 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
731
732         if (key_idx > 3)
733                 return -EINVAL;
734
735         if (info->attrs[NL80211_ATTR_MAC])
736                 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
737
738         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
739         if (err)
740                 return err;
741
742         if (!drv->ops->del_key) {
743                 err = -EOPNOTSUPP;
744                 goto out;
745         }
746
747         rtnl_lock();
748         err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
749         rtnl_unlock();
750
751  out:
752         cfg80211_put_dev(drv);
753         dev_put(dev);
754         return err;
755 }
756
757 static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
758 {
759         int (*call)(struct wiphy *wiphy, struct net_device *dev,
760                     struct beacon_parameters *info);
761         struct cfg80211_registered_device *drv;
762         int err;
763         struct net_device *dev;
764         struct beacon_parameters params;
765         int haveinfo = 0;
766
767         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
768         if (err)
769                 return err;
770
771         switch (info->genlhdr->cmd) {
772         case NL80211_CMD_NEW_BEACON:
773                 /* these are required for NEW_BEACON */
774                 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
775                     !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
776                     !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
777                         err = -EINVAL;
778                         goto out;
779                 }
780
781                 call = drv->ops->add_beacon;
782                 break;
783         case NL80211_CMD_SET_BEACON:
784                 call = drv->ops->set_beacon;
785                 break;
786         default:
787                 WARN_ON(1);
788                 err = -EOPNOTSUPP;
789                 goto out;
790         }
791
792         if (!call) {
793                 err = -EOPNOTSUPP;
794                 goto out;
795         }
796
797         memset(&params, 0, sizeof(params));
798
799         if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
800                 params.interval =
801                     nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
802                 haveinfo = 1;
803         }
804
805         if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
806                 params.dtim_period =
807                     nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
808                 haveinfo = 1;
809         }
810
811         if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
812                 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
813                 params.head_len =
814                     nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
815                 haveinfo = 1;
816         }
817
818         if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
819                 params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
820                 params.tail_len =
821                     nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
822                 haveinfo = 1;
823         }
824
825         if (!haveinfo) {
826                 err = -EINVAL;
827                 goto out;
828         }
829
830         rtnl_lock();
831         err = call(&drv->wiphy, dev, &params);
832         rtnl_unlock();
833
834  out:
835         cfg80211_put_dev(drv);
836         dev_put(dev);
837         return err;
838 }
839
840 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
841 {
842         struct cfg80211_registered_device *drv;
843         int err;
844         struct net_device *dev;
845
846         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
847         if (err)
848                 return err;
849
850         if (!drv->ops->del_beacon) {
851                 err = -EOPNOTSUPP;
852                 goto out;
853         }
854
855         rtnl_lock();
856         err = drv->ops->del_beacon(&drv->wiphy, dev);
857         rtnl_unlock();
858
859  out:
860         cfg80211_put_dev(drv);
861         dev_put(dev);
862         return err;
863 }
864
865 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
866         [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
867         [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
868         [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
869 };
870
871 static int parse_station_flags(struct nlattr *nla, u32 *staflags)
872 {
873         struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
874         int flag;
875
876         *staflags = 0;
877
878         if (!nla)
879                 return 0;
880
881         if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
882                              nla, sta_flags_policy))
883                 return -EINVAL;
884
885         *staflags = STATION_FLAG_CHANGED;
886
887         for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
888                 if (flags[flag])
889                         *staflags |= (1<<flag);
890
891         return 0;
892 }
893
894 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
895                                 int flags, struct net_device *dev,
896                                 u8 *mac_addr, struct station_info *sinfo)
897 {
898         void *hdr;
899         struct nlattr *sinfoattr;
900
901         hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
902         if (!hdr)
903                 return -1;
904
905         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
906         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
907
908         sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
909         if (!sinfoattr)
910                 goto nla_put_failure;
911         if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
912                 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
913                             sinfo->inactive_time);
914         if (sinfo->filled & STATION_INFO_RX_BYTES)
915                 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES,
916                             sinfo->rx_bytes);
917         if (sinfo->filled & STATION_INFO_TX_BYTES)
918                 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES,
919                             sinfo->tx_bytes);
920         if (sinfo->filled & STATION_INFO_LLID)
921                 NLA_PUT_U16(msg, NL80211_STA_INFO_LLID,
922                             sinfo->llid);
923         if (sinfo->filled & STATION_INFO_PLID)
924                 NLA_PUT_U16(msg, NL80211_STA_INFO_PLID,
925                             sinfo->plid);
926         if (sinfo->filled & STATION_INFO_PLINK_STATE)
927                 NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
928                             sinfo->plink_state);
929
930         nla_nest_end(msg, sinfoattr);
931
932         return genlmsg_end(msg, hdr);
933
934  nla_put_failure:
935         genlmsg_cancel(msg, hdr);
936         return -EMSGSIZE;
937 }
938
939 static int nl80211_dump_station(struct sk_buff *skb,
940                 struct netlink_callback *cb)
941 {
942         int wp_idx = 0;
943         int if_idx = 0;
944         int sta_idx = cb->args[2];
945         int wp_start = cb->args[0];
946         int if_start = cb->args[1];
947         struct station_info sinfo;
948         struct cfg80211_registered_device *dev;
949         struct wireless_dev *wdev;
950         u8 mac_addr[ETH_ALEN];
951         int err;
952         int exit = 0;
953
954         /* TODO: filter by device */
955         mutex_lock(&cfg80211_drv_mutex);
956         list_for_each_entry(dev, &cfg80211_drv_list, list) {
957                 if (exit)
958                         break;
959                 if (++wp_idx < wp_start)
960                         continue;
961                 if_idx = 0;
962
963                 mutex_lock(&dev->devlist_mtx);
964                 list_for_each_entry(wdev, &dev->netdev_list, list) {
965                         if (exit)
966                                 break;
967                         if (++if_idx < if_start)
968                                 continue;
969                         if (!dev->ops->dump_station)
970                                 continue;
971
972                         for (;; ++sta_idx) {
973                                 rtnl_lock();
974                                 err = dev->ops->dump_station(&dev->wiphy,
975                                                 wdev->netdev, sta_idx, mac_addr,
976                                                 &sinfo);
977                                 rtnl_unlock();
978                                 if (err) {
979                                         sta_idx = 0;
980                                         break;
981                                 }
982                                 if (nl80211_send_station(skb,
983                                                 NETLINK_CB(cb->skb).pid,
984                                                 cb->nlh->nlmsg_seq, NLM_F_MULTI,
985                                                 wdev->netdev, mac_addr,
986                                                 &sinfo) < 0) {
987                                         exit = 1;
988                                         break;
989                                 }
990                         }
991                 }
992                 mutex_unlock(&dev->devlist_mtx);
993         }
994         mutex_unlock(&cfg80211_drv_mutex);
995
996         cb->args[0] = wp_idx;
997         cb->args[1] = if_idx;
998         cb->args[2] = sta_idx;
999
1000         return skb->len;
1001 }
1002
1003 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1004 {
1005         struct cfg80211_registered_device *drv;
1006         int err;
1007         struct net_device *dev;
1008         struct station_info sinfo;
1009         struct sk_buff *msg;
1010         u8 *mac_addr = NULL;
1011
1012         memset(&sinfo, 0, sizeof(sinfo));
1013
1014         if (!info->attrs[NL80211_ATTR_MAC])
1015                 return -EINVAL;
1016
1017         mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1018
1019         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1020         if (err)
1021                 return err;
1022
1023         if (!drv->ops->get_station) {
1024                 err = -EOPNOTSUPP;
1025                 goto out;
1026         }
1027
1028         rtnl_lock();
1029         err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
1030         rtnl_unlock();
1031
1032         if (err)
1033                 goto out;
1034
1035         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1036         if (!msg)
1037                 goto out;
1038
1039         if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
1040                                  dev, mac_addr, &sinfo) < 0)
1041                 goto out_free;
1042
1043         err = genlmsg_unicast(msg, info->snd_pid);
1044         goto out;
1045
1046  out_free:
1047         nlmsg_free(msg);
1048
1049  out:
1050         cfg80211_put_dev(drv);
1051         dev_put(dev);
1052         return err;
1053 }
1054
1055 /*
1056  * Get vlan interface making sure it is on the right wiphy.
1057  */
1058 static int get_vlan(struct nlattr *vlanattr,
1059                     struct cfg80211_registered_device *rdev,
1060                     struct net_device **vlan)
1061 {
1062         *vlan = NULL;
1063
1064         if (vlanattr) {
1065                 *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
1066                 if (!*vlan)
1067                         return -ENODEV;
1068                 if (!(*vlan)->ieee80211_ptr)
1069                         return -EINVAL;
1070                 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
1071                         return -EINVAL;
1072         }
1073         return 0;
1074 }
1075
1076 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1077 {
1078         struct cfg80211_registered_device *drv;
1079         int err;
1080         struct net_device *dev;
1081         struct station_parameters params;
1082         u8 *mac_addr = NULL;
1083
1084         memset(&params, 0, sizeof(params));
1085
1086         params.listen_interval = -1;
1087
1088         if (info->attrs[NL80211_ATTR_STA_AID])
1089                 return -EINVAL;
1090
1091         if (!info->attrs[NL80211_ATTR_MAC])
1092                 return -EINVAL;
1093
1094         mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1095
1096         if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
1097                 params.supported_rates =
1098                         nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1099                 params.supported_rates_len =
1100                         nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1101         }
1102
1103         if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1104                 params.listen_interval =
1105                     nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1106
1107         if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1108                                 &params.station_flags))
1109                 return -EINVAL;
1110
1111         if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
1112                 params.plink_action =
1113                     nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
1114
1115         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1116         if (err)
1117                 return err;
1118
1119         err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1120         if (err)
1121                 goto out;
1122
1123         if (!drv->ops->change_station) {
1124                 err = -EOPNOTSUPP;
1125                 goto out;
1126         }
1127
1128         rtnl_lock();
1129         err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params);
1130         rtnl_unlock();
1131
1132  out:
1133         if (params.vlan)
1134                 dev_put(params.vlan);
1135         cfg80211_put_dev(drv);
1136         dev_put(dev);
1137         return err;
1138 }
1139
1140 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1141 {
1142         struct cfg80211_registered_device *drv;
1143         int err;
1144         struct net_device *dev;
1145         struct station_parameters params;
1146         u8 *mac_addr = NULL;
1147
1148         memset(&params, 0, sizeof(params));
1149
1150         if (!info->attrs[NL80211_ATTR_MAC])
1151                 return -EINVAL;
1152
1153         if (!info->attrs[NL80211_ATTR_STA_AID])
1154                 return -EINVAL;
1155
1156         if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1157                 return -EINVAL;
1158
1159         if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
1160                 return -EINVAL;
1161
1162         mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1163         params.supported_rates =
1164                 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1165         params.supported_rates_len =
1166                 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1167         params.listen_interval =
1168                 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1169         params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1170
1171         if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1172                                 &params.station_flags))
1173                 return -EINVAL;
1174
1175         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1176         if (err)
1177                 return err;
1178
1179         err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1180         if (err)
1181                 goto out;
1182
1183         if (!drv->ops->add_station) {
1184                 err = -EOPNOTSUPP;
1185                 goto out;
1186         }
1187
1188         rtnl_lock();
1189         err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params);
1190         rtnl_unlock();
1191
1192  out:
1193         if (params.vlan)
1194                 dev_put(params.vlan);
1195         cfg80211_put_dev(drv);
1196         dev_put(dev);
1197         return err;
1198 }
1199
1200 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1201 {
1202         struct cfg80211_registered_device *drv;
1203         int err;
1204         struct net_device *dev;
1205         u8 *mac_addr = NULL;
1206
1207         if (info->attrs[NL80211_ATTR_MAC])
1208                 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1209
1210         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1211         if (err)
1212                 return err;
1213
1214         if (!drv->ops->del_station) {
1215                 err = -EOPNOTSUPP;
1216                 goto out;
1217         }
1218
1219         rtnl_lock();
1220         err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
1221         rtnl_unlock();
1222
1223  out:
1224         cfg80211_put_dev(drv);
1225         dev_put(dev);
1226         return err;
1227 }
1228
1229 static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
1230                                 int flags, struct net_device *dev,
1231                                 u8 *dst, u8 *next_hop,
1232                                 struct mpath_info *pinfo)
1233 {
1234         void *hdr;
1235         struct nlattr *pinfoattr;
1236
1237         hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1238         if (!hdr)
1239                 return -1;
1240
1241         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1242         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
1243         NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
1244
1245         pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
1246         if (!pinfoattr)
1247                 goto nla_put_failure;
1248         if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
1249                 NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
1250                             pinfo->frame_qlen);
1251         if (pinfo->filled & MPATH_INFO_DSN)
1252                 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DSN,
1253                             pinfo->dsn);
1254         if (pinfo->filled & MPATH_INFO_METRIC)
1255                 NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
1256                             pinfo->metric);
1257         if (pinfo->filled & MPATH_INFO_EXPTIME)
1258                 NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME,
1259                             pinfo->exptime);
1260         if (pinfo->filled & MPATH_INFO_FLAGS)
1261                 NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS,
1262                             pinfo->flags);
1263         if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT)
1264                 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
1265                             pinfo->discovery_timeout);
1266         if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES)
1267                 NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
1268                             pinfo->discovery_retries);
1269
1270         nla_nest_end(msg, pinfoattr);
1271
1272         return genlmsg_end(msg, hdr);
1273
1274  nla_put_failure:
1275         genlmsg_cancel(msg, hdr);
1276         return -EMSGSIZE;
1277 }
1278
1279 static int nl80211_dump_mpath(struct sk_buff *skb,
1280                 struct netlink_callback *cb)
1281 {
1282         int wp_idx = 0;
1283         int if_idx = 0;
1284         int sta_idx = cb->args[2];
1285         int wp_start = cb->args[0];
1286         int if_start = cb->args[1];
1287         struct mpath_info pinfo;
1288         struct cfg80211_registered_device *dev;
1289         struct wireless_dev *wdev;
1290         u8 dst[ETH_ALEN];
1291         u8 next_hop[ETH_ALEN];
1292         int err;
1293         int exit = 0;
1294
1295         /* TODO: filter by device */
1296         mutex_lock(&cfg80211_drv_mutex);
1297         list_for_each_entry(dev, &cfg80211_drv_list, list) {
1298                 if (exit)
1299                         break;
1300                 if (++wp_idx < wp_start)
1301                         continue;
1302                 if_idx = 0;
1303
1304                 mutex_lock(&dev->devlist_mtx);
1305                 list_for_each_entry(wdev, &dev->netdev_list, list) {
1306                         if (exit)
1307                                 break;
1308                         if (++if_idx < if_start)
1309                                 continue;
1310                         if (!dev->ops->dump_mpath)
1311                                 continue;
1312
1313                         for (;; ++sta_idx) {
1314                                 rtnl_lock();
1315                                 err = dev->ops->dump_mpath(&dev->wiphy,
1316                                                 wdev->netdev, sta_idx, dst,
1317                                                 next_hop, &pinfo);
1318                                 rtnl_unlock();
1319                                 if (err) {
1320                                         sta_idx = 0;
1321                                         break;
1322                                 }
1323                                 if (nl80211_send_mpath(skb,
1324                                                 NETLINK_CB(cb->skb).pid,
1325                                                 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1326                                                 wdev->netdev, dst, next_hop,
1327                                                 &pinfo) < 0) {
1328                                         exit = 1;
1329                                         break;
1330                                 }
1331                         }
1332                 }
1333                 mutex_unlock(&dev->devlist_mtx);
1334         }
1335         mutex_unlock(&cfg80211_drv_mutex);
1336
1337         cb->args[0] = wp_idx;
1338         cb->args[1] = if_idx;
1339         cb->args[2] = sta_idx;
1340
1341         return skb->len;
1342 }
1343
1344 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1345 {
1346         struct cfg80211_registered_device *drv;
1347         int err;
1348         struct net_device *dev;
1349         struct mpath_info pinfo;
1350         struct sk_buff *msg;
1351         u8 *dst = NULL;
1352         u8 next_hop[ETH_ALEN];
1353
1354         memset(&pinfo, 0, sizeof(pinfo));
1355
1356         if (!info->attrs[NL80211_ATTR_MAC])
1357                 return -EINVAL;
1358
1359         dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1360
1361         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1362         if (err)
1363                 return err;
1364
1365         if (!drv->ops->get_mpath) {
1366                 err = -EOPNOTSUPP;
1367                 goto out;
1368         }
1369
1370         rtnl_lock();
1371         err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
1372         rtnl_unlock();
1373
1374         if (err)
1375                 goto out;
1376
1377         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1378         if (!msg)
1379                 goto out;
1380
1381         if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
1382                                  dev, dst, next_hop, &pinfo) < 0)
1383                 goto out_free;
1384
1385         err = genlmsg_unicast(msg, info->snd_pid);
1386         goto out;
1387
1388  out_free:
1389         nlmsg_free(msg);
1390
1391  out:
1392         cfg80211_put_dev(drv);
1393         dev_put(dev);
1394         return err;
1395 }
1396
1397 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
1398 {
1399         struct cfg80211_registered_device *drv;
1400         int err;
1401         struct net_device *dev;
1402         u8 *dst = NULL;
1403         u8 *next_hop = NULL;
1404
1405         if (!info->attrs[NL80211_ATTR_MAC])
1406                 return -EINVAL;
1407
1408         if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1409                 return -EINVAL;
1410
1411         dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1412         next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1413
1414         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1415         if (err)
1416                 return err;
1417
1418         if (!drv->ops->change_mpath) {
1419                 err = -EOPNOTSUPP;
1420                 goto out;
1421         }
1422
1423         rtnl_lock();
1424         err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
1425         rtnl_unlock();
1426
1427  out:
1428         cfg80211_put_dev(drv);
1429         dev_put(dev);
1430         return err;
1431 }
1432 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
1433 {
1434         struct cfg80211_registered_device *drv;
1435         int err;
1436         struct net_device *dev;
1437         u8 *dst = NULL;
1438         u8 *next_hop = NULL;
1439
1440         if (!info->attrs[NL80211_ATTR_MAC])
1441                 return -EINVAL;
1442
1443         if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1444                 return -EINVAL;
1445
1446         dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1447         next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1448
1449         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1450         if (err)
1451                 return err;
1452
1453         if (!drv->ops->add_mpath) {
1454                 err = -EOPNOTSUPP;
1455                 goto out;
1456         }
1457
1458         rtnl_lock();
1459         err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
1460         rtnl_unlock();
1461
1462  out:
1463         cfg80211_put_dev(drv);
1464         dev_put(dev);
1465         return err;
1466 }
1467
1468 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1469 {
1470         struct cfg80211_registered_device *drv;
1471         int err;
1472         struct net_device *dev;
1473         u8 *dst = NULL;
1474
1475         if (info->attrs[NL80211_ATTR_MAC])
1476                 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1477
1478         err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
1479         if (err)
1480                 return err;
1481
1482         if (!drv->ops->del_mpath) {
1483                 err = -EOPNOTSUPP;
1484                 goto out;
1485         }
1486
1487         rtnl_lock();
1488         err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
1489         rtnl_unlock();
1490
1491  out:
1492         cfg80211_put_dev(drv);
1493         dev_put(dev);
1494         return err;
1495 }
1496
1497 static struct genl_ops nl80211_ops[] = {
1498         {
1499                 .cmd = NL80211_CMD_GET_WIPHY,
1500                 .doit = nl80211_get_wiphy,
1501                 .dumpit = nl80211_dump_wiphy,
1502                 .policy = nl80211_policy,
1503                 /* can be retrieved by unprivileged users */
1504         },
1505         {
1506                 .cmd = NL80211_CMD_SET_WIPHY,
1507                 .doit = nl80211_set_wiphy,
1508                 .policy = nl80211_policy,
1509                 .flags = GENL_ADMIN_PERM,
1510         },
1511         {
1512                 .cmd = NL80211_CMD_GET_INTERFACE,
1513                 .doit = nl80211_get_interface,
1514                 .dumpit = nl80211_dump_interface,
1515                 .policy = nl80211_policy,
1516                 /* can be retrieved by unprivileged users */
1517         },
1518         {
1519                 .cmd = NL80211_CMD_SET_INTERFACE,
1520                 .doit = nl80211_set_interface,
1521                 .policy = nl80211_policy,
1522                 .flags = GENL_ADMIN_PERM,
1523         },
1524         {
1525                 .cmd = NL80211_CMD_NEW_INTERFACE,
1526                 .doit = nl80211_new_interface,
1527                 .policy = nl80211_policy,
1528                 .flags = GENL_ADMIN_PERM,
1529         },
1530         {
1531                 .cmd = NL80211_CMD_DEL_INTERFACE,
1532                 .doit = nl80211_del_interface,
1533                 .policy = nl80211_policy,
1534                 .flags = GENL_ADMIN_PERM,
1535         },
1536         {
1537                 .cmd = NL80211_CMD_GET_KEY,
1538                 .doit = nl80211_get_key,
1539                 .policy = nl80211_policy,
1540                 .flags = GENL_ADMIN_PERM,
1541         },
1542         {
1543                 .cmd = NL80211_CMD_SET_KEY,
1544                 .doit = nl80211_set_key,
1545                 .policy = nl80211_policy,
1546                 .flags = GENL_ADMIN_PERM,
1547         },
1548         {
1549                 .cmd = NL80211_CMD_NEW_KEY,
1550                 .doit = nl80211_new_key,
1551                 .policy = nl80211_policy,
1552                 .flags = GENL_ADMIN_PERM,
1553         },
1554         {
1555                 .cmd = NL80211_CMD_DEL_KEY,
1556                 .doit = nl80211_del_key,
1557                 .policy = nl80211_policy,
1558                 .flags = GENL_ADMIN_PERM,
1559         },
1560         {
1561                 .cmd = NL80211_CMD_SET_BEACON,
1562                 .policy = nl80211_policy,
1563                 .flags = GENL_ADMIN_PERM,
1564                 .doit = nl80211_addset_beacon,
1565         },
1566         {
1567                 .cmd = NL80211_CMD_NEW_BEACON,
1568                 .policy = nl80211_policy,
1569                 .flags = GENL_ADMIN_PERM,
1570                 .doit = nl80211_addset_beacon,
1571         },
1572         {
1573                 .cmd = NL80211_CMD_DEL_BEACON,
1574                 .policy = nl80211_policy,
1575                 .flags = GENL_ADMIN_PERM,
1576                 .doit = nl80211_del_beacon,
1577         },
1578         {
1579                 .cmd = NL80211_CMD_GET_STATION,
1580                 .doit = nl80211_get_station,
1581                 .dumpit = nl80211_dump_station,
1582                 .policy = nl80211_policy,
1583                 .flags = GENL_ADMIN_PERM,
1584         },
1585         {
1586                 .cmd = NL80211_CMD_SET_STATION,
1587                 .doit = nl80211_set_station,
1588                 .policy = nl80211_policy,
1589                 .flags = GENL_ADMIN_PERM,
1590         },
1591         {
1592                 .cmd = NL80211_CMD_NEW_STATION,
1593                 .doit = nl80211_new_station,
1594                 .policy = nl80211_policy,
1595                 .flags = GENL_ADMIN_PERM,
1596         },
1597         {
1598                 .cmd = NL80211_CMD_DEL_STATION,
1599                 .doit = nl80211_del_station,
1600                 .policy = nl80211_policy,
1601                 .flags = GENL_ADMIN_PERM,
1602         },
1603         {
1604                 .cmd = NL80211_CMD_GET_MPATH,
1605                 .doit = nl80211_get_mpath,
1606                 .dumpit = nl80211_dump_mpath,
1607                 .policy = nl80211_policy,
1608                 .flags = GENL_ADMIN_PERM,
1609         },
1610         {
1611                 .cmd = NL80211_CMD_SET_MPATH,
1612                 .doit = nl80211_set_mpath,
1613                 .policy = nl80211_policy,
1614                 .flags = GENL_ADMIN_PERM,
1615         },
1616         {
1617                 .cmd = NL80211_CMD_NEW_MPATH,
1618                 .doit = nl80211_new_mpath,
1619                 .policy = nl80211_policy,
1620                 .flags = GENL_ADMIN_PERM,
1621         },
1622         {
1623                 .cmd = NL80211_CMD_DEL_MPATH,
1624                 .doit = nl80211_del_mpath,
1625                 .policy = nl80211_policy,
1626                 .flags = GENL_ADMIN_PERM,
1627         },
1628 };
1629
1630 /* multicast groups */
1631 static struct genl_multicast_group nl80211_config_mcgrp = {
1632         .name = "config",
1633 };
1634
1635 /* notification functions */
1636
1637 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
1638 {
1639         struct sk_buff *msg;
1640
1641         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1642         if (!msg)
1643                 return;
1644
1645         if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
1646                 nlmsg_free(msg);
1647                 return;
1648         }
1649
1650         genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
1651 }
1652
1653 /* initialisation/exit functions */
1654
1655 int nl80211_init(void)
1656 {
1657         int err, i;
1658
1659         err = genl_register_family(&nl80211_fam);
1660         if (err)
1661                 return err;
1662
1663         for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
1664                 err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
1665                 if (err)
1666                         goto err_out;
1667         }
1668
1669         err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
1670         if (err)
1671                 goto err_out;
1672
1673         return 0;
1674  err_out:
1675         genl_unregister_family(&nl80211_fam);
1676         return err;
1677 }
1678
1679 void nl80211_exit(void)
1680 {
1681         genl_unregister_family(&nl80211_fam);
1682 }