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