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.c996
1 files changed, 811 insertions, 185 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2456e4ee445e..241bddd0b4f1 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)
450 sec_freq = freq + 20;
451 else
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; 524 goto bad_res;
525 else if (channel_type == NL80211_CHAN_HT40PLUS &&
526 (chan->flags & IEEE80211_CHAN_NO_HT40PLUS))
527 goto bad_res;
528
529 /*
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 */
460 534
461 if (sec_freq) { 535 ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
462 struct ieee80211_channel *schan;
463 536
464 /* no 40 MHz capabilities */ 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,51 +1124,23 @@ 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; 1128 return -EINVAL;
963 1129
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;
998 }
999
1000 rtnl_lock(); 1130 rtnl_lock();
1001 1131
1002 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 1132 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
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])
@@ -1520,6 +1691,51 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1520 if (err) 1691 if (err)
1521 goto out; 1692 goto out;
1522 1693
1694 /* validate settings */
1695 err = 0;
1696
1697 switch (dev->ieee80211_ptr->iftype) {
1698 case NL80211_IFTYPE_AP:
1699 case NL80211_IFTYPE_AP_VLAN:
1700 /* disallow mesh-specific things */
1701 if (params.plink_action)
1702 err = -EINVAL;
1703 break;
1704 case NL80211_IFTYPE_STATION:
1705 /* disallow everything but AUTHORIZED flag */
1706 if (params.plink_action)
1707 err = -EINVAL;
1708 if (params.vlan)
1709 err = -EINVAL;
1710 if (params.supported_rates)
1711 err = -EINVAL;
1712 if (params.ht_capa)
1713 err = -EINVAL;
1714 if (params.listen_interval >= 0)
1715 err = -EINVAL;
1716 if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
1717 err = -EINVAL;
1718 break;
1719 case NL80211_IFTYPE_MESH_POINT:
1720 /* disallow things mesh doesn't support */
1721 if (params.vlan)
1722 err = -EINVAL;
1723 if (params.ht_capa)
1724 err = -EINVAL;
1725 if (params.listen_interval >= 0)
1726 err = -EINVAL;
1727 if (params.supported_rates)
1728 err = -EINVAL;
1729 if (params.sta_flags_mask)
1730 err = -EINVAL;
1731 break;
1732 default:
1733 err = -EINVAL;
1734 }
1735
1736 if (err)
1737 goto out;
1738
1523 if (!drv->ops->change_station) { 1739 if (!drv->ops->change_station) {
1524 err = -EOPNOTSUPP; 1740 err = -EOPNOTSUPP;
1525 goto out; 1741 goto out;
@@ -1551,9 +1767,6 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1551 if (!info->attrs[NL80211_ATTR_MAC]) 1767 if (!info->attrs[NL80211_ATTR_MAC])
1552 return -EINVAL; 1768 return -EINVAL;
1553 1769
1554 if (!info->attrs[NL80211_ATTR_STA_AID])
1555 return -EINVAL;
1556
1557 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) 1770 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1558 return -EINVAL; 1771 return -EINVAL;
1559 1772
@@ -1567,13 +1780,18 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1567 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); 1780 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1568 params.listen_interval = 1781 params.listen_interval =
1569 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 1782 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1570 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 1783
1784 if (info->attrs[NL80211_ATTR_STA_AID]) {
1785 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1786 if (!params.aid || params.aid > IEEE80211_MAX_AID)
1787 return -EINVAL;
1788 }
1789
1571 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) 1790 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1572 params.ht_capa = 1791 params.ht_capa =
1573 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 1792 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1574 1793
1575 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1794 if (parse_station_flags(info, &params))
1576 &params.station_flags))
1577 return -EINVAL; 1795 return -EINVAL;
1578 1796
1579 rtnl_lock(); 1797 rtnl_lock();
@@ -1586,6 +1804,38 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1586 if (err) 1804 if (err)
1587 goto out; 1805 goto out;
1588 1806
1807 /* validate settings */
1808 err = 0;
1809
1810 switch (dev->ieee80211_ptr->iftype) {
1811 case NL80211_IFTYPE_AP:
1812 case NL80211_IFTYPE_AP_VLAN:
1813 /* all ok but must have AID */
1814 if (!params.aid)
1815 err = -EINVAL;
1816 break;
1817 case NL80211_IFTYPE_MESH_POINT:
1818 /* disallow things mesh doesn't support */
1819 if (params.vlan)
1820 err = -EINVAL;
1821 if (params.aid)
1822 err = -EINVAL;
1823 if (params.ht_capa)
1824 err = -EINVAL;
1825 if (params.listen_interval >= 0)
1826 err = -EINVAL;
1827 if (params.supported_rates)
1828 err = -EINVAL;
1829 if (params.sta_flags_mask)
1830 err = -EINVAL;
1831 break;
1832 default:
1833 err = -EINVAL;
1834 }
1835
1836 if (err)
1837 goto out;
1838
1589 if (!drv->ops->add_station) { 1839 if (!drv->ops->add_station) {
1590 err = -EOPNOTSUPP; 1840 err = -EOPNOTSUPP;
1591 goto out; 1841 goto out;
@@ -1625,6 +1875,13 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1625 if (err) 1875 if (err)
1626 goto out_rtnl; 1876 goto out_rtnl;
1627 1877
1878 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1879 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
1880 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
1881 err = -EINVAL;
1882 goto out;
1883 }
1884
1628 if (!drv->ops->del_station) { 1885 if (!drv->ops->del_station) {
1629 err = -EOPNOTSUPP; 1886 err = -EOPNOTSUPP;
1630 goto out; 1887 goto out;
@@ -1808,7 +2065,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
1808 if (err) 2065 if (err)
1809 goto out; 2066 goto out;
1810 2067
1811 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 2068 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1812 if (!msg) 2069 if (!msg)
1813 goto out; 2070 goto out;
1814 2071
@@ -2124,7 +2381,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2124 goto out; 2381 goto out;
2125 2382
2126 /* Draw up a netlink message to send back */ 2383 /* Draw up a netlink message to send back */
2127 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 2384 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2128 if (!msg) { 2385 if (!msg) {
2129 err = -ENOBUFS; 2386 err = -ENOBUFS;
2130 goto out; 2387 goto out;
@@ -2302,7 +2559,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
2302 if (!cfg80211_regdomain) 2559 if (!cfg80211_regdomain)
2303 goto out; 2560 goto out;
2304 2561
2305 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 2562 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2306 if (!msg) { 2563 if (!msg) {
2307 err = -ENOBUFS; 2564 err = -ENOBUFS;
2308 goto out; 2565 goto out;
@@ -2385,18 +2642,24 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2385 rem_reg_rules) { 2642 rem_reg_rules) {
2386 num_rules++; 2643 num_rules++;
2387 if (num_rules > NL80211_MAX_SUPP_REG_RULES) 2644 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
2388 goto bad_reg; 2645 return -EINVAL;
2389 } 2646 }
2390 2647
2391 if (!reg_is_valid_request(alpha2)) 2648 mutex_lock(&cfg80211_mutex);
2392 return -EINVAL; 2649
2650 if (!reg_is_valid_request(alpha2)) {
2651 r = -EINVAL;
2652 goto bad_reg;
2653 }
2393 2654
2394 size_of_regd = sizeof(struct ieee80211_regdomain) + 2655 size_of_regd = sizeof(struct ieee80211_regdomain) +
2395 (num_rules * sizeof(struct ieee80211_reg_rule)); 2656 (num_rules * sizeof(struct ieee80211_reg_rule));
2396 2657
2397 rd = kzalloc(size_of_regd, GFP_KERNEL); 2658 rd = kzalloc(size_of_regd, GFP_KERNEL);
2398 if (!rd) 2659 if (!rd) {
2399 return -ENOMEM; 2660 r = -ENOMEM;
2661 goto bad_reg;
2662 }
2400 2663
2401 rd->n_reg_rules = num_rules; 2664 rd->n_reg_rules = num_rules;
2402 rd->alpha2[0] = alpha2[0]; 2665 rd->alpha2[0] = alpha2[0];
@@ -2413,20 +2676,24 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2413 2676
2414 rule_idx++; 2677 rule_idx++;
2415 2678
2416 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) 2679 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
2680 r = -EINVAL;
2417 goto bad_reg; 2681 goto bad_reg;
2682 }
2418 } 2683 }
2419 2684
2420 BUG_ON(rule_idx != num_rules); 2685 BUG_ON(rule_idx != num_rules);
2421 2686
2422 mutex_lock(&cfg80211_mutex);
2423 r = set_regdom(rd); 2687 r = set_regdom(rd);
2688
2424 mutex_unlock(&cfg80211_mutex); 2689 mutex_unlock(&cfg80211_mutex);
2690
2425 return r; 2691 return r;
2426 2692
2427 bad_reg: 2693 bad_reg:
2694 mutex_unlock(&cfg80211_mutex);
2428 kfree(rd); 2695 kfree(rd);
2429 return -EINVAL; 2696 return r;
2430} 2697}
2431 2698
2432static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) 2699static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
@@ -2442,6 +2709,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2442 enum ieee80211_band band; 2709 enum ieee80211_band band;
2443 size_t ie_len; 2710 size_t ie_len;
2444 2711
2712 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2713 return -EINVAL;
2714
2445 rtnl_lock(); 2715 rtnl_lock();
2446 2716
2447 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 2717 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2492,6 +2762,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2492 else 2762 else
2493 ie_len = 0; 2763 ie_len = 0;
2494 2764
2765 if (ie_len > wiphy->max_scan_ie_len) {
2766 err = -EINVAL;
2767 goto out;
2768 }
2769
2495 request = kzalloc(sizeof(*request) 2770 request = kzalloc(sizeof(*request)
2496 + sizeof(*ssid) * n_ssids 2771 + sizeof(*ssid) * n_ssids
2497 + sizeof(channel) * n_channels 2772 + sizeof(channel) * n_channels
@@ -2554,7 +2829,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2554 2829
2555 if (info->attrs[NL80211_ATTR_IE]) { 2830 if (info->attrs[NL80211_ATTR_IE]) {
2556 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2831 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2557 memcpy(request->ie, nla_data(info->attrs[NL80211_ATTR_IE]), 2832 memcpy((void *)request->ie,
2833 nla_data(info->attrs[NL80211_ATTR_IE]),
2558 request->ie_len); 2834 request->ie_len);
2559 } 2835 }
2560 2836
@@ -2710,6 +2986,15 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2710 struct wiphy *wiphy; 2986 struct wiphy *wiphy;
2711 int err; 2987 int err;
2712 2988
2989 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2990 return -EINVAL;
2991
2992 if (!info->attrs[NL80211_ATTR_MAC])
2993 return -EINVAL;
2994
2995 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
2996 return -EINVAL;
2997
2713 rtnl_lock(); 2998 rtnl_lock();
2714 2999
2715 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3000 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2731,11 +3016,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2731 goto out; 3016 goto out;
2732 } 3017 }
2733 3018
2734 if (!info->attrs[NL80211_ATTR_MAC]) {
2735 err = -EINVAL;
2736 goto out;
2737 }
2738
2739 wiphy = &drv->wiphy; 3019 wiphy = &drv->wiphy;
2740 memset(&req, 0, sizeof(req)); 3020 memset(&req, 0, sizeof(req));
2741 3021
@@ -2761,13 +3041,10 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
2761 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3041 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2762 } 3042 }
2763 3043
2764 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { 3044 req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
2765 req.auth_type = 3045 if (!nl80211_valid_auth_type(req.auth_type)) {
2766 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); 3046 err = -EINVAL;
2767 if (!nl80211_valid_auth_type(req.auth_type)) { 3047 goto out;
2768 err = -EINVAL;
2769 goto out;
2770 }
2771 } 3048 }
2772 3049
2773 err = drv->ops->auth(&drv->wiphy, dev, &req); 3050 err = drv->ops->auth(&drv->wiphy, dev, &req);
@@ -2788,6 +3065,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2788 struct wiphy *wiphy; 3065 struct wiphy *wiphy;
2789 int err; 3066 int err;
2790 3067
3068 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3069 return -EINVAL;
3070
3071 if (!info->attrs[NL80211_ATTR_MAC] ||
3072 !info->attrs[NL80211_ATTR_SSID])
3073 return -EINVAL;
3074
2791 rtnl_lock(); 3075 rtnl_lock();
2792 3076
2793 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3077 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2809,12 +3093,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2809 goto out; 3093 goto out;
2810 } 3094 }
2811 3095
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; 3096 wiphy = &drv->wiphy;
2819 memset(&req, 0, sizeof(req)); 3097 memset(&req, 0, sizeof(req));
2820 3098
@@ -2838,6 +3116,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
2838 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3116 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2839 } 3117 }
2840 3118
3119 if (info->attrs[NL80211_ATTR_USE_MFP]) {
3120 enum nl80211_mfp use_mfp =
3121 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
3122 if (use_mfp == NL80211_MFP_REQUIRED)
3123 req.use_mfp = true;
3124 else if (use_mfp != NL80211_MFP_NO) {
3125 err = -EINVAL;
3126 goto out;
3127 }
3128 }
3129
3130 req.control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
3131
2841 err = drv->ops->assoc(&drv->wiphy, dev, &req); 3132 err = drv->ops->assoc(&drv->wiphy, dev, &req);
2842 3133
2843out: 3134out:
@@ -2856,6 +3147,15 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2856 struct wiphy *wiphy; 3147 struct wiphy *wiphy;
2857 int err; 3148 int err;
2858 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
2859 rtnl_lock(); 3159 rtnl_lock();
2860 3160
2861 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3161 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2877,24 +3177,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
2877 goto out; 3177 goto out;
2878 } 3178 }
2879 3179
2880 if (!info->attrs[NL80211_ATTR_MAC]) {
2881 err = -EINVAL;
2882 goto out;
2883 }
2884
2885 wiphy = &drv->wiphy; 3180 wiphy = &drv->wiphy;
2886 memset(&req, 0, sizeof(req)); 3181 memset(&req, 0, sizeof(req));
2887 3182
2888 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3183 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2889 3184
2890 if (info->attrs[NL80211_ATTR_REASON_CODE]) { 3185 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2891 req.reason_code = 3186 if (req.reason_code == 0) {
2892 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3187 /* Reason Code 0 is reserved */
2893 if (req.reason_code == 0) { 3188 err = -EINVAL;
2894 /* Reason Code 0 is reserved */ 3189 goto out;
2895 err = -EINVAL;
2896 goto out;
2897 }
2898 } 3190 }
2899 3191
2900 if (info->attrs[NL80211_ATTR_IE]) { 3192 if (info->attrs[NL80211_ATTR_IE]) {
@@ -2920,6 +3212,15 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2920 struct wiphy *wiphy; 3212 struct wiphy *wiphy;
2921 int err; 3213 int err;
2922 3214
3215 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3216 return -EINVAL;
3217
3218 if (!info->attrs[NL80211_ATTR_MAC])
3219 return -EINVAL;
3220
3221 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3222 return -EINVAL;
3223
2923 rtnl_lock(); 3224 rtnl_lock();
2924 3225
2925 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 3226 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2941,24 +3242,16 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
2941 goto out; 3242 goto out;
2942 } 3243 }
2943 3244
2944 if (!info->attrs[NL80211_ATTR_MAC]) {
2945 err = -EINVAL;
2946 goto out;
2947 }
2948
2949 wiphy = &drv->wiphy; 3245 wiphy = &drv->wiphy;
2950 memset(&req, 0, sizeof(req)); 3246 memset(&req, 0, sizeof(req));
2951 3247
2952 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3248 req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2953 3249
2954 if (info->attrs[NL80211_ATTR_REASON_CODE]) { 3250 req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
2955 req.reason_code = 3251 if (req.reason_code == 0) {
2956 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 3252 /* Reason Code 0 is reserved */
2957 if (req.reason_code == 0) { 3253 err = -EINVAL;
2958 /* Reason Code 0 is reserved */ 3254 goto out;
2959 err = -EINVAL;
2960 goto out;
2961 }
2962 } 3255 }
2963 3256
2964 if (info->attrs[NL80211_ATTR_IE]) { 3257 if (info->attrs[NL80211_ATTR_IE]) {
@@ -2976,6 +3269,124 @@ unlock_rtnl:
2976 return err; 3269 return err;
2977} 3270}
2978 3271
3272static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3273{
3274 struct cfg80211_registered_device *drv;
3275 struct net_device *dev;
3276 struct cfg80211_ibss_params ibss;
3277 struct wiphy *wiphy;
3278 int err;
3279
3280 memset(&ibss, 0, sizeof(ibss));
3281
3282 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3283 return -EINVAL;
3284
3285 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
3286 !info->attrs[NL80211_ATTR_SSID] ||
3287 !nla_len(info->attrs[NL80211_ATTR_SSID]))
3288 return -EINVAL;
3289
3290 ibss.beacon_interval = 100;
3291
3292 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
3293 ibss.beacon_interval =
3294 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3295 if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000)
3296 return -EINVAL;
3297 }
3298
3299 rtnl_lock();
3300
3301 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3302 if (err)
3303 goto unlock_rtnl;
3304
3305 if (!drv->ops->join_ibss) {
3306 err = -EOPNOTSUPP;
3307 goto out;
3308 }
3309
3310 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3311 err = -EOPNOTSUPP;
3312 goto out;
3313 }
3314
3315 if (!netif_running(dev)) {
3316 err = -ENETDOWN;
3317 goto out;
3318 }
3319
3320 wiphy = &drv->wiphy;
3321
3322 if (info->attrs[NL80211_ATTR_MAC])
3323 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3324 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3325 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
3326
3327 if (info->attrs[NL80211_ATTR_IE]) {
3328 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3329 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3330 }
3331
3332 ibss.channel = ieee80211_get_channel(wiphy,
3333 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3334 if (!ibss.channel ||
3335 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
3336 ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
3337 err = -EINVAL;
3338 goto out;
3339 }
3340
3341 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
3342
3343 err = cfg80211_join_ibss(drv, dev, &ibss);
3344
3345out:
3346 cfg80211_put_dev(drv);
3347 dev_put(dev);
3348unlock_rtnl:
3349 rtnl_unlock();
3350 return err;
3351}
3352
3353static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
3354{
3355 struct cfg80211_registered_device *drv;
3356 struct net_device *dev;
3357 int err;
3358
3359 rtnl_lock();
3360
3361 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
3362 if (err)
3363 goto unlock_rtnl;
3364
3365 if (!drv->ops->leave_ibss) {
3366 err = -EOPNOTSUPP;
3367 goto out;
3368 }
3369
3370 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3371 err = -EOPNOTSUPP;
3372 goto out;
3373 }
3374
3375 if (!netif_running(dev)) {
3376 err = -ENETDOWN;
3377 goto out;
3378 }
3379
3380 err = cfg80211_leave_ibss(drv, dev, false);
3381
3382out:
3383 cfg80211_put_dev(drv);
3384 dev_put(dev);
3385unlock_rtnl:
3386 rtnl_unlock();
3387 return err;
3388}
3389
2979static struct genl_ops nl80211_ops[] = { 3390static struct genl_ops nl80211_ops[] = {
2980 { 3391 {
2981 .cmd = NL80211_CMD_GET_WIPHY, 3392 .cmd = NL80211_CMD_GET_WIPHY,
@@ -3177,6 +3588,18 @@ static struct genl_ops nl80211_ops[] = {
3177 .policy = nl80211_policy, 3588 .policy = nl80211_policy,
3178 .flags = GENL_ADMIN_PERM, 3589 .flags = GENL_ADMIN_PERM,
3179 }, 3590 },
3591 {
3592 .cmd = NL80211_CMD_JOIN_IBSS,
3593 .doit = nl80211_join_ibss,
3594 .policy = nl80211_policy,
3595 .flags = GENL_ADMIN_PERM,
3596 },
3597 {
3598 .cmd = NL80211_CMD_LEAVE_IBSS,
3599 .doit = nl80211_leave_ibss,
3600 .policy = nl80211_policy,
3601 .flags = GENL_ADMIN_PERM,
3602 },
3180}; 3603};
3181static struct genl_multicast_group nl80211_mlme_mcgrp = { 3604static struct genl_multicast_group nl80211_mlme_mcgrp = {
3182 .name = "mlme", 3605 .name = "mlme",
@@ -3199,7 +3622,7 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
3199{ 3622{
3200 struct sk_buff *msg; 3623 struct sk_buff *msg;
3201 3624
3202 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 3625 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3203 if (!msg) 3626 if (!msg)
3204 return; 3627 return;
3205 3628
@@ -3211,11 +3634,43 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
3211 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); 3634 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
3212} 3635}
3213 3636
3637static int nl80211_add_scan_req(struct sk_buff *msg,
3638 struct cfg80211_registered_device *rdev)
3639{
3640 struct cfg80211_scan_request *req = rdev->scan_req;
3641 struct nlattr *nest;
3642 int i;
3643
3644 if (WARN_ON(!req))
3645 return 0;
3646
3647 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
3648 if (!nest)
3649 goto nla_put_failure;
3650 for (i = 0; i < req->n_ssids; i++)
3651 NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid);
3652 nla_nest_end(msg, nest);
3653
3654 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
3655 if (!nest)
3656 goto nla_put_failure;
3657 for (i = 0; i < req->n_channels; i++)
3658 NLA_PUT_U32(msg, i, req->channels[i]->center_freq);
3659 nla_nest_end(msg, nest);
3660
3661 if (req->ie)
3662 NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie);
3663
3664 return 0;
3665 nla_put_failure:
3666 return -ENOBUFS;
3667}
3668
3214static int nl80211_send_scan_donemsg(struct sk_buff *msg, 3669static int nl80211_send_scan_donemsg(struct sk_buff *msg,
3215 struct cfg80211_registered_device *rdev, 3670 struct cfg80211_registered_device *rdev,
3216 struct net_device *netdev, 3671 struct net_device *netdev,
3217 u32 pid, u32 seq, int flags, 3672 u32 pid, u32 seq, int flags,
3218 u32 cmd) 3673 u32 cmd)
3219{ 3674{
3220 void *hdr; 3675 void *hdr;
3221 3676
@@ -3226,7 +3681,8 @@ static int nl80211_send_scan_donemsg(struct sk_buff *msg,
3226 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); 3681 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3227 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); 3682 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3228 3683
3229 /* XXX: we should probably bounce back the request? */ 3684 /* ignore errors and send incomplete event anyway */
3685 nl80211_add_scan_req(msg, rdev);
3230 3686
3231 return genlmsg_end(msg, hdr); 3687 return genlmsg_end(msg, hdr);
3232 3688
@@ -3240,7 +3696,7 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
3240{ 3696{
3241 struct sk_buff *msg; 3697 struct sk_buff *msg;
3242 3698
3243 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 3699 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3244 if (!msg) 3700 if (!msg)
3245 return; 3701 return;
3246 3702
@@ -3258,7 +3714,7 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
3258{ 3714{
3259 struct sk_buff *msg; 3715 struct sk_buff *msg;
3260 3716
3261 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 3717 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3262 if (!msg) 3718 if (!msg)
3263 return; 3719 return;
3264 3720
@@ -3280,7 +3736,7 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
3280 struct sk_buff *msg; 3736 struct sk_buff *msg;
3281 void *hdr; 3737 void *hdr;
3282 3738
3283 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 3739 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3284 if (!msg) 3740 if (!msg)
3285 return; 3741 return;
3286 3742
@@ -3334,7 +3790,7 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
3334 struct sk_buff *msg; 3790 struct sk_buff *msg;
3335 void *hdr; 3791 void *hdr;
3336 3792
3337 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); 3793 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
3338 if (!msg) 3794 if (!msg)
3339 return; 3795 return;
3340 3796
@@ -3375,38 +3831,208 @@ void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
3375 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE); 3831 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
3376} 3832}
3377 3833
3378void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev, 3834void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
3379 struct net_device *netdev, const u8 *buf, 3835 struct net_device *netdev, const u8 *buf, size_t len)
3380 size_t len)
3381{ 3836{
3382 nl80211_send_mlme_event(rdev, netdev, buf, len, 3837 nl80211_send_mlme_event(rdev, netdev, buf, len,
3383 NL80211_CMD_DEAUTHENTICATE); 3838 NL80211_CMD_DEAUTHENTICATE);
3384} 3839}
3385 3840
3386void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev, 3841void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
3387 struct net_device *netdev, const u8 *buf, 3842 struct net_device *netdev, const u8 *buf,
3388 size_t len) 3843 size_t len)
3389{ 3844{
3390 nl80211_send_mlme_event(rdev, netdev, buf, len, 3845 nl80211_send_mlme_event(rdev, netdev, buf, len,
3391 NL80211_CMD_DISASSOCIATE); 3846 NL80211_CMD_DISASSOCIATE);
3392} 3847}
3393 3848
3849static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
3850 struct net_device *netdev, int cmd,
3851 const u8 *addr)
3852{
3853 struct sk_buff *msg;
3854 void *hdr;
3855
3856 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
3857 if (!msg)
3858 return;
3859
3860 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
3861 if (!hdr) {
3862 nlmsg_free(msg);
3863 return;
3864 }
3865
3866 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3867 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3868 NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT);
3869 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3870
3871 if (genlmsg_end(msg, hdr) < 0) {
3872 nlmsg_free(msg);
3873 return;
3874 }
3875
3876 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
3877 return;
3878
3879 nla_put_failure:
3880 genlmsg_cancel(msg, hdr);
3881 nlmsg_free(msg);
3882}
3883
3884void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
3885 struct net_device *netdev, const u8 *addr)
3886{
3887 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
3888 addr);
3889}
3890
3891void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
3892 struct net_device *netdev, const u8 *addr)
3893{
3894 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, addr);
3895}
3896
3897void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
3898 struct net_device *netdev, const u8 *bssid,
3899 gfp_t gfp)
3900{
3901 struct sk_buff *msg;
3902 void *hdr;
3903
3904 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
3905 if (!msg)
3906 return;
3907
3908 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
3909 if (!hdr) {
3910 nlmsg_free(msg);
3911 return;
3912 }
3913
3914 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3915 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3916 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
3917
3918 if (genlmsg_end(msg, hdr) < 0) {
3919 nlmsg_free(msg);
3920 return;
3921 }
3922
3923 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
3924 return;
3925
3926 nla_put_failure:
3927 genlmsg_cancel(msg, hdr);
3928 nlmsg_free(msg);
3929}
3930
3931void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
3932 struct net_device *netdev, const u8 *addr,
3933 enum nl80211_key_type key_type, int key_id,
3934 const u8 *tsc)
3935{
3936 struct sk_buff *msg;
3937 void *hdr;
3938
3939 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
3940 if (!msg)
3941 return;
3942
3943 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
3944 if (!hdr) {
3945 nlmsg_free(msg);
3946 return;
3947 }
3948
3949 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3950 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3951 if (addr)
3952 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3953 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
3954 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
3955 if (tsc)
3956 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
3957
3958 if (genlmsg_end(msg, hdr) < 0) {
3959 nlmsg_free(msg);
3960 return;
3961 }
3962
3963 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
3964 return;
3965
3966 nla_put_failure:
3967 genlmsg_cancel(msg, hdr);
3968 nlmsg_free(msg);
3969}
3970
3971void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
3972 struct ieee80211_channel *channel_before,
3973 struct ieee80211_channel *channel_after)
3974{
3975 struct sk_buff *msg;
3976 void *hdr;
3977 struct nlattr *nl_freq;
3978
3979 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
3980 if (!msg)
3981 return;
3982
3983 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
3984 if (!hdr) {
3985 nlmsg_free(msg);
3986 return;
3987 }
3988
3989 /*
3990 * Since we are applying the beacon hint to a wiphy we know its
3991 * wiphy_idx is valid
3992 */
3993 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
3994
3995 /* Before */
3996 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
3997 if (!nl_freq)
3998 goto nla_put_failure;
3999 if (nl80211_msg_put_channel(msg, channel_before))
4000 goto nla_put_failure;
4001 nla_nest_end(msg, nl_freq);
4002
4003 /* After */
4004 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
4005 if (!nl_freq)
4006 goto nla_put_failure;
4007 if (nl80211_msg_put_channel(msg, channel_after))
4008 goto nla_put_failure;
4009 nla_nest_end(msg, nl_freq);
4010
4011 if (genlmsg_end(msg, hdr) < 0) {
4012 nlmsg_free(msg);
4013 return;
4014 }
4015
4016 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC);
4017
4018 return;
4019
4020nla_put_failure:
4021 genlmsg_cancel(msg, hdr);
4022 nlmsg_free(msg);
4023}
4024
3394/* initialisation/exit functions */ 4025/* initialisation/exit functions */
3395 4026
3396int nl80211_init(void) 4027int nl80211_init(void)
3397{ 4028{
3398 int err, i; 4029 int err;
3399 4030
3400 err = genl_register_family(&nl80211_fam); 4031 err = genl_register_family_with_ops(&nl80211_fam,
4032 nl80211_ops, ARRAY_SIZE(nl80211_ops));
3401 if (err) 4033 if (err)
3402 return err; 4034 return err;
3403 4035
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); 4036 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
3411 if (err) 4037 if (err)
3412 goto err_out; 4038 goto err_out;