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 struct nlattr *nl_modes;
117 enum ieee80211_band band;
118 struct ieee80211_channel *chan;
119 struct ieee80211_rate *rate;
121 u16 ifmodes = dev->wiphy.interface_modes;
123 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
127 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
128 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
130 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
132 goto nla_put_failure;
137 NLA_PUT_FLAG(msg, i);
142 nla_nest_end(msg, nl_modes);
144 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
146 goto nla_put_failure;
148 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
149 if (!dev->wiphy.bands[band])
152 nl_band = nla_nest_start(msg, band);
154 goto nla_put_failure;
156 /* add frequencies */
157 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
159 goto nla_put_failure;
161 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
162 nl_freq = nla_nest_start(msg, i);
164 goto nla_put_failure;
166 chan = &dev->wiphy.bands[band]->channels[i];
167 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
170 if (chan->flags & IEEE80211_CHAN_DISABLED)
171 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
172 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
173 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
174 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
175 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
176 if (chan->flags & IEEE80211_CHAN_RADAR)
177 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
179 nla_nest_end(msg, nl_freq);
182 nla_nest_end(msg, nl_freqs);
185 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
187 goto nla_put_failure;
189 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
190 nl_rate = nla_nest_start(msg, i);
192 goto nla_put_failure;
194 rate = &dev->wiphy.bands[band]->bitrates[i];
195 NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
197 if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
199 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
201 nla_nest_end(msg, nl_rate);
204 nla_nest_end(msg, nl_rates);
206 nla_nest_end(msg, nl_band);
208 nla_nest_end(msg, nl_bands);
210 return genlmsg_end(msg, hdr);
213 genlmsg_cancel(msg, hdr);
217 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
220 int start = cb->args[0];
221 struct cfg80211_registered_device *dev;
223 mutex_lock(&cfg80211_drv_mutex);
224 list_for_each_entry(dev, &cfg80211_drv_list, list) {
227 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
228 cb->nlh->nlmsg_seq, NLM_F_MULTI,
234 mutex_unlock(&cfg80211_drv_mutex);
241 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
244 struct cfg80211_registered_device *dev;
246 dev = cfg80211_get_dev_from_info(info);
250 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
254 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
257 cfg80211_put_dev(dev);
259 return genlmsg_unicast(msg, info->snd_pid);
264 cfg80211_put_dev(dev);
268 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
270 struct cfg80211_registered_device *rdev;
273 if (!info->attrs[NL80211_ATTR_WIPHY_NAME])
276 rdev = cfg80211_get_dev_from_info(info);
278 return PTR_ERR(rdev);
280 result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
282 cfg80211_put_dev(rdev);
287 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
288 struct net_device *dev)
292 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
296 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
297 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
298 /* TODO: interface type */
299 return genlmsg_end(msg, hdr);
302 genlmsg_cancel(msg, hdr);
306 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
310 int wp_start = cb->args[0];
311 int if_start = cb->args[1];
312 struct cfg80211_registered_device *dev;
313 struct wireless_dev *wdev;
315 mutex_lock(&cfg80211_drv_mutex);
316 list_for_each_entry(dev, &cfg80211_drv_list, list) {
317 if (wp_idx < wp_start) {
323 mutex_lock(&dev->devlist_mtx);
324 list_for_each_entry(wdev, &dev->netdev_list, list) {
325 if (if_idx < if_start) {
329 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
330 cb->nlh->nlmsg_seq, NLM_F_MULTI,
332 mutex_unlock(&dev->devlist_mtx);
337 mutex_unlock(&dev->devlist_mtx);
342 mutex_unlock(&cfg80211_drv_mutex);
344 cb->args[0] = wp_idx;
345 cb->args[1] = if_idx;
350 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
353 struct cfg80211_registered_device *dev;
354 struct net_device *netdev;
357 err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev);
361 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
365 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0)
369 cfg80211_put_dev(dev);
371 return genlmsg_unicast(msg, info->snd_pid);
377 cfg80211_put_dev(dev);
381 static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
382 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
383 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
384 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
385 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
386 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
389 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
391 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
399 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
400 nla, mntr_flags_policy))
403 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
405 *mntrflags |= (1<<flag);
410 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
412 struct cfg80211_registered_device *drv;
413 struct vif_params params;
415 enum nl80211_iftype type;
416 struct net_device *dev;
419 memset(¶ms, 0, sizeof(params));
421 if (info->attrs[NL80211_ATTR_IFTYPE]) {
422 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
423 if (type > NL80211_IFTYPE_MAX)
428 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
431 ifindex = dev->ifindex;
434 if (!drv->ops->change_virtual_intf ||
435 !(drv->wiphy.interface_modes & (1 << type))) {
440 if (type == NL80211_IFTYPE_MESH_POINT &&
441 info->attrs[NL80211_ATTR_MESH_ID]) {
442 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
443 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
447 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
448 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
450 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
451 type, err ? NULL : &flags, ¶ms);
455 cfg80211_put_dev(drv);
459 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
461 struct cfg80211_registered_device *drv;
462 struct vif_params params;
464 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
467 memset(¶ms, 0, sizeof(params));
469 if (!info->attrs[NL80211_ATTR_IFNAME])
472 if (info->attrs[NL80211_ATTR_IFTYPE]) {
473 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
474 if (type > NL80211_IFTYPE_MAX)
478 drv = cfg80211_get_dev_from_info(info);
482 if (!drv->ops->add_virtual_intf ||
483 !(drv->wiphy.interface_modes & (1 << type))) {
488 if (type == NL80211_IFTYPE_MESH_POINT &&
489 info->attrs[NL80211_ATTR_MESH_ID]) {
490 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
491 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
495 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
496 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
498 err = drv->ops->add_virtual_intf(&drv->wiphy,
499 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
500 type, err ? NULL : &flags, ¶ms);
505 cfg80211_put_dev(drv);
509 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
511 struct cfg80211_registered_device *drv;
513 struct net_device *dev;
515 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
518 ifindex = dev->ifindex;
521 if (!drv->ops->del_virtual_intf) {
527 err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
531 cfg80211_put_dev(drv);
535 struct get_key_cookie {
540 static void get_key_callback(void *c, struct key_params *params)
542 struct get_key_cookie *cookie = c;
545 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
546 params->key_len, params->key);
549 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
550 params->seq_len, params->seq);
553 NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
561 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
563 struct cfg80211_registered_device *drv;
565 struct net_device *dev;
568 struct get_key_cookie cookie = {
574 if (info->attrs[NL80211_ATTR_KEY_IDX])
575 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
580 if (info->attrs[NL80211_ATTR_MAC])
581 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
583 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
587 if (!drv->ops->get_key) {
592 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
598 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
599 NL80211_CMD_NEW_KEY);
608 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
609 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
611 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
614 err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
615 &cookie, get_key_callback);
622 goto nla_put_failure;
624 genlmsg_end(msg, hdr);
625 err = genlmsg_unicast(msg, info->snd_pid);
632 cfg80211_put_dev(drv);
637 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
639 struct cfg80211_registered_device *drv;
641 struct net_device *dev;
644 if (!info->attrs[NL80211_ATTR_KEY_IDX])
647 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
652 /* currently only support setting default key */
653 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
656 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
660 if (!drv->ops->set_default_key) {
666 err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
670 cfg80211_put_dev(drv);
675 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
677 struct cfg80211_registered_device *drv;
679 struct net_device *dev;
680 struct key_params params;
684 memset(¶ms, 0, sizeof(params));
686 if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
689 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
690 params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
691 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
694 if (info->attrs[NL80211_ATTR_KEY_IDX])
695 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
697 params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
699 if (info->attrs[NL80211_ATTR_MAC])
700 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
706 * Disallow pairwise keys with non-zero index unless it's WEP
707 * (because current deployments use pairwise WEP keys with
708 * non-zero indizes but 802.11i clearly specifies to use zero)
710 if (mac_addr && key_idx &&
711 params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
712 params.cipher != WLAN_CIPHER_SUITE_WEP104)
715 /* TODO: add definitions for the lengths to linux/ieee80211.h */
716 switch (params.cipher) {
717 case WLAN_CIPHER_SUITE_WEP40:
718 if (params.key_len != 5)
721 case WLAN_CIPHER_SUITE_TKIP:
722 if (params.key_len != 32)
725 case WLAN_CIPHER_SUITE_CCMP:
726 if (params.key_len != 16)
729 case WLAN_CIPHER_SUITE_WEP104:
730 if (params.key_len != 13)
737 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
741 if (!drv->ops->add_key) {
747 err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, ¶ms);
751 cfg80211_put_dev(drv);
756 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
758 struct cfg80211_registered_device *drv;
760 struct net_device *dev;
764 if (info->attrs[NL80211_ATTR_KEY_IDX])
765 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
770 if (info->attrs[NL80211_ATTR_MAC])
771 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
773 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
777 if (!drv->ops->del_key) {
783 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
787 cfg80211_put_dev(drv);
792 static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
794 int (*call)(struct wiphy *wiphy, struct net_device *dev,
795 struct beacon_parameters *info);
796 struct cfg80211_registered_device *drv;
798 struct net_device *dev;
799 struct beacon_parameters params;
802 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
806 switch (info->genlhdr->cmd) {
807 case NL80211_CMD_NEW_BEACON:
808 /* these are required for NEW_BEACON */
809 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
810 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
811 !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
816 call = drv->ops->add_beacon;
818 case NL80211_CMD_SET_BEACON:
819 call = drv->ops->set_beacon;
832 memset(¶ms, 0, sizeof(params));
834 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
836 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
840 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
842 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
846 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
847 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
849 nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
853 if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
854 params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
856 nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
866 err = call(&drv->wiphy, dev, ¶ms);
870 cfg80211_put_dev(drv);
875 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
877 struct cfg80211_registered_device *drv;
879 struct net_device *dev;
881 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
885 if (!drv->ops->del_beacon) {
891 err = drv->ops->del_beacon(&drv->wiphy, dev);
895 cfg80211_put_dev(drv);
900 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
901 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
902 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
903 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
906 static int parse_station_flags(struct nlattr *nla, u32 *staflags)
908 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
916 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
917 nla, sta_flags_policy))
920 *staflags = STATION_FLAG_CHANGED;
922 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
924 *staflags |= (1<<flag);
929 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
930 int flags, struct net_device *dev,
931 u8 *mac_addr, struct station_info *sinfo)
934 struct nlattr *sinfoattr;
936 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
940 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
941 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
943 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
945 goto nla_put_failure;
946 if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
947 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
948 sinfo->inactive_time);
949 if (sinfo->filled & STATION_INFO_RX_BYTES)
950 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES,
952 if (sinfo->filled & STATION_INFO_TX_BYTES)
953 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES,
955 if (sinfo->filled & STATION_INFO_LLID)
956 NLA_PUT_U16(msg, NL80211_STA_INFO_LLID,
958 if (sinfo->filled & STATION_INFO_PLID)
959 NLA_PUT_U16(msg, NL80211_STA_INFO_PLID,
961 if (sinfo->filled & STATION_INFO_PLINK_STATE)
962 NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
965 nla_nest_end(msg, sinfoattr);
967 return genlmsg_end(msg, hdr);
970 genlmsg_cancel(msg, hdr);
974 static int nl80211_dump_station(struct sk_buff *skb,
975 struct netlink_callback *cb)
977 struct station_info sinfo;
978 struct cfg80211_registered_device *dev;
979 struct net_device *netdev;
980 u8 mac_addr[ETH_ALEN];
981 int ifidx = cb->args[0];
982 int sta_idx = cb->args[1];
986 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
987 nl80211_fam.attrbuf, nl80211_fam.maxattr,
992 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
995 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1000 netdev = dev_get_by_index(&init_net, ifidx);
1004 dev = cfg80211_get_dev_from_ifindex(ifidx);
1007 goto out_put_netdev;
1010 if (!dev->ops->dump_station) {
1018 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
1025 if (nl80211_send_station(skb,
1026 NETLINK_CB(cb->skb).pid,
1027 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1037 cb->args[1] = sta_idx;
1042 cfg80211_put_dev(dev);
1049 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1051 struct cfg80211_registered_device *drv;
1053 struct net_device *dev;
1054 struct station_info sinfo;
1055 struct sk_buff *msg;
1056 u8 *mac_addr = NULL;
1058 memset(&sinfo, 0, sizeof(sinfo));
1060 if (!info->attrs[NL80211_ATTR_MAC])
1063 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1065 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1069 if (!drv->ops->get_station) {
1075 err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
1081 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1085 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
1086 dev, mac_addr, &sinfo) < 0)
1089 err = genlmsg_unicast(msg, info->snd_pid);
1096 cfg80211_put_dev(drv);
1102 * Get vlan interface making sure it is on the right wiphy.
1104 static int get_vlan(struct nlattr *vlanattr,
1105 struct cfg80211_registered_device *rdev,
1106 struct net_device **vlan)
1111 *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
1114 if (!(*vlan)->ieee80211_ptr)
1116 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
1122 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1124 struct cfg80211_registered_device *drv;
1126 struct net_device *dev;
1127 struct station_parameters params;
1128 u8 *mac_addr = NULL;
1130 memset(¶ms, 0, sizeof(params));
1132 params.listen_interval = -1;
1134 if (info->attrs[NL80211_ATTR_STA_AID])
1137 if (!info->attrs[NL80211_ATTR_MAC])
1140 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1142 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
1143 params.supported_rates =
1144 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1145 params.supported_rates_len =
1146 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1149 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1150 params.listen_interval =
1151 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1153 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1155 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1157 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1158 ¶ms.station_flags))
1161 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
1162 params.plink_action =
1163 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
1165 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1169 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
1173 if (!drv->ops->change_station) {
1179 err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, ¶ms);
1184 dev_put(params.vlan);
1185 cfg80211_put_dev(drv);
1190 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1192 struct cfg80211_registered_device *drv;
1194 struct net_device *dev;
1195 struct station_parameters params;
1196 u8 *mac_addr = NULL;
1198 memset(¶ms, 0, sizeof(params));
1200 if (!info->attrs[NL80211_ATTR_MAC])
1203 if (!info->attrs[NL80211_ATTR_STA_AID])
1206 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1209 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
1212 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1213 params.supported_rates =
1214 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1215 params.supported_rates_len =
1216 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1217 params.listen_interval =
1218 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1219 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1220 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1222 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1224 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1225 ¶ms.station_flags))
1228 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1232 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan);
1236 if (!drv->ops->add_station) {
1242 err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, ¶ms);
1247 dev_put(params.vlan);
1248 cfg80211_put_dev(drv);
1253 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1255 struct cfg80211_registered_device *drv;
1257 struct net_device *dev;
1258 u8 *mac_addr = NULL;
1260 if (info->attrs[NL80211_ATTR_MAC])
1261 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1263 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1267 if (!drv->ops->del_station) {
1273 err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
1277 cfg80211_put_dev(drv);
1282 static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
1283 int flags, struct net_device *dev,
1284 u8 *dst, u8 *next_hop,
1285 struct mpath_info *pinfo)
1288 struct nlattr *pinfoattr;
1290 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1294 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1295 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
1296 NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
1298 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
1300 goto nla_put_failure;
1301 if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
1302 NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
1304 if (pinfo->filled & MPATH_INFO_DSN)
1305 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DSN,
1307 if (pinfo->filled & MPATH_INFO_METRIC)
1308 NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
1310 if (pinfo->filled & MPATH_INFO_EXPTIME)
1311 NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME,
1313 if (pinfo->filled & MPATH_INFO_FLAGS)
1314 NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS,
1316 if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT)
1317 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
1318 pinfo->discovery_timeout);
1319 if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES)
1320 NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
1321 pinfo->discovery_retries);
1323 nla_nest_end(msg, pinfoattr);
1325 return genlmsg_end(msg, hdr);
1328 genlmsg_cancel(msg, hdr);
1332 static int nl80211_dump_mpath(struct sk_buff *skb,
1333 struct netlink_callback *cb)
1335 struct mpath_info pinfo;
1336 struct cfg80211_registered_device *dev;
1337 struct net_device *netdev;
1339 u8 next_hop[ETH_ALEN];
1340 int ifidx = cb->args[0];
1341 int path_idx = cb->args[1];
1345 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1346 nl80211_fam.attrbuf, nl80211_fam.maxattr,
1351 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
1354 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1359 netdev = dev_get_by_index(&init_net, ifidx);
1363 dev = cfg80211_get_dev_from_ifindex(ifidx);
1366 goto out_put_netdev;
1369 if (!dev->ops->dump_mpath) {
1377 err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,
1378 dst, next_hop, &pinfo);
1384 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
1385 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1386 netdev, dst, next_hop,
1395 cb->args[1] = path_idx;
1400 cfg80211_put_dev(dev);
1407 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1409 struct cfg80211_registered_device *drv;
1411 struct net_device *dev;
1412 struct mpath_info pinfo;
1413 struct sk_buff *msg;
1415 u8 next_hop[ETH_ALEN];
1417 memset(&pinfo, 0, sizeof(pinfo));
1419 if (!info->attrs[NL80211_ATTR_MAC])
1422 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1424 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1428 if (!drv->ops->get_mpath) {
1434 err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
1440 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1444 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
1445 dev, dst, next_hop, &pinfo) < 0)
1448 err = genlmsg_unicast(msg, info->snd_pid);
1455 cfg80211_put_dev(drv);
1460 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
1462 struct cfg80211_registered_device *drv;
1464 struct net_device *dev;
1466 u8 *next_hop = NULL;
1468 if (!info->attrs[NL80211_ATTR_MAC])
1471 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1474 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1475 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1477 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1481 if (!drv->ops->change_mpath) {
1487 err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
1491 cfg80211_put_dev(drv);
1495 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
1497 struct cfg80211_registered_device *drv;
1499 struct net_device *dev;
1501 u8 *next_hop = NULL;
1503 if (!info->attrs[NL80211_ATTR_MAC])
1506 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
1509 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1510 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
1512 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1516 if (!drv->ops->add_mpath) {
1522 err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
1526 cfg80211_put_dev(drv);
1531 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1533 struct cfg80211_registered_device *drv;
1535 struct net_device *dev;
1538 if (info->attrs[NL80211_ATTR_MAC])
1539 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
1541 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1545 if (!drv->ops->del_mpath) {
1551 err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
1555 cfg80211_put_dev(drv);
1560 static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
1562 struct cfg80211_registered_device *drv;
1564 struct net_device *dev;
1565 struct bss_parameters params;
1567 memset(¶ms, 0, sizeof(params));
1568 /* default to not changing parameters */
1569 params.use_cts_prot = -1;
1570 params.use_short_preamble = -1;
1571 params.use_short_slot_time = -1;
1573 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
1574 params.use_cts_prot =
1575 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
1576 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
1577 params.use_short_preamble =
1578 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
1579 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
1580 params.use_short_slot_time =
1581 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
1583 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1587 if (!drv->ops->change_bss) {
1593 err = drv->ops->change_bss(&drv->wiphy, dev, ¶ms);
1597 cfg80211_put_dev(drv);
1602 static struct genl_ops nl80211_ops[] = {
1604 .cmd = NL80211_CMD_GET_WIPHY,
1605 .doit = nl80211_get_wiphy,
1606 .dumpit = nl80211_dump_wiphy,
1607 .policy = nl80211_policy,
1608 /* can be retrieved by unprivileged users */
1611 .cmd = NL80211_CMD_SET_WIPHY,
1612 .doit = nl80211_set_wiphy,
1613 .policy = nl80211_policy,
1614 .flags = GENL_ADMIN_PERM,
1617 .cmd = NL80211_CMD_GET_INTERFACE,
1618 .doit = nl80211_get_interface,
1619 .dumpit = nl80211_dump_interface,
1620 .policy = nl80211_policy,
1621 /* can be retrieved by unprivileged users */
1624 .cmd = NL80211_CMD_SET_INTERFACE,
1625 .doit = nl80211_set_interface,
1626 .policy = nl80211_policy,
1627 .flags = GENL_ADMIN_PERM,
1630 .cmd = NL80211_CMD_NEW_INTERFACE,
1631 .doit = nl80211_new_interface,
1632 .policy = nl80211_policy,
1633 .flags = GENL_ADMIN_PERM,
1636 .cmd = NL80211_CMD_DEL_INTERFACE,
1637 .doit = nl80211_del_interface,
1638 .policy = nl80211_policy,
1639 .flags = GENL_ADMIN_PERM,
1642 .cmd = NL80211_CMD_GET_KEY,
1643 .doit = nl80211_get_key,
1644 .policy = nl80211_policy,
1645 .flags = GENL_ADMIN_PERM,
1648 .cmd = NL80211_CMD_SET_KEY,
1649 .doit = nl80211_set_key,
1650 .policy = nl80211_policy,
1651 .flags = GENL_ADMIN_PERM,
1654 .cmd = NL80211_CMD_NEW_KEY,
1655 .doit = nl80211_new_key,
1656 .policy = nl80211_policy,
1657 .flags = GENL_ADMIN_PERM,
1660 .cmd = NL80211_CMD_DEL_KEY,
1661 .doit = nl80211_del_key,
1662 .policy = nl80211_policy,
1663 .flags = GENL_ADMIN_PERM,
1666 .cmd = NL80211_CMD_SET_BEACON,
1667 .policy = nl80211_policy,
1668 .flags = GENL_ADMIN_PERM,
1669 .doit = nl80211_addset_beacon,
1672 .cmd = NL80211_CMD_NEW_BEACON,
1673 .policy = nl80211_policy,
1674 .flags = GENL_ADMIN_PERM,
1675 .doit = nl80211_addset_beacon,
1678 .cmd = NL80211_CMD_DEL_BEACON,
1679 .policy = nl80211_policy,
1680 .flags = GENL_ADMIN_PERM,
1681 .doit = nl80211_del_beacon,
1684 .cmd = NL80211_CMD_GET_STATION,
1685 .doit = nl80211_get_station,
1686 .dumpit = nl80211_dump_station,
1687 .policy = nl80211_policy,
1688 .flags = GENL_ADMIN_PERM,
1691 .cmd = NL80211_CMD_SET_STATION,
1692 .doit = nl80211_set_station,
1693 .policy = nl80211_policy,
1694 .flags = GENL_ADMIN_PERM,
1697 .cmd = NL80211_CMD_NEW_STATION,
1698 .doit = nl80211_new_station,
1699 .policy = nl80211_policy,
1700 .flags = GENL_ADMIN_PERM,
1703 .cmd = NL80211_CMD_DEL_STATION,
1704 .doit = nl80211_del_station,
1705 .policy = nl80211_policy,
1706 .flags = GENL_ADMIN_PERM,
1709 .cmd = NL80211_CMD_GET_MPATH,
1710 .doit = nl80211_get_mpath,
1711 .dumpit = nl80211_dump_mpath,
1712 .policy = nl80211_policy,
1713 .flags = GENL_ADMIN_PERM,
1716 .cmd = NL80211_CMD_SET_MPATH,
1717 .doit = nl80211_set_mpath,
1718 .policy = nl80211_policy,
1719 .flags = GENL_ADMIN_PERM,
1722 .cmd = NL80211_CMD_NEW_MPATH,
1723 .doit = nl80211_new_mpath,
1724 .policy = nl80211_policy,
1725 .flags = GENL_ADMIN_PERM,
1728 .cmd = NL80211_CMD_DEL_MPATH,
1729 .doit = nl80211_del_mpath,
1730 .policy = nl80211_policy,
1731 .flags = GENL_ADMIN_PERM,
1734 .cmd = NL80211_CMD_SET_BSS,
1735 .doit = nl80211_set_bss,
1736 .policy = nl80211_policy,
1737 .flags = GENL_ADMIN_PERM,
1741 /* multicast groups */
1742 static struct genl_multicast_group nl80211_config_mcgrp = {
1746 /* notification functions */
1748 void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
1750 struct sk_buff *msg;
1752 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1756 if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
1761 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
1764 /* initialisation/exit functions */
1766 int nl80211_init(void)
1770 err = genl_register_family(&nl80211_fam);
1774 for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
1775 err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
1780 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
1786 genl_unregister_family(&nl80211_fam);
1790 void nl80211_exit(void)
1792 genl_unregister_family(&nl80211_fam);