2 * This is the new netlink-based wireless configuration interface.
4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
8 #include <linux/module.h>
10 #include <linux/list.h>
11 #include <linux/if_ether.h>
12 #include <linux/ieee80211.h>
13 #include <linux/nl80211.h>
14 #include <linux/rtnetlink.h>
15 #include <linux/netlink.h>
16 #include <linux/etherdevice.h>
17 #include <net/genetlink.h>
18 #include <net/cfg80211.h>
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,
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)
39 if (!attrs[NL80211_ATTR_IFINDEX])
42 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
43 *dev = dev_get_by_index(&init_net, ifindex);
47 *drv = cfg80211_get_dev_from_ifindex(ifindex);
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 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
65 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
66 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
67 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
69 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
71 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
72 .len = WLAN_MAX_KEY_LEN },
73 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
74 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
75 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
77 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
78 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
79 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
80 .len = IEEE80211_MAX_DATA_LEN },
81 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
82 .len = IEEE80211_MAX_DATA_LEN },
83 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
84 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
85 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
86 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
87 .len = NL80211_MAX_SUPP_RATES },
88 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
89 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
90 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
91 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
92 .len = IEEE80211_MAX_MESH_ID_LEN },
93 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
95 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
96 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
98 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
99 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
100 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
101 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
102 .len = NL80211_MAX_SUPP_RATES },
104 [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED },
106 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
107 .len = NL80211_HT_CAPABILITY_LEN },
109 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
110 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
111 .len = IEEE80211_MAX_DATA_LEN },
112 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
113 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
115 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
116 .len = IEEE80211_MAX_SSID_LEN },
117 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
118 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
119 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
123 static bool is_valid_ie_attr(const struct nlattr *attr)
131 pos = nla_data(attr);
152 /* message building helper */
153 static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
156 /* since there is no private header just add the generic one */
157 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
160 static int nl80211_msg_put_channel(struct sk_buff *msg,
161 struct ieee80211_channel *chan)
163 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
166 if (chan->flags & IEEE80211_CHAN_DISABLED)
167 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
168 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
169 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
170 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
171 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
172 if (chan->flags & IEEE80211_CHAN_RADAR)
173 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
175 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
176 DBM_TO_MBM(chan->max_power));
184 /* netlink command implementations */
186 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
187 struct cfg80211_registered_device *dev)
190 struct nlattr *nl_bands, *nl_band;
191 struct nlattr *nl_freqs, *nl_freq;
192 struct nlattr *nl_rates, *nl_rate;
193 struct nlattr *nl_modes;
194 struct nlattr *nl_cmds;
195 enum ieee80211_band band;
196 struct ieee80211_channel *chan;
197 struct ieee80211_rate *rate;
199 u16 ifmodes = dev->wiphy.interface_modes;
201 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
205 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
206 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
207 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
208 dev->wiphy.max_scan_ssids);
209 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
210 dev->wiphy.max_scan_ie_len);
212 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
213 sizeof(u32) * dev->wiphy.n_cipher_suites,
214 dev->wiphy.cipher_suites);
216 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
218 goto nla_put_failure;
223 NLA_PUT_FLAG(msg, i);
228 nla_nest_end(msg, nl_modes);
230 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
232 goto nla_put_failure;
234 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
235 if (!dev->wiphy.bands[band])
238 nl_band = nla_nest_start(msg, band);
240 goto nla_put_failure;
243 if (dev->wiphy.bands[band]->ht_cap.ht_supported) {
244 NLA_PUT(msg, NL80211_BAND_ATTR_HT_MCS_SET,
245 sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
246 &dev->wiphy.bands[band]->ht_cap.mcs);
247 NLA_PUT_U16(msg, NL80211_BAND_ATTR_HT_CAPA,
248 dev->wiphy.bands[band]->ht_cap.cap);
249 NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
250 dev->wiphy.bands[band]->ht_cap.ampdu_factor);
251 NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
252 dev->wiphy.bands[band]->ht_cap.ampdu_density);
255 /* add frequencies */
256 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
258 goto nla_put_failure;
260 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
261 nl_freq = nla_nest_start(msg, i);
263 goto nla_put_failure;
265 chan = &dev->wiphy.bands[band]->channels[i];
267 if (nl80211_msg_put_channel(msg, chan))
268 goto nla_put_failure;
270 nla_nest_end(msg, nl_freq);
273 nla_nest_end(msg, nl_freqs);
276 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
278 goto nla_put_failure;
280 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
281 nl_rate = nla_nest_start(msg, i);
283 goto nla_put_failure;
285 rate = &dev->wiphy.bands[band]->bitrates[i];
286 NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
288 if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
290 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
292 nla_nest_end(msg, nl_rate);
295 nla_nest_end(msg, nl_rates);
297 nla_nest_end(msg, nl_band);
299 nla_nest_end(msg, nl_bands);
301 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
303 goto nla_put_failure;
308 if (dev->ops->op) { \
310 NLA_PUT_U32(msg, i, NL80211_CMD_ ## n); \
314 CMD(add_virtual_intf, NEW_INTERFACE);
315 CMD(change_virtual_intf, SET_INTERFACE);
316 CMD(add_key, NEW_KEY);
317 CMD(add_beacon, NEW_BEACON);
318 CMD(add_station, NEW_STATION);
319 CMD(add_mpath, NEW_MPATH);
320 CMD(set_mesh_params, SET_MESH_PARAMS);
321 CMD(change_bss, SET_BSS);
322 CMD(auth, AUTHENTICATE);
323 CMD(assoc, ASSOCIATE);
324 CMD(deauth, DEAUTHENTICATE);
325 CMD(disassoc, DISASSOCIATE);
326 CMD(join_ibss, JOIN_IBSS);
329 nla_nest_end(msg, nl_cmds);
331 return genlmsg_end(msg, hdr);
334 genlmsg_cancel(msg, hdr);
338 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
341 int start = cb->args[0];
342 struct cfg80211_registered_device *dev;
344 mutex_lock(&cfg80211_mutex);
345 list_for_each_entry(dev, &cfg80211_drv_list, list) {
348 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
349 cb->nlh->nlmsg_seq, NLM_F_MULTI,
355 mutex_unlock(&cfg80211_mutex);
362 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
365 struct cfg80211_registered_device *dev;
367 dev = cfg80211_get_dev_from_info(info);
371 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
375 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
378 cfg80211_put_dev(dev);
380 return genlmsg_unicast(msg, info->snd_pid);
385 cfg80211_put_dev(dev);
389 static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
390 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
391 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
392 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
393 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
394 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
397 static int parse_txq_params(struct nlattr *tb[],
398 struct ieee80211_txq_params *txq_params)
400 if (!tb[NL80211_TXQ_ATTR_QUEUE] || !tb[NL80211_TXQ_ATTR_TXOP] ||
401 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
402 !tb[NL80211_TXQ_ATTR_AIFS])
405 txq_params->queue = nla_get_u8(tb[NL80211_TXQ_ATTR_QUEUE]);
406 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
407 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
408 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
409 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
414 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
416 struct cfg80211_registered_device *rdev;
417 int result = 0, rem_txq_params = 0;
418 struct nlattr *nl_txq_params;
422 mutex_lock(&cfg80211_mutex);
424 rdev = __cfg80211_drv_from_info(info);
426 result = PTR_ERR(rdev);
430 mutex_lock(&rdev->mtx);
432 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
433 result = cfg80211_dev_rename(
434 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
436 mutex_unlock(&cfg80211_mutex);
441 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
442 struct ieee80211_txq_params txq_params;
443 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
445 if (!rdev->ops->set_txq_params) {
446 result = -EOPNOTSUPP;
450 nla_for_each_nested(nl_txq_params,
451 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
453 nla_parse(tb, NL80211_TXQ_ATTR_MAX,
454 nla_data(nl_txq_params),
455 nla_len(nl_txq_params),
457 result = parse_txq_params(tb, &txq_params);
461 result = rdev->ops->set_txq_params(&rdev->wiphy,
468 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
469 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
470 struct ieee80211_channel *chan;
471 struct ieee80211_sta_ht_cap *ht_cap;
474 if (!rdev->ops->set_channel) {
475 result = -EOPNOTSUPP;
481 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
482 channel_type = nla_get_u32(info->attrs[
483 NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
484 if (channel_type != NL80211_CHAN_NO_HT &&
485 channel_type != NL80211_CHAN_HT20 &&
486 channel_type != NL80211_CHAN_HT40PLUS &&
487 channel_type != NL80211_CHAN_HT40MINUS)
491 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
492 chan = ieee80211_get_channel(&rdev->wiphy, freq);
494 /* Primary channel not allowed */
495 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
498 if (channel_type == NL80211_CHAN_HT40MINUS)
499 sec_freq = freq - 20;
500 else if (channel_type == NL80211_CHAN_HT40PLUS)
501 sec_freq = freq + 20;
505 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
507 /* no HT capabilities */
508 if (channel_type != NL80211_CHAN_NO_HT &&
509 !ht_cap->ht_supported)
513 struct ieee80211_channel *schan;
515 /* no 40 MHz capabilities */
516 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
517 (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
520 schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
522 /* Secondary channel not allowed */
523 if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
527 result = rdev->ops->set_channel(&rdev->wiphy, chan,
535 mutex_unlock(&rdev->mtx);
542 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
543 struct cfg80211_registered_device *rdev,
544 struct net_device *dev)
548 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
552 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
553 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
554 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
555 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
556 return genlmsg_end(msg, hdr);
559 genlmsg_cancel(msg, hdr);
563 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
567 int wp_start = cb->args[0];
568 int if_start = cb->args[1];
569 struct cfg80211_registered_device *dev;
570 struct wireless_dev *wdev;
572 mutex_lock(&cfg80211_mutex);
573 list_for_each_entry(dev, &cfg80211_drv_list, list) {
574 if (wp_idx < wp_start) {
580 mutex_lock(&dev->devlist_mtx);
581 list_for_each_entry(wdev, &dev->netdev_list, list) {
582 if (if_idx < if_start) {
586 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
587 cb->nlh->nlmsg_seq, NLM_F_MULTI,
588 dev, wdev->netdev) < 0) {
589 mutex_unlock(&dev->devlist_mtx);
594 mutex_unlock(&dev->devlist_mtx);
599 mutex_unlock(&cfg80211_mutex);
601 cb->args[0] = wp_idx;
602 cb->args[1] = if_idx;
607 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
610 struct cfg80211_registered_device *dev;
611 struct net_device *netdev;
614 err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev);
618 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
622 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
627 cfg80211_put_dev(dev);
629 return genlmsg_unicast(msg, info->snd_pid);
635 cfg80211_put_dev(dev);
639 static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
640 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
641 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
642 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
643 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
644 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
647 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
649 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
657 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
658 nla, mntr_flags_policy))
661 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
663 *mntrflags |= (1<<flag);
668 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
670 struct cfg80211_registered_device *drv;
671 struct vif_params params;
673 enum nl80211_iftype otype, ntype;
674 struct net_device *dev;
675 u32 _flags, *flags = NULL;
678 memset(¶ms, 0, sizeof(params));
682 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
686 ifindex = dev->ifindex;
687 otype = ntype = dev->ieee80211_ptr->iftype;
690 if (info->attrs[NL80211_ATTR_IFTYPE]) {
691 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
694 if (ntype > NL80211_IFTYPE_MAX) {
700 if (!drv->ops->change_virtual_intf ||
701 !(drv->wiphy.interface_modes & (1 << ntype))) {
706 if (info->attrs[NL80211_ATTR_MESH_ID]) {
707 if (ntype != NL80211_IFTYPE_MESH_POINT) {
711 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
712 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
716 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
717 if (ntype != NL80211_IFTYPE_MONITOR) {
721 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
731 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
732 ntype, flags, ¶ms);
736 dev = __dev_get_by_index(&init_net, ifindex);
737 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype));
739 if (dev && !err && (ntype != otype)) {
740 if (otype == NL80211_IFTYPE_ADHOC)
741 cfg80211_clear_ibss(dev);
745 cfg80211_put_dev(drv);
751 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
753 struct cfg80211_registered_device *drv;
754 struct vif_params params;
756 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
759 memset(¶ms, 0, sizeof(params));
761 if (!info->attrs[NL80211_ATTR_IFNAME])
764 if (info->attrs[NL80211_ATTR_IFTYPE]) {
765 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
766 if (type > NL80211_IFTYPE_MAX)
772 drv = cfg80211_get_dev_from_info(info);
778 if (!drv->ops->add_virtual_intf ||
779 !(drv->wiphy.interface_modes & (1 << type))) {
784 if (type == NL80211_IFTYPE_MESH_POINT &&
785 info->attrs[NL80211_ATTR_MESH_ID]) {
786 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
787 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
790 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
791 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
793 err = drv->ops->add_virtual_intf(&drv->wiphy,
794 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
795 type, err ? NULL : &flags, ¶ms);
798 cfg80211_put_dev(drv);
804 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
806 struct cfg80211_registered_device *drv;
808 struct net_device *dev;
812 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
815 ifindex = dev->ifindex;
818 if (!drv->ops->del_virtual_intf) {
823 err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
826 cfg80211_put_dev(drv);
832 struct get_key_cookie {
837 static void get_key_callback(void *c, struct key_params *params)
839 struct get_key_cookie *cookie = c;
842 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
843 params->key_len, params->key);
846 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
847 params->seq_len, params->seq);
850 NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
858 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
860 struct cfg80211_registered_device *drv;
862 struct net_device *dev;
865 struct get_key_cookie cookie = {
871 if (info->attrs[NL80211_ATTR_KEY_IDX])
872 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
877 if (info->attrs[NL80211_ATTR_MAC])
878 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
882 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
886 if (!drv->ops->get_key) {
891 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
897 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
898 NL80211_CMD_NEW_KEY);
907 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
908 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
910 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
912 err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
913 &cookie, get_key_callback);
919 goto nla_put_failure;
921 genlmsg_end(msg, hdr);
922 err = genlmsg_unicast(msg, info->snd_pid);
929 cfg80211_put_dev(drv);
937 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
939 struct cfg80211_registered_device *drv;
941 struct net_device *dev;
943 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
946 if (!info->attrs[NL80211_ATTR_KEY_IDX])
949 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
951 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]) {
952 if (key_idx < 4 || key_idx > 5)
954 } else if (key_idx > 3)
957 /* currently only support setting default key */
958 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT] &&
959 !info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT])
964 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
968 if (info->attrs[NL80211_ATTR_KEY_DEFAULT])
969 func = drv->ops->set_default_key;
971 func = drv->ops->set_default_mgmt_key;
978 err = func(&drv->wiphy, dev, key_idx);
981 cfg80211_put_dev(drv);
990 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
992 struct cfg80211_registered_device *drv;
994 struct net_device *dev;
995 struct key_params params;
999 memset(¶ms, 0, sizeof(params));
1001 if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
1004 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
1005 params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
1006 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
1009 if (info->attrs[NL80211_ATTR_KEY_IDX])
1010 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1012 params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
1014 if (info->attrs[NL80211_ATTR_MAC])
1015 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1021 * Disallow pairwise keys with non-zero index unless it's WEP
1022 * (because current deployments use pairwise WEP keys with
1023 * non-zero indizes but 802.11i clearly specifies to use zero)
1025 if (mac_addr && key_idx &&
1026 params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
1027 params.cipher != WLAN_CIPHER_SUITE_WEP104)
1030 /* TODO: add definitions for the lengths to linux/ieee80211.h */
1031 switch (params.cipher) {
1032 case WLAN_CIPHER_SUITE_WEP40:
1033 if (params.key_len != 5)
1036 case WLAN_CIPHER_SUITE_TKIP:
1037 if (params.key_len != 32)
1040 case WLAN_CIPHER_SUITE_CCMP:
1041 if (params.key_len != 16)
1044 case WLAN_CIPHER_SUITE_WEP104:
1045 if (params.key_len != 13)
1048 case WLAN_CIPHER_SUITE_AES_CMAC:
1049 if (params.key_len != 16)
1058 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1062 for (i = 0; i < drv->wiphy.n_cipher_suites; i++)
1063 if (params.cipher == drv->wiphy.cipher_suites[i])
1065 if (i == drv->wiphy.n_cipher_suites) {
1070 if (!drv->ops->add_key) {
1075 err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, ¶ms);
1078 cfg80211_put_dev(drv);
1086 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1088 struct cfg80211_registered_device *drv;
1090 struct net_device *dev;
1092 u8 *mac_addr = NULL;
1094 if (info->attrs[NL80211_ATTR_KEY_IDX])
1095 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1100 if (info->attrs[NL80211_ATTR_MAC])
1101 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1105 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1109 if (!drv->ops->del_key) {
1114 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
1117 cfg80211_put_dev(drv);
1126 static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1128 int (*call)(struct wiphy *wiphy, struct net_device *dev,
1129 struct beacon_parameters *info);
1130 struct cfg80211_registered_device *drv;
1132 struct net_device *dev;
1133 struct beacon_parameters params;
1136 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1141 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1145 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
1150 switch (info->genlhdr->cmd) {
1151 case NL80211_CMD_NEW_BEACON:
1152 /* these are required for NEW_BEACON */
1153 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
1154 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
1155 !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
1160 call = drv->ops->add_beacon;
1162 case NL80211_CMD_SET_BEACON:
1163 call = drv->ops->set_beacon;
1176 memset(¶ms, 0, sizeof(params));
1178 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
1180 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1184 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
1185 params.dtim_period =
1186 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1190 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
1191 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1193 nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1197 if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
1198 params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
1200 nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
1209 err = call(&drv->wiphy, dev, ¶ms);
1212 cfg80211_put_dev(drv);
1220 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1222 struct cfg80211_registered_device *drv;
1224 struct net_device *dev;
1228 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1232 if (!drv->ops->del_beacon) {
1237 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
1241 err = drv->ops->del_beacon(&drv->wiphy, dev);
1244 cfg80211_put_dev(drv);
1252 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
1253 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
1254 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
1255 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
1258 static int parse_station_flags(struct nlattr *nla, u32 *staflags)
1260 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
1268 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
1269 nla, sta_flags_policy))
1272 *staflags = STATION_FLAG_CHANGED;
1274 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
1276 *staflags |= (1<<flag);
1281 static u16 nl80211_calculate_bitrate(struct rate_info *rate)
1283 int modulation, streams, bitrate;
1285 if (!(rate->flags & RATE_INFO_FLAGS_MCS))
1286 return rate->legacy;
1288 /* the formula below does only work for MCS values smaller than 32 */
1289 if (rate->mcs >= 32)
1292 modulation = rate->mcs & 7;
1293 streams = (rate->mcs >> 3) + 1;
1295 bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
1299 bitrate *= (modulation + 1);
1300 else if (modulation == 4)
1301 bitrate *= (modulation + 2);
1303 bitrate *= (modulation + 3);
1307 if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
1308 bitrate = (bitrate / 9) * 10;
1310 /* do NOT round down here */
1311 return (bitrate + 50000) / 100000;
1314 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1315 int flags, struct net_device *dev,
1316 u8 *mac_addr, struct station_info *sinfo)
1319 struct nlattr *sinfoattr, *txrate;
1322 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1326 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1327 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
1329 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
1331 goto nla_put_failure;
1332 if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
1333 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
1334 sinfo->inactive_time);
1335 if (sinfo->filled & STATION_INFO_RX_BYTES)
1336 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES,
1338 if (sinfo->filled & STATION_INFO_TX_BYTES)
1339 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES,
1341 if (sinfo->filled & STATION_INFO_LLID)
1342 NLA_PUT_U16(msg, NL80211_STA_INFO_LLID,
1344 if (sinfo->filled & STATION_INFO_PLID)
1345 NLA_PUT_U16(msg, NL80211_STA_INFO_PLID,
1347 if (sinfo->filled & STATION_INFO_PLINK_STATE)
1348 NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
1349 sinfo->plink_state);
1350 if (sinfo->filled & STATION_INFO_SIGNAL)
1351 NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
1353 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
1354 txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
1356 goto nla_put_failure;
1358 /* nl80211_calculate_bitrate will return 0 for mcs >= 32 */
1359 bitrate = nl80211_calculate_bitrate(&sinfo->txrate);
1361 NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
1363 if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
1364 NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
1366 if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
1367 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
1368 if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
1369 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
1371 nla_nest_end(msg, txrate);
1373 if (sinfo->filled & STATION_INFO_RX_PACKETS)
1374 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS,
1376 if (sinfo->filled & STATION_INFO_TX_PACKETS)
1377 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS,
1379 nla_nest_end(msg, sinfoattr);
1381 return genlmsg_end(msg, hdr);
1384 genlmsg_cancel(msg, hdr);
1388 static int nl80211_dump_station(struct sk_buff *skb,
1389 struct netlink_callback *cb)
1391 struct station_info sinfo;
1392 struct cfg80211_registered_device *dev;
1393 struct net_device *netdev;
1394 u8 mac_addr[ETH_ALEN];
1395 int ifidx = cb->args[0];
1396 int sta_idx = cb->args[1];
1400 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1401 nl80211_fam.attrbuf, nl80211_fam.maxattr,
1406 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
1409 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1416 netdev = __dev_get_by_index(&init_net, ifidx);
1422 dev = cfg80211_get_dev_from_ifindex(ifidx);
1428 if (!dev->ops->dump_station) {
1434 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
1441 if (nl80211_send_station(skb,
1442 NETLINK_CB(cb->skb).pid,
1443 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1453 cb->args[1] = sta_idx;
1456 cfg80211_put_dev(dev);
1463 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1465 struct cfg80211_registered_device *drv;
1467 struct net_device *dev;
1468 struct station_info sinfo;
1469 struct sk_buff *msg;
1470 u8 *mac_addr = NULL;
1472 memset(&sinfo, 0, sizeof(sinfo));
1474 if (!info->attrs[NL80211_ATTR_MAC])
1477 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1481 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1485 if (!drv->ops->get_station) {
1490 err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
1494 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1498 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
1499 dev, mac_addr, &sinfo) < 0)
1502 err = genlmsg_unicast(msg, info->snd_pid);
1508 cfg80211_put_dev(drv);
1517 * Get vlan interface making sure it is on the right wiphy.
1519 static int get_vlan(struct nlattr *vlanattr,
1520 struct cfg80211_registered_device *rdev,
1521 struct net_device **vlan)
1526 *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
1529 if (!(*vlan)->ieee80211_ptr)
1531 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
1537 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1539 struct cfg80211_registered_device *drv;
1541 struct net_device *dev;
1542 struct station_parameters params;
1543 u8 *mac_addr = NULL;
1545 memset(¶ms, 0, sizeof(params));
1547 params.listen_interval = -1;
1549 if (info->attrs[NL80211_ATTR_STA_AID])
1552 if (!info->attrs[NL80211_ATTR_MAC])
1555 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1557 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
1558 params.supported_rates =
1559 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1560 params.supported_rates_len =
1561 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1564 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1565 params.listen_interval =
1566 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1568 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1570 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1572 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1573 ¶ms.station_flags))
1576 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
1577 params.plink_action =
1578 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
1582 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1586 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
1590 if (!drv->ops->change_station) {
1595 err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, ¶ms);
1599 dev_put(params.vlan);
1600 cfg80211_put_dev(drv);
1608 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1610 struct cfg80211_registered_device *drv;
1612 struct net_device *dev;
1613 struct station_parameters params;
1614 u8 *mac_addr = NULL;
1616 memset(¶ms, 0, sizeof(params));
1618 if (!info->attrs[NL80211_ATTR_MAC])
1621 if (!info->attrs[NL80211_ATTR_STA_AID])
1624 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1627 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
1630 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1631 params.supported_rates =
1632 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1633 params.supported_rates_len =
1634 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1635 params.listen_interval =
1636 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1637 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1638 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1640 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1642 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1643 ¶ms.station_flags))
1648 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1652 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
1656 if (!drv->ops->add_station) {
1661 if (!netif_running(dev)) {
1666 err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, ¶ms);
1670 dev_put(params.vlan);
1671 cfg80211_put_dev(drv);
1679 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1681 struct cfg80211_registered_device *drv;
1683 struct net_device *dev;
1684 u8 *mac_addr = NULL;
1686 if (info->attrs[NL80211_ATTR_MAC])
1687 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1691 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1695 if (!drv->ops->del_station) {
1700 err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
1703 cfg80211_put_dev(drv);
1711 static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
1712 int flags, struct net_device *dev,
1713 u8 *dst, u8 *next_hop,
1714 struct mpath_info *pinfo)
1717 struct nlattr *pinfoattr;
1719 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1723 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1724 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
1725 NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
1727 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
1729 goto nla_put_failure;
1730 if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
1731 NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
1733 if (pinfo->filled & MPATH_INFO_DSN)
1734 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DSN,
1736 if (pinfo->filled & MPATH_INFO_METRIC)
1737 NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
1739 if (pinfo->filled & MPATH_INFO_EXPTIME)
1740 NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME,
1742 if (pinfo->filled & MPATH_INFO_FLAGS)
1743 NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS,
1745 if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT)
1746 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
1747 pinfo->discovery_timeout);
1748 if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES)
1749 NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
1750 pinfo->discovery_retries);
1752 nla_nest_end(msg, pinfoattr);
1754 return genlmsg_end(msg, hdr);
1757 genlmsg_cancel(msg, hdr);
1761 static int nl80211_dump_mpath(struct sk_buff *skb,
1762 struct netlink_callback *cb)
1764 struct mpath_info pinfo;
1765 struct cfg80211_registered_device *dev;
1766 struct net_device *netdev;
1768 u8 next_hop[ETH_ALEN];
1769 int ifidx = cb->args[0];
1770 int path_idx = cb->args[1];
1774 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1775 nl80211_fam.attrbuf, nl80211_fam.maxattr,
1780 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
1783 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1790 netdev = __dev_get_by_index(&init_net, ifidx);
1796 dev = cfg80211_get_dev_from_ifindex(ifidx);
1802 if (!dev->ops->dump_mpath) {
1807 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
1813 err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,
1814 dst, next_hop, &pinfo);
1820 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
1821 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1822 netdev, dst, next_hop,
1831 cb->args[1] = path_idx;
1834 cfg80211_put_dev(dev);
1841 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1843 struct cfg80211_registered_device *drv;
1845 struct net_device *dev;
1846 struct mpath_info pinfo;
1847 struct sk_buff *msg;
1849 u8 next_hop[ETH_ALEN];
1851 memset(&pinfo, 0, sizeof(pinfo));
1853 if (!info->attrs[NL80211_ATTR_MAC])
1856 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1860 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1864 if (!drv->ops->get_mpath) {
1869 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
1874 err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
1878 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1882 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
1883 dev, dst, next_hop, &pinfo) < 0)
1886 err = genlmsg_unicast(msg, info->snd_pid);
1892 cfg80211_put_dev(drv);
1900 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
1902 struct cfg80211_registered_device *drv;
1904 struct net_device *dev;
1906 u8 *next_hop = NULL;
1908 if (!info->attrs[NL80211_ATTR_MAC])
1911 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1914 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1915 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1919 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1923 if (!drv->ops->change_mpath) {
1928 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
1933 if (!netif_running(dev)) {
1938 err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
1941 cfg80211_put_dev(drv);
1948 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
1950 struct cfg80211_registered_device *drv;
1952 struct net_device *dev;
1954 u8 *next_hop = NULL;
1956 if (!info->attrs[NL80211_ATTR_MAC])
1959 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1962 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1963 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1967 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1971 if (!drv->ops->add_mpath) {
1976 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
1981 if (!netif_running(dev)) {
1986 err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
1989 cfg80211_put_dev(drv);
1997 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1999 struct cfg80211_registered_device *drv;
2001 struct net_device *dev;
2004 if (info->attrs[NL80211_ATTR_MAC])
2005 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2009 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2013 if (!drv->ops->del_mpath) {
2018 err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
2021 cfg80211_put_dev(drv);
2029 static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
2031 struct cfg80211_registered_device *drv;
2033 struct net_device *dev;
2034 struct bss_parameters params;
2036 memset(¶ms, 0, sizeof(params));
2037 /* default to not changing parameters */
2038 params.use_cts_prot = -1;
2039 params.use_short_preamble = -1;
2040 params.use_short_slot_time = -1;
2042 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
2043 params.use_cts_prot =
2044 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
2045 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
2046 params.use_short_preamble =
2047 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
2048 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
2049 params.use_short_slot_time =
2050 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
2051 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
2052 params.basic_rates =
2053 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
2054 params.basic_rates_len =
2055 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
2060 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2064 if (!drv->ops->change_bss) {
2069 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
2074 err = drv->ops->change_bss(&drv->wiphy, dev, ¶ms);
2077 cfg80211_put_dev(drv);
2085 static const struct nla_policy
2086 reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
2087 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
2088 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
2089 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
2090 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
2091 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
2092 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
2095 static int parse_reg_rule(struct nlattr *tb[],
2096 struct ieee80211_reg_rule *reg_rule)
2098 struct ieee80211_freq_range *freq_range = ®_rule->freq_range;
2099 struct ieee80211_power_rule *power_rule = ®_rule->power_rule;
2101 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
2103 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
2105 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
2107 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
2109 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
2112 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
2114 freq_range->start_freq_khz =
2115 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
2116 freq_range->end_freq_khz =
2117 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
2118 freq_range->max_bandwidth_khz =
2119 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
2121 power_rule->max_eirp =
2122 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
2124 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
2125 power_rule->max_antenna_gain =
2126 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
2131 static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
2137 * You should only get this when cfg80211 hasn't yet initialized
2138 * completely when built-in to the kernel right between the time
2139 * window between nl80211_init() and regulatory_init(), if that is
2142 mutex_lock(&cfg80211_mutex);
2143 if (unlikely(!cfg80211_regdomain)) {
2144 mutex_unlock(&cfg80211_mutex);
2145 return -EINPROGRESS;
2147 mutex_unlock(&cfg80211_mutex);
2149 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
2152 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
2154 #ifdef CONFIG_WIRELESS_OLD_REGULATORY
2155 /* We ignore world regdom requests with the old regdom setup */
2156 if (is_world_regdom(data))
2160 r = regulatory_hint_user(data);
2165 static int nl80211_get_mesh_params(struct sk_buff *skb,
2166 struct genl_info *info)
2168 struct cfg80211_registered_device *drv;
2169 struct mesh_config cur_params;
2171 struct net_device *dev;
2173 struct nlattr *pinfoattr;
2174 struct sk_buff *msg;
2178 /* Look up our device */
2179 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2183 if (!drv->ops->get_mesh_params) {
2188 /* Get the mesh params */
2189 err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params);
2193 /* Draw up a netlink message to send back */
2194 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2199 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2200 NL80211_CMD_GET_MESH_PARAMS);
2202 goto nla_put_failure;
2203 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS);
2205 goto nla_put_failure;
2206 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
2207 NLA_PUT_U16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
2208 cur_params.dot11MeshRetryTimeout);
2209 NLA_PUT_U16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
2210 cur_params.dot11MeshConfirmTimeout);
2211 NLA_PUT_U16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
2212 cur_params.dot11MeshHoldingTimeout);
2213 NLA_PUT_U16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
2214 cur_params.dot11MeshMaxPeerLinks);
2215 NLA_PUT_U8(msg, NL80211_MESHCONF_MAX_RETRIES,
2216 cur_params.dot11MeshMaxRetries);
2217 NLA_PUT_U8(msg, NL80211_MESHCONF_TTL,
2218 cur_params.dot11MeshTTL);
2219 NLA_PUT_U8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
2220 cur_params.auto_open_plinks);
2221 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
2222 cur_params.dot11MeshHWMPmaxPREQretries);
2223 NLA_PUT_U32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
2224 cur_params.path_refresh_time);
2225 NLA_PUT_U16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
2226 cur_params.min_discovery_timeout);
2227 NLA_PUT_U32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
2228 cur_params.dot11MeshHWMPactivePathTimeout);
2229 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
2230 cur_params.dot11MeshHWMPpreqMinInterval);
2231 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
2232 cur_params.dot11MeshHWMPnetDiameterTraversalTime);
2233 nla_nest_end(msg, pinfoattr);
2234 genlmsg_end(msg, hdr);
2235 err = genlmsg_unicast(msg, info->snd_pid);
2239 genlmsg_cancel(msg, hdr);
2243 cfg80211_put_dev(drv);
2251 #define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
2253 if (table[attr_num]) {\
2254 cfg.param = nla_fn(table[attr_num]); \
2255 mask |= (1 << (attr_num - 1)); \
2259 static struct nla_policy
2260 nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] __read_mostly = {
2261 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
2262 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
2263 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
2264 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
2265 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
2266 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
2267 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
2269 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
2270 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
2271 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
2272 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
2273 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
2274 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
2277 static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2281 struct cfg80211_registered_device *drv;
2282 struct net_device *dev;
2283 struct mesh_config cfg;
2284 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
2285 struct nlattr *parent_attr;
2287 parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS];
2290 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
2291 parent_attr, nl80211_meshconf_params_policy))
2296 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2300 if (!drv->ops->set_mesh_params) {
2305 /* This makes sure that there aren't more than 32 mesh config
2306 * parameters (otherwise our bitfield scheme would not work.) */
2307 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
2309 /* Fill in the params struct */
2311 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
2312 mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
2313 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
2314 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16);
2315 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
2316 mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16);
2317 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
2318 mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16);
2319 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
2320 mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
2321 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
2322 mask, NL80211_MESHCONF_TTL, nla_get_u8);
2323 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
2324 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
2325 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
2326 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
2328 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
2329 mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32);
2330 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
2331 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
2333 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
2334 mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
2336 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
2337 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
2339 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
2340 dot11MeshHWMPnetDiameterTraversalTime,
2341 mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
2345 err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask);
2349 cfg80211_put_dev(drv);
2357 #undef FILL_IN_MESH_PARAM_IF_SET
2359 static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
2361 struct sk_buff *msg;
2363 struct nlattr *nl_reg_rules;
2367 mutex_lock(&cfg80211_mutex);
2369 if (!cfg80211_regdomain)
2372 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2378 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2379 NL80211_CMD_GET_REG);
2381 goto nla_put_failure;
2383 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2,
2384 cfg80211_regdomain->alpha2);
2386 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
2388 goto nla_put_failure;
2390 for (i = 0; i < cfg80211_regdomain->n_reg_rules; i++) {
2391 struct nlattr *nl_reg_rule;
2392 const struct ieee80211_reg_rule *reg_rule;
2393 const struct ieee80211_freq_range *freq_range;
2394 const struct ieee80211_power_rule *power_rule;
2396 reg_rule = &cfg80211_regdomain->reg_rules[i];
2397 freq_range = ®_rule->freq_range;
2398 power_rule = ®_rule->power_rule;
2400 nl_reg_rule = nla_nest_start(msg, i);
2402 goto nla_put_failure;
2404 NLA_PUT_U32(msg, NL80211_ATTR_REG_RULE_FLAGS,
2406 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_START,
2407 freq_range->start_freq_khz);
2408 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_END,
2409 freq_range->end_freq_khz);
2410 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
2411 freq_range->max_bandwidth_khz);
2412 NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
2413 power_rule->max_antenna_gain);
2414 NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
2415 power_rule->max_eirp);
2417 nla_nest_end(msg, nl_reg_rule);
2420 nla_nest_end(msg, nl_reg_rules);
2422 genlmsg_end(msg, hdr);
2423 err = genlmsg_unicast(msg, info->snd_pid);
2427 genlmsg_cancel(msg, hdr);
2430 mutex_unlock(&cfg80211_mutex);
2434 static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2436 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
2437 struct nlattr *nl_reg_rule;
2438 char *alpha2 = NULL;
2439 int rem_reg_rules = 0, r = 0;
2440 u32 num_rules = 0, rule_idx = 0, size_of_regd;
2441 struct ieee80211_regdomain *rd = NULL;
2443 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
2446 if (!info->attrs[NL80211_ATTR_REG_RULES])
2449 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
2451 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
2454 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
2458 if (!reg_is_valid_request(alpha2))
2461 size_of_regd = sizeof(struct ieee80211_regdomain) +
2462 (num_rules * sizeof(struct ieee80211_reg_rule));
2464 rd = kzalloc(size_of_regd, GFP_KERNEL);
2468 rd->n_reg_rules = num_rules;
2469 rd->alpha2[0] = alpha2[0];
2470 rd->alpha2[1] = alpha2[1];
2472 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
2474 nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
2475 nla_data(nl_reg_rule), nla_len(nl_reg_rule),
2477 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
2483 if (rule_idx > NL80211_MAX_SUPP_REG_RULES)
2487 BUG_ON(rule_idx != num_rules);
2489 mutex_lock(&cfg80211_mutex);
2491 mutex_unlock(&cfg80211_mutex);
2499 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2501 struct cfg80211_registered_device *drv;
2502 struct net_device *dev;
2503 struct cfg80211_scan_request *request;
2504 struct cfg80211_ssid *ssid;
2505 struct ieee80211_channel *channel;
2506 struct nlattr *attr;
2507 struct wiphy *wiphy;
2508 int err, tmp, n_ssids = 0, n_channels = 0, i;
2509 enum ieee80211_band band;
2512 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2517 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2521 wiphy = &drv->wiphy;
2523 if (!drv->ops->scan) {
2528 if (!netif_running(dev)) {
2533 if (drv->scan_req) {
2538 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
2539 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp)
2546 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
2547 if (wiphy->bands[band])
2548 n_channels += wiphy->bands[band]->n_channels;
2551 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
2552 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
2555 if (n_ssids > wiphy->max_scan_ssids) {
2560 if (info->attrs[NL80211_ATTR_IE])
2561 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2565 if (ie_len > wiphy->max_scan_ie_len) {
2570 request = kzalloc(sizeof(*request)
2571 + sizeof(*ssid) * n_ssids
2572 + sizeof(channel) * n_channels
2573 + ie_len, GFP_KERNEL);
2579 request->channels = (void *)((char *)request + sizeof(*request));
2580 request->n_channels = n_channels;
2582 request->ssids = (void *)(request->channels + n_channels);
2583 request->n_ssids = n_ssids;
2586 request->ie = (void *)(request->ssids + n_ssids);
2588 request->ie = (void *)(request->channels + n_channels);
2591 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
2592 /* user specified, bail out if channel not found */
2593 request->n_channels = n_channels;
2595 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
2596 request->channels[i] = ieee80211_get_channel(wiphy, nla_get_u32(attr));
2597 if (!request->channels[i]) {
2606 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2608 if (!wiphy->bands[band])
2610 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
2611 request->channels[i] = &wiphy->bands[band]->channels[j];
2618 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
2619 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
2620 if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) {
2624 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2625 request->ssids[i].ssid_len = nla_len(attr);
2630 if (info->attrs[NL80211_ATTR_IE]) {
2631 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2632 memcpy((void *)request->ie,
2633 nla_data(info->attrs[NL80211_ATTR_IE]),
2637 request->ifidx = dev->ifindex;
2638 request->wiphy = &drv->wiphy;
2640 drv->scan_req = request;
2641 err = drv->ops->scan(&drv->wiphy, dev, request);
2645 drv->scan_req = NULL;
2649 cfg80211_put_dev(drv);
2657 static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
2658 struct cfg80211_registered_device *rdev,
2659 struct net_device *dev,
2660 struct cfg80211_bss *res)
2665 hdr = nl80211hdr_put(msg, pid, seq, flags,
2666 NL80211_CMD_NEW_SCAN_RESULTS);
2670 NLA_PUT_U32(msg, NL80211_ATTR_SCAN_GENERATION,
2671 rdev->bss_generation);
2672 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
2674 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
2676 goto nla_put_failure;
2677 if (!is_zero_ether_addr(res->bssid))
2678 NLA_PUT(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid);
2679 if (res->information_elements && res->len_information_elements)
2680 NLA_PUT(msg, NL80211_BSS_INFORMATION_ELEMENTS,
2681 res->len_information_elements,
2682 res->information_elements);
2684 NLA_PUT_U64(msg, NL80211_BSS_TSF, res->tsf);
2685 if (res->beacon_interval)
2686 NLA_PUT_U16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval);
2687 NLA_PUT_U16(msg, NL80211_BSS_CAPABILITY, res->capability);
2688 NLA_PUT_U32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq);
2690 switch (rdev->wiphy.signal_type) {
2691 case CFG80211_SIGNAL_TYPE_MBM:
2692 NLA_PUT_U32(msg, NL80211_BSS_SIGNAL_MBM, res->signal);
2694 case CFG80211_SIGNAL_TYPE_UNSPEC:
2695 NLA_PUT_U8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal);
2701 nla_nest_end(msg, bss);
2703 return genlmsg_end(msg, hdr);
2706 genlmsg_cancel(msg, hdr);
2710 static int nl80211_dump_scan(struct sk_buff *skb,
2711 struct netlink_callback *cb)
2713 struct cfg80211_registered_device *dev;
2714 struct net_device *netdev;
2715 struct cfg80211_internal_bss *scan;
2716 int ifidx = cb->args[0];
2717 int start = cb->args[1], idx = 0;
2721 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
2722 nl80211_fam.attrbuf, nl80211_fam.maxattr,
2727 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
2730 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
2733 cb->args[0] = ifidx;
2736 netdev = dev_get_by_index(&init_net, ifidx);
2740 dev = cfg80211_get_dev_from_ifindex(ifidx);
2743 goto out_put_netdev;
2746 spin_lock_bh(&dev->bss_lock);
2747 cfg80211_bss_expire(dev);
2749 list_for_each_entry(scan, &dev->bss_list, list) {
2752 if (nl80211_send_bss(skb,
2753 NETLINK_CB(cb->skb).pid,
2754 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2755 dev, netdev, &scan->pub) < 0) {
2762 spin_unlock_bh(&dev->bss_lock);
2766 cfg80211_put_dev(dev);
2773 static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type)
2775 return auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM ||
2776 auth_type == NL80211_AUTHTYPE_SHARED_KEY ||
2777 auth_type == NL80211_AUTHTYPE_FT ||
2778 auth_type == NL80211_AUTHTYPE_NETWORK_EAP;
2781 static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2783 struct cfg80211_registered_device *drv;
2784 struct net_device *dev;
2785 struct cfg80211_auth_request req;
2786 struct wiphy *wiphy;
2789 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2792 if (!info->attrs[NL80211_ATTR_MAC])
2795 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
2800 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2804 if (!drv->ops->auth) {
2809 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
2814 if (!netif_running(dev)) {
2819 wiphy = &drv->wiphy;
2820 memset(&req, 0, sizeof(req));
2822 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2824 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2825 req.chan = ieee80211_get_channel(
2827 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
2834 if (info->attrs[NL80211_ATTR_SSID]) {
2835 req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
2836 req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
2839 if (info->attrs[NL80211_ATTR_IE]) {
2840 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
2841 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2844 req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
2845 if (!nl80211_valid_auth_type(req.auth_type)) {
2850 err = drv->ops->auth(&drv->wiphy, dev, &req);
2853 cfg80211_put_dev(drv);
2860 static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2862 struct cfg80211_registered_device *drv;
2863 struct net_device *dev;
2864 struct cfg80211_assoc_request req;
2865 struct wiphy *wiphy;
2868 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2871 if (!info->attrs[NL80211_ATTR_MAC] ||
2872 !info->attrs[NL80211_ATTR_SSID])
2877 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2881 if (!drv->ops->assoc) {
2886 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
2891 if (!netif_running(dev)) {
2896 wiphy = &drv->wiphy;
2897 memset(&req, 0, sizeof(req));
2899 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2901 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2902 req.chan = ieee80211_get_channel(
2904 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
2911 req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
2912 req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
2914 if (info->attrs[NL80211_ATTR_IE]) {
2915 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
2916 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2919 err = drv->ops->assoc(&drv->wiphy, dev, &req);
2922 cfg80211_put_dev(drv);
2929 static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2931 struct cfg80211_registered_device *drv;
2932 struct net_device *dev;
2933 struct cfg80211_deauth_request req;
2934 struct wiphy *wiphy;
2937 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2940 if (!info->attrs[NL80211_ATTR_MAC])
2943 if (!info->attrs[NL80211_ATTR_REASON_CODE])
2948 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
2952 if (!drv->ops->deauth) {
2957 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
2962 if (!netif_running(dev)) {
2967 wiphy = &drv->wiphy;
2968 memset(&req, 0, sizeof(req));
2970 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2972 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2973 if (req.reason_code == 0) {
2974 /* Reason Code 0 is reserved */
2979 if (info->attrs[NL80211_ATTR_IE]) {
2980 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
2981 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2984 err = drv->ops->deauth(&drv->wiphy, dev, &req);
2987 cfg80211_put_dev(drv);
2994 static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2996 struct cfg80211_registered_device *drv;
2997 struct net_device *dev;
2998 struct cfg80211_disassoc_request req;
2999 struct wiphy *wiphy;
3002 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3005 if (!info->attrs[NL80211_ATTR_MAC])
3008 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3013 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3017 if (!drv->ops->disassoc) {
3022 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
3027 if (!netif_running(dev)) {
3032 wiphy = &drv->wiphy;
3033 memset(&req, 0, sizeof(req));
3035 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3037 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
3038 if (req.reason_code == 0) {
3039 /* Reason Code 0 is reserved */
3044 if (info->attrs[NL80211_ATTR_IE]) {
3045 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3046 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3049 err = drv->ops->disassoc(&drv->wiphy, dev, &req);
3052 cfg80211_put_dev(drv);
3059 static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3061 struct cfg80211_registered_device *drv;
3062 struct net_device *dev;
3063 struct cfg80211_ibss_params ibss;
3064 struct wiphy *wiphy;
3067 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3070 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
3071 !info->attrs[NL80211_ATTR_SSID] ||
3072 !nla_len(info->attrs[NL80211_ATTR_SSID]))
3077 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3081 if (!drv->ops->join_ibss) {
3086 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3091 if (!netif_running(dev)) {
3096 wiphy = &drv->wiphy;
3097 memset(&ibss, 0, sizeof(ibss));
3099 if (info->attrs[NL80211_ATTR_MAC])
3100 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3101 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3102 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
3104 if (info->attrs[NL80211_ATTR_IE]) {
3105 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3106 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3109 ibss.channel = ieee80211_get_channel(wiphy,
3110 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3111 if (!ibss.channel ||
3112 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
3113 ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
3118 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
3120 err = cfg80211_join_ibss(drv, dev, &ibss);
3123 cfg80211_put_dev(drv);
3130 static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
3132 struct cfg80211_registered_device *drv;
3133 struct net_device *dev;
3138 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3142 if (!drv->ops->leave_ibss) {
3147 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3152 if (!netif_running(dev)) {
3157 err = cfg80211_leave_ibss(drv, dev);
3160 cfg80211_put_dev(drv);
3167 static struct genl_ops nl80211_ops[] = {
3169 .cmd = NL80211_CMD_GET_WIPHY,
3170 .doit = nl80211_get_wiphy,
3171 .dumpit = nl80211_dump_wiphy,
3172 .policy = nl80211_policy,
3173 /* can be retrieved by unprivileged users */
3176 .cmd = NL80211_CMD_SET_WIPHY,
3177 .doit = nl80211_set_wiphy,
3178 .policy = nl80211_policy,
3179 .flags = GENL_ADMIN_PERM,
3182 .cmd = NL80211_CMD_GET_INTERFACE,
3183 .doit = nl80211_get_interface,
3184 .dumpit = nl80211_dump_interface,
3185 .policy = nl80211_policy,
3186 /* can be retrieved by unprivileged users */
3189 .cmd = NL80211_CMD_SET_INTERFACE,
3190 .doit = nl80211_set_interface,
3191 .policy = nl80211_policy,
3192 .flags = GENL_ADMIN_PERM,
3195 .cmd = NL80211_CMD_NEW_INTERFACE,
3196 .doit = nl80211_new_interface,
3197 .policy = nl80211_policy,
3198 .flags = GENL_ADMIN_PERM,
3201 .cmd = NL80211_CMD_DEL_INTERFACE,
3202 .doit = nl80211_del_interface,
3203 .policy = nl80211_policy,
3204 .flags = GENL_ADMIN_PERM,
3207 .cmd = NL80211_CMD_GET_KEY,
3208 .doit = nl80211_get_key,
3209 .policy = nl80211_policy,
3210 .flags = GENL_ADMIN_PERM,
3213 .cmd = NL80211_CMD_SET_KEY,
3214 .doit = nl80211_set_key,
3215 .policy = nl80211_policy,
3216 .flags = GENL_ADMIN_PERM,
3219 .cmd = NL80211_CMD_NEW_KEY,
3220 .doit = nl80211_new_key,
3221 .policy = nl80211_policy,
3222 .flags = GENL_ADMIN_PERM,
3225 .cmd = NL80211_CMD_DEL_KEY,
3226 .doit = nl80211_del_key,
3227 .policy = nl80211_policy,
3228 .flags = GENL_ADMIN_PERM,
3231 .cmd = NL80211_CMD_SET_BEACON,
3232 .policy = nl80211_policy,
3233 .flags = GENL_ADMIN_PERM,
3234 .doit = nl80211_addset_beacon,
3237 .cmd = NL80211_CMD_NEW_BEACON,
3238 .policy = nl80211_policy,
3239 .flags = GENL_ADMIN_PERM,
3240 .doit = nl80211_addset_beacon,
3243 .cmd = NL80211_CMD_DEL_BEACON,
3244 .policy = nl80211_policy,
3245 .flags = GENL_ADMIN_PERM,
3246 .doit = nl80211_del_beacon,
3249 .cmd = NL80211_CMD_GET_STATION,
3250 .doit = nl80211_get_station,
3251 .dumpit = nl80211_dump_station,
3252 .policy = nl80211_policy,
3255 .cmd = NL80211_CMD_SET_STATION,
3256 .doit = nl80211_set_station,
3257 .policy = nl80211_policy,
3258 .flags = GENL_ADMIN_PERM,
3261 .cmd = NL80211_CMD_NEW_STATION,
3262 .doit = nl80211_new_station,
3263 .policy = nl80211_policy,
3264 .flags = GENL_ADMIN_PERM,
3267 .cmd = NL80211_CMD_DEL_STATION,
3268 .doit = nl80211_del_station,
3269 .policy = nl80211_policy,
3270 .flags = GENL_ADMIN_PERM,
3273 .cmd = NL80211_CMD_GET_MPATH,
3274 .doit = nl80211_get_mpath,
3275 .dumpit = nl80211_dump_mpath,
3276 .policy = nl80211_policy,
3277 .flags = GENL_ADMIN_PERM,
3280 .cmd = NL80211_CMD_SET_MPATH,
3281 .doit = nl80211_set_mpath,
3282 .policy = nl80211_policy,
3283 .flags = GENL_ADMIN_PERM,
3286 .cmd = NL80211_CMD_NEW_MPATH,
3287 .doit = nl80211_new_mpath,
3288 .policy = nl80211_policy,
3289 .flags = GENL_ADMIN_PERM,
3292 .cmd = NL80211_CMD_DEL_MPATH,
3293 .doit = nl80211_del_mpath,
3294 .policy = nl80211_policy,
3295 .flags = GENL_ADMIN_PERM,
3298 .cmd = NL80211_CMD_SET_BSS,
3299 .doit = nl80211_set_bss,
3300 .policy = nl80211_policy,
3301 .flags = GENL_ADMIN_PERM,
3304 .cmd = NL80211_CMD_GET_REG,
3305 .doit = nl80211_get_reg,
3306 .policy = nl80211_policy,
3307 /* can be retrieved by unprivileged users */
3310 .cmd = NL80211_CMD_SET_REG,
3311 .doit = nl80211_set_reg,
3312 .policy = nl80211_policy,
3313 .flags = GENL_ADMIN_PERM,
3316 .cmd = NL80211_CMD_REQ_SET_REG,
3317 .doit = nl80211_req_set_reg,
3318 .policy = nl80211_policy,
3319 .flags = GENL_ADMIN_PERM,
3322 .cmd = NL80211_CMD_GET_MESH_PARAMS,
3323 .doit = nl80211_get_mesh_params,
3324 .policy = nl80211_policy,
3325 /* can be retrieved by unprivileged users */
3328 .cmd = NL80211_CMD_SET_MESH_PARAMS,
3329 .doit = nl80211_set_mesh_params,
3330 .policy = nl80211_policy,
3331 .flags = GENL_ADMIN_PERM,
3334 .cmd = NL80211_CMD_TRIGGER_SCAN,
3335 .doit = nl80211_trigger_scan,
3336 .policy = nl80211_policy,
3337 .flags = GENL_ADMIN_PERM,
3340 .cmd = NL80211_CMD_GET_SCAN,
3341 .policy = nl80211_policy,
3342 .dumpit = nl80211_dump_scan,
3345 .cmd = NL80211_CMD_AUTHENTICATE,
3346 .doit = nl80211_authenticate,
3347 .policy = nl80211_policy,
3348 .flags = GENL_ADMIN_PERM,
3351 .cmd = NL80211_CMD_ASSOCIATE,
3352 .doit = nl80211_associate,
3353 .policy = nl80211_policy,
3354 .flags = GENL_ADMIN_PERM,
3357 .cmd = NL80211_CMD_DEAUTHENTICATE,
3358 .doit = nl80211_deauthenticate,
3359 .policy = nl80211_policy,
3360 .flags = GENL_ADMIN_PERM,
3363 .cmd = NL80211_CMD_DISASSOCIATE,
3364 .doit = nl80211_disassociate,
3365 .policy = nl80211_policy,
3366 .flags = GENL_ADMIN_PERM,
3369 .cmd = NL80211_CMD_JOIN_IBSS,
3370 .doit = nl80211_join_ibss,
3371 .policy = nl80211_policy,
3372 .flags = GENL_ADMIN_PERM,
3375 .cmd = NL80211_CMD_LEAVE_IBSS,
3376 .doit = nl80211_leave_ibss,
3377 .policy = nl80211_policy,
3378 .flags = GENL_ADMIN_PERM,
3381 static struct genl_multicast_group nl80211_mlme_mcgrp = {
3385 /* multicast groups */
3386 static struct genl_multicast_group nl80211_config_mcgrp = {
3389 static struct genl_multicast_group nl80211_scan_mcgrp = {
3392 static struct genl_multicast_group nl80211_regulatory_mcgrp = {
3393 .name = "regulatory",
3396 /* notification functions */
3398 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
3400 struct sk_buff *msg;
3402 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3406 if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
3411 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
3414 static int nl80211_send_scan_donemsg(struct sk_buff *msg,
3415 struct cfg80211_registered_device *rdev,
3416 struct net_device *netdev,
3417 u32 pid, u32 seq, int flags,
3422 hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
3426 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3427 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3429 /* XXX: we should probably bounce back the request? */
3431 return genlmsg_end(msg, hdr);
3434 genlmsg_cancel(msg, hdr);
3438 void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
3439 struct net_device *netdev)
3441 struct sk_buff *msg;
3443 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3447 if (nl80211_send_scan_donemsg(msg, rdev, netdev, 0, 0, 0,
3448 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
3453 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
3456 void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
3457 struct net_device *netdev)
3459 struct sk_buff *msg;
3461 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3465 if (nl80211_send_scan_donemsg(msg, rdev, netdev, 0, 0, 0,
3466 NL80211_CMD_SCAN_ABORTED) < 0) {
3471 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
3475 * This can happen on global regulatory changes or device specific settings
3476 * based on custom world regulatory domains.
3478 void nl80211_send_reg_change_event(struct regulatory_request *request)
3480 struct sk_buff *msg;
3483 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3487 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
3493 /* Userspace can always count this one always being set */
3494 NLA_PUT_U8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator);
3496 if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
3497 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
3498 NL80211_REGDOM_TYPE_WORLD);
3499 else if (request->alpha2[0] == '9' && request->alpha2[1] == '9')
3500 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
3501 NL80211_REGDOM_TYPE_CUSTOM_WORLD);
3502 else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
3504 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
3505 NL80211_REGDOM_TYPE_INTERSECTION);
3507 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
3508 NL80211_REGDOM_TYPE_COUNTRY);
3509 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, request->alpha2);
3512 if (wiphy_idx_valid(request->wiphy_idx))
3513 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx);
3515 if (genlmsg_end(msg, hdr) < 0) {
3520 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_KERNEL);
3525 genlmsg_cancel(msg, hdr);
3529 static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
3530 struct net_device *netdev,
3531 const u8 *buf, size_t len,
3532 enum nl80211_commands cmd)
3534 struct sk_buff *msg;
3537 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
3541 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
3547 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3548 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3549 NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
3551 if (genlmsg_end(msg, hdr) < 0) {
3556 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
3560 genlmsg_cancel(msg, hdr);
3564 void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
3565 struct net_device *netdev, const u8 *buf, size_t len)
3567 nl80211_send_mlme_event(rdev, netdev, buf, len,
3568 NL80211_CMD_AUTHENTICATE);
3571 void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
3572 struct net_device *netdev, const u8 *buf,
3575 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
3578 void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
3579 struct net_device *netdev, const u8 *buf, size_t len)
3581 nl80211_send_mlme_event(rdev, netdev, buf, len,
3582 NL80211_CMD_DEAUTHENTICATE);
3585 void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
3586 struct net_device *netdev, const u8 *buf,
3589 nl80211_send_mlme_event(rdev, netdev, buf, len,
3590 NL80211_CMD_DISASSOCIATE);
3593 void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
3594 struct net_device *netdev, const u8 *bssid,
3597 struct sk_buff *msg;
3600 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
3604 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
3610 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3611 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3612 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
3614 if (genlmsg_end(msg, hdr) < 0) {
3619 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
3623 genlmsg_cancel(msg, hdr);
3627 void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
3628 struct net_device *netdev, const u8 *addr,
3629 enum nl80211_key_type key_type, int key_id,
3632 struct sk_buff *msg;
3635 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3639 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
3645 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3646 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3648 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3649 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
3650 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
3652 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
3654 if (genlmsg_end(msg, hdr) < 0) {
3659 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
3663 genlmsg_cancel(msg, hdr);
3667 void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
3668 struct ieee80211_channel *channel_before,
3669 struct ieee80211_channel *channel_after)
3671 struct sk_buff *msg;
3673 struct nlattr *nl_freq;
3675 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
3679 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
3686 * Since we are applying the beacon hint to a wiphy we know its
3687 * wiphy_idx is valid
3689 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
3692 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
3694 goto nla_put_failure;
3695 if (nl80211_msg_put_channel(msg, channel_before))
3696 goto nla_put_failure;
3697 nla_nest_end(msg, nl_freq);
3700 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
3702 goto nla_put_failure;
3703 if (nl80211_msg_put_channel(msg, channel_after))
3704 goto nla_put_failure;
3705 nla_nest_end(msg, nl_freq);
3707 if (genlmsg_end(msg, hdr) < 0) {
3712 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC);
3717 genlmsg_cancel(msg, hdr);
3721 /* initialisation/exit functions */
3723 int nl80211_init(void)
3727 err = genl_register_family(&nl80211_fam);
3731 for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
3732 err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
3737 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
3741 err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp);
3745 err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp);
3749 err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp);
3755 genl_unregister_family(&nl80211_fam);
3759 void nl80211_exit(void)
3761 genl_unregister_family(&nl80211_fam);