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