aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c923
1 files changed, 742 insertions, 181 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2456e4ee445e..24168560ebae 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This is the new netlink-based wireless configuration interface. 2 * This is the new netlink-based wireless configuration interface.
3 * 3 *
4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6 6
7#include <linux/if.h> 7#include <linux/if.h>
@@ -57,10 +57,14 @@ static int get_drv_dev_by_info_ifindex(struct nlattr **attrs,
57static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { 57static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
58 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, 58 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
59 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, 59 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
60 .len = BUS_ID_SIZE-1 }, 60 .len = 20-1 },
61 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, 61 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
62 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, 62 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, 63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
64 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
65 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
66 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
67 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
64 68
65 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, 69 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
66 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 70 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -73,6 +77,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
73 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, 77 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
74 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, 78 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
75 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, 79 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
80 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
76 81
77 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, 82 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
78 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, 83 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
@@ -116,8 +121,45 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
116 .len = IEEE80211_MAX_SSID_LEN }, 121 .len = IEEE80211_MAX_SSID_LEN },
117 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 }, 122 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
118 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, 123 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
124 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
125 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
126 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
127 [NL80211_ATTR_STA_FLAGS2] = {
128 .len = sizeof(struct nl80211_sta_flag_update),
129 },
130 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
119}; 131};
120 132
133/* IE validation */
134static bool is_valid_ie_attr(const struct nlattr *attr)
135{
136 const u8 *pos;
137 int len;
138
139 if (!attr)
140 return true;
141
142 pos = nla_data(attr);
143 len = nla_len(attr);
144
145 while (len) {
146 u8 elemlen;
147
148 if (len < 2)
149 return false;
150 len -= 2;
151
152 elemlen = pos[1];
153 if (elemlen > len)
154 return false;
155
156 len -= elemlen;
157 pos += 2 + elemlen;
158 }
159
160 return true;
161}
162
121/* message building helper */ 163/* message building helper */
122static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq, 164static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
123 int flags, u8 cmd) 165 int flags, u8 cmd)
@@ -126,6 +168,30 @@ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
126 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd); 168 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
127} 169}
128 170
171static int nl80211_msg_put_channel(struct sk_buff *msg,
172 struct ieee80211_channel *chan)
173{
174 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
175 chan->center_freq);
176
177 if (chan->flags & IEEE80211_CHAN_DISABLED)
178 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
179 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
180 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
181 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
182 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
183 if (chan->flags & IEEE80211_CHAN_RADAR)
184 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
185
186 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
187 DBM_TO_MBM(chan->max_power));
188
189 return 0;
190
191 nla_put_failure:
192 return -ENOBUFS;
193}
194
129/* netlink command implementations */ 195/* netlink command implementations */
130 196
131static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, 197static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
@@ -149,8 +215,24 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
149 215
150 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx); 216 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
151 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 217 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
218
219 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
220 dev->wiphy.retry_short);
221 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
222 dev->wiphy.retry_long);
223 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
224 dev->wiphy.frag_threshold);
225 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
226 dev->wiphy.rts_threshold);
227
152 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, 228 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
153 dev->wiphy.max_scan_ssids); 229 dev->wiphy.max_scan_ssids);
230 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
231 dev->wiphy.max_scan_ie_len);
232
233 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
234 sizeof(u32) * dev->wiphy.n_cipher_suites,
235 dev->wiphy.cipher_suites);
154 236
155 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); 237 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
156 if (!nl_modes) 238 if (!nl_modes)
@@ -202,20 +284,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
202 goto nla_put_failure; 284 goto nla_put_failure;
203 285
204 chan = &dev->wiphy.bands[band]->channels[i]; 286 chan = &dev->wiphy.bands[band]->channels[i];
205 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
206 chan->center_freq);
207
208 if (chan->flags & IEEE80211_CHAN_DISABLED)
209 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
210 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
211 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
212 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
213 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
214 if (chan->flags & IEEE80211_CHAN_RADAR)
215 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
216 287
217 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 288 if (nl80211_msg_put_channel(msg, chan))
218 DBM_TO_MBM(chan->max_power)); 289 goto nla_put_failure;
219 290
220 nla_nest_end(msg, nl_freq); 291 nla_nest_end(msg, nl_freq);
221 } 292 }
@@ -273,6 +344,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
273 CMD(assoc, ASSOCIATE); 344 CMD(assoc, ASSOCIATE);
274 CMD(deauth, DEAUTHENTICATE); 345 CMD(deauth, DEAUTHENTICATE);
275 CMD(disassoc, DISASSOCIATE); 346 CMD(disassoc, DISASSOCIATE);
347 CMD(join_ibss, JOIN_IBSS);
276 348
277#undef CMD 349#undef CMD
278 nla_nest_end(msg, nl_cmds); 350 nla_nest_end(msg, nl_cmds);
@@ -317,7 +389,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
317 if (IS_ERR(dev)) 389 if (IS_ERR(dev))
318 return PTR_ERR(dev); 390 return PTR_ERR(dev);
319 391
320 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 392 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
321 if (!msg) 393 if (!msg)
322 goto out_err; 394 goto out_err;
323 395
@@ -365,6 +437,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
365 struct cfg80211_registered_device *rdev; 437 struct cfg80211_registered_device *rdev;
366 int result = 0, rem_txq_params = 0; 438 int result = 0, rem_txq_params = 0;
367 struct nlattr *nl_txq_params; 439 struct nlattr *nl_txq_params;
440 u32 changed;
441 u8 retry_short = 0, retry_long = 0;
442 u32 frag_threshold = 0, rts_threshold = 0;
368 443
369 rtnl_lock(); 444 rtnl_lock();
370 445
@@ -418,7 +493,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
418 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 493 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
419 struct ieee80211_channel *chan; 494 struct ieee80211_channel *chan;
420 struct ieee80211_sta_ht_cap *ht_cap; 495 struct ieee80211_sta_ht_cap *ht_cap;
421 u32 freq, sec_freq; 496 u32 freq;
422 497
423 if (!rdev->ops->set_channel) { 498 if (!rdev->ops->set_channel) {
424 result = -EOPNOTSUPP; 499 result = -EOPNOTSUPP;
@@ -444,33 +519,28 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
444 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) 519 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
445 goto bad_res; 520 goto bad_res;
446 521
447 if (channel_type == NL80211_CHAN_HT40MINUS) 522 if (channel_type == NL80211_CHAN_HT40MINUS &&
448 sec_freq = freq - 20; 523 (chan->flags & IEEE80211_CHAN_NO_HT40MINUS))
449 else if (channel_type == NL80211_CHAN_HT40PLUS) 524 goto bad_res;
450 sec_freq = freq + 20; 525 else if (channel_type == NL80211_CHAN_HT40PLUS &&
451 else 526 (chan->flags & IEEE80211_CHAN_NO_HT40PLUS))
452 sec_freq = 0;
453
454 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
455
456 /* no HT capabilities */
457 if (channel_type != NL80211_CHAN_NO_HT &&
458 !ht_cap->ht_supported)
459 goto bad_res; 527 goto bad_res;
460 528
461 if (sec_freq) { 529 /*
462 struct ieee80211_channel *schan; 530 * At this point we know if that if HT40 was requested
531 * we are allowed to use it and the extension channel
532 * exists.
533 */
463 534
464 /* no 40 MHz capabilities */ 535 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
536
537 /* no HT capabilities or intolerant */
538 if (channel_type != NL80211_CHAN_NO_HT) {
539 if (!ht_cap->ht_supported)
540 goto bad_res;
465 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || 541 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
466 (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)) 542 (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
467 goto bad_res; 543 goto bad_res;
468
469 schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
470
471 /* Secondary channel not allowed */
472 if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
473 goto bad_res;
474 } 544 }
475 545
476 result = rdev->ops->set_channel(&rdev->wiphy, chan, 546 result = rdev->ops->set_channel(&rdev->wiphy, chan,
@@ -479,6 +549,84 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
479 goto bad_res; 549 goto bad_res;
480 } 550 }
481 551
552 changed = 0;
553
554 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
555 retry_short = nla_get_u8(
556 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
557 if (retry_short == 0) {
558 result = -EINVAL;
559 goto bad_res;
560 }
561 changed |= WIPHY_PARAM_RETRY_SHORT;
562 }
563
564 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
565 retry_long = nla_get_u8(
566 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
567 if (retry_long == 0) {
568 result = -EINVAL;
569 goto bad_res;
570 }
571 changed |= WIPHY_PARAM_RETRY_LONG;
572 }
573
574 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
575 frag_threshold = nla_get_u32(
576 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
577 if (frag_threshold < 256) {
578 result = -EINVAL;
579 goto bad_res;
580 }
581 if (frag_threshold != (u32) -1) {
582 /*
583 * Fragments (apart from the last one) are required to
584 * have even length. Make the fragmentation code
585 * simpler by stripping LSB should someone try to use
586 * odd threshold value.
587 */
588 frag_threshold &= ~0x1;
589 }
590 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
591 }
592
593 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
594 rts_threshold = nla_get_u32(
595 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
596 changed |= WIPHY_PARAM_RTS_THRESHOLD;
597 }
598
599 if (changed) {
600 u8 old_retry_short, old_retry_long;
601 u32 old_frag_threshold, old_rts_threshold;
602
603 if (!rdev->ops->set_wiphy_params) {
604 result = -EOPNOTSUPP;
605 goto bad_res;
606 }
607
608 old_retry_short = rdev->wiphy.retry_short;
609 old_retry_long = rdev->wiphy.retry_long;
610 old_frag_threshold = rdev->wiphy.frag_threshold;
611 old_rts_threshold = rdev->wiphy.rts_threshold;
612
613 if (changed & WIPHY_PARAM_RETRY_SHORT)
614 rdev->wiphy.retry_short = retry_short;
615 if (changed & WIPHY_PARAM_RETRY_LONG)
616 rdev->wiphy.retry_long = retry_long;
617 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
618 rdev->wiphy.frag_threshold = frag_threshold;
619 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
620 rdev->wiphy.rts_threshold = rts_threshold;
621
622 result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
623 if (result) {
624 rdev->wiphy.retry_short = old_retry_short;
625 rdev->wiphy.retry_long = old_retry_long;
626 rdev->wiphy.frag_threshold = old_frag_threshold;
627 rdev->wiphy.rts_threshold = old_rts_threshold;
628 }
629 }
482 630
483 bad_res: 631 bad_res:
484 mutex_unlock(&rdev->mtx); 632 mutex_unlock(&rdev->mtx);
@@ -489,6 +637,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
489 637
490 638
491static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, 639static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
640 struct cfg80211_registered_device *rdev,
492 struct net_device *dev) 641 struct net_device *dev)
493{ 642{
494 void *hdr; 643 void *hdr;
@@ -498,6 +647,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
498 return -1; 647 return -1;
499 648
500 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 649 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
650 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
501 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name); 651 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
502 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype); 652 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
503 return genlmsg_end(msg, hdr); 653 return genlmsg_end(msg, hdr);
@@ -532,7 +682,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
532 } 682 }
533 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, 683 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
534 cb->nlh->nlmsg_seq, NLM_F_MULTI, 684 cb->nlh->nlmsg_seq, NLM_F_MULTI,
535 wdev->netdev) < 0) { 685 dev, wdev->netdev) < 0) {
536 mutex_unlock(&dev->devlist_mtx); 686 mutex_unlock(&dev->devlist_mtx);
537 goto out; 687 goto out;
538 } 688 }
@@ -562,11 +712,12 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
562 if (err) 712 if (err)
563 return err; 713 return err;
564 714
565 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 715 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
566 if (!msg) 716 if (!msg)
567 goto out_err; 717 goto out_err;
568 718
569 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0) 719 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
720 dev, netdev) < 0)
570 goto out_free; 721 goto out_free;
571 722
572 dev_put(netdev); 723 dev_put(netdev);
@@ -616,7 +767,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
616 struct cfg80211_registered_device *drv; 767 struct cfg80211_registered_device *drv;
617 struct vif_params params; 768 struct vif_params params;
618 int err, ifindex; 769 int err, ifindex;
619 enum nl80211_iftype type; 770 enum nl80211_iftype otype, ntype;
620 struct net_device *dev; 771 struct net_device *dev;
621 u32 _flags, *flags = NULL; 772 u32 _flags, *flags = NULL;
622 bool change = false; 773 bool change = false;
@@ -630,30 +781,27 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
630 goto unlock_rtnl; 781 goto unlock_rtnl;
631 782
632 ifindex = dev->ifindex; 783 ifindex = dev->ifindex;
633 type = dev->ieee80211_ptr->iftype; 784 otype = ntype = dev->ieee80211_ptr->iftype;
634 dev_put(dev); 785 dev_put(dev);
635 786
636 if (info->attrs[NL80211_ATTR_IFTYPE]) { 787 if (info->attrs[NL80211_ATTR_IFTYPE]) {
637 enum nl80211_iftype ntype;
638
639 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); 788 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
640 if (type != ntype) 789 if (otype != ntype)
641 change = true; 790 change = true;
642 type = ntype; 791 if (ntype > NL80211_IFTYPE_MAX) {
643 if (type > NL80211_IFTYPE_MAX) {
644 err = -EINVAL; 792 err = -EINVAL;
645 goto unlock; 793 goto unlock;
646 } 794 }
647 } 795 }
648 796
649 if (!drv->ops->change_virtual_intf || 797 if (!drv->ops->change_virtual_intf ||
650 !(drv->wiphy.interface_modes & (1 << type))) { 798 !(drv->wiphy.interface_modes & (1 << ntype))) {
651 err = -EOPNOTSUPP; 799 err = -EOPNOTSUPP;
652 goto unlock; 800 goto unlock;
653 } 801 }
654 802
655 if (info->attrs[NL80211_ATTR_MESH_ID]) { 803 if (info->attrs[NL80211_ATTR_MESH_ID]) {
656 if (type != NL80211_IFTYPE_MESH_POINT) { 804 if (ntype != NL80211_IFTYPE_MESH_POINT) {
657 err = -EINVAL; 805 err = -EINVAL;
658 goto unlock; 806 goto unlock;
659 } 807 }
@@ -663,7 +811,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
663 } 811 }
664 812
665 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { 813 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
666 if (type != NL80211_IFTYPE_MONITOR) { 814 if (ntype != NL80211_IFTYPE_MONITOR) {
667 err = -EINVAL; 815 err = -EINVAL;
668 goto unlock; 816 goto unlock;
669 } 817 }
@@ -678,12 +826,17 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
678 826
679 if (change) 827 if (change)
680 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, 828 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
681 type, flags, &params); 829 ntype, flags, &params);
682 else 830 else
683 err = 0; 831 err = 0;
684 832
685 dev = __dev_get_by_index(&init_net, ifindex); 833 dev = __dev_get_by_index(&init_net, ifindex);
686 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type)); 834 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype));
835
836 if (dev && !err && (ntype != otype)) {
837 if (otype == NL80211_IFTYPE_ADHOC)
838 cfg80211_clear_ibss(dev, false);
839 }
687 840
688 unlock: 841 unlock:
689 cfg80211_put_dev(drv); 842 cfg80211_put_dev(drv);
@@ -832,7 +985,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
832 goto out; 985 goto out;
833 } 986 }
834 987
835 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 988 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
836 if (!msg) { 989 if (!msg) {
837 err = -ENOMEM; 990 err = -ENOMEM;
838 goto out; 991 goto out;
@@ -920,6 +1073,14 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
920 } 1073 }
921 1074
922 err = func(&drv->wiphy, dev, key_idx); 1075 err = func(&drv->wiphy, dev, key_idx);
1076#ifdef CONFIG_WIRELESS_EXT
1077 if (!err) {
1078 if (func == drv->ops->set_default_key)
1079 dev->ieee80211_ptr->wext.default_key = key_idx;
1080 else
1081 dev->ieee80211_ptr->wext.default_mgmt_key = key_idx;
1082 }
1083#endif
923 1084
924 out: 1085 out:
925 cfg80211_put_dev(drv); 1086 cfg80211_put_dev(drv);
@@ -934,7 +1095,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
934static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) 1095static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
935{ 1096{
936 struct cfg80211_registered_device *drv; 1097 struct cfg80211_registered_device *drv;
937 int err; 1098 int err, i;
938 struct net_device *dev; 1099 struct net_device *dev;
939 struct key_params params; 1100 struct key_params params;
940 u8 key_idx = 0; 1101 u8 key_idx = 0;
@@ -950,6 +1111,11 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
950 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]); 1111 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
951 } 1112 }
952 1113
1114 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
1115 params.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
1116 params.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
1117 }
1118
953 if (info->attrs[NL80211_ATTR_KEY_IDX]) 1119 if (info->attrs[NL80211_ATTR_KEY_IDX])
954 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 1120 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
955 1121
@@ -958,44 +1124,8 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
958 if (info->attrs[NL80211_ATTR_MAC]) 1124 if (info->attrs[NL80211_ATTR_MAC])
959 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1125 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
960 1126
961 if (key_idx > 5) 1127 if (cfg80211_validate_key_settings(&params, key_idx, mac_addr))
962 return -EINVAL;
963
964 /*
965 * Disallow pairwise keys with non-zero index unless it's WEP
966 * (because current deployments use pairwise WEP keys with
967 * non-zero indizes but 802.11i clearly specifies to use zero)
968 */
969 if (mac_addr && key_idx &&
970 params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
971 params.cipher != WLAN_CIPHER_SUITE_WEP104)
972 return -EINVAL;
973
974 /* TODO: add definitions for the lengths to linux/ieee80211.h */
975 switch (params.cipher) {
976 case WLAN_CIPHER_SUITE_WEP40:
977 if (params.key_len != 5)
978 return -EINVAL;
979 break;
980 case WLAN_CIPHER_SUITE_TKIP:
981 if (params.key_len != 32)
982 return -EINVAL;
983 break;
984 case WLAN_CIPHER_SUITE_CCMP:
985 if (params.key_len != 16)
986 return -EINVAL;
987 break;
988 case WLAN_CIPHER_SUITE_WEP104:
989 if (params.key_len != 13)
990 return -EINVAL;
991 break;
992 case WLAN_CIPHER_SUITE_AES_CMAC:
993 if (params.key_len != 16)
994 return -EINVAL;
995 break;
996 default:
997 return -EINVAL; 1128 return -EINVAL;
998 }
999 1129
1000 rtnl_lock(); 1130 rtnl_lock();
1001 1131
@@ -1003,6 +1133,14 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1003 if (err) 1133 if (err)
1004 goto unlock_rtnl; 1134 goto unlock_rtnl;
1005 1135
1136 for (i = 0; i < drv->wiphy.n_cipher_suites; i++)
1137 if (params.cipher == drv->wiphy.cipher_suites[i])
1138 break;
1139 if (i == drv->wiphy.n_cipher_suites) {
1140 err = -EINVAL;
1141 goto out;
1142 }
1143
1006 if (!drv->ops->add_key) { 1144 if (!drv->ops->add_key) {
1007 err = -EOPNOTSUPP; 1145 err = -EOPNOTSUPP;
1008 goto out; 1146 goto out;
@@ -1049,6 +1187,15 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1049 1187
1050 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr); 1188 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
1051 1189
1190#ifdef CONFIG_WIRELESS_EXT
1191 if (!err) {
1192 if (key_idx == dev->ieee80211_ptr->wext.default_key)
1193 dev->ieee80211_ptr->wext.default_key = -1;
1194 else if (key_idx == dev->ieee80211_ptr->wext.default_mgmt_key)
1195 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
1196 }
1197#endif
1198
1052 out: 1199 out:
1053 cfg80211_put_dev(drv); 1200 cfg80211_put_dev(drv);
1054 dev_put(dev); 1201 dev_put(dev);
@@ -1069,6 +1216,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1069 struct beacon_parameters params; 1216 struct beacon_parameters params;
1070 int haveinfo = 0; 1217 int haveinfo = 0;
1071 1218
1219 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1220 return -EINVAL;
1221
1072 rtnl_lock(); 1222 rtnl_lock();
1073 1223
1074 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1224 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -1186,15 +1336,36 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
1186 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG }, 1336 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
1187 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, 1337 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
1188 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, 1338 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
1339 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
1189}; 1340};
1190 1341
1191static int parse_station_flags(struct nlattr *nla, u32 *staflags) 1342static int parse_station_flags(struct genl_info *info,
1343 struct station_parameters *params)
1192{ 1344{
1193 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1]; 1345 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
1346 struct nlattr *nla;
1194 int flag; 1347 int flag;
1195 1348
1196 *staflags = 0; 1349 /*
1350 * Try parsing the new attribute first so userspace
1351 * can specify both for older kernels.
1352 */
1353 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
1354 if (nla) {
1355 struct nl80211_sta_flag_update *sta_flags;
1356
1357 sta_flags = nla_data(nla);
1358 params->sta_flags_mask = sta_flags->mask;
1359 params->sta_flags_set = sta_flags->set;
1360 if ((params->sta_flags_mask |
1361 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
1362 return -EINVAL;
1363 return 0;
1364 }
1365
1366 /* if present, parse the old attribute */
1197 1367
1368 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
1198 if (!nla) 1369 if (!nla)
1199 return 0; 1370 return 0;
1200 1371
@@ -1202,11 +1373,12 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags)
1202 nla, sta_flags_policy)) 1373 nla, sta_flags_policy))
1203 return -EINVAL; 1374 return -EINVAL;
1204 1375
1205 *staflags = STATION_FLAG_CHANGED; 1376 params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1;
1377 params->sta_flags_mask &= ~1;
1206 1378
1207 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) 1379 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
1208 if (flags[flag]) 1380 if (flags[flag])
1209 *staflags |= (1<<flag); 1381 params->sta_flags_set |= (1<<flag);
1210 1382
1211 return 0; 1383 return 0;
1212} 1384}
@@ -1424,7 +1596,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1424 if (err) 1596 if (err)
1425 goto out; 1597 goto out;
1426 1598
1427 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 1599 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1428 if (!msg) 1600 if (!msg)
1429 goto out; 1601 goto out;
1430 1602
@@ -1502,8 +1674,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1502 params.ht_capa = 1674 params.ht_capa =
1503 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 1675 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1504 1676
1505 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1677 if (parse_station_flags(info, &params))
1506 &params.station_flags))
1507 return -EINVAL; 1678 return -EINVAL;
1508 1679
1509 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) 1680 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
@@ -1516,6 +1687,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1516 if (err) 1687 if (err)
1517 goto out_rtnl; 1688 goto out_rtnl;
1518 1689
1690 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1691 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
1692 err = -EINVAL;
1693 goto out;
1694 }
1695
1519 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan); 1696 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1520 if (err) 1697 if (err)
1521 goto out; 1698 goto out;
@@ -1567,13 +1744,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1567 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); 1744 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1568 params.listen_interval = 1745 params.listen_interval =
1569 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 1746 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1747
1570 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 1748 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1749 if (!params.aid || params.aid > IEEE80211_MAX_AID)
1750 return -EINVAL;
1751
1571 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) 1752 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1572 params.ht_capa = 1753 params.ht_capa =
1573 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 1754 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1574 1755
1575 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1756 if (parse_station_flags(info, &params))
1576 &params.station_flags))
1577 return -EINVAL; 1757 return -EINVAL;
1578 1758
1579 rtnl_lock(); 1759 rtnl_lock();
@@ -1582,6 +1762,12 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1582 if (err) 1762 if (err)
1583 goto out_rtnl; 1763 goto out_rtnl;
1584 1764
1765 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1766 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
1767 err = -EINVAL;
1768 goto out;
1769 }
1770
1585 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan); 1771 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1586 if (err) 1772 if (err)
1587 goto out; 1773 goto out;
@@ -1625,6 +1811,12 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1625 if (err) 1811 if (err)
1626 goto out_rtnl; 1812 goto out_rtnl;
1627 1813
1814 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1815 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
1816 err = -EINVAL;
1817 goto out;
1818 }
1819
1628 if (!drv->ops->del_station) { 1820 if (!drv->ops->del_station) {
1629 err = -EOPNOTSUPP; 1821 err = -EOPNOTSUPP;
1630 goto out; 1822 goto out;
@@ -1808,7 +2000,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1808 if (err) 2000 if (err)
1809 goto out; 2001 goto out;
1810 2002
1811 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 2003 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1812 if (!msg) 2004 if (!msg)
1813 goto out; 2005 goto out;
1814 2006
@@ -2124,7 +2316,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2124 goto out; 2316 goto out;
2125 2317
2126 /* Draw up a netlink message to send back */ 2318 /* Draw up a netlink message to send back */
2127 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 2319 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2128 if (!msg) { 2320 if (!msg) {
2129 err = -ENOBUFS; 2321 err = -ENOBUFS;
2130 goto out; 2322 goto out;
@@ -2302,7 +2494,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
2302 if (!cfg80211_regdomain) 2494 if (!cfg80211_regdomain)
2303 goto out; 2495 goto out;
2304 2496
2305 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 2497 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2306 if (!msg) { 2498 if (!msg) {
2307 err = -ENOBUFS; 2499 err = -ENOBUFS;
2308 goto out; 2500 goto out;
@@ -2385,18 +2577,24 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2385 rem_reg_rules) { 2577 rem_reg_rules) {
2386 num_rules++; 2578 num_rules++;
2387 if (num_rules > NL80211_MAX_SUPP_REG_RULES) 2579 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
2388 goto bad_reg; 2580 return -EINVAL;
2389 } 2581 }
2390 2582
2391 if (!reg_is_valid_request(alpha2)) 2583 mutex_lock(&cfg80211_mutex);
2392 return -EINVAL; 2584
2585 if (!reg_is_valid_request(alpha2)) {
2586 r = -EINVAL;
2587 goto bad_reg;
2588 }
2393 2589
2394 size_of_regd = sizeof(struct ieee80211_regdomain) + 2590 size_of_regd = sizeof(struct ieee80211_regdomain) +
2395 (num_rules * sizeof(struct ieee80211_reg_rule)); 2591 (num_rules * sizeof(struct ieee80211_reg_rule));
2396 2592
2397 rd = kzalloc(size_of_regd, GFP_KERNEL); 2593 rd = kzalloc(size_of_regd, GFP_KERNEL);
2398 if (!rd) 2594 if (!rd) {
2399 return -ENOMEM; 2595 r = -ENOMEM;
2596 goto bad_reg;
2597 }
2400 2598
2401 rd->n_reg_rules = num_rules; 2599 rd->n_reg_rules = num_rules;
2402 rd->alpha2[0] = alpha2[0]; 2600 rd->alpha2[0] = alpha2[0];
@@ -2413,20 +2611,24 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2413 2611
2414 rule_idx++; 2612 rule_idx++;
2415 2613
2416 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) 2614 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
2615 r = -EINVAL;
2417 goto bad_reg; 2616 goto bad_reg;
2617 }
2418 } 2618 }
2419 2619
2420 BUG_ON(rule_idx != num_rules); 2620 BUG_ON(rule_idx != num_rules);
2421 2621
2422 mutex_lock(&cfg80211_mutex);
2423 r = set_regdom(rd); 2622 r = set_regdom(rd);
2623
2424 mutex_unlock(&cfg80211_mutex); 2624 mutex_unlock(&cfg80211_mutex);
2625
2425 return r; 2626 return r;
2426 2627
2427 bad_reg: 2628 bad_reg:
2629 mutex_unlock(&cfg80211_mutex);
2428 kfree(rd); 2630 kfree(rd);
2429 return -EINVAL; 2631 return r;
2430} 2632}
2431 2633
2432static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) 2634static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
@@ -2442,6 +2644,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2442 enum ieee80211_band band; 2644 enum ieee80211_band band;
2443 size_t ie_len; 2645 size_t ie_len;
2444 2646
2647 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2648 return -EINVAL;
2649
2445 rtnl_lock(); 2650 rtnl_lock();
2446 2651
2447 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2652 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2492,6 +2697,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2492 else 2697 else
2493 ie_len = 0; 2698 ie_len = 0;
2494 2699
2700 if (ie_len > wiphy->max_scan_ie_len) {
2701 err = -EINVAL;
2702 goto out;
2703 }
2704
2495 request = kzalloc(sizeof(*request) 2705 request = kzalloc(sizeof(*request)
2496 + sizeof(*ssid) * n_ssids 2706 + sizeof(*ssid) * n_ssids
2497 + sizeof(channel) * n_channels 2707 + sizeof(channel) * n_channels
@@ -2554,7 +2764,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2554 2764
2555 if (info->attrs[NL80211_ATTR_IE]) { 2765 if (info->attrs[NL80211_ATTR_IE]) {
2556 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2766 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2557 memcpy(request->ie, nla_data(info->attrs[NL80211_ATTR_IE]), 2767 memcpy((void *)request->ie,
2768 nla_data(info->attrs[NL80211_ATTR_IE]),
2558 request->ie_len); 2769 request->ie_len);
2559 } 2770 }
2560 2771
@@ -2710,6 +2921,15 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2710 struct wiphy *wiphy; 2921 struct wiphy *wiphy;
2711 int err; 2922 int err;
2712 2923
2924 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2925 return -EINVAL;
2926
2927 if (!info->attrs[NL80211_ATTR_MAC])
2928 return -EINVAL;
2929
2930 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
2931 return -EINVAL;
2932
2713 rtnl_lock(); 2933 rtnl_lock();
2714 2934
2715 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2935 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2731,11 +2951,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2731 goto out; 2951 goto out;
2732 } 2952 }
2733 2953
2734 if (!info->attrs[NL80211_ATTR_MAC]) {
2735 err = -EINVAL;
2736 goto out;
2737 }
2738
2739 wiphy = &drv->wiphy; 2954 wiphy = &drv->wiphy;
2740 memset(&req, 0, sizeof(req)); 2955 memset(&req, 0, sizeof(req));
2741 2956
@@ -2761,13 +2976,10 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2761 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2976 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2762 } 2977 }
2763 2978
2764 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { 2979 req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
2765 req.auth_type = 2980 if (!nl80211_valid_auth_type(req.auth_type)) {
2766 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); 2981 err = -EINVAL;
2767 if (!nl80211_valid_auth_type(req.auth_type)) { 2982 goto out;
2768 err = -EINVAL;
2769 goto out;
2770 }
2771 } 2983 }
2772 2984
2773 err = drv->ops->auth(&drv->wiphy, dev, &req); 2985 err = drv->ops->auth(&drv->wiphy, dev, &req);
@@ -2788,6 +3000,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2788 struct wiphy *wiphy; 3000 struct wiphy *wiphy;
2789 int err; 3001 int err;
2790 3002
3003 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3004 return -EINVAL;
3005
3006 if (!info->attrs[NL80211_ATTR_MAC] ||
3007 !info->attrs[NL80211_ATTR_SSID])
3008 return -EINVAL;
3009
2791 rtnl_lock(); 3010 rtnl_lock();
2792 3011
2793 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3012 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2809,12 +3028,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2809 goto out; 3028 goto out;
2810 } 3029 }
2811 3030
2812 if (!info->attrs[NL80211_ATTR_MAC] ||
2813 !info->attrs[NL80211_ATTR_SSID]) {
2814 err = -EINVAL;
2815 goto out;
2816 }
2817
2818 wiphy = &drv->wiphy; 3031 wiphy = &drv->wiphy;
2819 memset(&req, 0, sizeof(req)); 3032 memset(&req, 0, sizeof(req));
2820 3033
@@ -2838,6 +3051,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2838 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3051 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2839 } 3052 }
2840 3053
3054 if (info->attrs[NL80211_ATTR_USE_MFP]) {
3055 enum nl80211_mfp use_mfp =
3056 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
3057 if (use_mfp == NL80211_MFP_REQUIRED)
3058 req.use_mfp = true;
3059 else if (use_mfp != NL80211_MFP_NO) {
3060 err = -EINVAL;
3061 goto out;
3062 }
3063 }
3064
3065 req.control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
3066
2841 err = drv->ops->assoc(&drv->wiphy, dev, &req); 3067 err = drv->ops->assoc(&drv->wiphy, dev, &req);
2842 3068
2843out: 3069out:
@@ -2856,6 +3082,15 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2856 struct wiphy *wiphy; 3082 struct wiphy *wiphy;
2857 int err; 3083 int err;
2858 3084
3085 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3086 return -EINVAL;
3087
3088 if (!info->attrs[NL80211_ATTR_MAC])
3089 return -EINVAL;
3090
3091 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3092 return -EINVAL;
3093
2859 rtnl_lock(); 3094 rtnl_lock();
2860 3095
2861 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3096 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2877,24 +3112,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2877 goto out; 3112 goto out;
2878 } 3113 }
2879 3114
2880 if (!info->attrs[NL80211_ATTR_MAC]) {
2881 err = -EINVAL;
2882 goto out;
2883 }
2884
2885 wiphy = &drv->wiphy; 3115 wiphy = &drv->wiphy;
2886 memset(&req, 0, sizeof(req)); 3116 memset(&req, 0, sizeof(req));
2887 3117
2888 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3118 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2889 3119
2890 if (info->attrs[NL80211_ATTR_REASON_CODE]) { 3120 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2891 req.reason_code = 3121 if (req.reason_code == 0) {
2892 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3122 /* Reason Code 0 is reserved */
2893 if (req.reason_code == 0) { 3123 err = -EINVAL;
2894 /* Reason Code 0 is reserved */ 3124 goto out;
2895 err = -EINVAL;
2896 goto out;
2897 }
2898 } 3125 }
2899 3126
2900 if (info->attrs[NL80211_ATTR_IE]) { 3127 if (info->attrs[NL80211_ATTR_IE]) {
@@ -2920,6 +3147,15 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2920 struct wiphy *wiphy; 3147 struct wiphy *wiphy;
2921 int err; 3148 int err;
2922 3149
3150 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3151 return -EINVAL;
3152
3153 if (!info->attrs[NL80211_ATTR_MAC])
3154 return -EINVAL;
3155
3156 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3157 return -EINVAL;
3158
2923 rtnl_lock(); 3159 rtnl_lock();
2924 3160
2925 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3161 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2941,24 +3177,16 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2941 goto out; 3177 goto out;
2942 } 3178 }
2943 3179
2944 if (!info->attrs[NL80211_ATTR_MAC]) {
2945 err = -EINVAL;
2946 goto out;
2947 }
2948
2949 wiphy = &drv->wiphy; 3180 wiphy = &drv->wiphy;
2950 memset(&req, 0, sizeof(req)); 3181 memset(&req, 0, sizeof(req));
2951 3182
2952 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3183 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2953 3184
2954 if (info->attrs[NL80211_ATTR_REASON_CODE]) { 3185 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2955 req.reason_code = 3186 if (req.reason_code == 0) {
2956 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3187 /* Reason Code 0 is reserved */
2957 if (req.reason_code == 0) { 3188 err = -EINVAL;
2958 /* Reason Code 0 is reserved */ 3189 goto out;
2959 err = -EINVAL;
2960 goto out;
2961 }
2962 } 3190 }
2963 3191
2964 if (info->attrs[NL80211_ATTR_IE]) { 3192 if (info->attrs[NL80211_ATTR_IE]) {
@@ -2976,6 +3204,124 @@ unlock_rtnl:
2976 return err; 3204 return err;
2977} 3205}
2978 3206
3207static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3208{
3209 struct cfg80211_registered_device *drv;
3210 struct net_device *dev;
3211 struct cfg80211_ibss_params ibss;
3212 struct wiphy *wiphy;
3213 int err;
3214
3215 memset(&ibss, 0, sizeof(ibss));
3216
3217 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3218 return -EINVAL;
3219
3220 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
3221 !info->attrs[NL80211_ATTR_SSID] ||
3222 !nla_len(info->attrs[NL80211_ATTR_SSID]))
3223 return -EINVAL;
3224
3225 ibss.beacon_interval = 100;
3226
3227 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
3228 ibss.beacon_interval =
3229 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3230 if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000)
3231 return -EINVAL;
3232 }
3233
3234 rtnl_lock();
3235
3236 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3237 if (err)
3238 goto unlock_rtnl;
3239
3240 if (!drv->ops->join_ibss) {
3241 err = -EOPNOTSUPP;
3242 goto out;
3243 }
3244
3245 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3246 err = -EOPNOTSUPP;
3247 goto out;
3248 }
3249
3250 if (!netif_running(dev)) {
3251 err = -ENETDOWN;
3252 goto out;
3253 }
3254
3255 wiphy = &drv->wiphy;
3256
3257 if (info->attrs[NL80211_ATTR_MAC])
3258 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3259 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3260 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
3261
3262 if (info->attrs[NL80211_ATTR_IE]) {
3263 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3264 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3265 }
3266
3267 ibss.channel = ieee80211_get_channel(wiphy,
3268 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3269 if (!ibss.channel ||
3270 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
3271 ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
3272 err = -EINVAL;
3273 goto out;
3274 }
3275
3276 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
3277
3278 err = cfg80211_join_ibss(drv, dev, &ibss);
3279
3280out:
3281 cfg80211_put_dev(drv);
3282 dev_put(dev);
3283unlock_rtnl:
3284 rtnl_unlock();
3285 return err;
3286}
3287
3288static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
3289{
3290 struct cfg80211_registered_device *drv;
3291 struct net_device *dev;
3292 int err;
3293
3294 rtnl_lock();
3295
3296 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3297 if (err)
3298 goto unlock_rtnl;
3299
3300 if (!drv->ops->leave_ibss) {
3301 err = -EOPNOTSUPP;
3302 goto out;
3303 }
3304
3305 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3306 err = -EOPNOTSUPP;
3307 goto out;
3308 }
3309
3310 if (!netif_running(dev)) {
3311 err = -ENETDOWN;
3312 goto out;
3313 }
3314
3315 err = cfg80211_leave_ibss(drv, dev, false);
3316
3317out:
3318 cfg80211_put_dev(drv);
3319 dev_put(dev);
3320unlock_rtnl:
3321 rtnl_unlock();
3322 return err;
3323}
3324
2979static struct genl_ops nl80211_ops[] = { 3325static struct genl_ops nl80211_ops[] = {
2980 { 3326 {
2981 .cmd = NL80211_CMD_GET_WIPHY, 3327 .cmd = NL80211_CMD_GET_WIPHY,
@@ -3177,6 +3523,18 @@ static struct genl_ops nl80211_ops[] = {
3177 .policy = nl80211_policy, 3523 .policy = nl80211_policy,
3178 .flags = GENL_ADMIN_PERM, 3524 .flags = GENL_ADMIN_PERM,
3179 }, 3525 },
3526 {
3527 .cmd = NL80211_CMD_JOIN_IBSS,
3528 .doit = nl80211_join_ibss,
3529 .policy = nl80211_policy,
3530 .flags = GENL_ADMIN_PERM,
3531 },
3532 {
3533 .cmd = NL80211_CMD_LEAVE_IBSS,
3534 .doit = nl80211_leave_ibss,
3535 .policy = nl80211_policy,
3536 .flags = GENL_ADMIN_PERM,
3537 },
3180}; 3538};
3181static struct genl_multicast_group nl80211_mlme_mcgrp = { 3539static struct genl_multicast_group nl80211_mlme_mcgrp = {
3182 .name = "mlme", 3540 .name = "mlme",
@@ -3199,7 +3557,7 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
3199{ 3557{
3200 struct sk_buff *msg; 3558 struct sk_buff *msg;
3201 3559
3202 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 3560 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3203 if (!msg) 3561 if (!msg)
3204 return; 3562 return;
3205 3563
@@ -3211,11 +3569,43 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
3211 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); 3569 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
3212} 3570}
3213 3571
3572static int nl80211_add_scan_req(struct sk_buff *msg,
3573 struct cfg80211_registered_device *rdev)
3574{
3575 struct cfg80211_scan_request *req = rdev->scan_req;
3576 struct nlattr *nest;
3577 int i;
3578
3579 if (WARN_ON(!req))
3580 return 0;
3581
3582 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
3583 if (!nest)
3584 goto nla_put_failure;
3585 for (i = 0; i < req->n_ssids; i++)
3586 NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid);
3587 nla_nest_end(msg, nest);
3588
3589 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
3590 if (!nest)
3591 goto nla_put_failure;
3592 for (i = 0; i < req->n_channels; i++)
3593 NLA_PUT_U32(msg, i, req->channels[i]->center_freq);
3594 nla_nest_end(msg, nest);
3595
3596 if (req->ie)
3597 NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie);
3598
3599 return 0;
3600 nla_put_failure:
3601 return -ENOBUFS;
3602}
3603
3214static int nl80211_send_scan_donemsg(struct sk_buff *msg, 3604static int nl80211_send_scan_donemsg(struct sk_buff *msg,
3215 struct cfg80211_registered_device *rdev, 3605 struct cfg80211_registered_device *rdev,
3216 struct net_device *netdev, 3606 struct net_device *netdev,
3217 u32 pid, u32 seq, int flags, 3607 u32 pid, u32 seq, int flags,
3218 u32 cmd) 3608 u32 cmd)
3219{ 3609{
3220 void *hdr; 3610 void *hdr;
3221 3611
@@ -3226,7 +3616,8 @@ static int nl80211_send_scan_donemsg(struct sk_buff *msg,
3226 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); 3616 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3227 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); 3617 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3228 3618
3229 /* XXX: we should probably bounce back the request? */ 3619 /* ignore errors and send incomplete event anyway */
3620 nl80211_add_scan_req(msg, rdev);
3230 3621
3231 return genlmsg_end(msg, hdr); 3622 return genlmsg_end(msg, hdr);
3232 3623
@@ -3240,7 +3631,7 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
3240{ 3631{
3241 struct sk_buff *msg; 3632 struct sk_buff *msg;
3242 3633
3243 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 3634 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3244 if (!msg) 3635 if (!msg)
3245 return; 3636 return;
3246 3637
@@ -3258,7 +3649,7 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
3258{ 3649{
3259 struct sk_buff *msg; 3650 struct sk_buff *msg;
3260 3651
3261 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 3652 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3262 if (!msg) 3653 if (!msg)
3263 return; 3654 return;
3264 3655
@@ -3280,7 +3671,7 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
3280 struct sk_buff *msg; 3671 struct sk_buff *msg;
3281 void *hdr; 3672 void *hdr;
3282 3673
3283 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 3674 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3284 if (!msg) 3675 if (!msg)
3285 return; 3676 return;
3286 3677
@@ -3334,7 +3725,7 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
3334 struct sk_buff *msg; 3725 struct sk_buff *msg;
3335 void *hdr; 3726 void *hdr;
3336 3727
3337 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); 3728 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
3338 if (!msg) 3729 if (!msg)
3339 return; 3730 return;
3340 3731
@@ -3375,38 +3766,208 @@ void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
3375 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE); 3766 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
3376} 3767}
3377 3768
3378void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev, 3769void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
3379 struct net_device *netdev, const u8 *buf, 3770 struct net_device *netdev, const u8 *buf, size_t len)
3380 size_t len)
3381{ 3771{
3382 nl80211_send_mlme_event(rdev, netdev, buf, len, 3772 nl80211_send_mlme_event(rdev, netdev, buf, len,
3383 NL80211_CMD_DEAUTHENTICATE); 3773 NL80211_CMD_DEAUTHENTICATE);
3384} 3774}
3385 3775
3386void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev, 3776void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
3387 struct net_device *netdev, const u8 *buf, 3777 struct net_device *netdev, const u8 *buf,
3388 size_t len) 3778 size_t len)
3389{ 3779{
3390 nl80211_send_mlme_event(rdev, netdev, buf, len, 3780 nl80211_send_mlme_event(rdev, netdev, buf, len,
3391 NL80211_CMD_DISASSOCIATE); 3781 NL80211_CMD_DISASSOCIATE);
3392} 3782}
3393 3783
3784static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
3785 struct net_device *netdev, int cmd,
3786 const u8 *addr)
3787{
3788 struct sk_buff *msg;
3789 void *hdr;
3790
3791 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
3792 if (!msg)
3793 return;
3794
3795 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
3796 if (!hdr) {
3797 nlmsg_free(msg);
3798 return;
3799 }
3800
3801 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3802 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3803 NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT);
3804 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3805
3806 if (genlmsg_end(msg, hdr) < 0) {
3807 nlmsg_free(msg);
3808 return;
3809 }
3810
3811 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
3812 return;
3813
3814 nla_put_failure:
3815 genlmsg_cancel(msg, hdr);
3816 nlmsg_free(msg);
3817}
3818
3819void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
3820 struct net_device *netdev, const u8 *addr)
3821{
3822 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
3823 addr);
3824}
3825
3826void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
3827 struct net_device *netdev, const u8 *addr)
3828{
3829 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, addr);
3830}
3831
3832void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
3833 struct net_device *netdev, const u8 *bssid,
3834 gfp_t gfp)
3835{
3836 struct sk_buff *msg;
3837 void *hdr;
3838
3839 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
3840 if (!msg)
3841 return;
3842
3843 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
3844 if (!hdr) {
3845 nlmsg_free(msg);
3846 return;
3847 }
3848
3849 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3850 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3851 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
3852
3853 if (genlmsg_end(msg, hdr) < 0) {
3854 nlmsg_free(msg);
3855 return;
3856 }
3857
3858 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
3859 return;
3860
3861 nla_put_failure:
3862 genlmsg_cancel(msg, hdr);
3863 nlmsg_free(msg);
3864}
3865
3866void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
3867 struct net_device *netdev, const u8 *addr,
3868 enum nl80211_key_type key_type, int key_id,
3869 const u8 *tsc)
3870{
3871 struct sk_buff *msg;
3872 void *hdr;
3873
3874 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
3875 if (!msg)
3876 return;
3877
3878 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
3879 if (!hdr) {
3880 nlmsg_free(msg);
3881 return;
3882 }
3883
3884 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3885 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3886 if (addr)
3887 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3888 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
3889 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
3890 if (tsc)
3891 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
3892
3893 if (genlmsg_end(msg, hdr) < 0) {
3894 nlmsg_free(msg);
3895 return;
3896 }
3897
3898 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
3899 return;
3900
3901 nla_put_failure:
3902 genlmsg_cancel(msg, hdr);
3903 nlmsg_free(msg);
3904}
3905
3906void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
3907 struct ieee80211_channel *channel_before,
3908 struct ieee80211_channel *channel_after)
3909{
3910 struct sk_buff *msg;
3911 void *hdr;
3912 struct nlattr *nl_freq;
3913
3914 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
3915 if (!msg)
3916 return;
3917
3918 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
3919 if (!hdr) {
3920 nlmsg_free(msg);
3921 return;
3922 }
3923
3924 /*
3925 * Since we are applying the beacon hint to a wiphy we know its
3926 * wiphy_idx is valid
3927 */
3928 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
3929
3930 /* Before */
3931 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
3932 if (!nl_freq)
3933 goto nla_put_failure;
3934 if (nl80211_msg_put_channel(msg, channel_before))
3935 goto nla_put_failure;
3936 nla_nest_end(msg, nl_freq);
3937
3938 /* After */
3939 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
3940 if (!nl_freq)
3941 goto nla_put_failure;
3942 if (nl80211_msg_put_channel(msg, channel_after))
3943 goto nla_put_failure;
3944 nla_nest_end(msg, nl_freq);
3945
3946 if (genlmsg_end(msg, hdr) < 0) {
3947 nlmsg_free(msg);
3948 return;
3949 }
3950
3951 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC);
3952
3953 return;
3954
3955nla_put_failure:
3956 genlmsg_cancel(msg, hdr);
3957 nlmsg_free(msg);
3958}
3959
3394/* initialisation/exit functions */ 3960/* initialisation/exit functions */
3395 3961
3396int nl80211_init(void) 3962int nl80211_init(void)
3397{ 3963{
3398 int err, i; 3964 int err;
3399 3965
3400 err = genl_register_family(&nl80211_fam); 3966 err = genl_register_family_with_ops(&nl80211_fam,
3967 nl80211_ops, ARRAY_SIZE(nl80211_ops));
3401 if (err) 3968 if (err)
3402 return err; 3969 return err;
3403 3970
3404 for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
3405 err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
3406 if (err)
3407 goto err_out;
3408 }
3409
3410 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp); 3971 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
3411 if (err) 3972 if (err)
3412 goto err_out; 3973 goto err_out;