aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/neighbour.c5
-rw-r--r--net/core/pktgen.c506
-rw-r--r--net/core/skbuff.c2
-rw-r--r--net/decnet/af_decnet.c13
-rw-r--r--net/ieee80211/Makefile3
-rw-r--r--net/ieee80211/ieee80211_crypt.c59
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c75
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c150
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c26
-rw-r--r--net/ieee80211/ieee80211_geo.c141
-rw-r--r--net/ieee80211/ieee80211_module.c65
-rw-r--r--net/ieee80211/ieee80211_rx.c610
-rw-r--r--net/ieee80211/ieee80211_tx.c321
-rw-r--r--net/ieee80211/ieee80211_wx.c372
-rw-r--r--net/ipv4/devinet.c3
-rw-r--r--net/ipv4/fib_trie.c2
-rw-r--r--net/ipv4/icmp.c5
-rw-r--r--net/ipv4/ip_output.c5
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c132
-rw-r--r--net/ipv4/proc.c4
-rw-r--r--net/ipv6/icmp.c9
-rw-r--r--net/ipv6/proc.c4
-rw-r--r--net/netlink/af_netlink.c3
-rw-r--r--net/rose/rose_route.c2
-rw-r--r--net/sctp/proc.c4
-rw-r--r--net/xfrm/xfrm_policy.c43
-rw-r--r--net/xfrm/xfrm_state.c6
27 files changed, 1736 insertions, 834 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 1dcf7fa1f0fe..e68700f950a5 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1625,12 +1625,9 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb,
1625 1625
1626 memset(&ndst, 0, sizeof(ndst)); 1626 memset(&ndst, 0, sizeof(ndst));
1627 1627
1628 for (cpu = 0; cpu < NR_CPUS; cpu++) { 1628 for_each_cpu(cpu) {
1629 struct neigh_statistics *st; 1629 struct neigh_statistics *st;
1630 1630
1631 if (!cpu_possible(cpu))
1632 continue;
1633
1634 st = per_cpu_ptr(tbl->stats, cpu); 1631 st = per_cpu_ptr(tbl->stats, cpu);
1635 ndst.ndts_allocs += st->allocs; 1632 ndst.ndts_allocs += st->allocs;
1636 ndst.ndts_destroys += st->destroys; 1633 ndst.ndts_destroys += st->destroys;
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 5f043d346694..7fc3e9e28c34 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -75,7 +75,7 @@
75 * By design there should only be *one* "controlling" process. In practice 75 * By design there should only be *one* "controlling" process. In practice
76 * multiple write accesses gives unpredictable result. Understood by "write" 76 * multiple write accesses gives unpredictable result. Understood by "write"
77 * to /proc gives result code thats should be read be the "writer". 77 * to /proc gives result code thats should be read be the "writer".
78 * For pratical use this should be no problem. 78 * For practical use this should be no problem.
79 * 79 *
80 * Note when adding devices to a specific CPU there good idea to also assign 80 * Note when adding devices to a specific CPU there good idea to also assign
81 * /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU. 81 * /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU.
@@ -96,7 +96,7 @@
96 * New xmit() return, do_div and misc clean up by Stephen Hemminger 96 * New xmit() return, do_div and misc clean up by Stephen Hemminger
97 * <shemminger@osdl.org> 040923 97 * <shemminger@osdl.org> 040923
98 * 98 *
99 * Rany Dunlap fixed u64 printk compiler waring 99 * Randy Dunlap fixed u64 printk compiler waring
100 * 100 *
101 * Remove FCS from BW calculation. Lennert Buytenhek <buytenh@wantstofly.org> 101 * Remove FCS from BW calculation. Lennert Buytenhek <buytenh@wantstofly.org>
102 * New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213 102 * New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213
@@ -137,6 +137,7 @@
137#include <linux/ipv6.h> 137#include <linux/ipv6.h>
138#include <linux/udp.h> 138#include <linux/udp.h>
139#include <linux/proc_fs.h> 139#include <linux/proc_fs.h>
140#include <linux/seq_file.h>
140#include <linux/wait.h> 141#include <linux/wait.h>
141#include <net/checksum.h> 142#include <net/checksum.h>
142#include <net/ipv6.h> 143#include <net/ipv6.h>
@@ -151,7 +152,7 @@
151#include <asm/timex.h> 152#include <asm/timex.h>
152 153
153 154
154#define VERSION "pktgen v2.62: Packet Generator for packet performance testing.\n" 155#define VERSION "pktgen v2.63: Packet Generator for packet performance testing.\n"
155 156
156/* #define PG_DEBUG(a) a */ 157/* #define PG_DEBUG(a) a */
157#define PG_DEBUG(a) 158#define PG_DEBUG(a)
@@ -177,8 +178,8 @@
177#define T_REMDEV (1<<3) /* Remove all devs */ 178#define T_REMDEV (1<<3) /* Remove all devs */
178 179
179/* Locks */ 180/* Locks */
180#define thread_lock() spin_lock(&_thread_lock) 181#define thread_lock() down(&pktgen_sem)
181#define thread_unlock() spin_unlock(&_thread_lock) 182#define thread_unlock() up(&pktgen_sem)
182 183
183/* If lock -- can be removed after some work */ 184/* If lock -- can be removed after some work */
184#define if_lock(t) spin_lock(&(t->if_lock)); 185#define if_lock(t) spin_lock(&(t->if_lock));
@@ -186,7 +187,9 @@
186 187
187/* Used to help with determining the pkts on receive */ 188/* Used to help with determining the pkts on receive */
188#define PKTGEN_MAGIC 0xbe9be955 189#define PKTGEN_MAGIC 0xbe9be955
189#define PG_PROC_DIR "net/pktgen" 190#define PG_PROC_DIR "pktgen"
191#define PGCTRL "pgctrl"
192static struct proc_dir_entry *pg_proc_dir = NULL;
190 193
191#define MAX_CFLOWS 65536 194#define MAX_CFLOWS 65536
192 195
@@ -202,11 +205,8 @@ struct pktgen_dev {
202 * Try to keep frequent/infrequent used vars. separated. 205 * Try to keep frequent/infrequent used vars. separated.
203 */ 206 */
204 207
205 char ifname[32]; 208 char ifname[IFNAMSIZ];
206 struct proc_dir_entry *proc_ent;
207 char result[512]; 209 char result[512];
208 /* proc file names */
209 char fname[80];
210 210
211 struct pktgen_thread* pg_thread; /* the owner */ 211 struct pktgen_thread* pg_thread; /* the owner */
212 struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */ 212 struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */
@@ -244,7 +244,7 @@ struct pktgen_dev {
244 __u32 seq_num; 244 __u32 seq_num;
245 245
246 int clone_skb; /* Use multiple SKBs during packet gen. If this number 246 int clone_skb; /* Use multiple SKBs during packet gen. If this number
247 * is greater than 1, then that many coppies of the same 247 * is greater than 1, then that many copies of the same
248 * packet will be sent before a new packet is allocated. 248 * packet will be sent before a new packet is allocated.
249 * For instance, if you want to send 1024 identical packets 249 * For instance, if you want to send 1024 identical packets
250 * before creating a new packet, set clone_skb to 1024. 250 * before creating a new packet, set clone_skb to 1024.
@@ -330,8 +330,6 @@ struct pktgen_thread {
330 struct pktgen_dev *if_list; /* All device here */ 330 struct pktgen_dev *if_list; /* All device here */
331 struct pktgen_thread* next; 331 struct pktgen_thread* next;
332 char name[32]; 332 char name[32];
333 char fname[128]; /* name of proc file */
334 struct proc_dir_entry *proc_ent;
335 char result[512]; 333 char result[512];
336 u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ 334 u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
337 335
@@ -396,7 +394,7 @@ static inline s64 divremdi3(s64 x, s64 y, int type)
396 394
397/* End of hacks to deal with 64-bit math on x86 */ 395/* End of hacks to deal with 64-bit math on x86 */
398 396
399/** Convert to miliseconds */ 397/** Convert to milliseconds */
400static inline __u64 tv_to_ms(const struct timeval* tv) 398static inline __u64 tv_to_ms(const struct timeval* tv)
401{ 399{
402 __u64 ms = tv->tv_usec / 1000; 400 __u64 ms = tv->tv_usec / 1000;
@@ -425,7 +423,7 @@ static inline __u64 pg_div64(__u64 n, __u64 base)
425{ 423{
426 __u64 tmp = n; 424 __u64 tmp = n;
427/* 425/*
428 * How do we know if the architectrure we are running on 426 * How do we know if the architecture we are running on
429 * supports division with 64 bit base? 427 * supports division with 64 bit base?
430 * 428 *
431 */ 429 */
@@ -473,16 +471,6 @@ static inline __u64 tv_diff(const struct timeval* a, const struct timeval* b)
473 471
474static char version[] __initdata = VERSION; 472static char version[] __initdata = VERSION;
475 473
476static ssize_t proc_pgctrl_read(struct file* file, char __user * buf, size_t count, loff_t *ppos);
477static ssize_t proc_pgctrl_write(struct file* file, const char __user * buf, size_t count, loff_t *ppos);
478static int proc_if_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
479
480static int proc_thread_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
481static int proc_if_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
482static int proc_thread_write(struct file *file, const char __user *user_buffer, unsigned long count, void *data);
483static int create_proc_dir(void);
484static int remove_proc_dir(void);
485
486static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i); 474static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i);
487static int pktgen_add_device(struct pktgen_thread* t, const char* ifname); 475static int pktgen_add_device(struct pktgen_thread* t, const char* ifname);
488static struct pktgen_thread* pktgen_find_thread(const char* name); 476static struct pktgen_thread* pktgen_find_thread(const char* name);
@@ -503,83 +491,41 @@ static int pg_delay_d = 0;
503static int pg_clone_skb_d = 0; 491static int pg_clone_skb_d = 0;
504static int debug = 0; 492static int debug = 0;
505 493
506static DEFINE_SPINLOCK(_thread_lock); 494static DECLARE_MUTEX(pktgen_sem);
507static struct pktgen_thread *pktgen_threads = NULL; 495static struct pktgen_thread *pktgen_threads = NULL;
508 496
509static char module_fname[128];
510static struct proc_dir_entry *module_proc_ent = NULL;
511
512static struct notifier_block pktgen_notifier_block = { 497static struct notifier_block pktgen_notifier_block = {
513 .notifier_call = pktgen_device_event, 498 .notifier_call = pktgen_device_event,
514}; 499};
515 500
516static struct file_operations pktgen_fops = {
517 .read = proc_pgctrl_read,
518 .write = proc_pgctrl_write,
519 /* .ioctl = pktgen_ioctl, later maybe */
520};
521
522/* 501/*
523 * /proc handling functions 502 * /proc handling functions
524 * 503 *
525 */ 504 */
526 505
527static struct proc_dir_entry *pg_proc_dir = NULL; 506static int pgctrl_show(struct seq_file *seq, void *v)
528static int proc_pgctrl_read_eof=0;
529
530static ssize_t proc_pgctrl_read(struct file* file, char __user * buf,
531 size_t count, loff_t *ppos)
532{ 507{
533 char data[200]; 508 seq_puts(seq, VERSION);
534 int len = 0; 509 return 0;
535
536 if(proc_pgctrl_read_eof) {
537 proc_pgctrl_read_eof=0;
538 len = 0;
539 goto out;
540 }
541
542 sprintf(data, "%s", VERSION);
543
544 len = strlen(data);
545
546 if(len > count) {
547 len =-EFAULT;
548 goto out;
549 }
550
551 if (copy_to_user(buf, data, len)) {
552 len =-EFAULT;
553 goto out;
554 }
555
556 *ppos += len;
557 proc_pgctrl_read_eof=1; /* EOF next call */
558
559 out:
560 return len;
561} 510}
562 511
563static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf, 512static ssize_t pgctrl_write(struct file* file,const char __user * buf,
564 size_t count, loff_t *ppos) 513 size_t count, loff_t *ppos)
565{ 514{
566 char *data = NULL;
567 int err = 0; 515 int err = 0;
516 char data[128];
568 517
569 if (!capable(CAP_NET_ADMIN)){ 518 if (!capable(CAP_NET_ADMIN)){
570 err = -EPERM; 519 err = -EPERM;
571 goto out; 520 goto out;
572 } 521 }
573 522
574 data = (void*)vmalloc ((unsigned int)count); 523 if (count > sizeof(data))
524 count = sizeof(data);
575 525
576 if(!data) {
577 err = -ENOMEM;
578 goto out;
579 }
580 if (copy_from_user(data, buf, count)) { 526 if (copy_from_user(data, buf, count)) {
581 err =-EFAULT; 527 err = -EFAULT;
582 goto out_free; 528 goto out;
583 } 529 }
584 data[count-1] = 0; /* Make string */ 530 data[count-1] = 0; /* Make string */
585 531
@@ -594,31 +540,40 @@ static ssize_t proc_pgctrl_write(struct file* file,const char __user * buf,
594 540
595 err = count; 541 err = count;
596 542
597 out_free:
598 vfree (data);
599 out: 543 out:
600 return err; 544 return err;
601} 545}
602 546
603static int proc_if_read(char *buf , char **start, off_t offset, 547static int pgctrl_open(struct inode *inode, struct file *file)
604 int len, int *eof, void *data) 548{
549 return single_open(file, pgctrl_show, PDE(inode)->data);
550}
551
552static struct file_operations pktgen_fops = {
553 .owner = THIS_MODULE,
554 .open = pgctrl_open,
555 .read = seq_read,
556 .llseek = seq_lseek,
557 .write = pgctrl_write,
558 .release = single_release,
559};
560
561static int pktgen_if_show(struct seq_file *seq, void *v)
605{ 562{
606 char *p;
607 int i; 563 int i;
608 struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data); 564 struct pktgen_dev *pkt_dev = seq->private;
609 __u64 sa; 565 __u64 sa;
610 __u64 stopped; 566 __u64 stopped;
611 __u64 now = getCurUs(); 567 __u64 now = getCurUs();
612 568
613 p = buf; 569 seq_printf(seq, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n",
614 p += sprintf(p, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n", 570 (unsigned long long) pkt_dev->count,
615 (unsigned long long) pkt_dev->count, 571 pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
616 pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
617 572
618 p += sprintf(p, " frags: %d delay: %u clone_skb: %d ifname: %s\n", 573 seq_printf(seq, " frags: %d delay: %u clone_skb: %d ifname: %s\n",
619 pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname); 574 pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
620 575
621 p += sprintf(p, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow); 576 seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
622 577
623 578
624 if(pkt_dev->flags & F_IPV6) { 579 if(pkt_dev->flags & F_IPV6) {
@@ -626,19 +581,19 @@ static int proc_if_read(char *buf , char **start, off_t offset,
626 fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr); 581 fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr);
627 fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr); 582 fmt_ip6(b2, pkt_dev->min_in6_saddr.s6_addr);
628 fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr); 583 fmt_ip6(b3, pkt_dev->max_in6_saddr.s6_addr);
629 p += sprintf(p, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3); 584 seq_printf(seq, " saddr: %s min_saddr: %s max_saddr: %s\n", b1, b2, b3);
630 585
631 fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr); 586 fmt_ip6(b1, pkt_dev->in6_daddr.s6_addr);
632 fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr); 587 fmt_ip6(b2, pkt_dev->min_in6_daddr.s6_addr);
633 fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr); 588 fmt_ip6(b3, pkt_dev->max_in6_daddr.s6_addr);
634 p += sprintf(p, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3); 589 seq_printf(seq, " daddr: %s min_daddr: %s max_daddr: %s\n", b1, b2, b3);
635 590
636 } 591 }
637 else 592 else
638 p += sprintf(p, " dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n", 593 seq_printf(seq," dst_min: %s dst_max: %s\n src_min: %s src_max: %s\n",
639 pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max); 594 pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
640 595
641 p += sprintf(p, " src_mac: "); 596 seq_puts(seq, " src_mac: ");
642 597
643 if ((pkt_dev->src_mac[0] == 0) && 598 if ((pkt_dev->src_mac[0] == 0) &&
644 (pkt_dev->src_mac[1] == 0) && 599 (pkt_dev->src_mac[1] == 0) &&
@@ -648,89 +603,89 @@ static int proc_if_read(char *buf , char **start, off_t offset,
648 (pkt_dev->src_mac[5] == 0)) 603 (pkt_dev->src_mac[5] == 0))
649 604
650 for (i = 0; i < 6; i++) 605 for (i = 0; i < 6; i++)
651 p += sprintf(p, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":"); 606 seq_printf(seq, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? " " : ":");
652 607
653 else 608 else
654 for (i = 0; i < 6; i++) 609 for (i = 0; i < 6; i++)
655 p += sprintf(p, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":"); 610 seq_printf(seq, "%02X%s", pkt_dev->src_mac[i], i == 5 ? " " : ":");
656 611
657 p += sprintf(p, "dst_mac: "); 612 seq_printf(seq, "dst_mac: ");
658 for (i = 0; i < 6; i++) 613 for (i = 0; i < 6; i++)
659 p += sprintf(p, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":"); 614 seq_printf(seq, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
660 615
661 p += sprintf(p, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n", 616 seq_printf(seq, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n",
662 pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min, 617 pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
663 pkt_dev->udp_dst_max); 618 pkt_dev->udp_dst_max);
664 619
665 p += sprintf(p, " src_mac_count: %d dst_mac_count: %d \n Flags: ", 620 seq_printf(seq, " src_mac_count: %d dst_mac_count: %d \n Flags: ",
666 pkt_dev->src_mac_count, pkt_dev->dst_mac_count); 621 pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
667 622
668 623
669 if (pkt_dev->flags & F_IPV6) 624 if (pkt_dev->flags & F_IPV6)
670 p += sprintf(p, "IPV6 "); 625 seq_printf(seq, "IPV6 ");
671 626
672 if (pkt_dev->flags & F_IPSRC_RND) 627 if (pkt_dev->flags & F_IPSRC_RND)
673 p += sprintf(p, "IPSRC_RND "); 628 seq_printf(seq, "IPSRC_RND ");
674 629
675 if (pkt_dev->flags & F_IPDST_RND) 630 if (pkt_dev->flags & F_IPDST_RND)
676 p += sprintf(p, "IPDST_RND "); 631 seq_printf(seq, "IPDST_RND ");
677 632
678 if (pkt_dev->flags & F_TXSIZE_RND) 633 if (pkt_dev->flags & F_TXSIZE_RND)
679 p += sprintf(p, "TXSIZE_RND "); 634 seq_printf(seq, "TXSIZE_RND ");
680 635
681 if (pkt_dev->flags & F_UDPSRC_RND) 636 if (pkt_dev->flags & F_UDPSRC_RND)
682 p += sprintf(p, "UDPSRC_RND "); 637 seq_printf(seq, "UDPSRC_RND ");
683 638
684 if (pkt_dev->flags & F_UDPDST_RND) 639 if (pkt_dev->flags & F_UDPDST_RND)
685 p += sprintf(p, "UDPDST_RND "); 640 seq_printf(seq, "UDPDST_RND ");
686 641
687 if (pkt_dev->flags & F_MACSRC_RND) 642 if (pkt_dev->flags & F_MACSRC_RND)
688 p += sprintf(p, "MACSRC_RND "); 643 seq_printf(seq, "MACSRC_RND ");
689 644
690 if (pkt_dev->flags & F_MACDST_RND) 645 if (pkt_dev->flags & F_MACDST_RND)
691 p += sprintf(p, "MACDST_RND "); 646 seq_printf(seq, "MACDST_RND ");
692 647
693 648
694 p += sprintf(p, "\n"); 649 seq_puts(seq, "\n");
695 650
696 sa = pkt_dev->started_at; 651 sa = pkt_dev->started_at;
697 stopped = pkt_dev->stopped_at; 652 stopped = pkt_dev->stopped_at;
698 if (pkt_dev->running) 653 if (pkt_dev->running)
699 stopped = now; /* not really stopped, more like last-running-at */ 654 stopped = now; /* not really stopped, more like last-running-at */
700 655
701 p += sprintf(p, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n", 656 seq_printf(seq, "Current:\n pkts-sofar: %llu errors: %llu\n started: %lluus stopped: %lluus idle: %lluus\n",
702 (unsigned long long) pkt_dev->sofar, 657 (unsigned long long) pkt_dev->sofar,
703 (unsigned long long) pkt_dev->errors, 658 (unsigned long long) pkt_dev->errors,
704 (unsigned long long) sa, 659 (unsigned long long) sa,
705 (unsigned long long) stopped, 660 (unsigned long long) stopped,
706 (unsigned long long) pkt_dev->idle_acc); 661 (unsigned long long) pkt_dev->idle_acc);
707 662
708 p += sprintf(p, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n", 663 seq_printf(seq, " seq_num: %d cur_dst_mac_offset: %d cur_src_mac_offset: %d\n",
709 pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset, pkt_dev->cur_src_mac_offset); 664 pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset,
665 pkt_dev->cur_src_mac_offset);
710 666
711 if(pkt_dev->flags & F_IPV6) { 667 if(pkt_dev->flags & F_IPV6) {
712 char b1[128], b2[128]; 668 char b1[128], b2[128];
713 fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr); 669 fmt_ip6(b1, pkt_dev->cur_in6_daddr.s6_addr);
714 fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr); 670 fmt_ip6(b2, pkt_dev->cur_in6_saddr.s6_addr);
715 p += sprintf(p, " cur_saddr: %s cur_daddr: %s\n", b2, b1); 671 seq_printf(seq, " cur_saddr: %s cur_daddr: %s\n", b2, b1);
716 } 672 }
717 else 673 else
718 p += sprintf(p, " cur_saddr: 0x%x cur_daddr: 0x%x\n", 674 seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
719 pkt_dev->cur_saddr, pkt_dev->cur_daddr); 675 pkt_dev->cur_saddr, pkt_dev->cur_daddr);
720 676
721 677
722 p += sprintf(p, " cur_udp_dst: %d cur_udp_src: %d\n", 678 seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n",
723 pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src); 679 pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
724 680
725 p += sprintf(p, " flows: %u\n", pkt_dev->nflows); 681 seq_printf(seq, " flows: %u\n", pkt_dev->nflows);
726 682
727 if (pkt_dev->result[0]) 683 if (pkt_dev->result[0])
728 p += sprintf(p, "Result: %s\n", pkt_dev->result); 684 seq_printf(seq, "Result: %s\n", pkt_dev->result);
729 else 685 else
730 p += sprintf(p, "Result: Idle\n"); 686 seq_printf(seq, "Result: Idle\n");
731 *eof = 1;
732 687
733 return p - buf; 688 return 0;
734} 689}
735 690
736 691
@@ -802,13 +757,14 @@ done_str:
802 return i; 757 return i;
803} 758}
804 759
805static int proc_if_write(struct file *file, const char __user *user_buffer, 760static ssize_t pktgen_if_write(struct file *file, const char __user *user_buffer,
806 unsigned long count, void *data) 761 size_t count, loff_t *offset)
807{ 762{
763 struct seq_file *seq = (struct seq_file *) file->private_data;
764 struct pktgen_dev *pkt_dev = seq->private;
808 int i = 0, max, len; 765 int i = 0, max, len;
809 char name[16], valstr[32]; 766 char name[16], valstr[32];
810 unsigned long value = 0; 767 unsigned long value = 0;
811 struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
812 char* pg_result = NULL; 768 char* pg_result = NULL;
813 int tmp = 0; 769 int tmp = 0;
814 char buf[128]; 770 char buf[128];
@@ -849,7 +805,8 @@ static int proc_if_write(struct file *file, const char __user *user_buffer,
849 if (copy_from_user(tb, user_buffer, count)) 805 if (copy_from_user(tb, user_buffer, count))
850 return -EFAULT; 806 return -EFAULT;
851 tb[count] = 0; 807 tb[count] = 0;
852 printk("pktgen: %s,%lu buffer -:%s:-\n", name, count, tb); 808 printk("pktgen: %s,%lu buffer -:%s:-\n", name,
809 (unsigned long) count, tb);
853 } 810 }
854 811
855 if (!strcmp(name, "min_pkt_size")) { 812 if (!strcmp(name, "min_pkt_size")) {
@@ -1335,92 +1292,98 @@ static int proc_if_write(struct file *file, const char __user *user_buffer,
1335 return -EINVAL; 1292 return -EINVAL;
1336} 1293}
1337 1294
1338static int proc_thread_read(char *buf , char **start, off_t offset, 1295static int pktgen_if_open(struct inode *inode, struct file *file)
1339 int len, int *eof, void *data)
1340{ 1296{
1341 char *p; 1297 return single_open(file, pktgen_if_show, PDE(inode)->data);
1342 struct pktgen_thread *t = (struct pktgen_thread*)(data); 1298}
1343 struct pktgen_dev *pkt_dev = NULL;
1344 1299
1300static struct file_operations pktgen_if_fops = {
1301 .owner = THIS_MODULE,
1302 .open = pktgen_if_open,
1303 .read = seq_read,
1304 .llseek = seq_lseek,
1305 .write = pktgen_if_write,
1306 .release = single_release,
1307};
1345 1308
1346 if (!t) { 1309static int pktgen_thread_show(struct seq_file *seq, void *v)
1347 printk("pktgen: ERROR: could not find thread in proc_thread_read\n"); 1310{
1348 return -EINVAL; 1311 struct pktgen_thread *t = seq->private;
1349 } 1312 struct pktgen_dev *pkt_dev = NULL;
1313
1314 BUG_ON(!t);
1350 1315
1351 p = buf; 1316 seq_printf(seq, "Name: %s max_before_softirq: %d\n",
1352 p += sprintf(p, "Name: %s max_before_softirq: %d\n",
1353 t->name, t->max_before_softirq); 1317 t->name, t->max_before_softirq);
1354 1318
1355 p += sprintf(p, "Running: "); 1319 seq_printf(seq, "Running: ");
1356 1320
1357 if_lock(t); 1321 if_lock(t);
1358 for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) 1322 for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
1359 if(pkt_dev->running) 1323 if(pkt_dev->running)
1360 p += sprintf(p, "%s ", pkt_dev->ifname); 1324 seq_printf(seq, "%s ", pkt_dev->ifname);
1361 1325
1362 p += sprintf(p, "\nStopped: "); 1326 seq_printf(seq, "\nStopped: ");
1363 1327
1364 for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next) 1328 for(pkt_dev = t->if_list;pkt_dev; pkt_dev = pkt_dev->next)
1365 if(!pkt_dev->running) 1329 if(!pkt_dev->running)
1366 p += sprintf(p, "%s ", pkt_dev->ifname); 1330 seq_printf(seq, "%s ", pkt_dev->ifname);
1367 1331
1368 if (t->result[0]) 1332 if (t->result[0])
1369 p += sprintf(p, "\nResult: %s\n", t->result); 1333 seq_printf(seq, "\nResult: %s\n", t->result);
1370 else 1334 else
1371 p += sprintf(p, "\nResult: NA\n"); 1335 seq_printf(seq, "\nResult: NA\n");
1372
1373 *eof = 1;
1374 1336
1375 if_unlock(t); 1337 if_unlock(t);
1376 1338
1377 return p - buf; 1339 return 0;
1378} 1340}
1379 1341
1380static int proc_thread_write(struct file *file, const char __user *user_buffer, 1342static ssize_t pktgen_thread_write(struct file *file,
1381 unsigned long count, void *data) 1343 const char __user *user_buffer,
1344 size_t count, loff_t *offset)
1382{ 1345{
1346 struct seq_file *seq = (struct seq_file *) file->private_data;
1347 struct pktgen_thread *t = seq->private;
1383 int i = 0, max, len, ret; 1348 int i = 0, max, len, ret;
1384 char name[40]; 1349 char name[40];
1385 struct pktgen_thread *t;
1386 char *pg_result; 1350 char *pg_result;
1387 unsigned long value = 0; 1351 unsigned long value = 0;
1388 1352
1389 if (count < 1) { 1353 if (count < 1) {
1390 // sprintf(pg_result, "Wrong command format"); 1354 // sprintf(pg_result, "Wrong command format");
1391 return -EINVAL; 1355 return -EINVAL;
1392 } 1356 }
1393 1357
1394 max = count - i; 1358 max = count - i;
1395 len = count_trail_chars(&user_buffer[i], max); 1359 len = count_trail_chars(&user_buffer[i], max);
1396 if (len < 0) 1360 if (len < 0)
1397 return len; 1361 return len;
1398 1362
1399 i += len; 1363 i += len;
1400 1364
1401 /* Read variable name */ 1365 /* Read variable name */
1402 1366
1403 len = strn_len(&user_buffer[i], sizeof(name) - 1); 1367 len = strn_len(&user_buffer[i], sizeof(name) - 1);
1404 if (len < 0) 1368 if (len < 0)
1405 return len; 1369 return len;
1406 1370
1407 memset(name, 0, sizeof(name)); 1371 memset(name, 0, sizeof(name));
1408 if (copy_from_user(name, &user_buffer[i], len)) 1372 if (copy_from_user(name, &user_buffer[i], len))
1409 return -EFAULT; 1373 return -EFAULT;
1410 i += len; 1374 i += len;
1411 1375
1412 max = count -i; 1376 max = count -i;
1413 len = count_trail_chars(&user_buffer[i], max); 1377 len = count_trail_chars(&user_buffer[i], max);
1414 if (len < 0) 1378 if (len < 0)
1415 return len; 1379 return len;
1416 1380
1417 i += len; 1381 i += len;
1418 1382
1419 if (debug) 1383 if (debug)
1420 printk("pktgen: t=%s, count=%lu\n", name, count); 1384 printk("pktgen: t=%s, count=%lu\n", name,
1421 1385 (unsigned long) count);
1422 1386
1423 t = (struct pktgen_thread*)(data);
1424 if(!t) { 1387 if(!t) {
1425 printk("pktgen: ERROR: No thread\n"); 1388 printk("pktgen: ERROR: No thread\n");
1426 ret = -EINVAL; 1389 ret = -EINVAL;
@@ -1474,21 +1437,19 @@ static int proc_thread_write(struct file *file, const char __user *user_buffer,
1474 return ret; 1437 return ret;
1475} 1438}
1476 1439
1477static int create_proc_dir(void) 1440static int pktgen_thread_open(struct inode *inode, struct file *file)
1478{ 1441{
1479 pg_proc_dir = proc_mkdir(PG_PROC_DIR, NULL); 1442 return single_open(file, pktgen_thread_show, PDE(inode)->data);
1480
1481 if (!pg_proc_dir)
1482 return -ENODEV;
1483
1484 return 0;
1485} 1443}
1486 1444
1487static int remove_proc_dir(void) 1445static struct file_operations pktgen_thread_fops = {
1488{ 1446 .owner = THIS_MODULE,
1489 remove_proc_entry(PG_PROC_DIR, NULL); 1447 .open = pktgen_thread_open,
1490 return 0; 1448 .read = seq_read,
1491} 1449 .llseek = seq_lseek,
1450 .write = pktgen_thread_write,
1451 .release = single_release,
1452};
1492 1453
1493/* Think find or remove for NN */ 1454/* Think find or remove for NN */
1494static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove) 1455static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove)
@@ -1702,7 +1663,7 @@ static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
1702 start = now = getCurUs(); 1663 start = now = getCurUs();
1703 printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now)); 1664 printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
1704 while (now < spin_until_us) { 1665 while (now < spin_until_us) {
1705 /* TODO: optimise sleeping behavior */ 1666 /* TODO: optimize sleeping behavior */
1706 if (spin_until_us - now > jiffies_to_usecs(1)+1) 1667 if (spin_until_us - now > jiffies_to_usecs(1)+1)
1707 schedule_timeout_interruptible(1); 1668 schedule_timeout_interruptible(1);
1708 else if (spin_until_us - now > 100) { 1669 else if (spin_until_us - now > 100) {
@@ -2361,7 +2322,7 @@ static void pktgen_stop_all_threads_ifs(void)
2361 pktgen_stop(t); 2322 pktgen_stop(t);
2362 t = t->next; 2323 t = t->next;
2363 } 2324 }
2364 thread_unlock(); 2325 thread_unlock();
2365} 2326}
2366 2327
2367static int thread_is_running(struct pktgen_thread *t ) 2328static int thread_is_running(struct pktgen_thread *t )
@@ -2552,10 +2513,9 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
2552 2513
2553 struct pktgen_thread *tmp = pktgen_threads; 2514 struct pktgen_thread *tmp = pktgen_threads;
2554 2515
2555 if (strlen(t->fname)) 2516 remove_proc_entry(t->name, pg_proc_dir);
2556 remove_proc_entry(t->fname, NULL);
2557 2517
2558 thread_lock(); 2518 thread_lock();
2559 2519
2560 if (tmp == t) 2520 if (tmp == t)
2561 pktgen_threads = tmp->next; 2521 pktgen_threads = tmp->next;
@@ -2825,7 +2785,7 @@ static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, const char* i
2825 if_lock(t); 2785 if_lock(t);
2826 2786
2827 for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) { 2787 for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
2828 if (strcmp(pkt_dev->ifname, ifname) == 0) { 2788 if (strncmp(pkt_dev->ifname, ifname, IFNAMSIZ) == 0) {
2829 break; 2789 break;
2830 } 2790 }
2831 } 2791 }
@@ -2864,74 +2824,70 @@ static int add_dev_to_thread(struct pktgen_thread *t, struct pktgen_dev *pkt_dev
2864static int pktgen_add_device(struct pktgen_thread *t, const char* ifname) 2824static int pktgen_add_device(struct pktgen_thread *t, const char* ifname)
2865{ 2825{
2866 struct pktgen_dev *pkt_dev; 2826 struct pktgen_dev *pkt_dev;
2827 struct proc_dir_entry *pe;
2867 2828
2868 /* We don't allow a device to be on several threads */ 2829 /* We don't allow a device to be on several threads */
2869 2830
2870 if( (pkt_dev = __pktgen_NN_threads(ifname, FIND)) == NULL) { 2831 pkt_dev = __pktgen_NN_threads(ifname, FIND);
2871 2832 if (pkt_dev) {
2872 pkt_dev = kmalloc(sizeof(struct pktgen_dev), GFP_KERNEL); 2833 printk("pktgen: ERROR: interface already used.\n");
2873 if (!pkt_dev) 2834 return -EBUSY;
2874 return -ENOMEM; 2835 }
2875 2836
2876 memset(pkt_dev, 0, sizeof(struct pktgen_dev)); 2837 pkt_dev = kzalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
2838 if (!pkt_dev)
2839 return -ENOMEM;
2877 2840
2878 pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state)); 2841 pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
2879 if (pkt_dev->flows == NULL) { 2842 if (pkt_dev->flows == NULL) {
2880 kfree(pkt_dev); 2843 kfree(pkt_dev);
2881 return -ENOMEM; 2844 return -ENOMEM;
2882 } 2845 }
2883 memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state)); 2846 memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
2884
2885 pkt_dev->min_pkt_size = ETH_ZLEN;
2886 pkt_dev->max_pkt_size = ETH_ZLEN;
2887 pkt_dev->nfrags = 0;
2888 pkt_dev->clone_skb = pg_clone_skb_d;
2889 pkt_dev->delay_us = pg_delay_d / 1000;
2890 pkt_dev->delay_ns = pg_delay_d % 1000;
2891 pkt_dev->count = pg_count_d;
2892 pkt_dev->sofar = 0;
2893 pkt_dev->udp_src_min = 9; /* sink port */
2894 pkt_dev->udp_src_max = 9;
2895 pkt_dev->udp_dst_min = 9;
2896 pkt_dev->udp_dst_max = 9;
2897
2898 strncpy(pkt_dev->ifname, ifname, 31);
2899 sprintf(pkt_dev->fname, "%s/%s", PG_PROC_DIR, ifname);
2900
2901 if (! pktgen_setup_dev(pkt_dev)) {
2902 printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
2903 if (pkt_dev->flows)
2904 vfree(pkt_dev->flows);
2905 kfree(pkt_dev);
2906 return -ENODEV;
2907 }
2908 2847
2909 pkt_dev->proc_ent = create_proc_entry(pkt_dev->fname, 0600, NULL); 2848 pkt_dev->min_pkt_size = ETH_ZLEN;
2910 if (!pkt_dev->proc_ent) { 2849 pkt_dev->max_pkt_size = ETH_ZLEN;
2911 printk("pktgen: cannot create %s procfs entry.\n", pkt_dev->fname); 2850 pkt_dev->nfrags = 0;
2912 if (pkt_dev->flows) 2851 pkt_dev->clone_skb = pg_clone_skb_d;
2913 vfree(pkt_dev->flows); 2852 pkt_dev->delay_us = pg_delay_d / 1000;
2914 kfree(pkt_dev); 2853 pkt_dev->delay_ns = pg_delay_d % 1000;
2915 return -EINVAL; 2854 pkt_dev->count = pg_count_d;
2916 } 2855 pkt_dev->sofar = 0;
2917 pkt_dev->proc_ent->read_proc = proc_if_read; 2856 pkt_dev->udp_src_min = 9; /* sink port */
2918 pkt_dev->proc_ent->write_proc = proc_if_write; 2857 pkt_dev->udp_src_max = 9;
2919 pkt_dev->proc_ent->data = (void*)(pkt_dev); 2858 pkt_dev->udp_dst_min = 9;
2920 pkt_dev->proc_ent->owner = THIS_MODULE; 2859 pkt_dev->udp_dst_max = 9;
2860
2861 strncpy(pkt_dev->ifname, ifname, IFNAMSIZ);
2862
2863 if (! pktgen_setup_dev(pkt_dev)) {
2864 printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
2865 if (pkt_dev->flows)
2866 vfree(pkt_dev->flows);
2867 kfree(pkt_dev);
2868 return -ENODEV;
2869 }
2870
2871 pe = create_proc_entry(ifname, 0600, pg_proc_dir);
2872 if (!pe) {
2873 printk("pktgen: cannot create %s/%s procfs entry.\n",
2874 PG_PROC_DIR, ifname);
2875 if (pkt_dev->flows)
2876 vfree(pkt_dev->flows);
2877 kfree(pkt_dev);
2878 return -EINVAL;
2879 }
2880 pe->proc_fops = &pktgen_if_fops;
2881 pe->data = pkt_dev;
2921 2882
2922 return add_dev_to_thread(t, pkt_dev); 2883 return add_dev_to_thread(t, pkt_dev);
2923 }
2924 else {
2925 printk("pktgen: ERROR: interface already used.\n");
2926 return -EBUSY;
2927 }
2928} 2884}
2929 2885
2930static struct pktgen_thread *pktgen_find_thread(const char* name) 2886static struct pktgen_thread *pktgen_find_thread(const char* name)
2931{ 2887{
2932 struct pktgen_thread *t = NULL; 2888 struct pktgen_thread *t = NULL;
2933 2889
2934 thread_lock(); 2890 thread_lock();
2935 2891
2936 t = pktgen_threads; 2892 t = pktgen_threads;
2937 while (t) { 2893 while (t) {
@@ -2947,6 +2903,7 @@ static struct pktgen_thread *pktgen_find_thread(const char* name)
2947static int pktgen_create_thread(const char* name, int cpu) 2903static int pktgen_create_thread(const char* name, int cpu)
2948{ 2904{
2949 struct pktgen_thread *t = NULL; 2905 struct pktgen_thread *t = NULL;
2906 struct proc_dir_entry *pe;
2950 2907
2951 if (strlen(name) > 31) { 2908 if (strlen(name) > 31) {
2952 printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n"); 2909 printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n");
@@ -2958,28 +2915,26 @@ static int pktgen_create_thread(const char* name, int cpu)
2958 return -EINVAL; 2915 return -EINVAL;
2959 } 2916 }
2960 2917
2961 t = (struct pktgen_thread*)(kmalloc(sizeof(struct pktgen_thread), GFP_KERNEL)); 2918 t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL);
2962 if (!t) { 2919 if (!t) {
2963 printk("pktgen: ERROR: out of memory, can't create new thread.\n"); 2920 printk("pktgen: ERROR: out of memory, can't create new thread.\n");
2964 return -ENOMEM; 2921 return -ENOMEM;
2965 } 2922 }
2966 2923
2967 memset(t, 0, sizeof(struct pktgen_thread));
2968 strcpy(t->name, name); 2924 strcpy(t->name, name);
2969 spin_lock_init(&t->if_lock); 2925 spin_lock_init(&t->if_lock);
2970 t->cpu = cpu; 2926 t->cpu = cpu;
2971 2927
2972 sprintf(t->fname, "%s/%s", PG_PROC_DIR, t->name); 2928 pe = create_proc_entry(t->name, 0600, pg_proc_dir);
2973 t->proc_ent = create_proc_entry(t->fname, 0600, NULL); 2929 if (!pe) {
2974 if (!t->proc_ent) { 2930 printk("pktgen: cannot create %s/%s procfs entry.\n",
2975 printk("pktgen: cannot create %s procfs entry.\n", t->fname); 2931 PG_PROC_DIR, t->name);
2976 kfree(t); 2932 kfree(t);
2977 return -EINVAL; 2933 return -EINVAL;
2978 } 2934 }
2979 t->proc_ent->read_proc = proc_thread_read; 2935
2980 t->proc_ent->write_proc = proc_thread_write; 2936 pe->proc_fops = &pktgen_thread_fops;
2981 t->proc_ent->data = (void*)(t); 2937 pe->data = t;
2982 t->proc_ent->owner = THIS_MODULE;
2983 2938
2984 t->next = pktgen_threads; 2939 t->next = pktgen_threads;
2985 pktgen_threads = t; 2940 pktgen_threads = t;
@@ -3034,8 +2989,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_
3034 2989
3035 /* Clean up proc file system */ 2990 /* Clean up proc file system */
3036 2991
3037 if (strlen(pkt_dev->fname)) 2992 remove_proc_entry(pkt_dev->ifname, pg_proc_dir);
3038 remove_proc_entry(pkt_dev->fname, NULL);
3039 2993
3040 if (pkt_dev->flows) 2994 if (pkt_dev->flows)
3041 vfree(pkt_dev->flows); 2995 vfree(pkt_dev->flows);
@@ -3046,31 +3000,31 @@ static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_
3046static int __init pg_init(void) 3000static int __init pg_init(void)
3047{ 3001{
3048 int cpu; 3002 int cpu;
3049 printk(version); 3003 struct proc_dir_entry *pe;
3050 3004
3051 module_fname[0] = 0; 3005 printk(version);
3052 3006
3053 create_proc_dir(); 3007 pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net);
3008 if (!pg_proc_dir)
3009 return -ENODEV;
3010 pg_proc_dir->owner = THIS_MODULE;
3054 3011
3055 sprintf(module_fname, "%s/pgctrl", PG_PROC_DIR); 3012 pe = create_proc_entry(PGCTRL, 0600, pg_proc_dir);
3056 module_proc_ent = create_proc_entry(module_fname, 0600, NULL); 3013 if (pe == NULL) {
3057 if (!module_proc_ent) { 3014 printk("pktgen: ERROR: cannot create %s procfs entry.\n", PGCTRL);
3058 printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname); 3015 proc_net_remove(PG_PROC_DIR);
3059 return -EINVAL; 3016 return -EINVAL;
3060 } 3017 }
3061 3018
3062 module_proc_ent->proc_fops = &pktgen_fops; 3019 pe->proc_fops = &pktgen_fops;
3063 module_proc_ent->data = NULL; 3020 pe->data = NULL;
3064 3021
3065 /* Register us to receive netdevice events */ 3022 /* Register us to receive netdevice events */
3066 register_netdevice_notifier(&pktgen_notifier_block); 3023 register_netdevice_notifier(&pktgen_notifier_block);
3067 3024
3068 for (cpu = 0; cpu < NR_CPUS ; cpu++) { 3025 for_each_online_cpu(cpu) {
3069 char buf[30]; 3026 char buf[30];
3070 3027
3071 if (!cpu_online(cpu))
3072 continue;
3073
3074 sprintf(buf, "kpktgend_%i", cpu); 3028 sprintf(buf, "kpktgend_%i", cpu);
3075 pktgen_create_thread(buf, cpu); 3029 pktgen_create_thread(buf, cpu);
3076 } 3030 }
@@ -3095,10 +3049,8 @@ static void __exit pg_cleanup(void)
3095 unregister_netdevice_notifier(&pktgen_notifier_block); 3049 unregister_netdevice_notifier(&pktgen_notifier_block);
3096 3050
3097 /* Clean up proc file system */ 3051 /* Clean up proc file system */
3098 3052 remove_proc_entry(PGCTRL, pg_proc_dir);
3099 remove_proc_entry(module_fname, NULL); 3053 proc_net_remove(PG_PROC_DIR);
3100
3101 remove_proc_dir();
3102} 3054}
3103 3055
3104 3056
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 02cd4cde2112..ef9d46b91eb9 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -122,6 +122,8 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
122 * __alloc_skb - allocate a network buffer 122 * __alloc_skb - allocate a network buffer
123 * @size: size to allocate 123 * @size: size to allocate
124 * @gfp_mask: allocation mask 124 * @gfp_mask: allocation mask
125 * @fclone: allocate from fclone cache instead of head cache
126 * and allocate a cloned (child) skb
125 * 127 *
126 * Allocate a new &sk_buff. The returned buffer has no headroom and a 128 * Allocate a new &sk_buff. The returned buffer has no headroom and a
127 * tail room of size bytes. The object has a reference count of one. 129 * tail room of size bytes. The object has a reference count of one.
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 1186dc44cdff..3f25cadccddd 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -719,22 +719,9 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
719 if (saddr->sdn_flags & ~SDF_WILD) 719 if (saddr->sdn_flags & ~SDF_WILD)
720 return -EINVAL; 720 return -EINVAL;
721 721
722#if 1
723 if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum || 722 if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum ||
724 (saddr->sdn_flags & SDF_WILD))) 723 (saddr->sdn_flags & SDF_WILD)))
725 return -EACCES; 724 return -EACCES;
726#else
727 /*
728 * Maybe put the default actions in the default security ops for
729 * dn_prot_sock ? Would be nice if the capable call would go there
730 * too.
731 */
732 if (security_dn_prot_sock(saddr) &&
733 !capable(CAP_NET_BIND_SERVICE) ||
734 saddr->sdn_objnum || (saddr->sdn_flags & SDF_WILD))
735 return -EACCES;
736#endif
737
738 725
739 if (!(saddr->sdn_flags & SDF_WILD)) { 726 if (!(saddr->sdn_flags & SDF_WILD)) {
740 if (dn_ntohs(saddr->sdn_nodeaddrl)) { 727 if (dn_ntohs(saddr->sdn_nodeaddrl)) {
diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile
index a6ccac5baea8..f988417121da 100644
--- a/net/ieee80211/Makefile
+++ b/net/ieee80211/Makefile
@@ -7,5 +7,6 @@ ieee80211-objs := \
7 ieee80211_module.o \ 7 ieee80211_module.o \
8 ieee80211_tx.o \ 8 ieee80211_tx.o \
9 ieee80211_rx.o \ 9 ieee80211_rx.o \
10 ieee80211_wx.o 10 ieee80211_wx.o \
11 ieee80211_geo.o
11 12
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
index 61a9d92e455b..f3b6aa3be638 100644
--- a/net/ieee80211/ieee80211_crypt.c
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -41,6 +41,12 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
41{ 41{
42 struct list_head *ptr, *n; 42 struct list_head *ptr, *n;
43 struct ieee80211_crypt_data *entry; 43 struct ieee80211_crypt_data *entry;
44 unsigned long flags;
45
46 spin_lock_irqsave(&ieee->lock, flags);
47
48 if (list_empty(&ieee->crypt_deinit_list))
49 goto unlock;
44 50
45 for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; 51 for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
46 ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { 52 ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
@@ -57,6 +63,18 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
57 } 63 }
58 kfree(entry); 64 kfree(entry);
59 } 65 }
66 unlock:
67 spin_unlock_irqrestore(&ieee->lock, flags);
68}
69
70/* After this, crypt_deinit_list won't accept new members */
71void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
72{
73 unsigned long flags;
74
75 spin_lock_irqsave(&ieee->lock, flags);
76 ieee->crypt_quiesced = 1;
77 spin_unlock_irqrestore(&ieee->lock, flags);
60} 78}
61 79
62void ieee80211_crypt_deinit_handler(unsigned long data) 80void ieee80211_crypt_deinit_handler(unsigned long data)
@@ -64,16 +82,16 @@ void ieee80211_crypt_deinit_handler(unsigned long data)
64 struct ieee80211_device *ieee = (struct ieee80211_device *)data; 82 struct ieee80211_device *ieee = (struct ieee80211_device *)data;
65 unsigned long flags; 83 unsigned long flags;
66 84
67 spin_lock_irqsave(&ieee->lock, flags);
68 ieee80211_crypt_deinit_entries(ieee, 0); 85 ieee80211_crypt_deinit_entries(ieee, 0);
69 if (!list_empty(&ieee->crypt_deinit_list)) { 86
87 spin_lock_irqsave(&ieee->lock, flags);
88 if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
70 printk(KERN_DEBUG "%s: entries remaining in delayed crypt " 89 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
71 "deletion list\n", ieee->dev->name); 90 "deletion list\n", ieee->dev->name);
72 ieee->crypt_deinit_timer.expires = jiffies + HZ; 91 ieee->crypt_deinit_timer.expires = jiffies + HZ;
73 add_timer(&ieee->crypt_deinit_timer); 92 add_timer(&ieee->crypt_deinit_timer);
74 } 93 }
75 spin_unlock_irqrestore(&ieee->lock, flags); 94 spin_unlock_irqrestore(&ieee->lock, flags);
76
77} 95}
78 96
79void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, 97void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
@@ -93,10 +111,12 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
93 * locking. */ 111 * locking. */
94 112
95 spin_lock_irqsave(&ieee->lock, flags); 113 spin_lock_irqsave(&ieee->lock, flags);
96 list_add(&tmp->list, &ieee->crypt_deinit_list); 114 if (!ieee->crypt_quiesced) {
97 if (!timer_pending(&ieee->crypt_deinit_timer)) { 115 list_add(&tmp->list, &ieee->crypt_deinit_list);
98 ieee->crypt_deinit_timer.expires = jiffies + HZ; 116 if (!timer_pending(&ieee->crypt_deinit_timer)) {
99 add_timer(&ieee->crypt_deinit_timer); 117 ieee->crypt_deinit_timer.expires = jiffies + HZ;
118 add_timer(&ieee->crypt_deinit_timer);
119 }
100 } 120 }
101 spin_unlock_irqrestore(&ieee->lock, flags); 121 spin_unlock_irqrestore(&ieee->lock, flags);
102} 122}
@@ -191,18 +211,18 @@ static void ieee80211_crypt_null_deinit(void *priv)
191} 211}
192 212
193static struct ieee80211_crypto_ops ieee80211_crypt_null = { 213static struct ieee80211_crypto_ops ieee80211_crypt_null = {
194 .name = "NULL", 214 .name = "NULL",
195 .init = ieee80211_crypt_null_init, 215 .init = ieee80211_crypt_null_init,
196 .deinit = ieee80211_crypt_null_deinit, 216 .deinit = ieee80211_crypt_null_deinit,
197 .encrypt_mpdu = NULL, 217 .encrypt_mpdu = NULL,
198 .decrypt_mpdu = NULL, 218 .decrypt_mpdu = NULL,
199 .encrypt_msdu = NULL, 219 .encrypt_msdu = NULL,
200 .decrypt_msdu = NULL, 220 .decrypt_msdu = NULL,
201 .set_key = NULL, 221 .set_key = NULL,
202 .get_key = NULL, 222 .get_key = NULL,
203 .extra_prefix_len = 0, 223 .extra_mpdu_prefix_len = 0,
204 .extra_postfix_len = 0, 224 .extra_mpdu_postfix_len = 0,
205 .owner = THIS_MODULE, 225 .owner = THIS_MODULE,
206}; 226};
207 227
208static int __init ieee80211_crypto_init(void) 228static int __init ieee80211_crypto_init(void)
@@ -249,6 +269,7 @@ static void __exit ieee80211_crypto_deinit(void)
249EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); 269EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
250EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); 270EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
251EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); 271EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
272EXPORT_SYMBOL(ieee80211_crypt_quiescing);
252 273
253EXPORT_SYMBOL(ieee80211_register_crypto_ops); 274EXPORT_SYMBOL(ieee80211_register_crypto_ops);
254EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); 275EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index 8fc13f45971e..05a853c13012 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -119,7 +119,7 @@ static inline void xor_block(u8 * b, u8 * a, size_t len)
119} 119}
120 120
121static void ccmp_init_blocks(struct crypto_tfm *tfm, 121static void ccmp_init_blocks(struct crypto_tfm *tfm,
122 struct ieee80211_hdr *hdr, 122 struct ieee80211_hdr_4addr *hdr,
123 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0) 123 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
124{ 124{
125 u8 *pos, qc = 0; 125 u8 *pos, qc = 0;
@@ -191,26 +191,18 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
191 ieee80211_ccmp_aes_encrypt(tfm, b0, s0); 191 ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
192} 192}
193 193
194static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 194static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv)
195{ 195{
196 struct ieee80211_ccmp_data *key = priv; 196 struct ieee80211_ccmp_data *key = priv;
197 int data_len, i, blocks, last, len; 197 int i;
198 u8 *pos, *mic; 198 u8 *pos;
199 struct ieee80211_hdr *hdr;
200 u8 *b0 = key->tx_b0;
201 u8 *b = key->tx_b;
202 u8 *e = key->tx_e;
203 u8 *s0 = key->tx_s0;
204 199
205 if (skb_headroom(skb) < CCMP_HDR_LEN || 200 if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len)
206 skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
207 return -1; 201 return -1;
208 202
209 data_len = skb->len - hdr_len;
210 pos = skb_push(skb, CCMP_HDR_LEN); 203 pos = skb_push(skb, CCMP_HDR_LEN);
211 memmove(pos, pos + CCMP_HDR_LEN, hdr_len); 204 memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
212 pos += hdr_len; 205 pos += hdr_len;
213 mic = skb_put(skb, CCMP_MIC_LEN);
214 206
215 i = CCMP_PN_LEN - 1; 207 i = CCMP_PN_LEN - 1;
216 while (i >= 0) { 208 while (i >= 0) {
@@ -229,7 +221,31 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
229 *pos++ = key->tx_pn[1]; 221 *pos++ = key->tx_pn[1];
230 *pos++ = key->tx_pn[0]; 222 *pos++ = key->tx_pn[0];
231 223
232 hdr = (struct ieee80211_hdr *)skb->data; 224 return CCMP_HDR_LEN;
225}
226
227static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
228{
229 struct ieee80211_ccmp_data *key = priv;
230 int data_len, i, blocks, last, len;
231 u8 *pos, *mic;
232 struct ieee80211_hdr_4addr *hdr;
233 u8 *b0 = key->tx_b0;
234 u8 *b = key->tx_b;
235 u8 *e = key->tx_e;
236 u8 *s0 = key->tx_s0;
237
238 if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
239 return -1;
240
241 data_len = skb->len - hdr_len;
242 len = ieee80211_ccmp_hdr(skb, hdr_len, priv);
243 if (len < 0)
244 return -1;
245
246 pos = skb->data + hdr_len + CCMP_HDR_LEN;
247 mic = skb_put(skb, CCMP_MIC_LEN);
248 hdr = (struct ieee80211_hdr_4addr *)skb->data;
233 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); 249 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
234 250
235 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; 251 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
@@ -258,7 +274,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
258{ 274{
259 struct ieee80211_ccmp_data *key = priv; 275 struct ieee80211_ccmp_data *key = priv;
260 u8 keyidx, *pos; 276 u8 keyidx, *pos;
261 struct ieee80211_hdr *hdr; 277 struct ieee80211_hdr_4addr *hdr;
262 u8 *b0 = key->rx_b0; 278 u8 *b0 = key->rx_b0;
263 u8 *b = key->rx_b; 279 u8 *b = key->rx_b;
264 u8 *a = key->rx_a; 280 u8 *a = key->rx_a;
@@ -272,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
272 return -1; 288 return -1;
273 } 289 }
274 290
275 hdr = (struct ieee80211_hdr *)skb->data; 291 hdr = (struct ieee80211_hdr_4addr *)skb->data;
276 pos = skb->data + hdr_len; 292 pos = skb->data + hdr_len;
277 keyidx = pos[3]; 293 keyidx = pos[3];
278 if (!(keyidx & (1 << 5))) { 294 if (!(keyidx & (1 << 5))) {
@@ -426,19 +442,20 @@ static char *ieee80211_ccmp_print_stats(char *p, void *priv)
426} 442}
427 443
428static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { 444static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
429 .name = "CCMP", 445 .name = "CCMP",
430 .init = ieee80211_ccmp_init, 446 .init = ieee80211_ccmp_init,
431 .deinit = ieee80211_ccmp_deinit, 447 .deinit = ieee80211_ccmp_deinit,
432 .encrypt_mpdu = ieee80211_ccmp_encrypt, 448 .build_iv = ieee80211_ccmp_hdr,
433 .decrypt_mpdu = ieee80211_ccmp_decrypt, 449 .encrypt_mpdu = ieee80211_ccmp_encrypt,
434 .encrypt_msdu = NULL, 450 .decrypt_mpdu = ieee80211_ccmp_decrypt,
435 .decrypt_msdu = NULL, 451 .encrypt_msdu = NULL,
436 .set_key = ieee80211_ccmp_set_key, 452 .decrypt_msdu = NULL,
437 .get_key = ieee80211_ccmp_get_key, 453 .set_key = ieee80211_ccmp_set_key,
438 .print_stats = ieee80211_ccmp_print_stats, 454 .get_key = ieee80211_ccmp_get_key,
439 .extra_prefix_len = CCMP_HDR_LEN, 455 .print_stats = ieee80211_ccmp_print_stats,
440 .extra_postfix_len = CCMP_MIC_LEN, 456 .extra_mpdu_prefix_len = CCMP_HDR_LEN,
441 .owner = THIS_MODULE, 457 .extra_mpdu_postfix_len = CCMP_MIC_LEN,
458 .owner = THIS_MODULE,
442}; 459};
443 460
444static int __init ieee80211_crypto_ccmp_init(void) 461static int __init ieee80211_crypto_ccmp_init(void)
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index d4f9164be1a1..2e34f29b7956 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -59,8 +59,24 @@ struct ieee80211_tkip_data {
59 59
60 /* scratch buffers for virt_to_page() (crypto API) */ 60 /* scratch buffers for virt_to_page() (crypto API) */
61 u8 rx_hdr[16], tx_hdr[16]; 61 u8 rx_hdr[16], tx_hdr[16];
62
63 unsigned long flags;
62}; 64};
63 65
66static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv)
67{
68 struct ieee80211_tkip_data *_priv = priv;
69 unsigned long old_flags = _priv->flags;
70 _priv->flags = flags;
71 return old_flags;
72}
73
74static unsigned long ieee80211_tkip_get_flags(void *priv)
75{
76 struct ieee80211_tkip_data *_priv = priv;
77 return _priv->flags;
78}
79
64static void *ieee80211_tkip_init(int key_idx) 80static void *ieee80211_tkip_init(int key_idx)
65{ 81{
66 struct ieee80211_tkip_data *priv; 82 struct ieee80211_tkip_data *priv;
@@ -69,6 +85,7 @@ static void *ieee80211_tkip_init(int key_idx)
69 if (priv == NULL) 85 if (priv == NULL)
70 goto fail; 86 goto fail;
71 memset(priv, 0, sizeof(*priv)); 87 memset(priv, 0, sizeof(*priv));
88
72 priv->key_idx = key_idx; 89 priv->key_idx = key_idx;
73 90
74 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0); 91 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
@@ -255,25 +272,27 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
255#endif 272#endif
256} 273}
257 274
258static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 275static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv)
259{ 276{
260 struct ieee80211_tkip_data *tkey = priv; 277 struct ieee80211_tkip_data *tkey = priv;
261 int len; 278 int len;
262 u8 rc4key[16], *pos, *icv; 279 u8 *rc4key, *pos, *icv;
263 struct ieee80211_hdr *hdr; 280 struct ieee80211_hdr_4addr *hdr;
264 u32 crc; 281 u32 crc;
265 struct scatterlist sg;
266 282
267 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 || 283 hdr = (struct ieee80211_hdr_4addr *)skb->data;
268 skb->len < hdr_len) 284
269 return -1; 285 if (skb_headroom(skb) < 8 || skb->len < hdr_len)
286 return NULL;
270 287
271 hdr = (struct ieee80211_hdr *)skb->data;
272 if (!tkey->tx_phase1_done) { 288 if (!tkey->tx_phase1_done) {
273 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, 289 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
274 tkey->tx_iv32); 290 tkey->tx_iv32);
275 tkey->tx_phase1_done = 1; 291 tkey->tx_phase1_done = 1;
276 } 292 }
293 rc4key = kmalloc(16, GFP_ATOMIC);
294 if (!rc4key)
295 return NULL;
277 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); 296 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
278 297
279 len = skb->len - hdr_len; 298 len = skb->len - hdr_len;
@@ -282,9 +301,9 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
282 pos += hdr_len; 301 pos += hdr_len;
283 icv = skb_put(skb, 4); 302 icv = skb_put(skb, 4);
284 303
285 *pos++ = rc4key[0]; 304 *pos++ = *rc4key;
286 *pos++ = rc4key[1]; 305 *pos++ = *(rc4key + 1);
287 *pos++ = rc4key[2]; 306 *pos++ = *(rc4key + 2);
288 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ; 307 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
289 *pos++ = tkey->tx_iv32 & 0xff; 308 *pos++ = tkey->tx_iv32 & 0xff;
290 *pos++ = (tkey->tx_iv32 >> 8) & 0xff; 309 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
@@ -297,6 +316,38 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
297 icv[2] = crc >> 16; 316 icv[2] = crc >> 16;
298 icv[3] = crc >> 24; 317 icv[3] = crc >> 24;
299 318
319 return rc4key;
320}
321
322static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
323{
324 struct ieee80211_tkip_data *tkey = priv;
325 int len;
326 const u8 *rc4key;
327 u8 *pos;
328 struct scatterlist sg;
329
330 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
331 if (net_ratelimit()) {
332 struct ieee80211_hdr_4addr *hdr =
333 (struct ieee80211_hdr_4addr *)skb->data;
334 printk(KERN_DEBUG "TKIP countermeasures: dropped "
335 "TX packet to " MAC_FMT "\n",
336 MAC_ARG(hdr->addr1));
337 }
338 return -1;
339 }
340
341 if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
342 return -1;
343
344 len = skb->len - hdr_len;
345 pos = skb->data + hdr_len;
346
347 rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv);
348 if (!rc4key)
349 return -1;
350
300 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); 351 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
301 sg.page = virt_to_page(pos); 352 sg.page = virt_to_page(pos);
302 sg.offset = offset_in_page(pos); 353 sg.offset = offset_in_page(pos);
@@ -319,16 +370,26 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
319 u8 keyidx, *pos; 370 u8 keyidx, *pos;
320 u32 iv32; 371 u32 iv32;
321 u16 iv16; 372 u16 iv16;
322 struct ieee80211_hdr *hdr; 373 struct ieee80211_hdr_4addr *hdr;
323 u8 icv[4]; 374 u8 icv[4];
324 u32 crc; 375 u32 crc;
325 struct scatterlist sg; 376 struct scatterlist sg;
326 int plen; 377 int plen;
327 378
379 hdr = (struct ieee80211_hdr_4addr *)skb->data;
380
381 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
382 if (net_ratelimit()) {
383 printk(KERN_DEBUG "TKIP countermeasures: dropped "
384 "received packet from " MAC_FMT "\n",
385 MAC_ARG(hdr->addr2));
386 }
387 return -1;
388 }
389
328 if (skb->len < hdr_len + 8 + 4) 390 if (skb->len < hdr_len + 8 + 4)
329 return -1; 391 return -1;
330 392
331 hdr = (struct ieee80211_hdr *)skb->data;
332 pos = skb->data + hdr_len; 393 pos = skb->data + hdr_len;
333 keyidx = pos[3]; 394 keyidx = pos[3];
334 if (!(keyidx & (1 << 5))) { 395 if (!(keyidx & (1 << 5))) {
@@ -441,9 +502,9 @@ static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
441 502
442static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) 503static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
443{ 504{
444 struct ieee80211_hdr *hdr11; 505 struct ieee80211_hdr_4addr *hdr11;
445 506
446 hdr11 = (struct ieee80211_hdr *)skb->data; 507 hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
447 switch (le16_to_cpu(hdr11->frame_ctl) & 508 switch (le16_to_cpu(hdr11->frame_ctl) &
448 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { 509 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
449 case IEEE80211_FCTL_TODS: 510 case IEEE80211_FCTL_TODS:
@@ -490,9 +551,9 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
490 return 0; 551 return 0;
491} 552}
492 553
493#if WIRELESS_EXT >= 18
494static void ieee80211_michael_mic_failure(struct net_device *dev, 554static void ieee80211_michael_mic_failure(struct net_device *dev,
495 struct ieee80211_hdr *hdr, int keyidx) 555 struct ieee80211_hdr_4addr *hdr,
556 int keyidx)
496{ 557{
497 union iwreq_data wrqu; 558 union iwreq_data wrqu;
498 struct iw_michaelmicfailure ev; 559 struct iw_michaelmicfailure ev;
@@ -510,28 +571,6 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
510 wrqu.data.length = sizeof(ev); 571 wrqu.data.length = sizeof(ev);
511 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); 572 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
512} 573}
513#elif WIRELESS_EXT >= 15
514static void ieee80211_michael_mic_failure(struct net_device *dev,
515 struct ieee80211_hdr *hdr, int keyidx)
516{
517 union iwreq_data wrqu;
518 char buf[128];
519
520 /* TODO: needed parameters: count, keyid, key type, TSC */
521 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
522 MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
523 MAC_ARG(hdr->addr2));
524 memset(&wrqu, 0, sizeof(wrqu));
525 wrqu.data.length = strlen(buf);
526 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
527}
528#else /* WIRELESS_EXT >= 15 */
529static inline void ieee80211_michael_mic_failure(struct net_device *dev,
530 struct ieee80211_hdr *hdr,
531 int keyidx)
532{
533}
534#endif /* WIRELESS_EXT >= 15 */
535 574
536static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, 575static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
537 int hdr_len, void *priv) 576 int hdr_len, void *priv)
@@ -547,8 +586,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
547 skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) 586 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
548 return -1; 587 return -1;
549 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { 588 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
550 struct ieee80211_hdr *hdr; 589 struct ieee80211_hdr_4addr *hdr;
551 hdr = (struct ieee80211_hdr *)skb->data; 590 hdr = (struct ieee80211_hdr_4addr *)skb->data;
552 printk(KERN_DEBUG "%s: Michael MIC verification failed for " 591 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
553 "MSDU from " MAC_FMT " keyidx=%d\n", 592 "MSDU from " MAC_FMT " keyidx=%d\n",
554 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), 593 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
@@ -654,19 +693,22 @@ static char *ieee80211_tkip_print_stats(char *p, void *priv)
654} 693}
655 694
656static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { 695static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
657 .name = "TKIP", 696 .name = "TKIP",
658 .init = ieee80211_tkip_init, 697 .init = ieee80211_tkip_init,
659 .deinit = ieee80211_tkip_deinit, 698 .deinit = ieee80211_tkip_deinit,
660 .encrypt_mpdu = ieee80211_tkip_encrypt, 699 .encrypt_mpdu = ieee80211_tkip_encrypt,
661 .decrypt_mpdu = ieee80211_tkip_decrypt, 700 .decrypt_mpdu = ieee80211_tkip_decrypt,
662 .encrypt_msdu = ieee80211_michael_mic_add, 701 .encrypt_msdu = ieee80211_michael_mic_add,
663 .decrypt_msdu = ieee80211_michael_mic_verify, 702 .decrypt_msdu = ieee80211_michael_mic_verify,
664 .set_key = ieee80211_tkip_set_key, 703 .set_key = ieee80211_tkip_set_key,
665 .get_key = ieee80211_tkip_get_key, 704 .get_key = ieee80211_tkip_get_key,
666 .print_stats = ieee80211_tkip_print_stats, 705 .print_stats = ieee80211_tkip_print_stats,
667 .extra_prefix_len = 4 + 4, /* IV + ExtIV */ 706 .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
668 .extra_postfix_len = 8 + 4, /* MIC + ICV */ 707 .extra_mpdu_postfix_len = 4, /* ICV */
669 .owner = THIS_MODULE, 708 .extra_msdu_postfix_len = 8, /* MIC */
709 .get_flags = ieee80211_tkip_get_flags,
710 .set_flags = ieee80211_tkip_set_flags,
711 .owner = THIS_MODULE,
670}; 712};
671 713
672static int __init ieee80211_crypto_tkip_init(void) 714static int __init ieee80211_crypto_tkip_init(void)
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index b4d2514a0902..7c08ed2f2628 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -229,19 +229,19 @@ static char *prism2_wep_print_stats(char *p, void *priv)
229} 229}
230 230
231static struct ieee80211_crypto_ops ieee80211_crypt_wep = { 231static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
232 .name = "WEP", 232 .name = "WEP",
233 .init = prism2_wep_init, 233 .init = prism2_wep_init,
234 .deinit = prism2_wep_deinit, 234 .deinit = prism2_wep_deinit,
235 .encrypt_mpdu = prism2_wep_encrypt, 235 .encrypt_mpdu = prism2_wep_encrypt,
236 .decrypt_mpdu = prism2_wep_decrypt, 236 .decrypt_mpdu = prism2_wep_decrypt,
237 .encrypt_msdu = NULL, 237 .encrypt_msdu = NULL,
238 .decrypt_msdu = NULL, 238 .decrypt_msdu = NULL,
239 .set_key = prism2_wep_set_key, 239 .set_key = prism2_wep_set_key,
240 .get_key = prism2_wep_get_key, 240 .get_key = prism2_wep_get_key,
241 .print_stats = prism2_wep_print_stats, 241 .print_stats = prism2_wep_print_stats,
242 .extra_prefix_len = 4, /* IV */ 242 .extra_mpdu_prefix_len = 4, /* IV */
243 .extra_postfix_len = 4, /* ICV */ 243 .extra_mpdu_postfix_len = 4, /* ICV */
244 .owner = THIS_MODULE, 244 .owner = THIS_MODULE,
245}; 245};
246 246
247static int __init ieee80211_crypto_wep_init(void) 247static int __init ieee80211_crypto_wep_init(void)
diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c
new file mode 100644
index 000000000000..c4b54ef8f6d5
--- /dev/null
+++ b/net/ieee80211/ieee80211_geo.c
@@ -0,0 +1,141 @@
1/******************************************************************************
2
3 Copyright(c) 2005 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************/
26#include <linux/compiler.h>
27#include <linux/config.h>
28#include <linux/errno.h>
29#include <linux/if_arp.h>
30#include <linux/in6.h>
31#include <linux/in.h>
32#include <linux/ip.h>
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/netdevice.h>
36#include <linux/proc_fs.h>
37#include <linux/skbuff.h>
38#include <linux/slab.h>
39#include <linux/tcp.h>
40#include <linux/types.h>
41#include <linux/version.h>
42#include <linux/wireless.h>
43#include <linux/etherdevice.h>
44#include <asm/uaccess.h>
45
46#include <net/ieee80211.h>
47
48int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
49{
50 int i;
51
52 /* Driver needs to initialize the geography map before using
53 * these helper functions */
54 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
55
56 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
57 for (i = 0; i < ieee->geo.bg_channels; i++)
58 /* NOTE: If G mode is currently supported but
59 * this is a B only channel, we don't see it
60 * as valid. */
61 if ((ieee->geo.bg[i].channel == channel) &&
62 (!(ieee->mode & IEEE_G) ||
63 !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
64 return IEEE80211_24GHZ_BAND;
65
66 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
67 for (i = 0; i < ieee->geo.a_channels; i++)
68 if (ieee->geo.a[i].channel == channel)
69 return IEEE80211_52GHZ_BAND;
70
71 return 0;
72}
73
74int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
75{
76 int i;
77
78 /* Driver needs to initialize the geography map before using
79 * these helper functions */
80 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
81
82 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
83 for (i = 0; i < ieee->geo.bg_channels; i++)
84 if (ieee->geo.bg[i].channel == channel)
85 return i;
86
87 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
88 for (i = 0; i < ieee->geo.a_channels; i++)
89 if (ieee->geo.a[i].channel == channel)
90 return i;
91
92 return -1;
93}
94
95u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
96{
97 int i;
98
99 /* Driver needs to initialize the geography map before using
100 * these helper functions */
101 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
102
103 freq /= 100000;
104
105 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
106 for (i = 0; i < ieee->geo.bg_channels; i++)
107 if (ieee->geo.bg[i].freq == freq)
108 return ieee->geo.bg[i].channel;
109
110 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
111 for (i = 0; i < ieee->geo.a_channels; i++)
112 if (ieee->geo.a[i].freq == freq)
113 return ieee->geo.a[i].channel;
114
115 return 0;
116}
117
118int ieee80211_set_geo(struct ieee80211_device *ieee,
119 const struct ieee80211_geo *geo)
120{
121 memcpy(ieee->geo.name, geo->name, 3);
122 ieee->geo.name[3] = '\0';
123 ieee->geo.bg_channels = geo->bg_channels;
124 ieee->geo.a_channels = geo->a_channels;
125 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
126 sizeof(struct ieee80211_channel));
127 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
128 sizeof(struct ieee80211_channel));
129 return 0;
130}
131
132const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee)
133{
134 return &ieee->geo;
135}
136
137EXPORT_SYMBOL(ieee80211_is_valid_channel);
138EXPORT_SYMBOL(ieee80211_freq_to_channel);
139EXPORT_SYMBOL(ieee80211_channel_to_index);
140EXPORT_SYMBOL(ieee80211_set_geo);
141EXPORT_SYMBOL(ieee80211_get_geo);
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index 6059e9e37123..f66d792cd204 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -1,6 +1,6 @@
1/******************************************************************************* 1/*******************************************************************************
2 2
3 Copyright(c) 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
4 4
5 Portions of this file are based on the WEP enablement code provided by the 5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3 6 Host AP project hostap-drivers v0.1.3
@@ -53,12 +53,15 @@
53 53
54#include <net/ieee80211.h> 54#include <net/ieee80211.h>
55 55
56MODULE_DESCRIPTION("802.11 data/management/control stack"); 56#define DRV_DESCRIPTION "802.11 data/management/control stack"
57MODULE_AUTHOR 57#define DRV_NAME "ieee80211"
58 ("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>"); 58#define DRV_VERSION IEEE80211_VERSION
59MODULE_LICENSE("GPL"); 59#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
60 60
61#define DRV_NAME "ieee80211" 61MODULE_VERSION(DRV_VERSION);
62MODULE_DESCRIPTION(DRV_DESCRIPTION);
63MODULE_AUTHOR(DRV_COPYRIGHT);
64MODULE_LICENSE("GPL");
62 65
63static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) 66static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
64{ 67{
@@ -126,26 +129,34 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
126 129
127 /* Default fragmentation threshold is maximum payload size */ 130 /* Default fragmentation threshold is maximum payload size */
128 ieee->fts = DEFAULT_FTS; 131 ieee->fts = DEFAULT_FTS;
132 ieee->rts = DEFAULT_FTS;
129 ieee->scan_age = DEFAULT_MAX_SCAN_AGE; 133 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
130 ieee->open_wep = 1; 134 ieee->open_wep = 1;
131 135
132 /* Default to enabling full open WEP with host based encrypt/decrypt */ 136 /* Default to enabling full open WEP with host based encrypt/decrypt */
133 ieee->host_encrypt = 1; 137 ieee->host_encrypt = 1;
134 ieee->host_decrypt = 1; 138 ieee->host_decrypt = 1;
139 ieee->host_mc_decrypt = 1;
140
141 /* Host fragementation in Open mode. Default is enabled.
142 * Note: host fragmentation is always enabled if host encryption
143 * is enabled. For cards can do hardware encryption, they must do
144 * hardware fragmentation as well. So we don't need a variable
145 * like host_enc_frag. */
146 ieee->host_open_frag = 1;
135 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ 147 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
136 148
137 INIT_LIST_HEAD(&ieee->crypt_deinit_list); 149 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
138 init_timer(&ieee->crypt_deinit_timer); 150 init_timer(&ieee->crypt_deinit_timer);
139 ieee->crypt_deinit_timer.data = (unsigned long)ieee; 151 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
140 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler; 152 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
153 ieee->crypt_quiesced = 0;
141 154
142 spin_lock_init(&ieee->lock); 155 spin_lock_init(&ieee->lock);
143 156
144 ieee->wpa_enabled = 0; 157 ieee->wpa_enabled = 0;
145 ieee->tkip_countermeasures = 0;
146 ieee->drop_unencrypted = 0; 158 ieee->drop_unencrypted = 0;
147 ieee->privacy_invoked = 0; 159 ieee->privacy_invoked = 0;
148 ieee->ieee802_1x = 1;
149 160
150 return dev; 161 return dev;
151 162
@@ -161,6 +172,7 @@ void free_ieee80211(struct net_device *dev)
161 172
162 int i; 173 int i;
163 174
175 ieee80211_crypt_quiescing(ieee);
164 del_timer_sync(&ieee->crypt_deinit_timer); 176 del_timer_sync(&ieee->crypt_deinit_timer);
165 ieee80211_crypt_deinit_entries(ieee, 1); 177 ieee80211_crypt_deinit_entries(ieee, 1);
166 178
@@ -195,38 +207,26 @@ static int show_debug_level(char *page, char **start, off_t offset,
195static int store_debug_level(struct file *file, const char __user * buffer, 207static int store_debug_level(struct file *file, const char __user * buffer,
196 unsigned long count, void *data) 208 unsigned long count, void *data)
197{ 209{
198 char buf[] = "0x00000000"; 210 char buf[] = "0x00000000\n";
199 char *p = (char *)buf; 211 unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
200 unsigned long val; 212 unsigned long val;
201 213
202 if (count > sizeof(buf) - 1) 214 if (copy_from_user(buf, buffer, len))
203 count = sizeof(buf) - 1;
204
205 if (copy_from_user(buf, buffer, count))
206 return count; 215 return count;
207 buf[count] = 0; 216 buf[len] = 0;
208 /* 217 if (sscanf(buf, "%li", &val) != 1)
209 * what a FPOS... What, sscanf(buf, "%i", &val) would be too
210 * scary?
211 */
212 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
213 p++;
214 if (p[0] == 'x' || p[0] == 'X')
215 p++;
216 val = simple_strtoul(p, &p, 16);
217 } else
218 val = simple_strtoul(p, &p, 10);
219 if (p == buf)
220 printk(KERN_INFO DRV_NAME 218 printk(KERN_INFO DRV_NAME
221 ": %s is not in hex or decimal form.\n", buf); 219 ": %s is not in hex or decimal form.\n", buf);
222 else 220 else
223 ieee80211_debug_level = val; 221 ieee80211_debug_level = val;
224 222
225 return strlen(buf); 223 return strnlen(buf, len);
226} 224}
225#endif /* CONFIG_IEEE80211_DEBUG */
227 226
228static int __init ieee80211_init(void) 227static int __init ieee80211_init(void)
229{ 228{
229#ifdef CONFIG_IEEE80211_DEBUG
230 struct proc_dir_entry *e; 230 struct proc_dir_entry *e;
231 231
232 ieee80211_debug_level = debug; 232 ieee80211_debug_level = debug;
@@ -246,26 +246,33 @@ static int __init ieee80211_init(void)
246 e->read_proc = show_debug_level; 246 e->read_proc = show_debug_level;
247 e->write_proc = store_debug_level; 247 e->write_proc = store_debug_level;
248 e->data = NULL; 248 e->data = NULL;
249#endif /* CONFIG_IEEE80211_DEBUG */
250
251 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
252 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
249 253
250 return 0; 254 return 0;
251} 255}
252 256
253static void __exit ieee80211_exit(void) 257static void __exit ieee80211_exit(void)
254{ 258{
259#ifdef CONFIG_IEEE80211_DEBUG
255 if (ieee80211_proc) { 260 if (ieee80211_proc) {
256 remove_proc_entry("debug_level", ieee80211_proc); 261 remove_proc_entry("debug_level", ieee80211_proc);
257 remove_proc_entry(DRV_NAME, proc_net); 262 remove_proc_entry(DRV_NAME, proc_net);
258 ieee80211_proc = NULL; 263 ieee80211_proc = NULL;
259 } 264 }
265#endif /* CONFIG_IEEE80211_DEBUG */
260} 266}
261 267
268#ifdef CONFIG_IEEE80211_DEBUG
262#include <linux/moduleparam.h> 269#include <linux/moduleparam.h>
263module_param(debug, int, 0444); 270module_param(debug, int, 0444);
264MODULE_PARM_DESC(debug, "debug output mask"); 271MODULE_PARM_DESC(debug, "debug output mask");
272#endif /* CONFIG_IEEE80211_DEBUG */
265 273
266module_exit(ieee80211_exit); 274module_exit(ieee80211_exit);
267module_init(ieee80211_init); 275module_init(ieee80211_init);
268#endif
269 276
270const char *escape_essid(const char *essid, u8 essid_len) 277const char *escape_essid(const char *essid, u8 essid_len)
271{ 278{
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index f7dcd854139e..ce694cf5c160 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -5,7 +5,7 @@
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi> 6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8 * Copyright (c) 2004, Intel Corporation 8 * Copyright (c) 2004-2005, Intel Corporation
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
@@ -87,7 +87,7 @@ static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
87 87
88/* Called only as a tasklet (software IRQ) */ 88/* Called only as a tasklet (software IRQ) */
89static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee, 89static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
90 struct ieee80211_hdr *hdr) 90 struct ieee80211_hdr_4addr *hdr)
91{ 91{
92 struct sk_buff *skb = NULL; 92 struct sk_buff *skb = NULL;
93 u16 sc; 93 u16 sc;
@@ -101,7 +101,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
101 if (frag == 0) { 101 if (frag == 0) {
102 /* Reserve enough space to fit maximum frame length */ 102 /* Reserve enough space to fit maximum frame length */
103 skb = dev_alloc_skb(ieee->dev->mtu + 103 skb = dev_alloc_skb(ieee->dev->mtu +
104 sizeof(struct ieee80211_hdr) + 104 sizeof(struct ieee80211_hdr_4addr) +
105 8 /* LLC */ + 105 8 /* LLC */ +
106 2 /* alignment */ + 106 2 /* alignment */ +
107 8 /* WEP */ + ETH_ALEN /* WDS */ ); 107 8 /* WEP */ + ETH_ALEN /* WDS */ );
@@ -138,7 +138,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
138 138
139/* Called only as a tasklet (software IRQ) */ 139/* Called only as a tasklet (software IRQ) */
140static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, 140static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
141 struct ieee80211_hdr *hdr) 141 struct ieee80211_hdr_4addr *hdr)
142{ 142{
143 u16 sc; 143 u16 sc;
144 unsigned int seq; 144 unsigned int seq;
@@ -176,7 +176,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
176 ieee->dev->name); 176 ieee->dev->name);
177 return 0; 177 return 0;
178/* 178/*
179 hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *) 179 hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
180 skb->data);*/ 180 skb->data);*/
181 } 181 }
182 182
@@ -232,13 +232,13 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
232{ 232{
233 struct net_device *dev = ieee->dev; 233 struct net_device *dev = ieee->dev;
234 u16 fc, ethertype; 234 u16 fc, ethertype;
235 struct ieee80211_hdr *hdr; 235 struct ieee80211_hdr_3addr *hdr;
236 u8 *pos; 236 u8 *pos;
237 237
238 if (skb->len < 24) 238 if (skb->len < 24)
239 return 0; 239 return 0;
240 240
241 hdr = (struct ieee80211_hdr *)skb->data; 241 hdr = (struct ieee80211_hdr_3addr *)skb->data;
242 fc = le16_to_cpu(hdr->frame_ctl); 242 fc = le16_to_cpu(hdr->frame_ctl);
243 243
244 /* check that the frame is unicast frame to us */ 244 /* check that the frame is unicast frame to us */
@@ -271,26 +271,15 @@ static inline int
271ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, 271ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
272 struct ieee80211_crypt_data *crypt) 272 struct ieee80211_crypt_data *crypt)
273{ 273{
274 struct ieee80211_hdr *hdr; 274 struct ieee80211_hdr_3addr *hdr;
275 int res, hdrlen; 275 int res, hdrlen;
276 276
277 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) 277 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
278 return 0; 278 return 0;
279 279
280 hdr = (struct ieee80211_hdr *)skb->data; 280 hdr = (struct ieee80211_hdr_3addr *)skb->data;
281 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); 281 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
282 282
283#ifdef CONFIG_IEEE80211_CRYPT_TKIP
284 if (ieee->tkip_countermeasures && strcmp(crypt->ops->name, "TKIP") == 0) {
285 if (net_ratelimit()) {
286 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
287 "received packet from " MAC_FMT "\n",
288 ieee->dev->name, MAC_ARG(hdr->addr2));
289 }
290 return -1;
291 }
292#endif
293
294 atomic_inc(&crypt->refcnt); 283 atomic_inc(&crypt->refcnt);
295 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); 284 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
296 atomic_dec(&crypt->refcnt); 285 atomic_dec(&crypt->refcnt);
@@ -314,13 +303,13 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
314 struct sk_buff *skb, int keyidx, 303 struct sk_buff *skb, int keyidx,
315 struct ieee80211_crypt_data *crypt) 304 struct ieee80211_crypt_data *crypt)
316{ 305{
317 struct ieee80211_hdr *hdr; 306 struct ieee80211_hdr_3addr *hdr;
318 int res, hdrlen; 307 int res, hdrlen;
319 308
320 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) 309 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
321 return 0; 310 return 0;
322 311
323 hdr = (struct ieee80211_hdr *)skb->data; 312 hdr = (struct ieee80211_hdr_3addr *)skb->data;
324 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); 313 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
325 314
326 atomic_inc(&crypt->refcnt); 315 atomic_inc(&crypt->refcnt);
@@ -343,7 +332,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
343 struct ieee80211_rx_stats *rx_stats) 332 struct ieee80211_rx_stats *rx_stats)
344{ 333{
345 struct net_device *dev = ieee->dev; 334 struct net_device *dev = ieee->dev;
346 struct ieee80211_hdr *hdr; 335 struct ieee80211_hdr_4addr *hdr;
347 size_t hdrlen; 336 size_t hdrlen;
348 u16 fc, type, stype, sc; 337 u16 fc, type, stype, sc;
349 struct net_device_stats *stats; 338 struct net_device_stats *stats;
@@ -363,7 +352,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
363 struct ieee80211_crypt_data *crypt = NULL; 352 struct ieee80211_crypt_data *crypt = NULL;
364 int keyidx = 0; 353 int keyidx = 0;
365 354
366 hdr = (struct ieee80211_hdr *)skb->data; 355 hdr = (struct ieee80211_hdr_4addr *)skb->data;
367 stats = &ieee->stats; 356 stats = &ieee->stats;
368 357
369 if (skb->len < 10) { 358 if (skb->len < 10) {
@@ -378,35 +367,51 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
378 frag = WLAN_GET_SEQ_FRAG(sc); 367 frag = WLAN_GET_SEQ_FRAG(sc);
379 hdrlen = ieee80211_get_hdrlen(fc); 368 hdrlen = ieee80211_get_hdrlen(fc);
380 369
381#ifdef NOT_YET
382#if WIRELESS_EXT > 15
383 /* Put this code here so that we avoid duplicating it in all 370 /* Put this code here so that we avoid duplicating it in all
384 * Rx paths. - Jean II */ 371 * Rx paths. - Jean II */
385#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ 372#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
386 /* If spy monitoring on */ 373 /* If spy monitoring on */
387 if (iface->spy_data.spy_number > 0) { 374 if (ieee->spy_data.spy_number > 0) {
388 struct iw_quality wstats; 375 struct iw_quality wstats;
389 wstats.level = rx_stats->signal; 376
390 wstats.noise = rx_stats->noise; 377 wstats.updated = 0;
391 wstats.updated = 6; /* No qual value */ 378 if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
379 wstats.level = rx_stats->rssi;
380 wstats.updated |= IW_QUAL_LEVEL_UPDATED;
381 } else
382 wstats.updated |= IW_QUAL_LEVEL_INVALID;
383
384 if (rx_stats->mask & IEEE80211_STATMASK_NOISE) {
385 wstats.noise = rx_stats->noise;
386 wstats.updated |= IW_QUAL_NOISE_UPDATED;
387 } else
388 wstats.updated |= IW_QUAL_NOISE_INVALID;
389
390 if (rx_stats->mask & IEEE80211_STATMASK_SIGNAL) {
391 wstats.qual = rx_stats->signal;
392 wstats.updated |= IW_QUAL_QUAL_UPDATED;
393 } else
394 wstats.updated |= IW_QUAL_QUAL_INVALID;
395
392 /* Update spy records */ 396 /* Update spy records */
393 wireless_spy_update(dev, hdr->addr2, &wstats); 397 wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
394 } 398 }
395#endif /* IW_WIRELESS_SPY */ 399#endif /* IW_WIRELESS_SPY */
396#endif /* WIRELESS_EXT > 15 */ 400
401#ifdef NOT_YET
397 hostap_update_rx_stats(local->ap, hdr, rx_stats); 402 hostap_update_rx_stats(local->ap, hdr, rx_stats);
398#endif 403#endif
399 404
400#if WIRELESS_EXT > 15
401 if (ieee->iw_mode == IW_MODE_MONITOR) { 405 if (ieee->iw_mode == IW_MODE_MONITOR) {
402 ieee80211_monitor_rx(ieee, skb, rx_stats); 406 ieee80211_monitor_rx(ieee, skb, rx_stats);
403 stats->rx_packets++; 407 stats->rx_packets++;
404 stats->rx_bytes += skb->len; 408 stats->rx_bytes += skb->len;
405 return 1; 409 return 1;
406 } 410 }
407#endif
408 411
409 if (ieee->host_decrypt) { 412 if ((is_multicast_ether_addr(hdr->addr1) ||
413 is_broadcast_ether_addr(hdr->addr2)) ? ieee->host_mc_decrypt :
414 ieee->host_decrypt) {
410 int idx = 0; 415 int idx = 0;
411 if (skb->len >= hdrlen + 3) 416 if (skb->len >= hdrlen + 3)
412 idx = skb->data[hdrlen + 3] >> 6; 417 idx = skb->data[hdrlen + 3] >> 6;
@@ -531,6 +536,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
531 536
532 /* Nullfunc frames may have PS-bit set, so they must be passed to 537 /* Nullfunc frames may have PS-bit set, so they must be passed to
533 * hostap_handle_sta_rx() before being dropped here. */ 538 * hostap_handle_sta_rx() before being dropped here. */
539
540 stype &= ~IEEE80211_STYPE_QOS_DATA;
541
534 if (stype != IEEE80211_STYPE_DATA && 542 if (stype != IEEE80211_STYPE_DATA &&
535 stype != IEEE80211_STYPE_DATA_CFACK && 543 stype != IEEE80211_STYPE_DATA_CFACK &&
536 stype != IEEE80211_STYPE_DATA_CFPOLL && 544 stype != IEEE80211_STYPE_DATA_CFPOLL &&
@@ -549,7 +557,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
549 (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) 557 (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
550 goto rx_dropped; 558 goto rx_dropped;
551 559
552 hdr = (struct ieee80211_hdr *)skb->data; 560 hdr = (struct ieee80211_hdr_4addr *)skb->data;
553 561
554 /* skb: hdr + (possibly fragmented) plaintext payload */ 562 /* skb: hdr + (possibly fragmented) plaintext payload */
555 // PR: FIXME: hostap has additional conditions in the "if" below: 563 // PR: FIXME: hostap has additional conditions in the "if" below:
@@ -603,7 +611,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
603 /* this was the last fragment and the frame will be 611 /* this was the last fragment and the frame will be
604 * delivered, so remove skb from fragment cache */ 612 * delivered, so remove skb from fragment cache */
605 skb = frag_skb; 613 skb = frag_skb;
606 hdr = (struct ieee80211_hdr *)skb->data; 614 hdr = (struct ieee80211_hdr_4addr *)skb->data;
607 ieee80211_frag_cache_invalidate(ieee, hdr); 615 ieee80211_frag_cache_invalidate(ieee, hdr);
608 } 616 }
609 617
@@ -613,7 +621,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
613 ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) 621 ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
614 goto rx_dropped; 622 goto rx_dropped;
615 623
616 hdr = (struct ieee80211_hdr *)skb->data; 624 hdr = (struct ieee80211_hdr_4addr *)skb->data;
617 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) { 625 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
618 if ( /*ieee->ieee802_1x && */ 626 if ( /*ieee->ieee802_1x && */
619 ieee80211_is_eapol_frame(ieee, skb)) { 627 ieee80211_is_eapol_frame(ieee, skb)) {
@@ -755,69 +763,179 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
755 763
756#define MGMT_FRAME_FIXED_PART_LENGTH 0x24 764#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
757 765
758static inline int ieee80211_is_ofdm_rate(u8 rate) 766static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
767
768/*
769* Make ther structure we read from the beacon packet has
770* the right values
771*/
772static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
773 *info_element, int sub_type)
759{ 774{
760 switch (rate & ~IEEE80211_BASIC_RATE_MASK) { 775
761 case IEEE80211_OFDM_RATE_6MB: 776 if (info_element->qui_subtype != sub_type)
762 case IEEE80211_OFDM_RATE_9MB: 777 return -1;
763 case IEEE80211_OFDM_RATE_12MB: 778 if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
764 case IEEE80211_OFDM_RATE_18MB: 779 return -1;
765 case IEEE80211_OFDM_RATE_24MB: 780 if (info_element->qui_type != QOS_OUI_TYPE)
766 case IEEE80211_OFDM_RATE_36MB: 781 return -1;
767 case IEEE80211_OFDM_RATE_48MB: 782 if (info_element->version != QOS_VERSION_1)
768 case IEEE80211_OFDM_RATE_54MB: 783 return -1;
769 return 1; 784
770 }
771 return 0; 785 return 0;
772} 786}
773 787
774static inline int ieee80211_network_init(struct ieee80211_device *ieee, 788/*
775 struct ieee80211_probe_response 789 * Parse a QoS parameter element
776 *beacon, 790 */
777 struct ieee80211_network *network, 791static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
778 struct ieee80211_rx_stats *stats) 792 *element_param, struct ieee80211_info_element
793 *info_element)
779{ 794{
780#ifdef CONFIG_IEEE80211_DEBUG 795 int ret = 0;
781 char rates_str[64]; 796 u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
782 char *p;
783#endif
784 struct ieee80211_info_element *info_element;
785 u16 left;
786 u8 i;
787 797
788 /* Pull out fixed field data */ 798 if ((info_element == NULL) || (element_param == NULL))
789 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); 799 return -1;
790 network->capability = beacon->capability;
791 network->last_scanned = jiffies;
792 network->time_stamp[0] = beacon->time_stamp[0];
793 network->time_stamp[1] = beacon->time_stamp[1];
794 network->beacon_interval = beacon->beacon_interval;
795 /* Where to pull this? beacon->listen_interval; */
796 network->listen_interval = 0x0A;
797 network->rates_len = network->rates_ex_len = 0;
798 network->last_associate = 0;
799 network->ssid_len = 0;
800 network->flags = 0;
801 network->atim_window = 0;
802 800
803 if (stats->freq == IEEE80211_52GHZ_BAND) { 801 if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
804 /* for A band (No DS info) */ 802 memcpy(element_param->info_element.qui, info_element->data,
805 network->channel = stats->received_channel; 803 info_element->len);
804 element_param->info_element.elementID = info_element->id;
805 element_param->info_element.length = info_element->len;
806 } else 806 } else
807 network->flags |= NETWORK_HAS_CCK; 807 ret = -1;
808 if (ret == 0)
809 ret = ieee80211_verify_qos_info(&element_param->info_element,
810 QOS_OUI_PARAM_SUB_TYPE);
811 return ret;
812}
808 813
809 network->wpa_ie_len = 0; 814/*
810 network->rsn_ie_len = 0; 815 * Parse a QoS information element
816 */
817static int ieee80211_read_qos_info_element(struct
818 ieee80211_qos_information_element
819 *element_info, struct ieee80211_info_element
820 *info_element)
821{
822 int ret = 0;
823 u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
824
825 if (element_info == NULL)
826 return -1;
827 if (info_element == NULL)
828 return -1;
829
830 if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
831 memcpy(element_info->qui, info_element->data,
832 info_element->len);
833 element_info->elementID = info_element->id;
834 element_info->length = info_element->len;
835 } else
836 ret = -1;
837
838 if (ret == 0)
839 ret = ieee80211_verify_qos_info(element_info,
840 QOS_OUI_INFO_SUB_TYPE);
841 return ret;
842}
843
844/*
845 * Write QoS parameters from the ac parameters.
846 */
847static int ieee80211_qos_convert_ac_to_parameters(struct
848 ieee80211_qos_parameter_info
849 *param_elm, struct
850 ieee80211_qos_parameters
851 *qos_param)
852{
853 int rc = 0;
854 int i;
855 struct ieee80211_qos_ac_parameter *ac_params;
856 u32 txop;
857 u8 cw_min;
858 u8 cw_max;
859
860 for (i = 0; i < QOS_QUEUE_NUM; i++) {
861 ac_params = &(param_elm->ac_params_record[i]);
862
863 qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F;
864 qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
865
866 cw_min = ac_params->ecw_min_max & 0x0F;
867 qos_param->cw_min[i] = (u16) ((1 << cw_min) - 1);
868
869 cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
870 qos_param->cw_max[i] = (u16) ((1 << cw_max) - 1);
871
872 qos_param->flag[i] =
873 (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
874
875 txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
876 qos_param->tx_op_limit[i] = (u16) txop;
877 }
878 return rc;
879}
880
881/*
882 * we have a generic data element which it may contain QoS information or
883 * parameters element. check the information element length to decide
884 * which type to read
885 */
886static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
887 *info_element,
888 struct ieee80211_network *network)
889{
890 int rc = 0;
891 struct ieee80211_qos_parameters *qos_param = NULL;
892 struct ieee80211_qos_information_element qos_info_element;
893
894 rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
895
896 if (rc == 0) {
897 network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
898 network->flags |= NETWORK_HAS_QOS_INFORMATION;
899 } else {
900 struct ieee80211_qos_parameter_info param_element;
901
902 rc = ieee80211_read_qos_param_element(&param_element,
903 info_element);
904 if (rc == 0) {
905 qos_param = &(network->qos_data.parameters);
906 ieee80211_qos_convert_ac_to_parameters(&param_element,
907 qos_param);
908 network->flags |= NETWORK_HAS_QOS_PARAMETERS;
909 network->qos_data.param_count =
910 param_element.info_element.ac_info & 0x0F;
911 }
912 }
913
914 if (rc == 0) {
915 IEEE80211_DEBUG_QOS("QoS is supported\n");
916 network->qos_data.supported = 1;
917 }
918 return rc;
919}
920
921static int ieee80211_parse_info_param(struct ieee80211_info_element
922 *info_element, u16 length,
923 struct ieee80211_network *network)
924{
925 u8 i;
926#ifdef CONFIG_IEEE80211_DEBUG
927 char rates_str[64];
928 char *p;
929#endif
811 930
812 info_element = &beacon->info_element; 931 while (length >= sizeof(*info_element)) {
813 left = stats->len - ((void *)info_element - (void *)beacon); 932 if (sizeof(*info_element) + info_element->len > length) {
814 while (left >= sizeof(struct ieee80211_info_element_hdr)) { 933 IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
815 if (sizeof(struct ieee80211_info_element_hdr) + 934 "info_element->len + 2 > left : "
816 info_element->len > left) { 935 "info_element->len+2=%zd left=%d, id=%d.\n",
817 IEEE80211_DEBUG_SCAN 936 info_element->len +
818 ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n", 937 sizeof(*info_element),
819 info_element->len + 938 length, info_element->id);
820 sizeof(struct ieee80211_info_element), left);
821 return 1; 939 return 1;
822 } 940 }
823 941
@@ -837,7 +955,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
837 memset(network->ssid + network->ssid_len, 0, 955 memset(network->ssid + network->ssid_len, 0,
838 IW_ESSID_MAX_SIZE - network->ssid_len); 956 IW_ESSID_MAX_SIZE - network->ssid_len);
839 957
840 IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n", 958 IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
841 network->ssid, network->ssid_len); 959 network->ssid, network->ssid_len);
842 break; 960 break;
843 961
@@ -845,15 +963,14 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
845#ifdef CONFIG_IEEE80211_DEBUG 963#ifdef CONFIG_IEEE80211_DEBUG
846 p = rates_str; 964 p = rates_str;
847#endif 965#endif
848 network->rates_len = 966 network->rates_len = min(info_element->len,
849 min(info_element->len, MAX_RATES_LENGTH); 967 MAX_RATES_LENGTH);
850 for (i = 0; i < network->rates_len; i++) { 968 for (i = 0; i < network->rates_len; i++) {
851 network->rates[i] = info_element->data[i]; 969 network->rates[i] = info_element->data[i];
852#ifdef CONFIG_IEEE80211_DEBUG 970#ifdef CONFIG_IEEE80211_DEBUG
853 p += snprintf(p, 971 p += snprintf(p, sizeof(rates_str) -
854 sizeof(rates_str) - (p - 972 (p - rates_str), "%02X ",
855 rates_str), 973 network->rates[i]);
856 "%02X ", network->rates[i]);
857#endif 974#endif
858 if (ieee80211_is_ofdm_rate 975 if (ieee80211_is_ofdm_rate
859 (info_element->data[i])) { 976 (info_element->data[i])) {
@@ -865,7 +982,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
865 } 982 }
866 } 983 }
867 984
868 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n", 985 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
869 rates_str, network->rates_len); 986 rates_str, network->rates_len);
870 break; 987 break;
871 988
@@ -873,15 +990,14 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
873#ifdef CONFIG_IEEE80211_DEBUG 990#ifdef CONFIG_IEEE80211_DEBUG
874 p = rates_str; 991 p = rates_str;
875#endif 992#endif
876 network->rates_ex_len = 993 network->rates_ex_len = min(info_element->len,
877 min(info_element->len, MAX_RATES_EX_LENGTH); 994 MAX_RATES_EX_LENGTH);
878 for (i = 0; i < network->rates_ex_len; i++) { 995 for (i = 0; i < network->rates_ex_len; i++) {
879 network->rates_ex[i] = info_element->data[i]; 996 network->rates_ex[i] = info_element->data[i];
880#ifdef CONFIG_IEEE80211_DEBUG 997#ifdef CONFIG_IEEE80211_DEBUG
881 p += snprintf(p, 998 p += snprintf(p, sizeof(rates_str) -
882 sizeof(rates_str) - (p - 999 (p - rates_str), "%02X ",
883 rates_str), 1000 network->rates[i]);
884 "%02X ", network->rates[i]);
885#endif 1001#endif
886 if (ieee80211_is_ofdm_rate 1002 if (ieee80211_is_ofdm_rate
887 (info_element->data[i])) { 1003 (info_element->data[i])) {
@@ -893,40 +1009,51 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
893 } 1009 }
894 } 1010 }
895 1011
896 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n", 1012 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
897 rates_str, network->rates_ex_len); 1013 rates_str, network->rates_ex_len);
898 break; 1014 break;
899 1015
900 case MFIE_TYPE_DS_SET: 1016 case MFIE_TYPE_DS_SET:
901 IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n", 1017 IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
902 info_element->data[0]); 1018 info_element->data[0]);
903 if (stats->freq == IEEE80211_24GHZ_BAND) 1019 network->channel = info_element->data[0];
904 network->channel = info_element->data[0];
905 break; 1020 break;
906 1021
907 case MFIE_TYPE_FH_SET: 1022 case MFIE_TYPE_FH_SET:
908 IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n"); 1023 IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
909 break; 1024 break;
910 1025
911 case MFIE_TYPE_CF_SET: 1026 case MFIE_TYPE_CF_SET:
912 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n"); 1027 IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
913 break; 1028 break;
914 1029
915 case MFIE_TYPE_TIM: 1030 case MFIE_TYPE_TIM:
916 IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n"); 1031 IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n");
1032 break;
1033
1034 case MFIE_TYPE_ERP_INFO:
1035 network->erp_value = info_element->data[0];
1036 IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
1037 network->erp_value);
917 break; 1038 break;
918 1039
919 case MFIE_TYPE_IBSS_SET: 1040 case MFIE_TYPE_IBSS_SET:
920 IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n"); 1041 network->atim_window = info_element->data[0];
1042 IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
1043 network->atim_window);
921 break; 1044 break;
922 1045
923 case MFIE_TYPE_CHALLENGE: 1046 case MFIE_TYPE_CHALLENGE:
924 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n"); 1047 IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
925 break; 1048 break;
926 1049
927 case MFIE_TYPE_GENERIC: 1050 case MFIE_TYPE_GENERIC:
928 IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", 1051 IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
929 info_element->len); 1052 info_element->len);
1053 if (!ieee80211_parse_qos_info_param_IE(info_element,
1054 network))
1055 break;
1056
930 if (info_element->len >= 4 && 1057 if (info_element->len >= 4 &&
931 info_element->data[0] == 0x00 && 1058 info_element->data[0] == 0x00 &&
932 info_element->data[1] == 0x50 && 1059 info_element->data[1] == 0x50 &&
@@ -940,7 +1067,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
940 break; 1067 break;
941 1068
942 case MFIE_TYPE_RSN: 1069 case MFIE_TYPE_RSN:
943 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n", 1070 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
944 info_element->len); 1071 info_element->len);
945 network->rsn_ie_len = min(info_element->len + 2, 1072 network->rsn_ie_len = min(info_element->len + 2,
946 MAX_WPA_IE_LEN); 1073 MAX_WPA_IE_LEN);
@@ -948,18 +1075,127 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
948 network->rsn_ie_len); 1075 network->rsn_ie_len);
949 break; 1076 break;
950 1077
1078 case MFIE_TYPE_QOS_PARAMETER:
1079 printk(KERN_ERR
1080 "QoS Error need to parse QOS_PARAMETER IE\n");
1081 break;
1082
951 default: 1083 default:
952 IEEE80211_DEBUG_SCAN("unsupported IE %d\n", 1084 IEEE80211_DEBUG_MGMT("unsupported IE %d\n",
953 info_element->id); 1085 info_element->id);
954 break; 1086 break;
955 } 1087 }
956 1088
957 left -= sizeof(struct ieee80211_info_element_hdr) + 1089 length -= sizeof(*info_element) + info_element->len;
958 info_element->len; 1090 info_element =
959 info_element = (struct ieee80211_info_element *) 1091 (struct ieee80211_info_element *)&info_element->
960 &info_element->data[info_element->len]; 1092 data[info_element->len];
1093 }
1094
1095 return 0;
1096}
1097
1098static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
1099 *frame, struct ieee80211_rx_stats *stats)
1100{
1101 struct ieee80211_network network_resp;
1102 struct ieee80211_network *network = &network_resp;
1103 struct net_device *dev = ieee->dev;
1104
1105 network->flags = 0;
1106 network->qos_data.active = 0;
1107 network->qos_data.supported = 0;
1108 network->qos_data.param_count = 0;
1109 network->qos_data.old_param_count = 0;
1110
1111 //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
1112 network->atim_window = le16_to_cpu(frame->aid);
1113 network->listen_interval = le16_to_cpu(frame->status);
1114 memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
1115 network->capability = le16_to_cpu(frame->capability);
1116 network->last_scanned = jiffies;
1117 network->rates_len = network->rates_ex_len = 0;
1118 network->last_associate = 0;
1119 network->ssid_len = 0;
1120 network->erp_value =
1121 (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
1122
1123 if (stats->freq == IEEE80211_52GHZ_BAND) {
1124 /* for A band (No DS info) */
1125 network->channel = stats->received_channel;
1126 } else
1127 network->flags |= NETWORK_HAS_CCK;
1128
1129 network->wpa_ie_len = 0;
1130 network->rsn_ie_len = 0;
1131
1132 if (ieee80211_parse_info_param
1133 (frame->info_element, stats->len - sizeof(*frame), network))
1134 return 1;
1135
1136 network->mode = 0;
1137 if (stats->freq == IEEE80211_52GHZ_BAND)
1138 network->mode = IEEE_A;
1139 else {
1140 if (network->flags & NETWORK_HAS_OFDM)
1141 network->mode |= IEEE_G;
1142 if (network->flags & NETWORK_HAS_CCK)
1143 network->mode |= IEEE_B;
961 } 1144 }
962 1145
1146 if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
1147 network->flags |= NETWORK_EMPTY_ESSID;
1148
1149 memcpy(&network->stats, stats, sizeof(network->stats));
1150
1151 if (ieee->handle_assoc_response != NULL)
1152 ieee->handle_assoc_response(dev, frame, network);
1153
1154 return 0;
1155}
1156
1157/***************************************************/
1158
1159static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
1160 *beacon,
1161 struct ieee80211_network *network,
1162 struct ieee80211_rx_stats *stats)
1163{
1164 network->qos_data.active = 0;
1165 network->qos_data.supported = 0;
1166 network->qos_data.param_count = 0;
1167 network->qos_data.old_param_count = 0;
1168
1169 /* Pull out fixed field data */
1170 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
1171 network->capability = le16_to_cpu(beacon->capability);
1172 network->last_scanned = jiffies;
1173 network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
1174 network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
1175 network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
1176 /* Where to pull this? beacon->listen_interval; */
1177 network->listen_interval = 0x0A;
1178 network->rates_len = network->rates_ex_len = 0;
1179 network->last_associate = 0;
1180 network->ssid_len = 0;
1181 network->flags = 0;
1182 network->atim_window = 0;
1183 network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
1184 0x3 : 0x0;
1185
1186 if (stats->freq == IEEE80211_52GHZ_BAND) {
1187 /* for A band (No DS info) */
1188 network->channel = stats->received_channel;
1189 } else
1190 network->flags |= NETWORK_HAS_CCK;
1191
1192 network->wpa_ie_len = 0;
1193 network->rsn_ie_len = 0;
1194
1195 if (ieee80211_parse_info_param
1196 (beacon->info_element, stats->len - sizeof(*beacon), network))
1197 return 1;
1198
963 network->mode = 0; 1199 network->mode = 0;
964 if (stats->freq == IEEE80211_52GHZ_BAND) 1200 if (stats->freq == IEEE80211_52GHZ_BAND)
965 network->mode = IEEE_A; 1201 network->mode = IEEE_A;
@@ -1002,6 +1238,9 @@ static inline int is_same_network(struct ieee80211_network *src,
1002static inline void update_network(struct ieee80211_network *dst, 1238static inline void update_network(struct ieee80211_network *dst,
1003 struct ieee80211_network *src) 1239 struct ieee80211_network *src)
1004{ 1240{
1241 int qos_active;
1242 u8 old_param;
1243
1005 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); 1244 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
1006 dst->capability = src->capability; 1245 dst->capability = src->capability;
1007 memcpy(dst->rates, src->rates, src->rates_len); 1246 memcpy(dst->rates, src->rates, src->rates_len);
@@ -1017,6 +1256,7 @@ static inline void update_network(struct ieee80211_network *dst,
1017 dst->beacon_interval = src->beacon_interval; 1256 dst->beacon_interval = src->beacon_interval;
1018 dst->listen_interval = src->listen_interval; 1257 dst->listen_interval = src->listen_interval;
1019 dst->atim_window = src->atim_window; 1258 dst->atim_window = src->atim_window;
1259 dst->erp_value = src->erp_value;
1020 1260
1021 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); 1261 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
1022 dst->wpa_ie_len = src->wpa_ie_len; 1262 dst->wpa_ie_len = src->wpa_ie_len;
@@ -1024,22 +1264,48 @@ static inline void update_network(struct ieee80211_network *dst,
1024 dst->rsn_ie_len = src->rsn_ie_len; 1264 dst->rsn_ie_len = src->rsn_ie_len;
1025 1265
1026 dst->last_scanned = jiffies; 1266 dst->last_scanned = jiffies;
1267 qos_active = src->qos_data.active;
1268 old_param = dst->qos_data.old_param_count;
1269 if (dst->flags & NETWORK_HAS_QOS_MASK)
1270 memcpy(&dst->qos_data, &src->qos_data,
1271 sizeof(struct ieee80211_qos_data));
1272 else {
1273 dst->qos_data.supported = src->qos_data.supported;
1274 dst->qos_data.param_count = src->qos_data.param_count;
1275 }
1276
1277 if (dst->qos_data.supported == 1) {
1278 if (dst->ssid_len)
1279 IEEE80211_DEBUG_QOS
1280 ("QoS the network %s is QoS supported\n",
1281 dst->ssid);
1282 else
1283 IEEE80211_DEBUG_QOS
1284 ("QoS the network is QoS supported\n");
1285 }
1286 dst->qos_data.active = qos_active;
1287 dst->qos_data.old_param_count = old_param;
1288
1027 /* dst->last_associate is not overwritten */ 1289 /* dst->last_associate is not overwritten */
1028} 1290}
1029 1291
1292static inline int is_beacon(int fc)
1293{
1294 return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
1295}
1296
1030static inline void ieee80211_process_probe_response(struct ieee80211_device 1297static inline void ieee80211_process_probe_response(struct ieee80211_device
1031 *ieee, 1298 *ieee, struct
1032 struct
1033 ieee80211_probe_response 1299 ieee80211_probe_response
1034 *beacon, 1300 *beacon, struct ieee80211_rx_stats
1035 struct ieee80211_rx_stats
1036 *stats) 1301 *stats)
1037{ 1302{
1303 struct net_device *dev = ieee->dev;
1038 struct ieee80211_network network; 1304 struct ieee80211_network network;
1039 struct ieee80211_network *target; 1305 struct ieee80211_network *target;
1040 struct ieee80211_network *oldest = NULL; 1306 struct ieee80211_network *oldest = NULL;
1041#ifdef CONFIG_IEEE80211_DEBUG 1307#ifdef CONFIG_IEEE80211_DEBUG
1042 struct ieee80211_info_element *info_element = &beacon->info_element; 1308 struct ieee80211_info_element *info_element = beacon->info_element;
1043#endif 1309#endif
1044 unsigned long flags; 1310 unsigned long flags;
1045 1311
@@ -1070,10 +1336,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
1070 escape_essid(info_element->data, 1336 escape_essid(info_element->data,
1071 info_element->len), 1337 info_element->len),
1072 MAC_ARG(beacon->header.addr3), 1338 MAC_ARG(beacon->header.addr3),
1073 WLAN_FC_GET_STYPE(beacon->header. 1339 is_beacon(le16_to_cpu
1074 frame_ctl) == 1340 (beacon->header.
1075 IEEE80211_STYPE_PROBE_RESP ? 1341 frame_ctl)) ?
1076 "PROBE RESPONSE" : "BEACON"); 1342 "BEACON" : "PROBE RESPONSE");
1077 return; 1343 return;
1078 } 1344 }
1079 1345
@@ -1122,10 +1388,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
1122 escape_essid(network.ssid, 1388 escape_essid(network.ssid,
1123 network.ssid_len), 1389 network.ssid_len),
1124 MAC_ARG(network.bssid), 1390 MAC_ARG(network.bssid),
1125 WLAN_FC_GET_STYPE(beacon->header. 1391 is_beacon(le16_to_cpu
1126 frame_ctl) == 1392 (beacon->header.
1127 IEEE80211_STYPE_PROBE_RESP ? 1393 frame_ctl)) ?
1128 "PROBE RESPONSE" : "BEACON"); 1394 "BEACON" : "PROBE RESPONSE");
1129#endif 1395#endif
1130 memcpy(target, &network, sizeof(*target)); 1396 memcpy(target, &network, sizeof(*target));
1131 list_add_tail(&target->list, &ieee->network_list); 1397 list_add_tail(&target->list, &ieee->network_list);
@@ -1134,34 +1400,60 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
1134 escape_essid(target->ssid, 1400 escape_essid(target->ssid,
1135 target->ssid_len), 1401 target->ssid_len),
1136 MAC_ARG(target->bssid), 1402 MAC_ARG(target->bssid),
1137 WLAN_FC_GET_STYPE(beacon->header. 1403 is_beacon(le16_to_cpu
1138 frame_ctl) == 1404 (beacon->header.
1139 IEEE80211_STYPE_PROBE_RESP ? 1405 frame_ctl)) ?
1140 "PROBE RESPONSE" : "BEACON"); 1406 "BEACON" : "PROBE RESPONSE");
1141 update_network(target, &network); 1407 update_network(target, &network);
1142 } 1408 }
1143 1409
1144 spin_unlock_irqrestore(&ieee->lock, flags); 1410 spin_unlock_irqrestore(&ieee->lock, flags);
1411
1412 if (is_beacon(le16_to_cpu(beacon->header.frame_ctl))) {
1413 if (ieee->handle_beacon != NULL)
1414 ieee->handle_beacon(dev, beacon, &network);
1415 } else {
1416 if (ieee->handle_probe_response != NULL)
1417 ieee->handle_probe_response(dev, beacon, &network);
1418 }
1145} 1419}
1146 1420
1147void ieee80211_rx_mgt(struct ieee80211_device *ieee, 1421void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1148 struct ieee80211_hdr *header, 1422 struct ieee80211_hdr_4addr *header,
1149 struct ieee80211_rx_stats *stats) 1423 struct ieee80211_rx_stats *stats)
1150{ 1424{
1151 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { 1425 switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
1152 case IEEE80211_STYPE_ASSOC_RESP: 1426 case IEEE80211_STYPE_ASSOC_RESP:
1153 IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n", 1427 IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
1154 WLAN_FC_GET_STYPE(header->frame_ctl)); 1428 WLAN_FC_GET_STYPE(le16_to_cpu
1429 (header->frame_ctl)));
1430 ieee80211_handle_assoc_resp(ieee,
1431 (struct ieee80211_assoc_response *)
1432 header, stats);
1155 break; 1433 break;
1156 1434
1157 case IEEE80211_STYPE_REASSOC_RESP: 1435 case IEEE80211_STYPE_REASSOC_RESP:
1158 IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n", 1436 IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
1159 WLAN_FC_GET_STYPE(header->frame_ctl)); 1437 WLAN_FC_GET_STYPE(le16_to_cpu
1438 (header->frame_ctl)));
1439 break;
1440
1441 case IEEE80211_STYPE_PROBE_REQ:
1442 IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
1443 WLAN_FC_GET_STYPE(le16_to_cpu
1444 (header->frame_ctl)));
1445
1446 if (ieee->handle_probe_request != NULL)
1447 ieee->handle_probe_request(ieee->dev,
1448 (struct
1449 ieee80211_probe_request *)
1450 header, stats);
1160 break; 1451 break;
1161 1452
1162 case IEEE80211_STYPE_PROBE_RESP: 1453 case IEEE80211_STYPE_PROBE_RESP:
1163 IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n", 1454 IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
1164 WLAN_FC_GET_STYPE(header->frame_ctl)); 1455 WLAN_FC_GET_STYPE(le16_to_cpu
1456 (header->frame_ctl)));
1165 IEEE80211_DEBUG_SCAN("Probe response\n"); 1457 IEEE80211_DEBUG_SCAN("Probe response\n");
1166 ieee80211_process_probe_response(ieee, 1458 ieee80211_process_probe_response(ieee,
1167 (struct 1459 (struct
@@ -1171,20 +1463,46 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1171 1463
1172 case IEEE80211_STYPE_BEACON: 1464 case IEEE80211_STYPE_BEACON:
1173 IEEE80211_DEBUG_MGMT("received BEACON (%d)\n", 1465 IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
1174 WLAN_FC_GET_STYPE(header->frame_ctl)); 1466 WLAN_FC_GET_STYPE(le16_to_cpu
1467 (header->frame_ctl)));
1175 IEEE80211_DEBUG_SCAN("Beacon\n"); 1468 IEEE80211_DEBUG_SCAN("Beacon\n");
1176 ieee80211_process_probe_response(ieee, 1469 ieee80211_process_probe_response(ieee,
1177 (struct 1470 (struct
1178 ieee80211_probe_response *) 1471 ieee80211_probe_response *)
1179 header, stats); 1472 header, stats);
1180 break; 1473 break;
1474 case IEEE80211_STYPE_AUTH:
1181 1475
1476 IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
1477 WLAN_FC_GET_STYPE(le16_to_cpu
1478 (header->frame_ctl)));
1479
1480 if (ieee->handle_auth != NULL)
1481 ieee->handle_auth(ieee->dev,
1482 (struct ieee80211_auth *)header);
1483 break;
1484
1485 case IEEE80211_STYPE_DISASSOC:
1486 if (ieee->handle_disassoc != NULL)
1487 ieee->handle_disassoc(ieee->dev,
1488 (struct ieee80211_disassoc *)
1489 header);
1490 break;
1491
1492 case IEEE80211_STYPE_DEAUTH:
1493 printk("DEAUTH from AP\n");
1494 if (ieee->handle_deauth != NULL)
1495 ieee->handle_deauth(ieee->dev, (struct ieee80211_auth *)
1496 header);
1497 break;
1182 default: 1498 default:
1183 IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n", 1499 IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
1184 WLAN_FC_GET_STYPE(header->frame_ctl)); 1500 WLAN_FC_GET_STYPE(le16_to_cpu
1501 (header->frame_ctl)));
1185 IEEE80211_WARNING("%s: Unknown management packet: %d\n", 1502 IEEE80211_WARNING("%s: Unknown management packet: %d\n",
1186 ieee->dev->name, 1503 ieee->dev->name,
1187 WLAN_FC_GET_STYPE(header->frame_ctl)); 1504 WLAN_FC_GET_STYPE(le16_to_cpu
1505 (header->frame_ctl)));
1188 break; 1506 break;
1189 } 1507 }
1190} 1508}
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index eed07bbbe6b6..95ccbadbf55b 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -128,7 +128,7 @@ payload of each frame is reduced to 492 bytes.
128static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; 128static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
129static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; 129static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
130 130
131static inline int ieee80211_put_snap(u8 * data, u16 h_proto) 131static inline int ieee80211_copy_snap(u8 * data, u16 h_proto)
132{ 132{
133 struct ieee80211_snap_hdr *snap; 133 struct ieee80211_snap_hdr *snap;
134 u8 *oui; 134 u8 *oui;
@@ -157,31 +157,14 @@ static inline int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
157 struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx]; 157 struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
158 int res; 158 int res;
159 159
160#ifdef CONFIG_IEEE80211_CRYPT_TKIP 160 if (crypt == NULL)
161 struct ieee80211_hdr *header;
162
163 if (ieee->tkip_countermeasures &&
164 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
165 header = (struct ieee80211_hdr *)frag->data;
166 if (net_ratelimit()) {
167 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
168 "TX packet to " MAC_FMT "\n",
169 ieee->dev->name, MAC_ARG(header->addr1));
170 }
171 return -1; 161 return -1;
172 } 162
173#endif
174 /* To encrypt, frame format is: 163 /* To encrypt, frame format is:
175 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */ 164 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
176
177 // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
178 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
179 * call both MSDU and MPDU encryption functions from here. */
180 atomic_inc(&crypt->refcnt); 165 atomic_inc(&crypt->refcnt);
181 res = 0; 166 res = 0;
182 if (crypt->ops->encrypt_msdu) 167 if (crypt->ops && crypt->ops->encrypt_mpdu)
183 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
184 if (res == 0 && crypt->ops->encrypt_mpdu)
185 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); 168 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
186 169
187 atomic_dec(&crypt->refcnt); 170 atomic_dec(&crypt->refcnt);
@@ -207,7 +190,7 @@ void ieee80211_txb_free(struct ieee80211_txb *txb)
207} 190}
208 191
209static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, 192static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
210 gfp_t gfp_mask) 193 int headroom, gfp_t gfp_mask)
211{ 194{
212 struct ieee80211_txb *txb; 195 struct ieee80211_txb *txb;
213 int i; 196 int i;
@@ -221,11 +204,13 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
221 txb->frag_size = txb_size; 204 txb->frag_size = txb_size;
222 205
223 for (i = 0; i < nr_frags; i++) { 206 for (i = 0; i < nr_frags; i++) {
224 txb->fragments[i] = dev_alloc_skb(txb_size); 207 txb->fragments[i] = __dev_alloc_skb(txb_size + headroom,
208 gfp_mask);
225 if (unlikely(!txb->fragments[i])) { 209 if (unlikely(!txb->fragments[i])) {
226 i--; 210 i--;
227 break; 211 break;
228 } 212 }
213 skb_reserve(txb->fragments[i], headroom);
229 } 214 }
230 if (unlikely(i != nr_frags)) { 215 if (unlikely(i != nr_frags)) {
231 while (i >= 0) 216 while (i >= 0)
@@ -236,25 +221,31 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
236 return txb; 221 return txb;
237} 222}
238 223
239/* SKBs are added to the ieee->tx_queue. */ 224/* Incoming skb is converted to a txb which consists of
225 * a block of 802.11 fragment packets (stored as skbs) */
240int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) 226int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
241{ 227{
242 struct ieee80211_device *ieee = netdev_priv(dev); 228 struct ieee80211_device *ieee = netdev_priv(dev);
243 struct ieee80211_txb *txb = NULL; 229 struct ieee80211_txb *txb = NULL;
244 struct ieee80211_hdr *frag_hdr; 230 struct ieee80211_hdr_3addr *frag_hdr;
245 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; 231 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
232 rts_required;
246 unsigned long flags; 233 unsigned long flags;
247 struct net_device_stats *stats = &ieee->stats; 234 struct net_device_stats *stats = &ieee->stats;
248 int ether_type, encrypt; 235 int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
249 int bytes, fc, hdr_len; 236 int bytes, fc, hdr_len;
250 struct sk_buff *skb_frag; 237 struct sk_buff *skb_frag;
251 struct ieee80211_hdr header = { /* Ensure zero initialized */ 238 struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */
252 .duration_id = 0, 239 .duration_id = 0,
253 .seq_ctl = 0 240 .seq_ctl = 0
254 }; 241 };
255 u8 dest[ETH_ALEN], src[ETH_ALEN]; 242 u8 dest[ETH_ALEN], src[ETH_ALEN];
256
257 struct ieee80211_crypt_data *crypt; 243 struct ieee80211_crypt_data *crypt;
244 int priority = skb->priority;
245 int snapped = 0;
246
247 if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))
248 return NETDEV_TX_BUSY;
258 249
259 spin_lock_irqsave(&ieee->lock, flags); 250 spin_lock_irqsave(&ieee->lock, flags);
260 251
@@ -276,7 +267,11 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
276 crypt = ieee->crypt[ieee->tx_keyidx]; 267 crypt = ieee->crypt[ieee->tx_keyidx];
277 268
278 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && 269 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
279 ieee->host_encrypt && crypt && crypt->ops; 270 ieee->sec.encrypt;
271
272 host_encrypt = ieee->host_encrypt && encrypt && crypt;
273 host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
274 host_build_iv = ieee->host_build_iv && encrypt && crypt;
280 275
281 if (!encrypt && ieee->ieee802_1x && 276 if (!encrypt && ieee->ieee802_1x &&
282 ieee->drop_unencrypted && ether_type != ETH_P_PAE) { 277 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
@@ -285,8 +280,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
285 } 280 }
286 281
287 /* Save source and destination addresses */ 282 /* Save source and destination addresses */
288 memcpy(&dest, skb->data, ETH_ALEN); 283 memcpy(dest, skb->data, ETH_ALEN);
289 memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN); 284 memcpy(src, skb->data + ETH_ALEN, ETH_ALEN);
290 285
291 /* Advance the SKB to the start of the payload */ 286 /* Advance the SKB to the start of the payload */
292 skb_pull(skb, sizeof(struct ethhdr)); 287 skb_pull(skb, sizeof(struct ethhdr));
@@ -294,7 +289,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
294 /* Determine total amount of storage required for TXB packets */ 289 /* Determine total amount of storage required for TXB packets */
295 bytes = skb->len + SNAP_SIZE + sizeof(u16); 290 bytes = skb->len + SNAP_SIZE + sizeof(u16);
296 291
297 if (encrypt) 292 if (host_encrypt)
298 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | 293 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
299 IEEE80211_FCTL_PROTECTED; 294 IEEE80211_FCTL_PROTECTED;
300 else 295 else
@@ -302,70 +297,144 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
302 297
303 if (ieee->iw_mode == IW_MODE_INFRA) { 298 if (ieee->iw_mode == IW_MODE_INFRA) {
304 fc |= IEEE80211_FCTL_TODS; 299 fc |= IEEE80211_FCTL_TODS;
305 /* To DS: Addr1 = BSSID, Addr2 = SA, 300 /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
306 Addr3 = DA */ 301 memcpy(header.addr1, ieee->bssid, ETH_ALEN);
307 memcpy(&header.addr1, ieee->bssid, ETH_ALEN); 302 memcpy(header.addr2, src, ETH_ALEN);
308 memcpy(&header.addr2, &src, ETH_ALEN); 303 memcpy(header.addr3, dest, ETH_ALEN);
309 memcpy(&header.addr3, &dest, ETH_ALEN);
310 } else if (ieee->iw_mode == IW_MODE_ADHOC) { 304 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
311 /* not From/To DS: Addr1 = DA, Addr2 = SA, 305 /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
312 Addr3 = BSSID */ 306 memcpy(header.addr1, dest, ETH_ALEN);
313 memcpy(&header.addr1, dest, ETH_ALEN); 307 memcpy(header.addr2, src, ETH_ALEN);
314 memcpy(&header.addr2, src, ETH_ALEN); 308 memcpy(header.addr3, ieee->bssid, ETH_ALEN);
315 memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
316 } 309 }
317 header.frame_ctl = cpu_to_le16(fc); 310 header.frame_ctl = cpu_to_le16(fc);
318 hdr_len = IEEE80211_3ADDR_LEN; 311 hdr_len = IEEE80211_3ADDR_LEN;
319 312
320 /* Determine fragmentation size based on destination (multicast 313 /* Encrypt msdu first on the whole data packet. */
321 * and broadcast are not fragmented) */ 314 if ((host_encrypt || host_encrypt_msdu) &&
322 if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest)) 315 crypt && crypt->ops && crypt->ops->encrypt_msdu) {
323 frag_size = MAX_FRAG_THRESHOLD; 316 int res = 0;
324 else 317 int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
325 frag_size = ieee->fts; 318 crypt->ops->extra_msdu_postfix_len;
319 struct sk_buff *skb_new = dev_alloc_skb(len);
320
321 if (unlikely(!skb_new))
322 goto failed;
323
324 skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
325 memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
326 snapped = 1;
327 ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
328 ether_type);
329 memcpy(skb_put(skb_new, skb->len), skb->data, skb->len);
330 res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
331 if (res < 0) {
332 IEEE80211_ERROR("msdu encryption failed\n");
333 dev_kfree_skb_any(skb_new);
334 goto failed;
335 }
336 dev_kfree_skb_any(skb);
337 skb = skb_new;
338 bytes += crypt->ops->extra_msdu_prefix_len +
339 crypt->ops->extra_msdu_postfix_len;
340 skb_pull(skb, hdr_len);
341 }
326 342
327 /* Determine amount of payload per fragment. Regardless of if 343 if (host_encrypt || ieee->host_open_frag) {
328 * this stack is providing the full 802.11 header, one will 344 /* Determine fragmentation size based on destination (multicast
329 * eventually be affixed to this fragment -- so we must account for 345 * and broadcast are not fragmented) */
330 * it when determining the amount of payload space. */ 346 if (is_multicast_ether_addr(dest) ||
331 bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN; 347 is_broadcast_ether_addr(dest))
332 if (ieee->config & 348 frag_size = MAX_FRAG_THRESHOLD;
333 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) 349 else
334 bytes_per_frag -= IEEE80211_FCS_LEN; 350 frag_size = ieee->fts;
335 351
336 /* Each fragment may need to have room for encryptiong pre/postfix */ 352 /* Determine amount of payload per fragment. Regardless of if
337 if (encrypt) 353 * this stack is providing the full 802.11 header, one will
338 bytes_per_frag -= crypt->ops->extra_prefix_len + 354 * eventually be affixed to this fragment -- so we must account
339 crypt->ops->extra_postfix_len; 355 * for it when determining the amount of payload space. */
340 356 bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
341 /* Number of fragments is the total bytes_per_frag / 357 if (ieee->config &
342 * payload_per_fragment */ 358 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
343 nr_frags = bytes / bytes_per_frag; 359 bytes_per_frag -= IEEE80211_FCS_LEN;
344 bytes_last_frag = bytes % bytes_per_frag; 360
345 if (bytes_last_frag) 361 /* Each fragment may need to have room for encryptiong
362 * pre/postfix */
363 if (host_encrypt)
364 bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
365 crypt->ops->extra_mpdu_postfix_len;
366
367 /* Number of fragments is the total
368 * bytes_per_frag / payload_per_fragment */
369 nr_frags = bytes / bytes_per_frag;
370 bytes_last_frag = bytes % bytes_per_frag;
371 if (bytes_last_frag)
372 nr_frags++;
373 else
374 bytes_last_frag = bytes_per_frag;
375 } else {
376 nr_frags = 1;
377 bytes_per_frag = bytes_last_frag = bytes;
378 frag_size = bytes + IEEE80211_3ADDR_LEN;
379 }
380
381 rts_required = (frag_size > ieee->rts
382 && ieee->config & CFG_IEEE80211_RTS);
383 if (rts_required)
346 nr_frags++; 384 nr_frags++;
347 else
348 bytes_last_frag = bytes_per_frag;
349 385
350 /* When we allocate the TXB we allocate enough space for the reserve 386 /* When we allocate the TXB we allocate enough space for the reserve
351 * and full fragment bytes (bytes_per_frag doesn't include prefix, 387 * and full fragment bytes (bytes_per_frag doesn't include prefix,
352 * postfix, header, FCS, etc.) */ 388 * postfix, header, FCS, etc.) */
353 txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC); 389 txb = ieee80211_alloc_txb(nr_frags, frag_size,
390 ieee->tx_headroom, GFP_ATOMIC);
354 if (unlikely(!txb)) { 391 if (unlikely(!txb)) {
355 printk(KERN_WARNING "%s: Could not allocate TXB\n", 392 printk(KERN_WARNING "%s: Could not allocate TXB\n",
356 ieee->dev->name); 393 ieee->dev->name);
357 goto failed; 394 goto failed;
358 } 395 }
359 txb->encrypted = encrypt; 396 txb->encrypted = encrypt;
360 txb->payload_size = bytes; 397 if (host_encrypt)
398 txb->payload_size = frag_size * (nr_frags - 1) +
399 bytes_last_frag;
400 else
401 txb->payload_size = bytes;
402
403 if (rts_required) {
404 skb_frag = txb->fragments[0];
405 frag_hdr =
406 (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
407
408 /*
409 * Set header frame_ctl to the RTS.
410 */
411 header.frame_ctl =
412 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
413 memcpy(frag_hdr, &header, hdr_len);
361 414
362 for (i = 0; i < nr_frags; i++) { 415 /*
416 * Restore header frame_ctl to the original data setting.
417 */
418 header.frame_ctl = cpu_to_le16(fc);
419
420 if (ieee->config &
421 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
422 skb_put(skb_frag, 4);
423
424 txb->rts_included = 1;
425 i = 1;
426 } else
427 i = 0;
428
429 for (; i < nr_frags; i++) {
363 skb_frag = txb->fragments[i]; 430 skb_frag = txb->fragments[i];
364 431
365 if (encrypt) 432 if (host_encrypt || host_build_iv)
366 skb_reserve(skb_frag, crypt->ops->extra_prefix_len); 433 skb_reserve(skb_frag,
434 crypt->ops->extra_mpdu_prefix_len);
367 435
368 frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len); 436 frag_hdr =
437 (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
369 memcpy(frag_hdr, &header, hdr_len); 438 memcpy(frag_hdr, &header, hdr_len);
370 439
371 /* If this is not the last fragment, then add the MOREFRAGS 440 /* If this is not the last fragment, then add the MOREFRAGS
@@ -379,11 +448,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
379 bytes = bytes_last_frag; 448 bytes = bytes_last_frag;
380 } 449 }
381 450
382 /* Put a SNAP header on the first fragment */ 451 if (i == 0 && !snapped) {
383 if (i == 0) { 452 ieee80211_copy_snap(skb_put
384 ieee80211_put_snap(skb_put 453 (skb_frag, SNAP_SIZE + sizeof(u16)),
385 (skb_frag, SNAP_SIZE + sizeof(u16)), 454 ether_type);
386 ether_type);
387 bytes -= SNAP_SIZE + sizeof(u16); 455 bytes -= SNAP_SIZE + sizeof(u16);
388 } 456 }
389 457
@@ -394,8 +462,19 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
394 462
395 /* Encryption routine will move the header forward in order 463 /* Encryption routine will move the header forward in order
396 * to insert the IV between the header and the payload */ 464 * to insert the IV between the header and the payload */
397 if (encrypt) 465 if (host_encrypt)
398 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); 466 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
467 else if (host_build_iv) {
468 struct ieee80211_crypt_data *crypt;
469
470 crypt = ieee->crypt[ieee->tx_keyidx];
471 atomic_inc(&crypt->refcnt);
472 if (crypt->ops->build_iv)
473 crypt->ops->build_iv(skb_frag, hdr_len,
474 crypt->priv);
475 atomic_dec(&crypt->refcnt);
476 }
477
399 if (ieee->config & 478 if (ieee->config &
400 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) 479 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
401 skb_put(skb_frag, 4); 480 skb_put(skb_frag, 4);
@@ -407,11 +486,20 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
407 dev_kfree_skb_any(skb); 486 dev_kfree_skb_any(skb);
408 487
409 if (txb) { 488 if (txb) {
410 if ((*ieee->hard_start_xmit) (txb, dev) == 0) { 489 int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
490 if (ret == 0) {
411 stats->tx_packets++; 491 stats->tx_packets++;
412 stats->tx_bytes += txb->payload_size; 492 stats->tx_bytes += txb->payload_size;
413 return 0; 493 return 0;
414 } 494 }
495
496 if (ret == NETDEV_TX_BUSY) {
497 printk(KERN_ERR "%s: NETDEV_TX_BUSY returned; "
498 "driver should report queue full via "
499 "ieee_device->is_queue_full.\n",
500 ieee->dev->name);
501 }
502
415 ieee80211_txb_free(txb); 503 ieee80211_txb_free(txb);
416 } 504 }
417 505
@@ -422,7 +510,72 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
422 netif_stop_queue(dev); 510 netif_stop_queue(dev);
423 stats->tx_errors++; 511 stats->tx_errors++;
424 return 1; 512 return 1;
513}
514
515/* Incoming 802.11 strucure is converted to a TXB
516 * a block of 802.11 fragment packets (stored as skbs) */
517int ieee80211_tx_frame(struct ieee80211_device *ieee,
518 struct ieee80211_hdr *frame, int len)
519{
520 struct ieee80211_txb *txb = NULL;
521 unsigned long flags;
522 struct net_device_stats *stats = &ieee->stats;
523 struct sk_buff *skb_frag;
524 int priority = -1;
525
526 spin_lock_irqsave(&ieee->lock, flags);
425 527
528 /* If there is no driver handler to take the TXB, dont' bother
529 * creating it... */
530 if (!ieee->hard_start_xmit) {
531 printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
532 goto success;
533 }
534
535 if (unlikely(len < 24)) {
536 printk(KERN_WARNING "%s: skb too small (%d).\n",
537 ieee->dev->name, len);
538 goto success;
539 }
540
541 /* When we allocate the TXB we allocate enough space for the reserve
542 * and full fragment bytes (bytes_per_frag doesn't include prefix,
543 * postfix, header, FCS, etc.) */
544 txb = ieee80211_alloc_txb(1, len, ieee->tx_headroom, GFP_ATOMIC);
545 if (unlikely(!txb)) {
546 printk(KERN_WARNING "%s: Could not allocate TXB\n",
547 ieee->dev->name);
548 goto failed;
549 }
550 txb->encrypted = 0;
551 txb->payload_size = len;
552
553 skb_frag = txb->fragments[0];
554
555 memcpy(skb_put(skb_frag, len), frame, len);
556
557 if (ieee->config &
558 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
559 skb_put(skb_frag, 4);
560
561 success:
562 spin_unlock_irqrestore(&ieee->lock, flags);
563
564 if (txb) {
565 if ((*ieee->hard_start_xmit) (txb, ieee->dev, priority) == 0) {
566 stats->tx_packets++;
567 stats->tx_bytes += txb->payload_size;
568 return 0;
569 }
570 ieee80211_txb_free(txb);
571 }
572 return 0;
573
574 failed:
575 spin_unlock_irqrestore(&ieee->lock, flags);
576 stats->tx_errors++;
577 return 1;
426} 578}
427 579
580EXPORT_SYMBOL(ieee80211_tx_frame);
428EXPORT_SYMBOL(ieee80211_txb_free); 581EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 94882f39b072..1ce7af9bec35 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
4 4
5 Portions of this file are based on the WEP enablement code provided by the 5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3 6 Host AP project hostap-drivers v0.1.3
@@ -32,6 +32,7 @@
32 32
33#include <linux/kmod.h> 33#include <linux/kmod.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/jiffies.h>
35 36
36#include <net/ieee80211.h> 37#include <net/ieee80211.h>
37#include <linux/wireless.h> 38#include <linux/wireless.h>
@@ -140,18 +141,41 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
140 start = iwe_stream_add_point(start, stop, &iwe, custom); 141 start = iwe_stream_add_point(start, stop, &iwe, custom);
141 142
142 /* Add quality statistics */ 143 /* Add quality statistics */
143 /* TODO: Fix these values... */
144 iwe.cmd = IWEVQUAL; 144 iwe.cmd = IWEVQUAL;
145 iwe.u.qual.qual = network->stats.signal; 145 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
146 iwe.u.qual.level = network->stats.rssi; 146 IW_QUAL_NOISE_UPDATED;
147 iwe.u.qual.noise = network->stats.noise; 147
148 iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK; 148 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) {
149 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) 149 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID |
150 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID; 150 IW_QUAL_LEVEL_INVALID;
151 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) 151 iwe.u.qual.qual = 0;
152 iwe.u.qual.level = 0;
153 } else {
154 iwe.u.qual.level = network->stats.rssi;
155 if (ieee->perfect_rssi == ieee->worst_rssi)
156 iwe.u.qual.qual = 100;
157 else
158 iwe.u.qual.qual =
159 (100 *
160 (ieee->perfect_rssi - ieee->worst_rssi) *
161 (ieee->perfect_rssi - ieee->worst_rssi) -
162 (ieee->perfect_rssi - network->stats.rssi) *
163 (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
164 62 * (ieee->perfect_rssi - network->stats.rssi))) /
165 ((ieee->perfect_rssi - ieee->worst_rssi) *
166 (ieee->perfect_rssi - ieee->worst_rssi));
167 if (iwe.u.qual.qual > 100)
168 iwe.u.qual.qual = 100;
169 else if (iwe.u.qual.qual < 1)
170 iwe.u.qual.qual = 0;
171 }
172
173 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) {
152 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID; 174 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
153 if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) 175 iwe.u.qual.noise = 0;
154 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID; 176 } else {
177 iwe.u.qual.noise = network->stats.noise;
178 }
155 179
156 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); 180 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
157 181
@@ -162,7 +186,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
162 if (iwe.u.data.length) 186 if (iwe.u.data.length)
163 start = iwe_stream_add_point(start, stop, &iwe, custom); 187 start = iwe_stream_add_point(start, stop, &iwe, custom);
164 188
165 if (ieee->wpa_enabled && network->wpa_ie_len) { 189 if (network->wpa_ie_len) {
166 char buf[MAX_WPA_IE_LEN * 2 + 30]; 190 char buf[MAX_WPA_IE_LEN * 2 + 30];
167 191
168 u8 *p = buf; 192 u8 *p = buf;
@@ -177,7 +201,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
177 start = iwe_stream_add_point(start, stop, &iwe, buf); 201 start = iwe_stream_add_point(start, stop, &iwe, buf);
178 } 202 }
179 203
180 if (ieee->wpa_enabled && network->rsn_ie_len) { 204 if (network->rsn_ie_len) {
181 char buf[MAX_WPA_IE_LEN * 2 + 30]; 205 char buf[MAX_WPA_IE_LEN * 2 + 30];
182 206
183 u8 *p = buf; 207 u8 *p = buf;
@@ -197,8 +221,8 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
197 iwe.cmd = IWEVCUSTOM; 221 iwe.cmd = IWEVCUSTOM;
198 p = custom; 222 p = custom;
199 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), 223 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
200 " Last beacon: %lums ago", 224 " Last beacon: %dms ago",
201 (jiffies - network->last_scanned) / (HZ / 100)); 225 jiffies_to_msecs(jiffies - network->last_scanned));
202 iwe.u.data.length = p - custom; 226 iwe.u.data.length = p - custom;
203 if (iwe.u.data.length) 227 if (iwe.u.data.length)
204 start = iwe_stream_add_point(start, stop, &iwe, custom); 228 start = iwe_stream_add_point(start, stop, &iwe, custom);
@@ -228,13 +252,13 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
228 ev = ipw2100_translate_scan(ieee, ev, stop, network); 252 ev = ipw2100_translate_scan(ieee, ev, stop, network);
229 else 253 else
230 IEEE80211_DEBUG_SCAN("Not showing network '%s (" 254 IEEE80211_DEBUG_SCAN("Not showing network '%s ("
231 MAC_FMT ")' due to age (%lums).\n", 255 MAC_FMT ")' due to age (%dms).\n",
232 escape_essid(network->ssid, 256 escape_essid(network->ssid,
233 network->ssid_len), 257 network->ssid_len),
234 MAC_ARG(network->bssid), 258 MAC_ARG(network->bssid),
235 (jiffies - 259 jiffies_to_msecs(jiffies -
236 network->last_scanned) / (HZ / 260 network->
237 100)); 261 last_scanned));
238 } 262 }
239 263
240 spin_unlock_irqrestore(&ieee->lock, flags); 264 spin_unlock_irqrestore(&ieee->lock, flags);
@@ -258,6 +282,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
258 }; 282 };
259 int i, key, key_provided, len; 283 int i, key, key_provided, len;
260 struct ieee80211_crypt_data **crypt; 284 struct ieee80211_crypt_data **crypt;
285 int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
261 286
262 IEEE80211_DEBUG_WX("SET_ENCODE\n"); 287 IEEE80211_DEBUG_WX("SET_ENCODE\n");
263 288
@@ -298,15 +323,17 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
298 323
299 if (i == WEP_KEYS) { 324 if (i == WEP_KEYS) {
300 sec.enabled = 0; 325 sec.enabled = 0;
326 sec.encrypt = 0;
301 sec.level = SEC_LEVEL_0; 327 sec.level = SEC_LEVEL_0;
302 sec.flags |= SEC_ENABLED | SEC_LEVEL; 328 sec.flags |= SEC_ENABLED | SEC_LEVEL | SEC_ENCRYPT;
303 } 329 }
304 330
305 goto done; 331 goto done;
306 } 332 }
307 333
308 sec.enabled = 1; 334 sec.enabled = 1;
309 sec.flags |= SEC_ENABLED; 335 sec.encrypt = 1;
336 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
310 337
311 if (*crypt != NULL && (*crypt)->ops != NULL && 338 if (*crypt != NULL && (*crypt)->ops != NULL &&
312 strcmp((*crypt)->ops->name, "WEP") != 0) { 339 strcmp((*crypt)->ops->name, "WEP") != 0) {
@@ -315,7 +342,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
315 ieee80211_crypt_delayed_deinit(ieee, crypt); 342 ieee80211_crypt_delayed_deinit(ieee, crypt);
316 } 343 }
317 344
318 if (*crypt == NULL) { 345 if (*crypt == NULL && host_crypto) {
319 struct ieee80211_crypt_data *new_crypt; 346 struct ieee80211_crypt_data *new_crypt;
320 347
321 /* take WEP into use */ 348 /* take WEP into use */
@@ -355,49 +382,56 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
355 key, escape_essid(sec.keys[key], len), 382 key, escape_essid(sec.keys[key], len),
356 erq->length, len); 383 erq->length, len);
357 sec.key_sizes[key] = len; 384 sec.key_sizes[key] = len;
358 (*crypt)->ops->set_key(sec.keys[key], len, NULL, 385 if (*crypt)
359 (*crypt)->priv); 386 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
387 (*crypt)->priv);
360 sec.flags |= (1 << key); 388 sec.flags |= (1 << key);
361 /* This ensures a key will be activated if no key is 389 /* This ensures a key will be activated if no key is
362 * explicitely set */ 390 * explicitely set */
363 if (key == sec.active_key) 391 if (key == sec.active_key)
364 sec.flags |= SEC_ACTIVE_KEY; 392 sec.flags |= SEC_ACTIVE_KEY;
393
365 } else { 394 } else {
366 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN, 395 if (host_crypto) {
367 NULL, (*crypt)->priv); 396 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
368 if (len == 0) { 397 NULL, (*crypt)->priv);
369 /* Set a default key of all 0 */ 398 if (len == 0) {
370 IEEE80211_DEBUG_WX("Setting key %d to all zero.\n", 399 /* Set a default key of all 0 */
371 key); 400 IEEE80211_DEBUG_WX("Setting key %d to all "
372 memset(sec.keys[key], 0, 13); 401 "zero.\n", key);
373 (*crypt)->ops->set_key(sec.keys[key], 13, NULL, 402 memset(sec.keys[key], 0, 13);
374 (*crypt)->priv); 403 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
375 sec.key_sizes[key] = 13; 404 (*crypt)->priv);
376 sec.flags |= (1 << key); 405 sec.key_sizes[key] = 13;
406 sec.flags |= (1 << key);
407 }
377 } 408 }
378
379 /* No key data - just set the default TX key index */ 409 /* No key data - just set the default TX key index */
380 if (key_provided) { 410 if (key_provided) {
381 IEEE80211_DEBUG_WX 411 IEEE80211_DEBUG_WX("Setting key %d to default Tx "
382 ("Setting key %d to default Tx key.\n", key); 412 "key.\n", key);
383 ieee->tx_keyidx = key; 413 ieee->tx_keyidx = key;
384 sec.active_key = key; 414 sec.active_key = key;
385 sec.flags |= SEC_ACTIVE_KEY; 415 sec.flags |= SEC_ACTIVE_KEY;
386 } 416 }
387 } 417 }
388 418 if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
389 done: 419 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
390 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); 420 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
391 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; 421 WLAN_AUTH_SHARED_KEY;
392 sec.flags |= SEC_AUTH_MODE; 422 sec.flags |= SEC_AUTH_MODE;
393 IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? 423 IEEE80211_DEBUG_WX("Auth: %s\n",
394 "OPEN" : "SHARED KEY"); 424 sec.auth_mode == WLAN_AUTH_OPEN ?
425 "OPEN" : "SHARED KEY");
426 }
395 427
396 /* For now we just support WEP, so only set that security level... 428 /* For now we just support WEP, so only set that security level...
397 * TODO: When WPA is added this is one place that needs to change */ 429 * TODO: When WPA is added this is one place that needs to change */
398 sec.flags |= SEC_LEVEL; 430 sec.flags |= SEC_LEVEL;
399 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ 431 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
432 sec.encode_alg[key] = SEC_ALG_WEP;
400 433
434 done:
401 if (ieee->set_security) 435 if (ieee->set_security)
402 ieee->set_security(dev, &sec); 436 ieee->set_security(dev, &sec);
403 437
@@ -422,6 +456,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
422 struct iw_point *erq = &(wrqu->encoding); 456 struct iw_point *erq = &(wrqu->encoding);
423 int len, key; 457 int len, key;
424 struct ieee80211_crypt_data *crypt; 458 struct ieee80211_crypt_data *crypt;
459 struct ieee80211_security *sec = &ieee->sec;
425 460
426 IEEE80211_DEBUG_WX("GET_ENCODE\n"); 461 IEEE80211_DEBUG_WX("GET_ENCODE\n");
427 462
@@ -436,23 +471,16 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
436 crypt = ieee->crypt[key]; 471 crypt = ieee->crypt[key];
437 erq->flags = key + 1; 472 erq->flags = key + 1;
438 473
439 if (crypt == NULL || crypt->ops == NULL) { 474 if (!sec->enabled) {
440 erq->length = 0; 475 erq->length = 0;
441 erq->flags |= IW_ENCODE_DISABLED; 476 erq->flags |= IW_ENCODE_DISABLED;
442 return 0; 477 return 0;
443 } 478 }
444 479
445 if (strcmp(crypt->ops->name, "WEP") != 0) { 480 len = sec->key_sizes[key];
446 /* only WEP is supported with wireless extensions, so just 481 memcpy(keybuf, sec->keys[key], len);
447 * report that encryption is used */
448 erq->length = 0;
449 erq->flags |= IW_ENCODE_ENABLED;
450 return 0;
451 }
452 482
453 len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
454 erq->length = (len >= 0 ? len : 0); 483 erq->length = (len >= 0 ? len : 0);
455
456 erq->flags |= IW_ENCODE_ENABLED; 484 erq->flags |= IW_ENCODE_ENABLED;
457 485
458 if (ieee->open_wep) 486 if (ieee->open_wep)
@@ -463,6 +491,240 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
463 return 0; 491 return 0;
464} 492}
465 493
494int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
495 struct iw_request_info *info,
496 union iwreq_data *wrqu, char *extra)
497{
498 struct net_device *dev = ieee->dev;
499 struct iw_point *encoding = &wrqu->encoding;
500 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
501 int i, idx, ret = 0;
502 int group_key = 0;
503 const char *alg, *module;
504 struct ieee80211_crypto_ops *ops;
505 struct ieee80211_crypt_data **crypt;
506
507 struct ieee80211_security sec = {
508 .flags = 0,
509 };
510
511 idx = encoding->flags & IW_ENCODE_INDEX;
512 if (idx) {
513 if (idx < 1 || idx > WEP_KEYS)
514 return -EINVAL;
515 idx--;
516 } else
517 idx = ieee->tx_keyidx;
518
519 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
520 crypt = &ieee->crypt[idx];
521 group_key = 1;
522 } else {
523 if (idx != 0)
524 return -EINVAL;
525 if (ieee->iw_mode == IW_MODE_INFRA)
526 crypt = &ieee->crypt[idx];
527 else
528 return -EINVAL;
529 }
530
531 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
532 if ((encoding->flags & IW_ENCODE_DISABLED) ||
533 ext->alg == IW_ENCODE_ALG_NONE) {
534 if (*crypt)
535 ieee80211_crypt_delayed_deinit(ieee, crypt);
536
537 for (i = 0; i < WEP_KEYS; i++)
538 if (ieee->crypt[i] != NULL)
539 break;
540
541 if (i == WEP_KEYS) {
542 sec.enabled = 0;
543 sec.encrypt = 0;
544 sec.level = SEC_LEVEL_0;
545 sec.flags |= SEC_LEVEL;
546 }
547 goto done;
548 }
549
550 sec.enabled = 1;
551 sec.encrypt = 1;
552
553 if (group_key ? !ieee->host_mc_decrypt :
554 !(ieee->host_encrypt || ieee->host_decrypt ||
555 ieee->host_encrypt_msdu))
556 goto skip_host_crypt;
557
558 switch (ext->alg) {
559 case IW_ENCODE_ALG_WEP:
560 alg = "WEP";
561 module = "ieee80211_crypt_wep";
562 break;
563 case IW_ENCODE_ALG_TKIP:
564 alg = "TKIP";
565 module = "ieee80211_crypt_tkip";
566 break;
567 case IW_ENCODE_ALG_CCMP:
568 alg = "CCMP";
569 module = "ieee80211_crypt_ccmp";
570 break;
571 default:
572 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
573 dev->name, ext->alg);
574 ret = -EINVAL;
575 goto done;
576 }
577
578 ops = ieee80211_get_crypto_ops(alg);
579 if (ops == NULL) {
580 request_module(module);
581 ops = ieee80211_get_crypto_ops(alg);
582 }
583 if (ops == NULL) {
584 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
585 dev->name, ext->alg);
586 ret = -EINVAL;
587 goto done;
588 }
589
590 if (*crypt == NULL || (*crypt)->ops != ops) {
591 struct ieee80211_crypt_data *new_crypt;
592
593 ieee80211_crypt_delayed_deinit(ieee, crypt);
594
595 new_crypt = (struct ieee80211_crypt_data *)
596 kmalloc(sizeof(*new_crypt), GFP_KERNEL);
597 if (new_crypt == NULL) {
598 ret = -ENOMEM;
599 goto done;
600 }
601 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
602 new_crypt->ops = ops;
603 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
604 new_crypt->priv = new_crypt->ops->init(idx);
605 if (new_crypt->priv == NULL) {
606 kfree(new_crypt);
607 ret = -EINVAL;
608 goto done;
609 }
610 *crypt = new_crypt;
611 }
612
613 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
614 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
615 (*crypt)->priv) < 0) {
616 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
617 ret = -EINVAL;
618 goto done;
619 }
620
621 skip_host_crypt:
622 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
623 ieee->tx_keyidx = idx;
624 sec.active_key = idx;
625 sec.flags |= SEC_ACTIVE_KEY;
626 }
627
628 if (ext->alg != IW_ENCODE_ALG_NONE) {
629 memcpy(sec.keys[idx], ext->key, ext->key_len);
630 sec.key_sizes[idx] = ext->key_len;
631 sec.flags |= (1 << idx);
632 if (ext->alg == IW_ENCODE_ALG_WEP) {
633 sec.encode_alg[idx] = SEC_ALG_WEP;
634 sec.flags |= SEC_LEVEL;
635 sec.level = SEC_LEVEL_1;
636 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
637 sec.encode_alg[idx] = SEC_ALG_TKIP;
638 sec.flags |= SEC_LEVEL;
639 sec.level = SEC_LEVEL_2;
640 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
641 sec.encode_alg[idx] = SEC_ALG_CCMP;
642 sec.flags |= SEC_LEVEL;
643 sec.level = SEC_LEVEL_3;
644 }
645 /* Don't set sec level for group keys. */
646 if (group_key)
647 sec.flags &= ~SEC_LEVEL;
648 }
649 done:
650 if (ieee->set_security)
651 ieee->set_security(ieee->dev, &sec);
652
653 /*
654 * Do not reset port if card is in Managed mode since resetting will
655 * generate new IEEE 802.11 authentication which may end up in looping
656 * with IEEE 802.1X. If your hardware requires a reset after WEP
657 * configuration (for example... Prism2), implement the reset_port in
658 * the callbacks structures used to initialize the 802.11 stack.
659 */
660 if (ieee->reset_on_keychange &&
661 ieee->iw_mode != IW_MODE_INFRA &&
662 ieee->reset_port && ieee->reset_port(dev)) {
663 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
664 return -EINVAL;
665 }
666
667 return ret;
668}
669
670int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
671 struct iw_request_info *info,
672 union iwreq_data *wrqu, char *extra)
673{
674 struct iw_point *encoding = &wrqu->encoding;
675 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
676 struct ieee80211_security *sec = &ieee->sec;
677 int idx, max_key_len;
678
679 max_key_len = encoding->length - sizeof(*ext);
680 if (max_key_len < 0)
681 return -EINVAL;
682
683 idx = encoding->flags & IW_ENCODE_INDEX;
684 if (idx) {
685 if (idx < 1 || idx > WEP_KEYS)
686 return -EINVAL;
687 idx--;
688 } else
689 idx = ieee->tx_keyidx;
690
691 if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
692 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
693 return -EINVAL;
694
695 encoding->flags = idx + 1;
696 memset(ext, 0, sizeof(*ext));
697
698 if (!sec->enabled) {
699 ext->alg = IW_ENCODE_ALG_NONE;
700 ext->key_len = 0;
701 encoding->flags |= IW_ENCODE_DISABLED;
702 } else {
703 if (sec->encode_alg[idx] == SEC_ALG_WEP)
704 ext->alg = IW_ENCODE_ALG_WEP;
705 else if (sec->encode_alg[idx] == SEC_ALG_TKIP)
706 ext->alg = IW_ENCODE_ALG_TKIP;
707 else if (sec->encode_alg[idx] == SEC_ALG_CCMP)
708 ext->alg = IW_ENCODE_ALG_CCMP;
709 else
710 return -EINVAL;
711
712 ext->key_len = sec->key_sizes[idx];
713 memcpy(ext->key, sec->keys[idx], ext->key_len);
714 encoding->flags |= IW_ENCODE_ENABLED;
715 if (ext->key_len &&
716 (ext->alg == IW_ENCODE_ALG_TKIP ||
717 ext->alg == IW_ENCODE_ALG_CCMP))
718 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
719
720 }
721
722 return 0;
723}
724
725EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
726EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
727
466EXPORT_SYMBOL(ieee80211_wx_get_scan); 728EXPORT_SYMBOL(ieee80211_wx_get_scan);
467EXPORT_SYMBOL(ieee80211_wx_set_encode); 729EXPORT_SYMBOL(ieee80211_wx_set_encode);
468EXPORT_SYMBOL(ieee80211_wx_get_encode); 730EXPORT_SYMBOL(ieee80211_wx_get_encode);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 74f2207e131a..4ec4b2ca6ab1 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -715,6 +715,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
715 break; 715 break;
716 ret = 0; 716 ret = 0;
717 if (ifa->ifa_mask != sin->sin_addr.s_addr) { 717 if (ifa->ifa_mask != sin->sin_addr.s_addr) {
718 u32 old_mask = ifa->ifa_mask;
718 inet_del_ifa(in_dev, ifap, 0); 719 inet_del_ifa(in_dev, ifap, 0);
719 ifa->ifa_mask = sin->sin_addr.s_addr; 720 ifa->ifa_mask = sin->sin_addr.s_addr;
720 ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask); 721 ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
@@ -728,7 +729,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
728 if ((dev->flags & IFF_BROADCAST) && 729 if ((dev->flags & IFF_BROADCAST) &&
729 (ifa->ifa_prefixlen < 31) && 730 (ifa->ifa_prefixlen < 31) &&
730 (ifa->ifa_broadcast == 731 (ifa->ifa_broadcast ==
731 (ifa->ifa_local|~ifa->ifa_mask))) { 732 (ifa->ifa_local|~old_mask))) {
732 ifa->ifa_broadcast = (ifa->ifa_local | 733 ifa->ifa_broadcast = (ifa->ifa_local |
733 ~sin->sin_addr.s_addr); 734 ~sin->sin_addr.s_addr);
734 } 735 }
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 0093ea08c7f5..66247f38b371 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -2404,7 +2404,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
2404 prefix = htonl(l->key); 2404 prefix = htonl(l->key);
2405 2405
2406 list_for_each_entry_rcu(fa, &li->falh, fa_list) { 2406 list_for_each_entry_rcu(fa, &li->falh, fa_list) {
2407 const struct fib_info *fi = rcu_dereference(fa->fa_info); 2407 const struct fib_info *fi = fa->fa_info;
2408 unsigned flags = fib_flag_trans(fa->fa_type, mask, fi); 2408 unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
2409 2409
2410 if (fa->fa_type == RTN_BROADCAST 2410 if (fa->fa_type == RTN_BROADCAST
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 90dca711ac9f..175e093ec564 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -1108,12 +1108,9 @@ void __init icmp_init(struct net_proto_family *ops)
1108 struct inet_sock *inet; 1108 struct inet_sock *inet;
1109 int i; 1109 int i;
1110 1110
1111 for (i = 0; i < NR_CPUS; i++) { 1111 for_each_cpu(i) {
1112 int err; 1112 int err;
1113 1113
1114 if (!cpu_possible(i))
1115 continue;
1116
1117 err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, 1114 err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,
1118 &per_cpu(__icmp_socket, i)); 1115 &per_cpu(__icmp_socket, i));
1119 1116
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 1ad5202e556b..87e350069abb 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1023,10 +1023,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1023 int alloclen; 1023 int alloclen;
1024 1024
1025 skb_prev = skb; 1025 skb_prev = skb;
1026 if (skb_prev) 1026 fraggap = skb_prev->len - maxfraglen;
1027 fraggap = skb_prev->len - maxfraglen;
1028 else
1029 fraggap = 0;
1030 1027
1031 alloclen = fragheaderlen + hh_len + fraggap + 15; 1028 alloclen = fragheaderlen + hh_len + fraggap + 15;
1032 skb = sock_wmalloc(sk, alloclen, 1, sk->sk_allocation); 1029 skb = sock_wmalloc(sk, alloclen, 1, sk->sk_allocation);
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 07a80b56e8dc..422ab68ee7fb 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -50,7 +50,7 @@
50#include <linux/netfilter_ipv4/ip_conntrack_core.h> 50#include <linux/netfilter_ipv4/ip_conntrack_core.h>
51#include <linux/netfilter_ipv4/listhelp.h> 51#include <linux/netfilter_ipv4/listhelp.h>
52 52
53#define IP_CONNTRACK_VERSION "2.3" 53#define IP_CONNTRACK_VERSION "2.4"
54 54
55#if 0 55#if 0
56#define DEBUGP printk 56#define DEBUGP printk
@@ -148,16 +148,20 @@ DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
148static int ip_conntrack_hash_rnd_initted; 148static int ip_conntrack_hash_rnd_initted;
149static unsigned int ip_conntrack_hash_rnd; 149static unsigned int ip_conntrack_hash_rnd;
150 150
151static u_int32_t 151static u_int32_t __hash_conntrack(const struct ip_conntrack_tuple *tuple,
152hash_conntrack(const struct ip_conntrack_tuple *tuple) 152 unsigned int size, unsigned int rnd)
153{ 153{
154#if 0
155 dump_tuple(tuple);
156#endif
157 return (jhash_3words(tuple->src.ip, 154 return (jhash_3words(tuple->src.ip,
158 (tuple->dst.ip ^ tuple->dst.protonum), 155 (tuple->dst.ip ^ tuple->dst.protonum),
159 (tuple->src.u.all | (tuple->dst.u.all << 16)), 156 (tuple->src.u.all | (tuple->dst.u.all << 16)),
160 ip_conntrack_hash_rnd) % ip_conntrack_htable_size); 157 rnd) % size);
158}
159
160static u_int32_t
161hash_conntrack(const struct ip_conntrack_tuple *tuple)
162{
163 return __hash_conntrack(tuple, ip_conntrack_htable_size,
164 ip_conntrack_hash_rnd);
161} 165}
162 166
163int 167int
@@ -1341,14 +1345,13 @@ static int kill_all(struct ip_conntrack *i, void *data)
1341 return 1; 1345 return 1;
1342} 1346}
1343 1347
1344static void free_conntrack_hash(void) 1348static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size)
1345{ 1349{
1346 if (ip_conntrack_vmalloc) 1350 if (vmalloced)
1347 vfree(ip_conntrack_hash); 1351 vfree(hash);
1348 else 1352 else
1349 free_pages((unsigned long)ip_conntrack_hash, 1353 free_pages((unsigned long)hash,
1350 get_order(sizeof(struct list_head) 1354 get_order(sizeof(struct list_head) * size));
1351 * ip_conntrack_htable_size));
1352} 1355}
1353 1356
1354void ip_conntrack_flush() 1357void ip_conntrack_flush()
@@ -1378,12 +1381,83 @@ void ip_conntrack_cleanup(void)
1378 ip_conntrack_flush(); 1381 ip_conntrack_flush();
1379 kmem_cache_destroy(ip_conntrack_cachep); 1382 kmem_cache_destroy(ip_conntrack_cachep);
1380 kmem_cache_destroy(ip_conntrack_expect_cachep); 1383 kmem_cache_destroy(ip_conntrack_expect_cachep);
1381 free_conntrack_hash(); 1384 free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
1385 ip_conntrack_htable_size);
1382 nf_unregister_sockopt(&so_getorigdst); 1386 nf_unregister_sockopt(&so_getorigdst);
1383} 1387}
1384 1388
1385static int hashsize; 1389static struct list_head *alloc_hashtable(int size, int *vmalloced)
1386module_param(hashsize, int, 0400); 1390{
1391 struct list_head *hash;
1392 unsigned int i;
1393
1394 *vmalloced = 0;
1395 hash = (void*)__get_free_pages(GFP_KERNEL,
1396 get_order(sizeof(struct list_head)
1397 * size));
1398 if (!hash) {
1399 *vmalloced = 1;
1400 printk(KERN_WARNING"ip_conntrack: falling back to vmalloc.\n");
1401 hash = vmalloc(sizeof(struct list_head) * size);
1402 }
1403
1404 if (hash)
1405 for (i = 0; i < size; i++)
1406 INIT_LIST_HEAD(&hash[i]);
1407
1408 return hash;
1409}
1410
1411int set_hashsize(const char *val, struct kernel_param *kp)
1412{
1413 int i, bucket, hashsize, vmalloced;
1414 int old_vmalloced, old_size;
1415 int rnd;
1416 struct list_head *hash, *old_hash;
1417 struct ip_conntrack_tuple_hash *h;
1418
1419 /* On boot, we can set this without any fancy locking. */
1420 if (!ip_conntrack_htable_size)
1421 return param_set_int(val, kp);
1422
1423 hashsize = simple_strtol(val, NULL, 0);
1424 if (!hashsize)
1425 return -EINVAL;
1426
1427 hash = alloc_hashtable(hashsize, &vmalloced);
1428 if (!hash)
1429 return -ENOMEM;
1430
1431 /* We have to rehash for the new table anyway, so we also can
1432 * use a new random seed */
1433 get_random_bytes(&rnd, 4);
1434
1435 write_lock_bh(&ip_conntrack_lock);
1436 for (i = 0; i < ip_conntrack_htable_size; i++) {
1437 while (!list_empty(&ip_conntrack_hash[i])) {
1438 h = list_entry(ip_conntrack_hash[i].next,
1439 struct ip_conntrack_tuple_hash, list);
1440 list_del(&h->list);
1441 bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
1442 list_add_tail(&h->list, &hash[bucket]);
1443 }
1444 }
1445 old_size = ip_conntrack_htable_size;
1446 old_vmalloced = ip_conntrack_vmalloc;
1447 old_hash = ip_conntrack_hash;
1448
1449 ip_conntrack_htable_size = hashsize;
1450 ip_conntrack_vmalloc = vmalloced;
1451 ip_conntrack_hash = hash;
1452 ip_conntrack_hash_rnd = rnd;
1453 write_unlock_bh(&ip_conntrack_lock);
1454
1455 free_conntrack_hash(old_hash, old_vmalloced, old_size);
1456 return 0;
1457}
1458
1459module_param_call(hashsize, set_hashsize, param_get_uint,
1460 &ip_conntrack_htable_size, 0600);
1387 1461
1388int __init ip_conntrack_init(void) 1462int __init ip_conntrack_init(void)
1389{ 1463{
@@ -1392,9 +1466,7 @@ int __init ip_conntrack_init(void)
1392 1466
1393 /* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB 1467 /* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
1394 * machine has 256 buckets. >= 1GB machines have 8192 buckets. */ 1468 * machine has 256 buckets. >= 1GB machines have 8192 buckets. */
1395 if (hashsize) { 1469 if (!ip_conntrack_htable_size) {
1396 ip_conntrack_htable_size = hashsize;
1397 } else {
1398 ip_conntrack_htable_size 1470 ip_conntrack_htable_size
1399 = (((num_physpages << PAGE_SHIFT) / 16384) 1471 = (((num_physpages << PAGE_SHIFT) / 16384)
1400 / sizeof(struct list_head)); 1472 / sizeof(struct list_head));
@@ -1416,20 +1488,8 @@ int __init ip_conntrack_init(void)
1416 return ret; 1488 return ret;
1417 } 1489 }
1418 1490
1419 /* AK: the hash table is twice as big than needed because it 1491 ip_conntrack_hash = alloc_hashtable(ip_conntrack_htable_size,
1420 uses list_head. it would be much nicer to caches to use a 1492 &ip_conntrack_vmalloc);
1421 single pointer list head here. */
1422 ip_conntrack_vmalloc = 0;
1423 ip_conntrack_hash
1424 =(void*)__get_free_pages(GFP_KERNEL,
1425 get_order(sizeof(struct list_head)
1426 *ip_conntrack_htable_size));
1427 if (!ip_conntrack_hash) {
1428 ip_conntrack_vmalloc = 1;
1429 printk(KERN_WARNING "ip_conntrack: falling back to vmalloc.\n");
1430 ip_conntrack_hash = vmalloc(sizeof(struct list_head)
1431 * ip_conntrack_htable_size);
1432 }
1433 if (!ip_conntrack_hash) { 1493 if (!ip_conntrack_hash) {
1434 printk(KERN_ERR "Unable to create ip_conntrack_hash\n"); 1494 printk(KERN_ERR "Unable to create ip_conntrack_hash\n");
1435 goto err_unreg_sockopt; 1495 goto err_unreg_sockopt;
@@ -1461,9 +1521,6 @@ int __init ip_conntrack_init(void)
1461 ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp; 1521 ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
1462 write_unlock_bh(&ip_conntrack_lock); 1522 write_unlock_bh(&ip_conntrack_lock);
1463 1523
1464 for (i = 0; i < ip_conntrack_htable_size; i++)
1465 INIT_LIST_HEAD(&ip_conntrack_hash[i]);
1466
1467 /* For use by ipt_REJECT */ 1524 /* For use by ipt_REJECT */
1468 ip_ct_attach = ip_conntrack_attach; 1525 ip_ct_attach = ip_conntrack_attach;
1469 1526
@@ -1478,7 +1535,8 @@ int __init ip_conntrack_init(void)
1478err_free_conntrack_slab: 1535err_free_conntrack_slab:
1479 kmem_cache_destroy(ip_conntrack_cachep); 1536 kmem_cache_destroy(ip_conntrack_cachep);
1480err_free_hash: 1537err_free_hash:
1481 free_conntrack_hash(); 1538 free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
1539 ip_conntrack_htable_size);
1482err_unreg_sockopt: 1540err_unreg_sockopt:
1483 nf_unregister_sockopt(&so_getorigdst); 1541 nf_unregister_sockopt(&so_getorigdst);
1484 1542
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index f7943ba1f43c..a65e508fbd40 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -90,9 +90,7 @@ fold_field(void *mib[], int offt)
90 unsigned long res = 0; 90 unsigned long res = 0;
91 int i; 91 int i;
92 92
93 for (i = 0; i < NR_CPUS; i++) { 93 for_each_cpu(i) {
94 if (!cpu_possible(i))
95 continue;
96 res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt); 94 res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt);
97 res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt); 95 res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt);
98 } 96 }
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index b7185fb3377c..23e540365a14 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -700,10 +700,7 @@ int __init icmpv6_init(struct net_proto_family *ops)
700 struct sock *sk; 700 struct sock *sk;
701 int err, i, j; 701 int err, i, j;
702 702
703 for (i = 0; i < NR_CPUS; i++) { 703 for_each_cpu(i) {
704 if (!cpu_possible(i))
705 continue;
706
707 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, 704 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
708 &per_cpu(__icmpv6_socket, i)); 705 &per_cpu(__icmpv6_socket, i));
709 if (err < 0) { 706 if (err < 0) {
@@ -749,9 +746,7 @@ void icmpv6_cleanup(void)
749{ 746{
750 int i; 747 int i;
751 748
752 for (i = 0; i < NR_CPUS; i++) { 749 for_each_cpu(i) {
753 if (!cpu_possible(i))
754 continue;
755 sock_release(per_cpu(__icmpv6_socket, i)); 750 sock_release(per_cpu(__icmpv6_socket, i));
756 } 751 }
757 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); 752 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 334a5967831e..50a13e75d70e 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -140,9 +140,7 @@ fold_field(void *mib[], int offt)
140 unsigned long res = 0; 140 unsigned long res = 0;
141 int i; 141 int i;
142 142
143 for (i = 0; i < NR_CPUS; i++) { 143 for_each_cpu(i) {
144 if (!cpu_possible(i))
145 continue;
146 res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt); 144 res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt);
147 res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt); 145 res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt);
148 } 146 }
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 291df2e4c492..5ca283537bc6 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -740,11 +740,8 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long t
740 740
741int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol) 741int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol)
742{ 742{
743 struct netlink_sock *nlk;
744 int len = skb->len; 743 int len = skb->len;
745 744
746 nlk = nlk_sk(sk);
747
748 skb_queue_tail(&sk->sk_receive_queue, skb); 745 skb_queue_tail(&sk->sk_receive_queue, skb);
749 sk->sk_data_ready(sk, len); 746 sk->sk_data_ready(sk, len);
750 sock_put(sk); 747 sock_put(sk);
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index e556d92c0bc4..b18fe5043019 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -727,7 +727,7 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg)
727 } 727 }
728 if (rose_route.mask > 10) /* Mask can't be more than 10 digits */ 728 if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
729 return -EINVAL; 729 return -EINVAL;
730 if (rose_route.ndigis > 8) /* No more than 8 digipeats */ 730 if (rose_route.ndigis > AX25_MAX_DIGIS)
731 return -EINVAL; 731 return -EINVAL;
732 err = rose_add_node(&rose_route, dev); 732 err = rose_add_node(&rose_route, dev);
733 dev_put(dev); 733 dev_put(dev);
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index b74f7772b576..6e4dc28874d7 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -69,9 +69,7 @@ fold_field(void *mib[], int nr)
69 unsigned long res = 0; 69 unsigned long res = 0;
70 int i; 70 int i;
71 71
72 for (i = 0; i < NR_CPUS; i++) { 72 for_each_cpu(i) {
73 if (!cpu_possible(i))
74 continue;
75 res += 73 res +=
76 *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) + 74 *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
77 sizeof (unsigned long) * nr)); 75 sizeof (unsigned long) * nr));
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index cbb0ba34a600..0db9e57013fd 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1192,46 +1192,6 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
1192 1192
1193EXPORT_SYMBOL(xfrm_bundle_ok); 1193EXPORT_SYMBOL(xfrm_bundle_ok);
1194 1194
1195/* Well... that's _TASK_. We need to scan through transformation
1196 * list and figure out what mss tcp should generate in order to
1197 * final datagram fit to mtu. Mama mia... :-)
1198 *
1199 * Apparently, some easy way exists, but we used to choose the most
1200 * bizarre ones. :-) So, raising Kalashnikov... tra-ta-ta.
1201 *
1202 * Consider this function as something like dark humour. :-)
1203 */
1204static int xfrm_get_mss(struct dst_entry *dst, u32 mtu)
1205{
1206 int res = mtu - dst->header_len;
1207
1208 for (;;) {
1209 struct dst_entry *d = dst;
1210 int m = res;
1211
1212 do {
1213 struct xfrm_state *x = d->xfrm;
1214 if (x) {
1215 spin_lock_bh(&x->lock);
1216 if (x->km.state == XFRM_STATE_VALID &&
1217 x->type && x->type->get_max_size)
1218 m = x->type->get_max_size(d->xfrm, m);
1219 else
1220 m += x->props.header_len;
1221 spin_unlock_bh(&x->lock);
1222 }
1223 } while ((d = d->child) != NULL);
1224
1225 if (m <= mtu)
1226 break;
1227 res -= (m - mtu);
1228 if (res < 88)
1229 return mtu;
1230 }
1231
1232 return res + dst->header_len;
1233}
1234
1235int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) 1195int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
1236{ 1196{
1237 int err = 0; 1197 int err = 0;
@@ -1252,8 +1212,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
1252 dst_ops->negative_advice = xfrm_negative_advice; 1212 dst_ops->negative_advice = xfrm_negative_advice;
1253 if (likely(dst_ops->link_failure == NULL)) 1213 if (likely(dst_ops->link_failure == NULL))
1254 dst_ops->link_failure = xfrm_link_failure; 1214 dst_ops->link_failure = xfrm_link_failure;
1255 if (likely(dst_ops->get_mss == NULL))
1256 dst_ops->get_mss = xfrm_get_mss;
1257 if (likely(afinfo->garbage_collect == NULL)) 1215 if (likely(afinfo->garbage_collect == NULL))
1258 afinfo->garbage_collect = __xfrm_garbage_collect; 1216 afinfo->garbage_collect = __xfrm_garbage_collect;
1259 xfrm_policy_afinfo[afinfo->family] = afinfo; 1217 xfrm_policy_afinfo[afinfo->family] = afinfo;
@@ -1281,7 +1239,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
1281 dst_ops->check = NULL; 1239 dst_ops->check = NULL;
1282 dst_ops->negative_advice = NULL; 1240 dst_ops->negative_advice = NULL;
1283 dst_ops->link_failure = NULL; 1241 dst_ops->link_failure = NULL;
1284 dst_ops->get_mss = NULL;
1285 afinfo->garbage_collect = NULL; 1242 afinfo->garbage_collect = NULL;
1286 } 1243 }
1287 } 1244 }
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9d206c282cf1..8b9a4747417d 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1026,6 +1026,12 @@ void xfrm_state_delete_tunnel(struct xfrm_state *x)
1026} 1026}
1027EXPORT_SYMBOL(xfrm_state_delete_tunnel); 1027EXPORT_SYMBOL(xfrm_state_delete_tunnel);
1028 1028
1029/*
1030 * This function is NOT optimal. For example, with ESP it will give an
1031 * MTU that's usually two bytes short of being optimal. However, it will
1032 * usually give an answer that's a multiple of 4 provided the input is
1033 * also a multiple of 4.
1034 */
1029int xfrm_state_mtu(struct xfrm_state *x, int mtu) 1035int xfrm_state_mtu(struct xfrm_state *x, int mtu)
1030{ 1036{
1031 int res = mtu; 1037 int res = mtu;