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