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/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>
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 },
62 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
63 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
64 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
66 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
68 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
69 .len = WLAN_MAX_KEY_LEN },
70 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
71 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
72 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
74 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
75 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
76 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
77 .len = IEEE80211_MAX_DATA_LEN },
78 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
79 .len = IEEE80211_MAX_DATA_LEN },
80 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
81 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
82 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
83 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
84 .len = NL80211_MAX_SUPP_RATES },
85 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
86 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
87 [NL80211_ATTR_MNTR_FLAGS] = { .type = NLA_NESTED },
88 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
89 .len = IEEE80211_MAX_MESH_ID_LEN },
90 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
92 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
93 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
95 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
96 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
97 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
99 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
100 .len = NL80211_HT_CAPABILITY_LEN },
103 /* message building helper */
104 static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
107 /* since there is no private header just add the generic one */
108 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
111 /* netlink command implementations */
113 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
114 struct cfg80211_registered_device *dev)
117 struct nlattr *nl_bands, *nl_band;
118 struct nlattr *nl_freqs, *nl_freq;
119 struct nlattr *nl_rates, *nl_rate;
120 struct nlattr *nl_modes;
121 enum ieee80211_band band;
122 struct ieee80211_channel *chan;
123 struct ieee80211_rate *rate;
125 u16 ifmodes = dev->wiphy.interface_modes;
127 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
131 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
132 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
134 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
136 goto nla_put_failure;
141 NLA_PUT_FLAG(msg, i);
146 nla_nest_end(msg, nl_modes);
148 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
150 goto nla_put_failure;
152 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
153 if (!dev->wiphy.bands[band])
156 nl_band = nla_nest_start(msg, band);
158 goto nla_put_failure;
161 if (dev->wiphy.bands[band]->ht_cap.ht_supported) {
162 NLA_PUT(msg, NL80211_BAND_ATTR_HT_MCS_SET,
163 sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
164 &dev->wiphy.bands[band]->ht_cap.mcs);
165 NLA_PUT_U16(msg, NL80211_BAND_ATTR_HT_CAPA,
166 dev->wiphy.bands[band]->ht_cap.cap);
167 NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
168 dev->wiphy.bands[band]->ht_cap.ampdu_factor);
169 NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
170 dev->wiphy.bands[band]->ht_cap.ampdu_density);
173 /* add frequencies */
174 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
176 goto nla_put_failure;
178 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
179 nl_freq = nla_nest_start(msg, i);
181 goto nla_put_failure;
183 chan = &dev->wiphy.bands[band]->channels[i];
184 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
187 if (chan->flags & IEEE80211_CHAN_DISABLED)
188 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
189 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
190 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
191 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
192 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
193 if (chan->flags & IEEE80211_CHAN_RADAR)
194 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
196 nla_nest_end(msg, nl_freq);
199 nla_nest_end(msg, nl_freqs);
202 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
204 goto nla_put_failure;
206 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
207 nl_rate = nla_nest_start(msg, i);
209 goto nla_put_failure;
211 rate = &dev->wiphy.bands[band]->bitrates[i];
212 NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
214 if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
216 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
218 nla_nest_end(msg, nl_rate);
221 nla_nest_end(msg, nl_rates);
223 nla_nest_end(msg, nl_band);
225 nla_nest_end(msg, nl_bands);
227 return genlmsg_end(msg, hdr);
230 genlmsg_cancel(msg, hdr);
234 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
237 int start = cb->args[0];
238 struct cfg80211_registered_device *dev;
240 mutex_lock(&cfg80211_drv_mutex);
241 list_for_each_entry(dev, &cfg80211_drv_list, list) {
244 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
245 cb->nlh->nlmsg_seq, NLM_F_MULTI,
251 mutex_unlock(&cfg80211_drv_mutex);
258 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
261 struct cfg80211_registered_device *dev;
263 dev = cfg80211_get_dev_from_info(info);
267 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
271 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
274 cfg80211_put_dev(dev);
276 return genlmsg_unicast(msg, info->snd_pid);
281 cfg80211_put_dev(dev);
285 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
287 struct cfg80211_registered_device *rdev;
290 if (!info->attrs[NL80211_ATTR_WIPHY_NAME])
293 rdev = cfg80211_get_dev_from_info(info);
295 return PTR_ERR(rdev);
297 result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
299 cfg80211_put_dev(rdev);
304 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
305 struct net_device *dev)
309 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
313 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
314 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
315 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
316 return genlmsg_end(msg, hdr);
319 genlmsg_cancel(msg, hdr);
323 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
327 int wp_start = cb->args[0];
328 int if_start = cb->args[1];
329 struct cfg80211_registered_device *dev;
330 struct wireless_dev *wdev;
332 mutex_lock(&cfg80211_drv_mutex);
333 list_for_each_entry(dev, &cfg80211_drv_list, list) {
334 if (wp_idx < wp_start) {
340 mutex_lock(&dev->devlist_mtx);
341 list_for_each_entry(wdev, &dev->netdev_list, list) {
342 if (if_idx < if_start) {
346 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
347 cb->nlh->nlmsg_seq, NLM_F_MULTI,
349 mutex_unlock(&dev->devlist_mtx);
354 mutex_unlock(&dev->devlist_mtx);
359 mutex_unlock(&cfg80211_drv_mutex);
361 cb->args[0] = wp_idx;
362 cb->args[1] = if_idx;
367 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
370 struct cfg80211_registered_device *dev;
371 struct net_device *netdev;
374 err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev);
378 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
382 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0)
386 cfg80211_put_dev(dev);
388 return genlmsg_unicast(msg, info->snd_pid);
394 cfg80211_put_dev(dev);
398 static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
399 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
400 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
401 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
402 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
403 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
406 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
408 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
416 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
417 nla, mntr_flags_policy))
420 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
422 *mntrflags |= (1<<flag);
427 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
429 struct cfg80211_registered_device *drv;
430 struct vif_params params;
432 enum nl80211_iftype type;
433 struct net_device *dev;
434 u32 _flags, *flags = NULL;
436 memset(¶ms, 0, sizeof(params));
438 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
441 ifindex = dev->ifindex;
442 type = dev->ieee80211_ptr->iftype;
446 if (info->attrs[NL80211_ATTR_IFTYPE]) {
447 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
448 if (type > NL80211_IFTYPE_MAX)
452 if (!drv->ops->change_virtual_intf ||
453 !(drv->wiphy.interface_modes & (1 << type))) {
458 if (info->attrs[NL80211_ATTR_MESH_ID]) {
459 if (type != NL80211_IFTYPE_MESH_POINT) {
463 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
464 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
467 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
468 if (type != NL80211_IFTYPE_MONITOR) {
472 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
478 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
479 type, flags, ¶ms);
481 dev = __dev_get_by_index(&init_net, ifindex);
482 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
487 cfg80211_put_dev(drv);
491 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
493 struct cfg80211_registered_device *drv;
494 struct vif_params params;
496 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
499 memset(¶ms, 0, sizeof(params));
501 if (!info->attrs[NL80211_ATTR_IFNAME])
504 if (info->attrs[NL80211_ATTR_IFTYPE]) {
505 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
506 if (type > NL80211_IFTYPE_MAX)
510 drv = cfg80211_get_dev_from_info(info);
514 if (!drv->ops->add_virtual_intf ||
515 !(drv->wiphy.interface_modes & (1 << type))) {
520 if (type == NL80211_IFTYPE_MESH_POINT &&
521 info->attrs[NL80211_ATTR_MESH_ID]) {
522 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
523 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
527 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
528 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
530 err = drv->ops->add_virtual_intf(&drv->wiphy,
531 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
532 type, err ? NULL : &flags, ¶ms);
537 cfg80211_put_dev(drv);
541 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
543 struct cfg80211_registered_device *drv;
545 struct net_device *dev;
547 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
550 ifindex = dev->ifindex;
553 if (!drv->ops->del_virtual_intf) {
559 err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
563 cfg80211_put_dev(drv);
567 struct get_key_cookie {
572 static void get_key_callback(void *c, struct key_params *params)
574 struct get_key_cookie *cookie = c;
577 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
578 params->key_len, params->key);
581 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
582 params->seq_len, params->seq);
585 NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
593 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
595 struct cfg80211_registered_device *drv;
597 struct net_device *dev;
600 struct get_key_cookie cookie = {
606 if (info->attrs[NL80211_ATTR_KEY_IDX])
607 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
612 if (info->attrs[NL80211_ATTR_MAC])
613 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
615 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
619 if (!drv->ops->get_key) {
624 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
630 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
631 NL80211_CMD_NEW_KEY);
640 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
641 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
643 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
646 err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
647 &cookie, get_key_callback);
654 goto nla_put_failure;
656 genlmsg_end(msg, hdr);
657 err = genlmsg_unicast(msg, info->snd_pid);
664 cfg80211_put_dev(drv);
669 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
671 struct cfg80211_registered_device *drv;
673 struct net_device *dev;
676 if (!info->attrs[NL80211_ATTR_KEY_IDX])
679 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
684 /* currently only support setting default key */
685 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
688 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
692 if (!drv->ops->set_default_key) {
698 err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
702 cfg80211_put_dev(drv);
707 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
709 struct cfg80211_registered_device *drv;
711 struct net_device *dev;
712 struct key_params params;
716 memset(¶ms, 0, sizeof(params));
718 if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
721 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
722 params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
723 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
726 if (info->attrs[NL80211_ATTR_KEY_IDX])
727 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
729 params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
731 if (info->attrs[NL80211_ATTR_MAC])
732 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
738 * Disallow pairwise keys with non-zero index unless it's WEP
739 * (because current deployments use pairwise WEP keys with
740 * non-zero indizes but 802.11i clearly specifies to use zero)
742 if (mac_addr && key_idx &&
743 params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
744 params.cipher != WLAN_CIPHER_SUITE_WEP104)
747 /* TODO: add definitions for the lengths to linux/ieee80211.h */
748 switch (params.cipher) {
749 case WLAN_CIPHER_SUITE_WEP40:
750 if (params.key_len != 5)
753 case WLAN_CIPHER_SUITE_TKIP:
754 if (params.key_len != 32)
757 case WLAN_CIPHER_SUITE_CCMP:
758 if (params.key_len != 16)
761 case WLAN_CIPHER_SUITE_WEP104:
762 if (params.key_len != 13)
769 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
773 if (!drv->ops->add_key) {
779 err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, ¶ms);
783 cfg80211_put_dev(drv);
788 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
790 struct cfg80211_registered_device *drv;
792 struct net_device *dev;
796 if (info->attrs[NL80211_ATTR_KEY_IDX])
797 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
802 if (info->attrs[NL80211_ATTR_MAC])
803 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
805 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
809 if (!drv->ops->del_key) {
815 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
819 cfg80211_put_dev(drv);
824 static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
826 int (*call)(struct wiphy *wiphy, struct net_device *dev,
827 struct beacon_parameters *info);
828 struct cfg80211_registered_device *drv;
830 struct net_device *dev;
831 struct beacon_parameters params;
834 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
838 switch (info->genlhdr->cmd) {
839 case NL80211_CMD_NEW_BEACON:
840 /* these are required for NEW_BEACON */
841 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
842 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
843 !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
848 call = drv->ops->add_beacon;
850 case NL80211_CMD_SET_BEACON:
851 call = drv->ops->set_beacon;
864 memset(¶ms, 0, sizeof(params));
866 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
868 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
872 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
874 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
878 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
879 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
881 nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
885 if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
886 params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
888 nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
898 err = call(&drv->wiphy, dev, ¶ms);
902 cfg80211_put_dev(drv);
907 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
909 struct cfg80211_registered_device *drv;
911 struct net_device *dev;
913 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
917 if (!drv->ops->del_beacon) {
923 err = drv->ops->del_beacon(&drv->wiphy, dev);
927 cfg80211_put_dev(drv);
932 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
933 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
934 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
935 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
938 static int parse_station_flags(struct nlattr *nla, u32 *staflags)
940 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
948 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
949 nla, sta_flags_policy))
952 *staflags = STATION_FLAG_CHANGED;
954 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
956 *staflags |= (1<<flag);
961 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
962 int flags, struct net_device *dev,
963 u8 *mac_addr, struct station_info *sinfo)
966 struct nlattr *sinfoattr;
968 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
972 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
973 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
975 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
977 goto nla_put_failure;
978 if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
979 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
980 sinfo->inactive_time);
981 if (sinfo->filled & STATION_INFO_RX_BYTES)
982 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES,
984 if (sinfo->filled & STATION_INFO_TX_BYTES)
985 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES,
987 if (sinfo->filled & STATION_INFO_LLID)
988 NLA_PUT_U16(msg, NL80211_STA_INFO_LLID,
990 if (sinfo->filled & STATION_INFO_PLID)
991 NLA_PUT_U16(msg, NL80211_STA_INFO_PLID,
993 if (sinfo->filled & STATION_INFO_PLINK_STATE)
994 NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
997 nla_nest_end(msg, sinfoattr);
999 return genlmsg_end(msg, hdr);
1002 genlmsg_cancel(msg, hdr);
1006 static int nl80211_dump_station(struct sk_buff *skb,
1007 struct netlink_callback *cb)
1009 struct station_info sinfo;
1010 struct cfg80211_registered_device *dev;
1011 struct net_device *netdev;
1012 u8 mac_addr[ETH_ALEN];
1013 int ifidx = cb->args[0];
1014 int sta_idx = cb->args[1];
1018 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1019 nl80211_fam.attrbuf, nl80211_fam.maxattr,
1024 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
1027 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1032 netdev = dev_get_by_index(&init_net, ifidx);
1036 dev = cfg80211_get_dev_from_ifindex(ifidx);
1039 goto out_put_netdev;
1042 if (!dev->ops->dump_station) {
1050 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
1057 if (nl80211_send_station(skb,
1058 NETLINK_CB(cb->skb).pid,
1059 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1069 cb->args[1] = sta_idx;
1074 cfg80211_put_dev(dev);
1081 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1083 struct cfg80211_registered_device *drv;
1085 struct net_device *dev;
1086 struct station_info sinfo;
1087 struct sk_buff *msg;
1088 u8 *mac_addr = NULL;
1090 memset(&sinfo, 0, sizeof(sinfo));
1092 if (!info->attrs[NL80211_ATTR_MAC])
1095 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1097 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1101 if (!drv->ops->get_station) {
1107 err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
1113 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1117 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
1118 dev, mac_addr, &sinfo) < 0)
1121 err = genlmsg_unicast(msg, info->snd_pid);
1128 cfg80211_put_dev(drv);
1134 * Get vlan interface making sure it is on the right wiphy.
1136 static int get_vlan(struct nlattr *vlanattr,
1137 struct cfg80211_registered_device *rdev,
1138 struct net_device **vlan)
1143 *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
1146 if (!(*vlan)->ieee80211_ptr)
1148 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
1154 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1156 struct cfg80211_registered_device *drv;
1158 struct net_device *dev;
1159 struct station_parameters params;
1160 u8 *mac_addr = NULL;
1162 memset(¶ms, 0, sizeof(params));
1164 params.listen_interval = -1;
1166 if (info->attrs[NL80211_ATTR_STA_AID])
1169 if (!info->attrs[NL80211_ATTR_MAC])
1172 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1174 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
1175 params.supported_rates =
1176 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1177 params.supported_rates_len =
1178 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1181 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1182 params.listen_interval =
1183 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1185 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1187 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1189 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1190 ¶ms.station_flags))
1193 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
1194 params.plink_action =
1195 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
1197 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1201 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
1205 if (!drv->ops->change_station) {
1211 err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, ¶ms);
1216 dev_put(params.vlan);
1217 cfg80211_put_dev(drv);
1222 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1224 struct cfg80211_registered_device *drv;
1226 struct net_device *dev;
1227 struct station_parameters params;
1228 u8 *mac_addr = NULL;
1230 memset(¶ms, 0, sizeof(params));
1232 if (!info->attrs[NL80211_ATTR_MAC])
1235 if (!info->attrs[NL80211_ATTR_STA_AID])
1238 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1241 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
1244 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1245 params.supported_rates =
1246 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1247 params.supported_rates_len =
1248 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1249 params.listen_interval =
1250 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1251 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1252 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1254 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1256 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1257 ¶ms.station_flags))
1260 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1264 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
1268 if (!drv->ops->add_station) {
1274 err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, ¶ms);
1279 dev_put(params.vlan);
1280 cfg80211_put_dev(drv);
1285 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1287 struct cfg80211_registered_device *drv;
1289 struct net_device *dev;
1290 u8 *mac_addr = NULL;
1292 if (info->attrs[NL80211_ATTR_MAC])
1293 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1295 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1299 if (!drv->ops->del_station) {
1305 err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
1309 cfg80211_put_dev(drv);
1314 static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
1315 int flags, struct net_device *dev,
1316 u8 *dst, u8 *next_hop,
1317 struct mpath_info *pinfo)
1320 struct nlattr *pinfoattr;
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, dst);
1328 NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
1330 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
1332 goto nla_put_failure;
1333 if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
1334 NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
1336 if (pinfo->filled & MPATH_INFO_DSN)
1337 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DSN,
1339 if (pinfo->filled & MPATH_INFO_METRIC)
1340 NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
1342 if (pinfo->filled & MPATH_INFO_EXPTIME)
1343 NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME,
1345 if (pinfo->filled & MPATH_INFO_FLAGS)
1346 NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS,
1348 if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT)
1349 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
1350 pinfo->discovery_timeout);
1351 if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES)
1352 NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
1353 pinfo->discovery_retries);
1355 nla_nest_end(msg, pinfoattr);
1357 return genlmsg_end(msg, hdr);
1360 genlmsg_cancel(msg, hdr);
1364 static int nl80211_dump_mpath(struct sk_buff *skb,
1365 struct netlink_callback *cb)
1367 struct mpath_info pinfo;
1368 struct cfg80211_registered_device *dev;
1369 struct net_device *netdev;
1371 u8 next_hop[ETH_ALEN];
1372 int ifidx = cb->args[0];
1373 int path_idx = cb->args[1];
1377 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1378 nl80211_fam.attrbuf, nl80211_fam.maxattr,
1383 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
1386 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1391 netdev = dev_get_by_index(&init_net, ifidx);
1395 dev = cfg80211_get_dev_from_ifindex(ifidx);
1398 goto out_put_netdev;
1401 if (!dev->ops->dump_mpath) {
1409 err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,
1410 dst, next_hop, &pinfo);
1416 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
1417 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1418 netdev, dst, next_hop,
1427 cb->args[1] = path_idx;
1432 cfg80211_put_dev(dev);
1439 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1441 struct cfg80211_registered_device *drv;
1443 struct net_device *dev;
1444 struct mpath_info pinfo;
1445 struct sk_buff *msg;
1447 u8 next_hop[ETH_ALEN];
1449 memset(&pinfo, 0, sizeof(pinfo));
1451 if (!info->attrs[NL80211_ATTR_MAC])
1454 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1456 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1460 if (!drv->ops->get_mpath) {
1466 err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
1472 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1476 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
1477 dev, dst, next_hop, &pinfo) < 0)
1480 err = genlmsg_unicast(msg, info->snd_pid);
1487 cfg80211_put_dev(drv);
1492 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
1494 struct cfg80211_registered_device *drv;
1496 struct net_device *dev;
1498 u8 *next_hop = NULL;
1500 if (!info->attrs[NL80211_ATTR_MAC])
1503 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1506 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1507 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1509 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1513 if (!drv->ops->change_mpath) {
1519 err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
1523 cfg80211_put_dev(drv);
1527 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
1529 struct cfg80211_registered_device *drv;
1531 struct net_device *dev;
1533 u8 *next_hop = NULL;
1535 if (!info->attrs[NL80211_ATTR_MAC])
1538 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1541 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1542 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1544 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1548 if (!drv->ops->add_mpath) {
1554 err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
1558 cfg80211_put_dev(drv);
1563 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1565 struct cfg80211_registered_device *drv;
1567 struct net_device *dev;
1570 if (info->attrs[NL80211_ATTR_MAC])
1571 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1573 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1577 if (!drv->ops->del_mpath) {
1583 err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
1587 cfg80211_put_dev(drv);
1592 static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
1594 struct cfg80211_registered_device *drv;
1596 struct net_device *dev;
1597 struct bss_parameters params;
1599 memset(¶ms, 0, sizeof(params));
1600 /* default to not changing parameters */
1601 params.use_cts_prot = -1;
1602 params.use_short_preamble = -1;
1603 params.use_short_slot_time = -1;
1605 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
1606 params.use_cts_prot =
1607 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
1608 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
1609 params.use_short_preamble =
1610 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
1611 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
1612 params.use_short_slot_time =
1613 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
1615 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1619 if (!drv->ops->change_bss) {
1625 err = drv->ops->change_bss(&drv->wiphy, dev, ¶ms);
1629 cfg80211_put_dev(drv);
1634 static const struct nla_policy
1635 reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
1636 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
1637 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
1638 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
1639 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
1640 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
1641 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
1644 static int parse_reg_rule(struct nlattr *tb[],
1645 struct ieee80211_reg_rule *reg_rule)
1647 struct ieee80211_freq_range *freq_range = ®_rule->freq_range;
1648 struct ieee80211_power_rule *power_rule = ®_rule->power_rule;
1650 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
1652 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
1654 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
1656 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
1658 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
1661 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
1663 freq_range->start_freq_khz =
1664 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
1665 freq_range->end_freq_khz =
1666 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
1667 freq_range->max_bandwidth_khz =
1668 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
1670 power_rule->max_eirp =
1671 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
1673 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
1674 power_rule->max_antenna_gain =
1675 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
1680 static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
1685 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
1688 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
1690 #ifdef CONFIG_WIRELESS_OLD_REGULATORY
1691 /* We ignore world regdom requests with the old regdom setup */
1692 if (is_world_regdom(data))
1695 mutex_lock(&cfg80211_drv_mutex);
1696 r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, NULL);
1697 mutex_unlock(&cfg80211_drv_mutex);
1701 static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
1703 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
1704 struct nlattr *nl_reg_rule;
1705 char *alpha2 = NULL;
1706 int rem_reg_rules = 0, r = 0;
1707 u32 num_rules = 0, rule_idx = 0, size_of_regd;
1708 struct ieee80211_regdomain *rd = NULL;
1710 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
1713 if (!info->attrs[NL80211_ATTR_REG_RULES])
1716 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
1718 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1721 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
1725 if (!reg_is_valid_request(alpha2))
1728 size_of_regd = sizeof(struct ieee80211_regdomain) +
1729 (num_rules * sizeof(struct ieee80211_reg_rule));
1731 rd = kzalloc(size_of_regd, GFP_KERNEL);
1735 rd->n_reg_rules = num_rules;
1736 rd->alpha2[0] = alpha2[0];
1737 rd->alpha2[1] = alpha2[1];
1739 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1741 nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
1742 nla_data(nl_reg_rule), nla_len(nl_reg_rule),
1744 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
1750 if (rule_idx > NL80211_MAX_SUPP_REG_RULES)
1754 BUG_ON(rule_idx != num_rules);
1756 mutex_lock(&cfg80211_drv_mutex);
1758 mutex_unlock(&cfg80211_drv_mutex);
1769 static struct genl_ops nl80211_ops[] = {
1771 .cmd = NL80211_CMD_GET_WIPHY,
1772 .doit = nl80211_get_wiphy,
1773 .dumpit = nl80211_dump_wiphy,
1774 .policy = nl80211_policy,
1775 /* can be retrieved by unprivileged users */
1778 .cmd = NL80211_CMD_SET_WIPHY,
1779 .doit = nl80211_set_wiphy,
1780 .policy = nl80211_policy,
1781 .flags = GENL_ADMIN_PERM,
1784 .cmd = NL80211_CMD_GET_INTERFACE,
1785 .doit = nl80211_get_interface,
1786 .dumpit = nl80211_dump_interface,
1787 .policy = nl80211_policy,
1788 /* can be retrieved by unprivileged users */
1791 .cmd = NL80211_CMD_SET_INTERFACE,
1792 .doit = nl80211_set_interface,
1793 .policy = nl80211_policy,
1794 .flags = GENL_ADMIN_PERM,
1797 .cmd = NL80211_CMD_NEW_INTERFACE,
1798 .doit = nl80211_new_interface,
1799 .policy = nl80211_policy,
1800 .flags = GENL_ADMIN_PERM,
1803 .cmd = NL80211_CMD_DEL_INTERFACE,
1804 .doit = nl80211_del_interface,
1805 .policy = nl80211_policy,
1806 .flags = GENL_ADMIN_PERM,
1809 .cmd = NL80211_CMD_GET_KEY,
1810 .doit = nl80211_get_key,
1811 .policy = nl80211_policy,
1812 .flags = GENL_ADMIN_PERM,
1815 .cmd = NL80211_CMD_SET_KEY,
1816 .doit = nl80211_set_key,
1817 .policy = nl80211_policy,
1818 .flags = GENL_ADMIN_PERM,
1821 .cmd = NL80211_CMD_NEW_KEY,
1822 .doit = nl80211_new_key,
1823 .policy = nl80211_policy,
1824 .flags = GENL_ADMIN_PERM,
1827 .cmd = NL80211_CMD_DEL_KEY,
1828 .doit = nl80211_del_key,
1829 .policy = nl80211_policy,
1830 .flags = GENL_ADMIN_PERM,
1833 .cmd = NL80211_CMD_SET_BEACON,
1834 .policy = nl80211_policy,
1835 .flags = GENL_ADMIN_PERM,
1836 .doit = nl80211_addset_beacon,
1839 .cmd = NL80211_CMD_NEW_BEACON,
1840 .policy = nl80211_policy,
1841 .flags = GENL_ADMIN_PERM,
1842 .doit = nl80211_addset_beacon,
1845 .cmd = NL80211_CMD_DEL_BEACON,
1846 .policy = nl80211_policy,
1847 .flags = GENL_ADMIN_PERM,
1848 .doit = nl80211_del_beacon,
1851 .cmd = NL80211_CMD_GET_STATION,
1852 .doit = nl80211_get_station,
1853 .dumpit = nl80211_dump_station,
1854 .policy = nl80211_policy,
1855 .flags = GENL_ADMIN_PERM,
1858 .cmd = NL80211_CMD_SET_STATION,
1859 .doit = nl80211_set_station,
1860 .policy = nl80211_policy,
1861 .flags = GENL_ADMIN_PERM,
1864 .cmd = NL80211_CMD_NEW_STATION,
1865 .doit = nl80211_new_station,
1866 .policy = nl80211_policy,
1867 .flags = GENL_ADMIN_PERM,
1870 .cmd = NL80211_CMD_DEL_STATION,
1871 .doit = nl80211_del_station,
1872 .policy = nl80211_policy,
1873 .flags = GENL_ADMIN_PERM,
1876 .cmd = NL80211_CMD_GET_MPATH,
1877 .doit = nl80211_get_mpath,
1878 .dumpit = nl80211_dump_mpath,
1879 .policy = nl80211_policy,
1880 .flags = GENL_ADMIN_PERM,
1883 .cmd = NL80211_CMD_SET_MPATH,
1884 .doit = nl80211_set_mpath,
1885 .policy = nl80211_policy,
1886 .flags = GENL_ADMIN_PERM,
1889 .cmd = NL80211_CMD_NEW_MPATH,
1890 .doit = nl80211_new_mpath,
1891 .policy = nl80211_policy,
1892 .flags = GENL_ADMIN_PERM,
1895 .cmd = NL80211_CMD_DEL_MPATH,
1896 .doit = nl80211_del_mpath,
1897 .policy = nl80211_policy,
1898 .flags = GENL_ADMIN_PERM,
1901 .cmd = NL80211_CMD_SET_BSS,
1902 .doit = nl80211_set_bss,
1903 .policy = nl80211_policy,
1904 .flags = GENL_ADMIN_PERM,
1907 .cmd = NL80211_CMD_SET_REG,
1908 .doit = nl80211_set_reg,
1909 .policy = nl80211_policy,
1910 .flags = GENL_ADMIN_PERM,
1913 .cmd = NL80211_CMD_REQ_SET_REG,
1914 .doit = nl80211_req_set_reg,
1915 .policy = nl80211_policy,
1916 .flags = GENL_ADMIN_PERM,
1920 /* multicast groups */
1921 static struct genl_multicast_group nl80211_config_mcgrp = {
1925 /* notification functions */
1927 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
1929 struct sk_buff *msg;
1931 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1935 if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
1940 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
1943 /* initialisation/exit functions */
1945 int nl80211_init(void)
1949 err = genl_register_family(&nl80211_fam);
1953 for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
1954 err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
1959 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
1965 genl_unregister_family(&nl80211_fam);
1969 void nl80211_exit(void)
1971 genl_unregister_family(&nl80211_fam);