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>
22 /* the netlink family */
23 static struct genl_family nl80211_fam = {
24 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
25 .name = "nl80211", /* have users key off the name instead */
26 .hdrsize = 0, /* no private header */
27 .version = 1, /* no particular meaning now */
28 .maxattr = NL80211_ATTR_MAX,
31 /* internal helper: get drv and dev */
32 static int get_drv_dev_by_info_ifindex(struct nlattr **attrs,
33 struct cfg80211_registered_device **drv,
34 struct net_device **dev)
38 if (!attrs[NL80211_ATTR_IFINDEX])
41 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
42 *dev = dev_get_by_index(&init_net, ifindex);
46 *drv = cfg80211_get_dev_from_ifindex(ifindex);
55 /* policy for the attributes */
56 static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
57 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
58 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
59 .len = BUS_ID_SIZE-1 },
61 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
62 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
63 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
65 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
67 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
68 .len = WLAN_MAX_KEY_LEN },
69 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
70 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
71 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
73 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
74 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
75 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
76 .len = IEEE80211_MAX_DATA_LEN },
77 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
78 .len = IEEE80211_MAX_DATA_LEN },
79 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
80 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
81 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
82 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
83 .len = NL80211_MAX_SUPP_RATES },
84 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
85 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
86 [NL80211_ATTR_MNTR_FLAGS] = { .type = NLA_NESTED },
87 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
88 .len = IEEE80211_MAX_MESH_ID_LEN },
89 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
91 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
92 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
93 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
95 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
96 .len = NL80211_HT_CAPABILITY_LEN },
99 /* message building helper */
100 static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
103 /* since there is no private header just add the generic one */
104 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
107 /* netlink command implementations */
109 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
110 struct cfg80211_registered_device *dev)
113 struct nlattr *nl_bands, *nl_band;
114 struct nlattr *nl_freqs, *nl_freq;
115 struct nlattr *nl_rates, *nl_rate;
116 enum ieee80211_band band;
117 struct ieee80211_channel *chan;
118 struct ieee80211_rate *rate;
121 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
125 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
126 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
128 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
130 goto nla_put_failure;
132 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
133 if (!dev->wiphy.bands[band])
136 nl_band = nla_nest_start(msg, band);
138 goto nla_put_failure;
140 /* add frequencies */
141 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
143 goto nla_put_failure;
145 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
146 nl_freq = nla_nest_start(msg, i);
148 goto nla_put_failure;
150 chan = &dev->wiphy.bands[band]->channels[i];
151 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
154 if (chan->flags & IEEE80211_CHAN_DISABLED)
155 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
156 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
157 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
158 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
159 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
160 if (chan->flags & IEEE80211_CHAN_RADAR)
161 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
163 nla_nest_end(msg, nl_freq);
166 nla_nest_end(msg, nl_freqs);
169 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
171 goto nla_put_failure;
173 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
174 nl_rate = nla_nest_start(msg, i);
176 goto nla_put_failure;
178 rate = &dev->wiphy.bands[band]->bitrates[i];
179 NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
181 if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
183 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
185 nla_nest_end(msg, nl_rate);
188 nla_nest_end(msg, nl_rates);
190 nla_nest_end(msg, nl_band);
192 nla_nest_end(msg, nl_bands);
194 return genlmsg_end(msg, hdr);
197 genlmsg_cancel(msg, hdr);
201 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
204 int start = cb->args[0];
205 struct cfg80211_registered_device *dev;
207 mutex_lock(&cfg80211_drv_mutex);
208 list_for_each_entry(dev, &cfg80211_drv_list, list) {
211 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
212 cb->nlh->nlmsg_seq, NLM_F_MULTI,
218 mutex_unlock(&cfg80211_drv_mutex);
225 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
228 struct cfg80211_registered_device *dev;
230 dev = cfg80211_get_dev_from_info(info);
234 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
238 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
241 cfg80211_put_dev(dev);
243 return genlmsg_unicast(msg, info->snd_pid);
248 cfg80211_put_dev(dev);
252 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
254 struct cfg80211_registered_device *rdev;
257 if (!info->attrs[NL80211_ATTR_WIPHY_NAME])
260 rdev = cfg80211_get_dev_from_info(info);
262 return PTR_ERR(rdev);
264 result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
266 cfg80211_put_dev(rdev);
271 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
272 struct net_device *dev)
276 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
280 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
281 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
282 /* TODO: interface type */
283 return genlmsg_end(msg, hdr);
286 genlmsg_cancel(msg, hdr);
290 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
294 int wp_start = cb->args[0];
295 int if_start = cb->args[1];
296 struct cfg80211_registered_device *dev;
297 struct wireless_dev *wdev;
299 mutex_lock(&cfg80211_drv_mutex);
300 list_for_each_entry(dev, &cfg80211_drv_list, list) {
301 if (wp_idx < wp_start) {
307 mutex_lock(&dev->devlist_mtx);
308 list_for_each_entry(wdev, &dev->netdev_list, list) {
309 if (if_idx < if_start) {
313 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
314 cb->nlh->nlmsg_seq, NLM_F_MULTI,
316 mutex_unlock(&dev->devlist_mtx);
321 mutex_unlock(&dev->devlist_mtx);
326 mutex_unlock(&cfg80211_drv_mutex);
328 cb->args[0] = wp_idx;
329 cb->args[1] = if_idx;
334 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
337 struct cfg80211_registered_device *dev;
338 struct net_device *netdev;
341 err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev);
345 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
349 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0)
353 cfg80211_put_dev(dev);
355 return genlmsg_unicast(msg, info->snd_pid);
361 cfg80211_put_dev(dev);
365 static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
366 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
367 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
368 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
369 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
370 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
373 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
375 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
383 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
384 nla, mntr_flags_policy))
387 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
389 *mntrflags |= (1<<flag);
394 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
396 struct cfg80211_registered_device *drv;
397 struct vif_params params;
399 enum nl80211_iftype type;
400 struct net_device *dev;
403 memset(¶ms, 0, sizeof(params));
405 if (info->attrs[NL80211_ATTR_IFTYPE]) {
406 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
407 if (type > NL80211_IFTYPE_MAX)
412 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
415 ifindex = dev->ifindex;
418 if (!drv->ops->change_virtual_intf) {
423 if (type == NL80211_IFTYPE_MESH_POINT &&
424 info->attrs[NL80211_ATTR_MESH_ID]) {
425 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
426 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
430 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
431 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
433 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
434 type, err ? NULL : &flags, ¶ms);
438 cfg80211_put_dev(drv);
442 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
444 struct cfg80211_registered_device *drv;
445 struct vif_params params;
447 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
450 memset(¶ms, 0, sizeof(params));
452 if (!info->attrs[NL80211_ATTR_IFNAME])
455 if (info->attrs[NL80211_ATTR_IFTYPE]) {
456 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
457 if (type > NL80211_IFTYPE_MAX)
461 drv = cfg80211_get_dev_from_info(info);
465 if (!drv->ops->add_virtual_intf) {
470 if (type == NL80211_IFTYPE_MESH_POINT &&
471 info->attrs[NL80211_ATTR_MESH_ID]) {
472 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
473 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
477 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
478 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
480 err = drv->ops->add_virtual_intf(&drv->wiphy,
481 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
482 type, err ? NULL : &flags, ¶ms);
487 cfg80211_put_dev(drv);
491 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
493 struct cfg80211_registered_device *drv;
495 struct net_device *dev;
497 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
500 ifindex = dev->ifindex;
503 if (!drv->ops->del_virtual_intf) {
509 err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
513 cfg80211_put_dev(drv);
517 struct get_key_cookie {
522 static void get_key_callback(void *c, struct key_params *params)
524 struct get_key_cookie *cookie = c;
527 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
528 params->key_len, params->key);
531 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
532 params->seq_len, params->seq);
535 NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
543 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
545 struct cfg80211_registered_device *drv;
547 struct net_device *dev;
550 struct get_key_cookie cookie = {
556 if (info->attrs[NL80211_ATTR_KEY_IDX])
557 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
562 if (info->attrs[NL80211_ATTR_MAC])
563 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
565 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
569 if (!drv->ops->get_key) {
574 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
580 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
581 NL80211_CMD_NEW_KEY);
590 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
591 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
593 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
596 err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
597 &cookie, get_key_callback);
604 goto nla_put_failure;
606 genlmsg_end(msg, hdr);
607 err = genlmsg_unicast(msg, info->snd_pid);
614 cfg80211_put_dev(drv);
619 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
621 struct cfg80211_registered_device *drv;
623 struct net_device *dev;
626 if (!info->attrs[NL80211_ATTR_KEY_IDX])
629 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
634 /* currently only support setting default key */
635 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
638 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
642 if (!drv->ops->set_default_key) {
648 err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
652 cfg80211_put_dev(drv);
657 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
659 struct cfg80211_registered_device *drv;
661 struct net_device *dev;
662 struct key_params params;
666 memset(¶ms, 0, sizeof(params));
668 if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
671 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
672 params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
673 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
676 if (info->attrs[NL80211_ATTR_KEY_IDX])
677 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
679 params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
681 if (info->attrs[NL80211_ATTR_MAC])
682 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
688 * Disallow pairwise keys with non-zero index unless it's WEP
689 * (because current deployments use pairwise WEP keys with
690 * non-zero indizes but 802.11i clearly specifies to use zero)
692 if (mac_addr && key_idx &&
693 params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
694 params.cipher != WLAN_CIPHER_SUITE_WEP104)
697 /* TODO: add definitions for the lengths to linux/ieee80211.h */
698 switch (params.cipher) {
699 case WLAN_CIPHER_SUITE_WEP40:
700 if (params.key_len != 5)
703 case WLAN_CIPHER_SUITE_TKIP:
704 if (params.key_len != 32)
707 case WLAN_CIPHER_SUITE_CCMP:
708 if (params.key_len != 16)
711 case WLAN_CIPHER_SUITE_WEP104:
712 if (params.key_len != 13)
719 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
723 if (!drv->ops->add_key) {
729 err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, ¶ms);
733 cfg80211_put_dev(drv);
738 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
740 struct cfg80211_registered_device *drv;
742 struct net_device *dev;
746 if (info->attrs[NL80211_ATTR_KEY_IDX])
747 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
752 if (info->attrs[NL80211_ATTR_MAC])
753 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
755 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
759 if (!drv->ops->del_key) {
765 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
769 cfg80211_put_dev(drv);
774 static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
776 int (*call)(struct wiphy *wiphy, struct net_device *dev,
777 struct beacon_parameters *info);
778 struct cfg80211_registered_device *drv;
780 struct net_device *dev;
781 struct beacon_parameters params;
784 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
788 switch (info->genlhdr->cmd) {
789 case NL80211_CMD_NEW_BEACON:
790 /* these are required for NEW_BEACON */
791 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
792 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
793 !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
798 call = drv->ops->add_beacon;
800 case NL80211_CMD_SET_BEACON:
801 call = drv->ops->set_beacon;
814 memset(¶ms, 0, sizeof(params));
816 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
818 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
822 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
824 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
828 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
829 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
831 nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
835 if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
836 params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
838 nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
848 err = call(&drv->wiphy, dev, ¶ms);
852 cfg80211_put_dev(drv);
857 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
859 struct cfg80211_registered_device *drv;
861 struct net_device *dev;
863 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
867 if (!drv->ops->del_beacon) {
873 err = drv->ops->del_beacon(&drv->wiphy, dev);
877 cfg80211_put_dev(drv);
882 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
883 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
884 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
885 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
888 static int parse_station_flags(struct nlattr *nla, u32 *staflags)
890 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
898 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
899 nla, sta_flags_policy))
902 *staflags = STATION_FLAG_CHANGED;
904 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
906 *staflags |= (1<<flag);
911 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
912 int flags, struct net_device *dev,
913 u8 *mac_addr, struct station_info *sinfo)
916 struct nlattr *sinfoattr;
918 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
922 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
923 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
925 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
927 goto nla_put_failure;
928 if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
929 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
930 sinfo->inactive_time);
931 if (sinfo->filled & STATION_INFO_RX_BYTES)
932 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES,
934 if (sinfo->filled & STATION_INFO_TX_BYTES)
935 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES,
937 if (sinfo->filled & STATION_INFO_LLID)
938 NLA_PUT_U16(msg, NL80211_STA_INFO_LLID,
940 if (sinfo->filled & STATION_INFO_PLID)
941 NLA_PUT_U16(msg, NL80211_STA_INFO_PLID,
943 if (sinfo->filled & STATION_INFO_PLINK_STATE)
944 NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
947 nla_nest_end(msg, sinfoattr);
949 return genlmsg_end(msg, hdr);
952 genlmsg_cancel(msg, hdr);
956 static int nl80211_dump_station(struct sk_buff *skb,
957 struct netlink_callback *cb)
959 struct station_info sinfo;
960 struct cfg80211_registered_device *dev;
961 struct net_device *netdev;
962 u8 mac_addr[ETH_ALEN];
963 int ifidx = cb->args[0];
964 int sta_idx = cb->args[1];
968 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
969 nl80211_fam.attrbuf, nl80211_fam.maxattr,
974 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
977 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
982 netdev = dev_get_by_index(&init_net, ifidx);
986 dev = cfg80211_get_dev_from_ifindex(ifidx);
992 if (!dev->ops->dump_station) {
1000 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
1007 if (nl80211_send_station(skb,
1008 NETLINK_CB(cb->skb).pid,
1009 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1019 cb->args[1] = sta_idx;
1024 cfg80211_put_dev(dev);
1031 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1033 struct cfg80211_registered_device *drv;
1035 struct net_device *dev;
1036 struct station_info sinfo;
1037 struct sk_buff *msg;
1038 u8 *mac_addr = NULL;
1040 memset(&sinfo, 0, sizeof(sinfo));
1042 if (!info->attrs[NL80211_ATTR_MAC])
1045 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1047 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1051 if (!drv->ops->get_station) {
1057 err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
1063 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1067 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
1068 dev, mac_addr, &sinfo) < 0)
1071 err = genlmsg_unicast(msg, info->snd_pid);
1078 cfg80211_put_dev(drv);
1084 * Get vlan interface making sure it is on the right wiphy.
1086 static int get_vlan(struct nlattr *vlanattr,
1087 struct cfg80211_registered_device *rdev,
1088 struct net_device **vlan)
1093 *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
1096 if (!(*vlan)->ieee80211_ptr)
1098 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
1104 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1106 struct cfg80211_registered_device *drv;
1108 struct net_device *dev;
1109 struct station_parameters params;
1110 u8 *mac_addr = NULL;
1112 memset(¶ms, 0, sizeof(params));
1114 params.listen_interval = -1;
1116 if (info->attrs[NL80211_ATTR_STA_AID])
1119 if (!info->attrs[NL80211_ATTR_MAC])
1122 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1124 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
1125 params.supported_rates =
1126 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1127 params.supported_rates_len =
1128 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1131 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1132 params.listen_interval =
1133 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1135 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1137 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1139 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1140 ¶ms.station_flags))
1143 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
1144 params.plink_action =
1145 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
1147 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1151 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
1155 if (!drv->ops->change_station) {
1161 err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, ¶ms);
1166 dev_put(params.vlan);
1167 cfg80211_put_dev(drv);
1172 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1174 struct cfg80211_registered_device *drv;
1176 struct net_device *dev;
1177 struct station_parameters params;
1178 u8 *mac_addr = NULL;
1180 memset(¶ms, 0, sizeof(params));
1182 if (!info->attrs[NL80211_ATTR_MAC])
1185 if (!info->attrs[NL80211_ATTR_STA_AID])
1188 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1191 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
1194 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1195 params.supported_rates =
1196 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1197 params.supported_rates_len =
1198 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1199 params.listen_interval =
1200 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1201 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1202 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1204 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1206 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1207 ¶ms.station_flags))
1210 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1214 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
1218 if (!drv->ops->add_station) {
1224 err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, ¶ms);
1229 dev_put(params.vlan);
1230 cfg80211_put_dev(drv);
1235 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1237 struct cfg80211_registered_device *drv;
1239 struct net_device *dev;
1240 u8 *mac_addr = NULL;
1242 if (info->attrs[NL80211_ATTR_MAC])
1243 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1245 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1249 if (!drv->ops->del_station) {
1255 err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
1259 cfg80211_put_dev(drv);
1264 static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
1265 int flags, struct net_device *dev,
1266 u8 *dst, u8 *next_hop,
1267 struct mpath_info *pinfo)
1270 struct nlattr *pinfoattr;
1272 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1276 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1277 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
1278 NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
1280 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
1282 goto nla_put_failure;
1283 if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
1284 NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
1286 if (pinfo->filled & MPATH_INFO_DSN)
1287 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DSN,
1289 if (pinfo->filled & MPATH_INFO_METRIC)
1290 NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
1292 if (pinfo->filled & MPATH_INFO_EXPTIME)
1293 NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME,
1295 if (pinfo->filled & MPATH_INFO_FLAGS)
1296 NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS,
1298 if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT)
1299 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
1300 pinfo->discovery_timeout);
1301 if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES)
1302 NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
1303 pinfo->discovery_retries);
1305 nla_nest_end(msg, pinfoattr);
1307 return genlmsg_end(msg, hdr);
1310 genlmsg_cancel(msg, hdr);
1314 static int nl80211_dump_mpath(struct sk_buff *skb,
1315 struct netlink_callback *cb)
1317 struct mpath_info pinfo;
1318 struct cfg80211_registered_device *dev;
1319 struct net_device *netdev;
1321 u8 next_hop[ETH_ALEN];
1322 int ifidx = cb->args[0];
1323 int path_idx = cb->args[1];
1327 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1328 nl80211_fam.attrbuf, nl80211_fam.maxattr,
1333 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
1336 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1341 netdev = dev_get_by_index(&init_net, ifidx);
1345 dev = cfg80211_get_dev_from_ifindex(ifidx);
1348 goto out_put_netdev;
1351 if (!dev->ops->dump_mpath) {
1359 err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,
1360 dst, next_hop, &pinfo);
1366 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
1367 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1368 netdev, dst, next_hop,
1377 cb->args[1] = path_idx;
1382 cfg80211_put_dev(dev);
1389 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1391 struct cfg80211_registered_device *drv;
1393 struct net_device *dev;
1394 struct mpath_info pinfo;
1395 struct sk_buff *msg;
1397 u8 next_hop[ETH_ALEN];
1399 memset(&pinfo, 0, sizeof(pinfo));
1401 if (!info->attrs[NL80211_ATTR_MAC])
1404 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1406 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1410 if (!drv->ops->get_mpath) {
1416 err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
1422 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1426 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
1427 dev, dst, next_hop, &pinfo) < 0)
1430 err = genlmsg_unicast(msg, info->snd_pid);
1437 cfg80211_put_dev(drv);
1442 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
1444 struct cfg80211_registered_device *drv;
1446 struct net_device *dev;
1448 u8 *next_hop = NULL;
1450 if (!info->attrs[NL80211_ATTR_MAC])
1453 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1456 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1457 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1459 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1463 if (!drv->ops->change_mpath) {
1469 err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
1473 cfg80211_put_dev(drv);
1477 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
1479 struct cfg80211_registered_device *drv;
1481 struct net_device *dev;
1483 u8 *next_hop = NULL;
1485 if (!info->attrs[NL80211_ATTR_MAC])
1488 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1491 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1492 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1494 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1498 if (!drv->ops->add_mpath) {
1504 err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
1508 cfg80211_put_dev(drv);
1513 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1515 struct cfg80211_registered_device *drv;
1517 struct net_device *dev;
1520 if (info->attrs[NL80211_ATTR_MAC])
1521 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1523 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1527 if (!drv->ops->del_mpath) {
1533 err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
1537 cfg80211_put_dev(drv);
1542 static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
1544 struct cfg80211_registered_device *drv;
1546 struct net_device *dev;
1547 struct bss_parameters params;
1549 memset(¶ms, 0, sizeof(params));
1550 /* default to not changing parameters */
1551 params.use_cts_prot = -1;
1552 params.use_short_preamble = -1;
1553 params.use_short_slot_time = -1;
1555 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
1556 params.use_cts_prot =
1557 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
1558 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
1559 params.use_short_preamble =
1560 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
1561 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
1562 params.use_short_slot_time =
1563 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
1565 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1569 if (!drv->ops->change_bss) {
1575 err = drv->ops->change_bss(&drv->wiphy, dev, ¶ms);
1579 cfg80211_put_dev(drv);
1584 static struct genl_ops nl80211_ops[] = {
1586 .cmd = NL80211_CMD_GET_WIPHY,
1587 .doit = nl80211_get_wiphy,
1588 .dumpit = nl80211_dump_wiphy,
1589 .policy = nl80211_policy,
1590 /* can be retrieved by unprivileged users */
1593 .cmd = NL80211_CMD_SET_WIPHY,
1594 .doit = nl80211_set_wiphy,
1595 .policy = nl80211_policy,
1596 .flags = GENL_ADMIN_PERM,
1599 .cmd = NL80211_CMD_GET_INTERFACE,
1600 .doit = nl80211_get_interface,
1601 .dumpit = nl80211_dump_interface,
1602 .policy = nl80211_policy,
1603 /* can be retrieved by unprivileged users */
1606 .cmd = NL80211_CMD_SET_INTERFACE,
1607 .doit = nl80211_set_interface,
1608 .policy = nl80211_policy,
1609 .flags = GENL_ADMIN_PERM,
1612 .cmd = NL80211_CMD_NEW_INTERFACE,
1613 .doit = nl80211_new_interface,
1614 .policy = nl80211_policy,
1615 .flags = GENL_ADMIN_PERM,
1618 .cmd = NL80211_CMD_DEL_INTERFACE,
1619 .doit = nl80211_del_interface,
1620 .policy = nl80211_policy,
1621 .flags = GENL_ADMIN_PERM,
1624 .cmd = NL80211_CMD_GET_KEY,
1625 .doit = nl80211_get_key,
1626 .policy = nl80211_policy,
1627 .flags = GENL_ADMIN_PERM,
1630 .cmd = NL80211_CMD_SET_KEY,
1631 .doit = nl80211_set_key,
1632 .policy = nl80211_policy,
1633 .flags = GENL_ADMIN_PERM,
1636 .cmd = NL80211_CMD_NEW_KEY,
1637 .doit = nl80211_new_key,
1638 .policy = nl80211_policy,
1639 .flags = GENL_ADMIN_PERM,
1642 .cmd = NL80211_CMD_DEL_KEY,
1643 .doit = nl80211_del_key,
1644 .policy = nl80211_policy,
1645 .flags = GENL_ADMIN_PERM,
1648 .cmd = NL80211_CMD_SET_BEACON,
1649 .policy = nl80211_policy,
1650 .flags = GENL_ADMIN_PERM,
1651 .doit = nl80211_addset_beacon,
1654 .cmd = NL80211_CMD_NEW_BEACON,
1655 .policy = nl80211_policy,
1656 .flags = GENL_ADMIN_PERM,
1657 .doit = nl80211_addset_beacon,
1660 .cmd = NL80211_CMD_DEL_BEACON,
1661 .policy = nl80211_policy,
1662 .flags = GENL_ADMIN_PERM,
1663 .doit = nl80211_del_beacon,
1666 .cmd = NL80211_CMD_GET_STATION,
1667 .doit = nl80211_get_station,
1668 .dumpit = nl80211_dump_station,
1669 .policy = nl80211_policy,
1670 .flags = GENL_ADMIN_PERM,
1673 .cmd = NL80211_CMD_SET_STATION,
1674 .doit = nl80211_set_station,
1675 .policy = nl80211_policy,
1676 .flags = GENL_ADMIN_PERM,
1679 .cmd = NL80211_CMD_NEW_STATION,
1680 .doit = nl80211_new_station,
1681 .policy = nl80211_policy,
1682 .flags = GENL_ADMIN_PERM,
1685 .cmd = NL80211_CMD_DEL_STATION,
1686 .doit = nl80211_del_station,
1687 .policy = nl80211_policy,
1688 .flags = GENL_ADMIN_PERM,
1691 .cmd = NL80211_CMD_GET_MPATH,
1692 .doit = nl80211_get_mpath,
1693 .dumpit = nl80211_dump_mpath,
1694 .policy = nl80211_policy,
1695 .flags = GENL_ADMIN_PERM,
1698 .cmd = NL80211_CMD_SET_MPATH,
1699 .doit = nl80211_set_mpath,
1700 .policy = nl80211_policy,
1701 .flags = GENL_ADMIN_PERM,
1704 .cmd = NL80211_CMD_NEW_MPATH,
1705 .doit = nl80211_new_mpath,
1706 .policy = nl80211_policy,
1707 .flags = GENL_ADMIN_PERM,
1710 .cmd = NL80211_CMD_DEL_MPATH,
1711 .doit = nl80211_del_mpath,
1712 .policy = nl80211_policy,
1713 .flags = GENL_ADMIN_PERM,
1716 .cmd = NL80211_CMD_SET_BSS,
1717 .doit = nl80211_set_bss,
1718 .policy = nl80211_policy,
1719 .flags = GENL_ADMIN_PERM,
1723 /* multicast groups */
1724 static struct genl_multicast_group nl80211_config_mcgrp = {
1728 /* notification functions */
1730 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
1732 struct sk_buff *msg;
1734 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1738 if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
1743 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
1746 /* initialisation/exit functions */
1748 int nl80211_init(void)
1752 err = genl_register_family(&nl80211_fam);
1756 for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
1757 err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
1762 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
1768 genl_unregister_family(&nl80211_fam);
1772 void nl80211_exit(void)
1774 genl_unregister_family(&nl80211_fam);