aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-09-08 05:39:55 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-08 05:39:55 -0400
commitc324b44c34050cf2a9b58830e11c974806bd85d8 (patch)
tree3ac45a783221283925cd698334a8f5e7dd4c1df8 /net
parent2fcf522509cceea524b6e7ece8fd6759b682175a (diff)
parentcaf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff)
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'net')
-rw-r--r--net/Kconfig1
-rw-r--r--net/Makefile1
-rw-r--r--net/atm/ioctl.c1
-rw-r--r--net/ax25/af_ax25.c7
-rw-r--r--net/ax25/ax25_addr.c3
-rw-r--r--net/ax25/ax25_route.c7
-rw-r--r--net/ax25/ax25_uid.c4
-rw-r--r--net/core/ethtool.c2
-rw-r--r--net/core/filter.c6
-rw-r--r--net/core/sock.c11
-rw-r--r--net/core/wireless.c58
-rw-r--r--net/decnet/af_decnet.c40
-rw-r--r--net/decnet/dn_nsp_out.c63
-rw-r--r--net/ieee80211/Kconfig69
-rw-r--r--net/ieee80211/Makefile11
-rw-r--r--net/ieee80211/ieee80211_crypt.c258
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c455
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c683
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c258
-rw-r--r--net/ieee80211/ieee80211_module.c297
-rw-r--r--net/ieee80211/ieee80211_rx.c1193
-rw-r--r--net/ieee80211/ieee80211_tx.c428
-rw-r--r--net/ieee80211/ieee80211_wx.c468
-rw-r--r--net/ipv4/ah4.c18
-rw-r--r--net/ipv4/esp4.c24
-rw-r--r--net/ipv4/ip_fragment.c2
-rw-r--r--net/ipv4/ipcomp.c3
-rw-r--r--net/ipv4/ipconfig.c1
-rw-r--r--net/ipv4/netfilter/Kconfig20
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c38
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_irc.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netbios_ns.c131
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c13
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_tftp.c1
-rw-r--r--net/ipv4/netfilter/ip_nat_rule.c21
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c8
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c2
-rw-r--r--net/ipv4/tcp.c17
-rw-r--r--net/ipv4/tcp_input.c36
-rw-r--r--net/ipv4/tcp_output.c55
-rw-r--r--net/ipv6/addrconf.c6
-rw-r--r--net/ipv6/ah6.c18
-rw-r--r--net/ipv6/esp6.c24
-rw-r--r--net/ipv6/icmp.c2
-rw-r--r--net/ipv6/ipcomp6.c3
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/irda/irlan/irlan_filter.c1
-rw-r--r--net/irda/qos.c1
-rw-r--r--net/netfilter/nfnetlink.c4
-rw-r--r--net/netfilter/nfnetlink_queue.c23
-rw-r--r--net/netlink/af_netlink.c59
-rw-r--r--net/netrom/af_netrom.c7
-rw-r--r--net/netrom/nr_route.c8
-rw-r--r--net/packet/af_packet.c6
-rw-r--r--net/rose/af_rose.c6
-rw-r--r--net/rose/rose_route.c14
-rw-r--r--net/rose/rose_subr.c5
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/socket.c3
-rw-r--r--net/sctp/sysctl.c1
-rw-r--r--net/socket.c22
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c5
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c9
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c12
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c8
-rw-r--r--net/sunrpc/cache.c8
-rw-r--r--net/sunrpc/rpc_pipe.c2
-rw-r--r--net/sunrpc/stats.c16
-rw-r--r--net/sunrpc/sunrpc_syms.c6
-rw-r--r--net/sunrpc/svcauth.c1
-rw-r--r--net/sunrpc/svcauth_unix.c1
76 files changed, 4645 insertions, 364 deletions
diff --git a/net/Kconfig b/net/Kconfig
index c07aafb59a0f..2bdd5623fdd5 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -215,6 +215,7 @@ endmenu
215source "net/ax25/Kconfig" 215source "net/ax25/Kconfig"
216source "net/irda/Kconfig" 216source "net/irda/Kconfig"
217source "net/bluetooth/Kconfig" 217source "net/bluetooth/Kconfig"
218source "net/ieee80211/Kconfig"
218 219
219endif # if NET 220endif # if NET
220endmenu # Networking 221endmenu # Networking
diff --git a/net/Makefile b/net/Makefile
index 7e6eff206c81..4aa2f46d2a56 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_ECONET) += econet/
44obj-$(CONFIG_VLAN_8021Q) += 8021q/ 44obj-$(CONFIG_VLAN_8021Q) += 8021q/
45obj-$(CONFIG_IP_DCCP) += dccp/ 45obj-$(CONFIG_IP_DCCP) += dccp/
46obj-$(CONFIG_IP_SCTP) += sctp/ 46obj-$(CONFIG_IP_SCTP) += sctp/
47obj-$(CONFIG_IEEE80211) += ieee80211/
47 48
48ifeq ($(CONFIG_NET),y) 49ifeq ($(CONFIG_NET),y)
49obj-$(CONFIG_SYSCTL) += sysctl_net.o 50obj-$(CONFIG_SYSCTL) += sysctl_net.o
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 4dbb5af34a5e..d89056ec44d4 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -21,6 +21,7 @@
21 21
22#include "resources.h" 22#include "resources.h"
23#include "signaling.h" /* for WAITING and sigd_attach */ 23#include "signaling.h" /* for WAITING and sigd_attach */
24#include "common.h"
24 25
25 26
26static DECLARE_MUTEX(ioctl_mutex); 27static DECLARE_MUTEX(ioctl_mutex);
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index ea43dfb774e2..ed705ddad56b 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1874,6 +1874,7 @@ static void ax25_info_stop(struct seq_file *seq, void *v)
1874static int ax25_info_show(struct seq_file *seq, void *v) 1874static int ax25_info_show(struct seq_file *seq, void *v)
1875{ 1875{
1876 ax25_cb *ax25 = v; 1876 ax25_cb *ax25 = v;
1877 char buf[11];
1877 int k; 1878 int k;
1878 1879
1879 1880
@@ -1885,13 +1886,13 @@ static int ax25_info_show(struct seq_file *seq, void *v)
1885 seq_printf(seq, "%8.8lx %s %s%s ", 1886 seq_printf(seq, "%8.8lx %s %s%s ",
1886 (long) ax25, 1887 (long) ax25,
1887 ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name, 1888 ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name,
1888 ax2asc(&ax25->source_addr), 1889 ax2asc(buf, &ax25->source_addr),
1889 ax25->iamdigi? "*":""); 1890 ax25->iamdigi? "*":"");
1890 seq_printf(seq, "%s", ax2asc(&ax25->dest_addr)); 1891 seq_printf(seq, "%s", ax2asc(buf, &ax25->dest_addr));
1891 1892
1892 for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) { 1893 for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) {
1893 seq_printf(seq, ",%s%s", 1894 seq_printf(seq, ",%s%s",
1894 ax2asc(&ax25->digipeat->calls[k]), 1895 ax2asc(buf, &ax25->digipeat->calls[k]),
1895 ax25->digipeat->repeated[k]? "*":""); 1896 ax25->digipeat->repeated[k]? "*":"");
1896 } 1897 }
1897 1898
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
index f4fa6dfb846e..dca179daf415 100644
--- a/net/ax25/ax25_addr.c
+++ b/net/ax25/ax25_addr.c
@@ -36,9 +36,8 @@ ax25_address null_ax25_address = {{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00}};
36/* 36/*
37 * ax25 -> ascii conversion 37 * ax25 -> ascii conversion
38 */ 38 */
39char *ax2asc(ax25_address *a) 39char *ax2asc(char *buf, ax25_address *a)
40{ 40{
41 static char buf[11];
42 char c, *s; 41 char c, *s;
43 int n; 42 int n;
44 43
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index c288526da4ce..26b77d972220 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -298,6 +298,8 @@ static void ax25_rt_seq_stop(struct seq_file *seq, void *v)
298 298
299static int ax25_rt_seq_show(struct seq_file *seq, void *v) 299static int ax25_rt_seq_show(struct seq_file *seq, void *v)
300{ 300{
301 char buf[11];
302
301 if (v == SEQ_START_TOKEN) 303 if (v == SEQ_START_TOKEN)
302 seq_puts(seq, "callsign dev mode digipeaters\n"); 304 seq_puts(seq, "callsign dev mode digipeaters\n");
303 else { 305 else {
@@ -308,7 +310,7 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
308 if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0) 310 if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0)
309 callsign = "default"; 311 callsign = "default";
310 else 312 else
311 callsign = ax2asc(&ax25_rt->callsign); 313 callsign = ax2asc(buf, &ax25_rt->callsign);
312 314
313 seq_printf(seq, "%-9s %-4s", 315 seq_printf(seq, "%-9s %-4s",
314 callsign, 316 callsign,
@@ -328,7 +330,8 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
328 330
329 if (ax25_rt->digipeat != NULL) 331 if (ax25_rt->digipeat != NULL)
330 for (i = 0; i < ax25_rt->digipeat->ndigi; i++) 332 for (i = 0; i < ax25_rt->digipeat->ndigi; i++)
331 seq_printf(seq, " %s", ax2asc(&ax25_rt->digipeat->calls[i])); 333 seq_printf(seq, " %s",
334 ax2asc(buf, &ax25_rt->digipeat->calls[i]));
332 335
333 seq_puts(seq, "\n"); 336 seq_puts(seq, "\n");
334 } 337 }
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
index a8b3822f3ee4..d53cc8615865 100644
--- a/net/ax25/ax25_uid.c
+++ b/net/ax25/ax25_uid.c
@@ -168,12 +168,14 @@ static void ax25_uid_seq_stop(struct seq_file *seq, void *v)
168 168
169static int ax25_uid_seq_show(struct seq_file *seq, void *v) 169static int ax25_uid_seq_show(struct seq_file *seq, void *v)
170{ 170{
171 char buf[11];
172
171 if (v == SEQ_START_TOKEN) 173 if (v == SEQ_START_TOKEN)
172 seq_printf(seq, "Policy: %d\n", ax25_uid_policy); 174 seq_printf(seq, "Policy: %d\n", ax25_uid_policy);
173 else { 175 else {
174 struct ax25_uid_assoc *pt = v; 176 struct ax25_uid_assoc *pt = v;
175 177
176 seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(&pt->call)); 178 seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(buf, &pt->call));
177 } 179 }
178 return 0; 180 return 0;
179} 181}
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 289c1b5a8e4a..404b761e82ce 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -695,7 +695,7 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
695 return ret; 695 return ret;
696} 696}
697 697
698static int ethtool_get_perm_addr(struct net_device *dev, void *useraddr) 698static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
699{ 699{
700 struct ethtool_perm_addr epaddr; 700 struct ethtool_perm_addr epaddr;
701 u8 *data; 701 u8 *data;
diff --git a/net/core/filter.c b/net/core/filter.c
index cd91a24f9720..079c2edff789 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -182,7 +182,7 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
182 A = ntohl(*(u32 *)ptr); 182 A = ntohl(*(u32 *)ptr);
183 continue; 183 continue;
184 } 184 }
185 return 0; 185 break;
186 case BPF_LD|BPF_H|BPF_ABS: 186 case BPF_LD|BPF_H|BPF_ABS:
187 k = fentry->k; 187 k = fentry->k;
188 load_h: 188 load_h:
@@ -191,7 +191,7 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
191 A = ntohs(*(u16 *)ptr); 191 A = ntohs(*(u16 *)ptr);
192 continue; 192 continue;
193 } 193 }
194 return 0; 194 break;
195 case BPF_LD|BPF_B|BPF_ABS: 195 case BPF_LD|BPF_B|BPF_ABS:
196 k = fentry->k; 196 k = fentry->k;
197load_b: 197load_b:
@@ -200,7 +200,7 @@ load_b:
200 A = *(u8 *)ptr; 200 A = *(u8 *)ptr;
201 continue; 201 continue;
202 } 202 }
203 return 0; 203 break;
204 case BPF_LD|BPF_W|BPF_LEN: 204 case BPF_LD|BPF_W|BPF_LEN:
205 A = skb->len; 205 A = skb->len;
206 continue; 206 continue;
diff --git a/net/core/sock.c b/net/core/sock.c
index ccd10fd65682..ac63b56e23b2 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -341,11 +341,11 @@ set_rcvbuf:
341 sock_reset_flag(sk, SOCK_LINGER); 341 sock_reset_flag(sk, SOCK_LINGER);
342 else { 342 else {
343#if (BITS_PER_LONG == 32) 343#if (BITS_PER_LONG == 32)
344 if (ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ) 344 if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
345 sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT; 345 sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT;
346 else 346 else
347#endif 347#endif
348 sk->sk_lingertime = ling.l_linger * HZ; 348 sk->sk_lingertime = (unsigned int)ling.l_linger * HZ;
349 sock_set_flag(sk, SOCK_LINGER); 349 sock_set_flag(sk, SOCK_LINGER);
350 } 350 }
351 break; 351 break;
@@ -1529,6 +1529,8 @@ EXPORT_SYMBOL(proto_register);
1529void proto_unregister(struct proto *prot) 1529void proto_unregister(struct proto *prot)
1530{ 1530{
1531 write_lock(&proto_list_lock); 1531 write_lock(&proto_list_lock);
1532 list_del(&prot->node);
1533 write_unlock(&proto_list_lock);
1532 1534
1533 if (prot->slab != NULL) { 1535 if (prot->slab != NULL) {
1534 kmem_cache_destroy(prot->slab); 1536 kmem_cache_destroy(prot->slab);
@@ -1550,9 +1552,6 @@ void proto_unregister(struct proto *prot)
1550 kfree(name); 1552 kfree(name);
1551 prot->twsk_slab = NULL; 1553 prot->twsk_slab = NULL;
1552 } 1554 }
1553
1554 list_del(&prot->node);
1555 write_unlock(&proto_list_lock);
1556} 1555}
1557 1556
1558EXPORT_SYMBOL(proto_unregister); 1557EXPORT_SYMBOL(proto_unregister);
@@ -1719,8 +1718,8 @@ EXPORT_SYMBOL(sock_wfree);
1719EXPORT_SYMBOL(sock_wmalloc); 1718EXPORT_SYMBOL(sock_wmalloc);
1720EXPORT_SYMBOL(sock_i_uid); 1719EXPORT_SYMBOL(sock_i_uid);
1721EXPORT_SYMBOL(sock_i_ino); 1720EXPORT_SYMBOL(sock_i_ino);
1722#ifdef CONFIG_SYSCTL
1723EXPORT_SYMBOL(sysctl_optmem_max); 1721EXPORT_SYMBOL(sysctl_optmem_max);
1722#ifdef CONFIG_SYSCTL
1724EXPORT_SYMBOL(sysctl_rmem_max); 1723EXPORT_SYMBOL(sysctl_rmem_max);
1725EXPORT_SYMBOL(sysctl_wmem_max); 1724EXPORT_SYMBOL(sysctl_wmem_max);
1726#endif 1725#endif
diff --git a/net/core/wireless.c b/net/core/wireless.c
index 5caae2399f3a..d17f1583ea3e 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -58,6 +58,13 @@
58 * o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus 58 * o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus
59 * Based on patch from Pavel Roskin <proski@gnu.org> : 59 * Based on patch from Pavel Roskin <proski@gnu.org> :
60 * o Fix kernel data leak to user space in private handler handling 60 * o Fix kernel data leak to user space in private handler handling
61 *
62 * v7 - 18.3.05 - Jean II
63 * o Remove (struct iw_point *)->pointer from events and streams
64 * o Remove spy_offset from struct iw_handler_def
65 * o Start deprecating dev->get_wireless_stats, output a warning
66 * o If IW_QUAL_DBM is set, show dBm values in /proc/net/wireless
67 * o Don't loose INVALID/DBM flags when clearing UPDATED flags (iwstats)
61 */ 68 */
62 69
63/***************************** INCLUDES *****************************/ 70/***************************** INCLUDES *****************************/
@@ -446,10 +453,14 @@ static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
446 (dev->wireless_handlers->get_wireless_stats != NULL)) 453 (dev->wireless_handlers->get_wireless_stats != NULL))
447 return dev->wireless_handlers->get_wireless_stats(dev); 454 return dev->wireless_handlers->get_wireless_stats(dev);
448 455
449 /* Old location, will be phased out in next WE */ 456 /* Old location, field to be removed in next WE */
450 return (dev->get_wireless_stats ? 457 if(dev->get_wireless_stats) {
451 dev->get_wireless_stats(dev) : 458 printk(KERN_DEBUG "%s (WE) : Driver using old /proc/net/wireless support, please fix driver !\n",
452 (struct iw_statistics *) NULL); 459 dev->name);
460 return dev->get_wireless_stats(dev);
461 }
462 /* Not found */
463 return (struct iw_statistics *) NULL;
453} 464}
454 465
455/* ---------------------------------------------------------------- */ 466/* ---------------------------------------------------------------- */
@@ -541,16 +552,18 @@ static __inline__ void wireless_seq_printf_stats(struct seq_file *seq,
541 dev->name, stats->status, stats->qual.qual, 552 dev->name, stats->status, stats->qual.qual,
542 stats->qual.updated & IW_QUAL_QUAL_UPDATED 553 stats->qual.updated & IW_QUAL_QUAL_UPDATED
543 ? '.' : ' ', 554 ? '.' : ' ',
544 ((__u8) stats->qual.level), 555 ((__s32) stats->qual.level) -
556 ((stats->qual.updated & IW_QUAL_DBM) ? 0x100 : 0),
545 stats->qual.updated & IW_QUAL_LEVEL_UPDATED 557 stats->qual.updated & IW_QUAL_LEVEL_UPDATED
546 ? '.' : ' ', 558 ? '.' : ' ',
547 ((__u8) stats->qual.noise), 559 ((__s32) stats->qual.noise) -
560 ((stats->qual.updated & IW_QUAL_DBM) ? 0x100 : 0),
548 stats->qual.updated & IW_QUAL_NOISE_UPDATED 561 stats->qual.updated & IW_QUAL_NOISE_UPDATED
549 ? '.' : ' ', 562 ? '.' : ' ',
550 stats->discard.nwid, stats->discard.code, 563 stats->discard.nwid, stats->discard.code,
551 stats->discard.fragment, stats->discard.retries, 564 stats->discard.fragment, stats->discard.retries,
552 stats->discard.misc, stats->miss.beacon); 565 stats->discard.misc, stats->miss.beacon);
553 stats->qual.updated = 0; 566 stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
554 } 567 }
555} 568}
556 569
@@ -593,6 +606,7 @@ static struct file_operations wireless_seq_fops = {
593 606
594int __init wireless_proc_init(void) 607int __init wireless_proc_init(void)
595{ 608{
609 /* Create /proc/net/wireless entry */
596 if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops)) 610 if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops))
597 return -ENOMEM; 611 return -ENOMEM;
598 612
@@ -627,9 +641,9 @@ static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
627 sizeof(struct iw_statistics))) 641 sizeof(struct iw_statistics)))
628 return -EFAULT; 642 return -EFAULT;
629 643
630 /* Check if we need to clear the update flag */ 644 /* Check if we need to clear the updated flag */
631 if(wrq->u.data.flags != 0) 645 if(wrq->u.data.flags != 0)
632 stats->qual.updated = 0; 646 stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
633 return 0; 647 return 0;
634 } else 648 } else
635 return -EOPNOTSUPP; 649 return -EOPNOTSUPP;
@@ -1161,10 +1175,11 @@ void wireless_send_event(struct net_device * dev,
1161 struct iw_event *event; /* Mallocated whole event */ 1175 struct iw_event *event; /* Mallocated whole event */
1162 int event_len; /* Its size */ 1176 int event_len; /* Its size */
1163 int hdr_len; /* Size of the event header */ 1177 int hdr_len; /* Size of the event header */
1178 int wrqu_off = 0; /* Offset in wrqu */
1164 /* Don't "optimise" the following variable, it will crash */ 1179 /* Don't "optimise" the following variable, it will crash */
1165 unsigned cmd_index; /* *MUST* be unsigned */ 1180 unsigned cmd_index; /* *MUST* be unsigned */
1166 1181
1167 /* Get the description of the IOCTL */ 1182 /* Get the description of the Event */
1168 if(cmd <= SIOCIWLAST) { 1183 if(cmd <= SIOCIWLAST) {
1169 cmd_index = cmd - SIOCIWFIRST; 1184 cmd_index = cmd - SIOCIWFIRST;
1170 if(cmd_index < standard_ioctl_num) 1185 if(cmd_index < standard_ioctl_num)
@@ -1207,6 +1222,8 @@ void wireless_send_event(struct net_device * dev,
1207 /* Calculate extra_len - extra is NULL for restricted events */ 1222 /* Calculate extra_len - extra is NULL for restricted events */
1208 if(extra != NULL) 1223 if(extra != NULL)
1209 extra_len = wrqu->data.length * descr->token_size; 1224 extra_len = wrqu->data.length * descr->token_size;
1225 /* Always at an offset in wrqu */
1226 wrqu_off = IW_EV_POINT_OFF;
1210#ifdef WE_EVENT_DEBUG 1227#ifdef WE_EVENT_DEBUG
1211 printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len); 1228 printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len);
1212#endif /* WE_EVENT_DEBUG */ 1229#endif /* WE_EVENT_DEBUG */
@@ -1217,7 +1234,7 @@ void wireless_send_event(struct net_device * dev,
1217 event_len = hdr_len + extra_len; 1234 event_len = hdr_len + extra_len;
1218 1235
1219#ifdef WE_EVENT_DEBUG 1236#ifdef WE_EVENT_DEBUG
1220 printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, event_len %d\n", dev->name, cmd, hdr_len, event_len); 1237 printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, wrqu_off %d, event_len %d\n", dev->name, cmd, hdr_len, wrqu_off, event_len);
1221#endif /* WE_EVENT_DEBUG */ 1238#endif /* WE_EVENT_DEBUG */
1222 1239
1223 /* Create temporary buffer to hold the event */ 1240 /* Create temporary buffer to hold the event */
@@ -1228,7 +1245,7 @@ void wireless_send_event(struct net_device * dev,
1228 /* Fill event */ 1245 /* Fill event */
1229 event->len = event_len; 1246 event->len = event_len;
1230 event->cmd = cmd; 1247 event->cmd = cmd;
1231 memcpy(&event->u, wrqu, hdr_len - IW_EV_LCP_LEN); 1248 memcpy(&event->u, ((char *) wrqu) + wrqu_off, hdr_len - IW_EV_LCP_LEN);
1232 if(extra != NULL) 1249 if(extra != NULL)
1233 memcpy(((char *) event) + hdr_len, extra, extra_len); 1250 memcpy(((char *) event) + hdr_len, extra, extra_len);
1234 1251
@@ -1249,7 +1266,7 @@ void wireless_send_event(struct net_device * dev,
1249 * Now, the driver can delegate this task to Wireless Extensions. 1266 * Now, the driver can delegate this task to Wireless Extensions.
1250 * It needs to use those standard spy iw_handler in struct iw_handler_def, 1267 * It needs to use those standard spy iw_handler in struct iw_handler_def,
1251 * push data to us via wireless_spy_update() and include struct iw_spy_data 1268 * push data to us via wireless_spy_update() and include struct iw_spy_data
1252 * in its private part (and advertise it in iw_handler_def->spy_offset). 1269 * in its private part (and export it in net_device->wireless_data->spy_data).
1253 * One of the main advantage of centralising spy support here is that 1270 * One of the main advantage of centralising spy support here is that
1254 * it becomes much easier to improve and extend it without having to touch 1271 * it becomes much easier to improve and extend it without having to touch
1255 * the drivers. One example is the addition of the Spy-Threshold events. 1272 * the drivers. One example is the addition of the Spy-Threshold events.
@@ -1266,10 +1283,7 @@ static inline struct iw_spy_data * get_spydata(struct net_device *dev)
1266 /* This is the new way */ 1283 /* This is the new way */
1267 if(dev->wireless_data) 1284 if(dev->wireless_data)
1268 return(dev->wireless_data->spy_data); 1285 return(dev->wireless_data->spy_data);
1269 1286 return NULL;
1270 /* This is the old way. Doesn't work for multi-headed drivers.
1271 * It will be removed in the next version of WE. */
1272 return (dev->priv + dev->wireless_handlers->spy_offset);
1273} 1287}
1274 1288
1275/*------------------------------------------------------------------*/ 1289/*------------------------------------------------------------------*/
@@ -1284,10 +1298,6 @@ int iw_handler_set_spy(struct net_device * dev,
1284 struct iw_spy_data * spydata = get_spydata(dev); 1298 struct iw_spy_data * spydata = get_spydata(dev);
1285 struct sockaddr * address = (struct sockaddr *) extra; 1299 struct sockaddr * address = (struct sockaddr *) extra;
1286 1300
1287 if(!dev->wireless_data)
1288 /* Help user know that driver needs updating */
1289 printk(KERN_DEBUG "%s (WE) : Driver using old/buggy spy support, please fix driver !\n",
1290 dev->name);
1291 /* Make sure driver is not buggy or using the old API */ 1301 /* Make sure driver is not buggy or using the old API */
1292 if(!spydata) 1302 if(!spydata)
1293 return -EOPNOTSUPP; 1303 return -EOPNOTSUPP;
@@ -1318,7 +1328,7 @@ int iw_handler_set_spy(struct net_device * dev,
1318 sizeof(struct iw_quality) * IW_MAX_SPY); 1328 sizeof(struct iw_quality) * IW_MAX_SPY);
1319 1329
1320#ifdef WE_SPY_DEBUG 1330#ifdef WE_SPY_DEBUG
1321 printk(KERN_DEBUG "iw_handler_set_spy() : offset %ld, spydata %p, num %d\n", dev->wireless_handlers->spy_offset, spydata, wrqu->data.length); 1331 printk(KERN_DEBUG "iw_handler_set_spy() : wireless_data %p, spydata %p, num %d\n", dev->wireless_data, spydata, wrqu->data.length);
1322 for (i = 0; i < wrqu->data.length; i++) 1332 for (i = 0; i < wrqu->data.length; i++)
1323 printk(KERN_DEBUG 1333 printk(KERN_DEBUG
1324 "%02X:%02X:%02X:%02X:%02X:%02X \n", 1334 "%02X:%02X:%02X:%02X:%02X:%02X \n",
@@ -1371,7 +1381,7 @@ int iw_handler_get_spy(struct net_device * dev,
1371 sizeof(struct iw_quality) * spydata->spy_number); 1381 sizeof(struct iw_quality) * spydata->spy_number);
1372 /* Reset updated flags. */ 1382 /* Reset updated flags. */
1373 for(i = 0; i < spydata->spy_number; i++) 1383 for(i = 0; i < spydata->spy_number; i++)
1374 spydata->spy_stat[i].updated = 0; 1384 spydata->spy_stat[i].updated &= ~IW_QUAL_ALL_UPDATED;
1375 return 0; 1385 return 0;
1376} 1386}
1377 1387
@@ -1486,7 +1496,7 @@ void wireless_spy_update(struct net_device * dev,
1486 return; 1496 return;
1487 1497
1488#ifdef WE_SPY_DEBUG 1498#ifdef WE_SPY_DEBUG
1489 printk(KERN_DEBUG "wireless_spy_update() : offset %ld, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_handlers->spy_offset, spydata, address[0], address[1], address[2], address[3], address[4], address[5]); 1499 printk(KERN_DEBUG "wireless_spy_update() : wireless_data %p, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_data, spydata, address[0], address[1], address[2], address[3], address[4], address[5]);
1490#endif /* WE_SPY_DEBUG */ 1500#endif /* WE_SPY_DEBUG */
1491 1501
1492 /* Update all records that match */ 1502 /* Update all records that match */
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 621680f127af..348f36b529f7 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -1876,8 +1876,27 @@ static inline unsigned int dn_current_mss(struct sock *sk, int flags)
1876 return mss_now; 1876 return mss_now;
1877} 1877}
1878 1878
1879/*
1880 * N.B. We get the timeout wrong here, but then we always did get it
1881 * wrong before and this is another step along the road to correcting
1882 * it. It ought to get updated each time we pass through the routine,
1883 * but in practise it probably doesn't matter too much for now.
1884 */
1885static inline struct sk_buff *dn_alloc_send_pskb(struct sock *sk,
1886 unsigned long datalen, int noblock,
1887 int *errcode)
1888{
1889 struct sk_buff *skb = sock_alloc_send_skb(sk, datalen,
1890 noblock, errcode);
1891 if (skb) {
1892 skb->protocol = __constant_htons(ETH_P_DNA_RT);
1893 skb->pkt_type = PACKET_OUTGOING;
1894 }
1895 return skb;
1896}
1897
1879static int dn_sendmsg(struct kiocb *iocb, struct socket *sock, 1898static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1880 struct msghdr *msg, size_t size) 1899 struct msghdr *msg, size_t size)
1881{ 1900{
1882 struct sock *sk = sock->sk; 1901 struct sock *sk = sock->sk;
1883 struct dn_scp *scp = DN_SK(sk); 1902 struct dn_scp *scp = DN_SK(sk);
@@ -1892,7 +1911,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1892 struct dn_skb_cb *cb; 1911 struct dn_skb_cb *cb;
1893 size_t len; 1912 size_t len;
1894 unsigned char fctype; 1913 unsigned char fctype;
1895 long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); 1914 long timeo;
1896 1915
1897 if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT)) 1916 if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT))
1898 return -EOPNOTSUPP; 1917 return -EOPNOTSUPP;
@@ -1900,18 +1919,21 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1900 if (addr_len && (addr_len != sizeof(struct sockaddr_dn))) 1919 if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
1901 return -EINVAL; 1920 return -EINVAL;
1902 1921
1922 lock_sock(sk);
1923 timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
1903 /* 1924 /*
1904 * The only difference between stream sockets and sequenced packet 1925 * The only difference between stream sockets and sequenced packet
1905 * sockets is that the stream sockets always behave as if MSG_EOR 1926 * sockets is that the stream sockets always behave as if MSG_EOR
1906 * has been set. 1927 * has been set.
1907 */ 1928 */
1908 if (sock->type == SOCK_STREAM) { 1929 if (sock->type == SOCK_STREAM) {
1909 if (flags & MSG_EOR) 1930 if (flags & MSG_EOR) {
1910 return -EINVAL; 1931 err = -EINVAL;
1932 goto out;
1933 }
1911 flags |= MSG_EOR; 1934 flags |= MSG_EOR;
1912 } 1935 }
1913 1936
1914 lock_sock(sk);
1915 1937
1916 err = dn_check_state(sk, addr, addr_len, &timeo, flags); 1938 err = dn_check_state(sk, addr, addr_len, &timeo, flags);
1917 if (err) 1939 if (err)
@@ -1980,8 +2002,12 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1980 2002
1981 /* 2003 /*
1982 * Get a suitably sized skb. 2004 * Get a suitably sized skb.
2005 * 64 is a bit of a hack really, but its larger than any
2006 * link-layer headers and has served us well as a good
2007 * guess as to their real length.
1983 */ 2008 */
1984 skb = dn_alloc_send_skb(sk, &len, flags & MSG_DONTWAIT, timeo, &err); 2009 skb = dn_alloc_send_pskb(sk, len + 64 + DN_MAX_NSP_DATA_HEADER,
2010 flags & MSG_DONTWAIT, &err);
1985 2011
1986 if (err) 2012 if (err)
1987 break; 2013 break;
@@ -1991,7 +2017,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
1991 2017
1992 cb = DN_SKB_CB(skb); 2018 cb = DN_SKB_CB(skb);
1993 2019
1994 skb_reserve(skb, DN_MAX_NSP_DATA_HEADER); 2020 skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER);
1995 2021
1996 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 2022 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
1997 err = -EFAULT; 2023 err = -EFAULT;
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index e0bebf4bbcad..53633d352868 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -137,69 +137,6 @@ struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri)
137} 137}
138 138
139/* 139/*
140 * Wrapper for the above, for allocs of data skbs. We try and get the
141 * whole size thats been asked for (plus 11 bytes of header). If this
142 * fails, then we try for any size over 16 bytes for SOCK_STREAMS.
143 */
144struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, long timeo, int *err)
145{
146 int space;
147 int len;
148 struct sk_buff *skb = NULL;
149
150 *err = 0;
151
152 while(skb == NULL) {
153 if (signal_pending(current)) {
154 *err = sock_intr_errno(timeo);
155 break;
156 }
157
158 if (sk->sk_shutdown & SEND_SHUTDOWN) {
159 *err = EINVAL;
160 break;
161 }
162
163 if (sk->sk_err)
164 break;
165
166 len = *size + 11;
167 space = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
168
169 if (space < len) {
170 if ((sk->sk_socket->type == SOCK_STREAM) &&
171 (space >= (16 + 11)))
172 len = space;
173 }
174
175 if (space < len) {
176 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
177 if (noblock) {
178 *err = EWOULDBLOCK;
179 break;
180 }
181
182 clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
183 SOCK_SLEEP_PRE(sk)
184
185 if ((sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc)) <
186 len)
187 schedule();
188
189 SOCK_SLEEP_POST(sk)
190 continue;
191 }
192
193 if ((skb = dn_alloc_skb(sk, len, sk->sk_allocation)) == NULL)
194 continue;
195
196 *size = len - 11;
197 }
198
199 return skb;
200}
201
202/*
203 * Calculate persist timer based upon the smoothed round 140 * Calculate persist timer based upon the smoothed round
204 * trip time and the variance. Backoff according to the 141 * trip time and the variance. Backoff according to the
205 * nsp_backoff[] array. 142 * nsp_backoff[] array.
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
new file mode 100644
index 000000000000..58ed4319e693
--- /dev/null
+++ b/net/ieee80211/Kconfig
@@ -0,0 +1,69 @@
1config IEEE80211
2 tristate "Generic IEEE 802.11 Networking Stack"
3 select NET_RADIO
4 ---help---
5 This option enables the hardware independent IEEE 802.11
6 networking stack.
7
8config IEEE80211_DEBUG
9 bool "Enable full debugging output"
10 depends on IEEE80211
11 ---help---
12 This option will enable debug tracing output for the
13 ieee80211 network stack.
14
15 This will result in the kernel module being ~70k larger. You
16 can control which debug output is sent to the kernel log by
17 setting the value in
18
19 /proc/net/ieee80211/debug_level
20
21 For example:
22
23 % echo 0x00000FFO > /proc/net/ieee80211/debug_level
24
25 For a list of values you can assign to debug_level, you
26 can look at the bit mask values in <net/ieee80211.h>
27
28 If you are not trying to debug or develop the ieee80211
29 subsystem, you most likely want to say N here.
30
31config IEEE80211_CRYPT_WEP
32 tristate "IEEE 802.11 WEP encryption (802.1x)"
33 depends on IEEE80211
34 select CRYPTO
35 select CRYPTO_ARC4
36 select CRC32
37 ---help---
38 Include software based cipher suites in support of IEEE
39 802.11's WEP. This is needed for WEP as well as 802.1x.
40
41 This can be compiled as a modules and it will be called
42 "ieee80211_crypt_wep".
43
44config IEEE80211_CRYPT_CCMP
45 tristate "IEEE 802.11i CCMP support"
46 depends on IEEE80211
47 select CRYPTO
48 select CRYPTO_AES
49 ---help---
50 Include software based cipher suites in support of IEEE 802.11i
51 (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with CCMP enabled
52 networks.
53
54 This can be compiled as a modules and it will be called
55 "ieee80211_crypt_ccmp".
56
57config IEEE80211_CRYPT_TKIP
58 tristate "IEEE 802.11i TKIP encryption"
59 depends on IEEE80211
60 select CRYPTO
61 select CRYPTO_MICHAEL_MIC
62 ---help---
63 Include software based cipher suites in support of IEEE 802.11i
64 (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled
65 networks.
66
67 This can be compiled as a modules and it will be called
68 "ieee80211_crypt_tkip".
69
diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile
new file mode 100644
index 000000000000..a6ccac5baea8
--- /dev/null
+++ b/net/ieee80211/Makefile
@@ -0,0 +1,11 @@
1obj-$(CONFIG_IEEE80211) += ieee80211.o
2obj-$(CONFIG_IEEE80211) += ieee80211_crypt.o
3obj-$(CONFIG_IEEE80211_CRYPT_WEP) += ieee80211_crypt_wep.o
4obj-$(CONFIG_IEEE80211_CRYPT_CCMP) += ieee80211_crypt_ccmp.o
5obj-$(CONFIG_IEEE80211_CRYPT_TKIP) += ieee80211_crypt_tkip.o
6ieee80211-objs := \
7 ieee80211_module.o \
8 ieee80211_tx.o \
9 ieee80211_rx.o \
10 ieee80211_wx.o
11
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
new file mode 100644
index 000000000000..61a9d92e455b
--- /dev/null
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -0,0 +1,258 @@
1/*
2 * Host AP crypto routines
3 *
4 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. See README and COPYING for
10 * more details.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/version.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <asm/string.h>
20#include <asm/errno.h>
21
22#include <net/ieee80211.h>
23
24MODULE_AUTHOR("Jouni Malinen");
25MODULE_DESCRIPTION("HostAP crypto");
26MODULE_LICENSE("GPL");
27
28struct ieee80211_crypto_alg {
29 struct list_head list;
30 struct ieee80211_crypto_ops *ops;
31};
32
33struct ieee80211_crypto {
34 struct list_head algs;
35 spinlock_t lock;
36};
37
38static struct ieee80211_crypto *hcrypt;
39
40void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
41{
42 struct list_head *ptr, *n;
43 struct ieee80211_crypt_data *entry;
44
45 for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
46 ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
47 entry = list_entry(ptr, struct ieee80211_crypt_data, list);
48
49 if (atomic_read(&entry->refcnt) != 0 && !force)
50 continue;
51
52 list_del(ptr);
53
54 if (entry->ops) {
55 entry->ops->deinit(entry->priv);
56 module_put(entry->ops->owner);
57 }
58 kfree(entry);
59 }
60}
61
62void ieee80211_crypt_deinit_handler(unsigned long data)
63{
64 struct ieee80211_device *ieee = (struct ieee80211_device *)data;
65 unsigned long flags;
66
67 spin_lock_irqsave(&ieee->lock, flags);
68 ieee80211_crypt_deinit_entries(ieee, 0);
69 if (!list_empty(&ieee->crypt_deinit_list)) {
70 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
71 "deletion list\n", ieee->dev->name);
72 ieee->crypt_deinit_timer.expires = jiffies + HZ;
73 add_timer(&ieee->crypt_deinit_timer);
74 }
75 spin_unlock_irqrestore(&ieee->lock, flags);
76
77}
78
79void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
80 struct ieee80211_crypt_data **crypt)
81{
82 struct ieee80211_crypt_data *tmp;
83 unsigned long flags;
84
85 if (*crypt == NULL)
86 return;
87
88 tmp = *crypt;
89 *crypt = NULL;
90
91 /* must not run ops->deinit() while there may be pending encrypt or
92 * decrypt operations. Use a list of delayed deinits to avoid needing
93 * locking. */
94
95 spin_lock_irqsave(&ieee->lock, flags);
96 list_add(&tmp->list, &ieee->crypt_deinit_list);
97 if (!timer_pending(&ieee->crypt_deinit_timer)) {
98 ieee->crypt_deinit_timer.expires = jiffies + HZ;
99 add_timer(&ieee->crypt_deinit_timer);
100 }
101 spin_unlock_irqrestore(&ieee->lock, flags);
102}
103
104int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
105{
106 unsigned long flags;
107 struct ieee80211_crypto_alg *alg;
108
109 if (hcrypt == NULL)
110 return -1;
111
112 alg = kmalloc(sizeof(*alg), GFP_KERNEL);
113 if (alg == NULL)
114 return -ENOMEM;
115
116 memset(alg, 0, sizeof(*alg));
117 alg->ops = ops;
118
119 spin_lock_irqsave(&hcrypt->lock, flags);
120 list_add(&alg->list, &hcrypt->algs);
121 spin_unlock_irqrestore(&hcrypt->lock, flags);
122
123 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
124 ops->name);
125
126 return 0;
127}
128
129int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
130{
131 unsigned long flags;
132 struct list_head *ptr;
133 struct ieee80211_crypto_alg *del_alg = NULL;
134
135 if (hcrypt == NULL)
136 return -1;
137
138 spin_lock_irqsave(&hcrypt->lock, flags);
139 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
140 struct ieee80211_crypto_alg *alg =
141 (struct ieee80211_crypto_alg *)ptr;
142 if (alg->ops == ops) {
143 list_del(&alg->list);
144 del_alg = alg;
145 break;
146 }
147 }
148 spin_unlock_irqrestore(&hcrypt->lock, flags);
149
150 if (del_alg) {
151 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
152 "'%s'\n", ops->name);
153 kfree(del_alg);
154 }
155
156 return del_alg ? 0 : -1;
157}
158
159struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
160{
161 unsigned long flags;
162 struct list_head *ptr;
163 struct ieee80211_crypto_alg *found_alg = NULL;
164
165 if (hcrypt == NULL)
166 return NULL;
167
168 spin_lock_irqsave(&hcrypt->lock, flags);
169 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
170 struct ieee80211_crypto_alg *alg =
171 (struct ieee80211_crypto_alg *)ptr;
172 if (strcmp(alg->ops->name, name) == 0) {
173 found_alg = alg;
174 break;
175 }
176 }
177 spin_unlock_irqrestore(&hcrypt->lock, flags);
178
179 if (found_alg)
180 return found_alg->ops;
181 else
182 return NULL;
183}
184
185static void *ieee80211_crypt_null_init(int keyidx)
186{
187 return (void *)1;
188}
189static void ieee80211_crypt_null_deinit(void *priv)
190{
191}
192
193static struct ieee80211_crypto_ops ieee80211_crypt_null = {
194 .name = "NULL",
195 .init = ieee80211_crypt_null_init,
196 .deinit = ieee80211_crypt_null_deinit,
197 .encrypt_mpdu = NULL,
198 .decrypt_mpdu = NULL,
199 .encrypt_msdu = NULL,
200 .decrypt_msdu = NULL,
201 .set_key = NULL,
202 .get_key = NULL,
203 .extra_prefix_len = 0,
204 .extra_postfix_len = 0,
205 .owner = THIS_MODULE,
206};
207
208static int __init ieee80211_crypto_init(void)
209{
210 int ret = -ENOMEM;
211
212 hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
213 if (!hcrypt)
214 goto out;
215
216 memset(hcrypt, 0, sizeof(*hcrypt));
217 INIT_LIST_HEAD(&hcrypt->algs);
218 spin_lock_init(&hcrypt->lock);
219
220 ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
221 if (ret < 0) {
222 kfree(hcrypt);
223 hcrypt = NULL;
224 }
225 out:
226 return ret;
227}
228
229static void __exit ieee80211_crypto_deinit(void)
230{
231 struct list_head *ptr, *n;
232
233 if (hcrypt == NULL)
234 return;
235
236 for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
237 ptr = n, n = ptr->next) {
238 struct ieee80211_crypto_alg *alg =
239 (struct ieee80211_crypto_alg *)ptr;
240 list_del(ptr);
241 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
242 "'%s' (deinit)\n", alg->ops->name);
243 kfree(alg);
244 }
245
246 kfree(hcrypt);
247}
248
249EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
250EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
251EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
252
253EXPORT_SYMBOL(ieee80211_register_crypto_ops);
254EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
255EXPORT_SYMBOL(ieee80211_get_crypto_ops);
256
257module_init(ieee80211_crypto_init);
258module_exit(ieee80211_crypto_deinit);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
new file mode 100644
index 000000000000..8fc13f45971e
--- /dev/null
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -0,0 +1,455 @@
1/*
2 * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <asm/string.h>
23#include <linux/wireless.h>
24
25#include <net/ieee80211.h>
26
27#include <linux/crypto.h>
28#include <asm/scatterlist.h>
29
30MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Host AP crypt: CCMP");
32MODULE_LICENSE("GPL");
33
34#define AES_BLOCK_LEN 16
35#define CCMP_HDR_LEN 8
36#define CCMP_MIC_LEN 8
37#define CCMP_TK_LEN 16
38#define CCMP_PN_LEN 6
39
40struct ieee80211_ccmp_data {
41 u8 key[CCMP_TK_LEN];
42 int key_set;
43
44 u8 tx_pn[CCMP_PN_LEN];
45 u8 rx_pn[CCMP_PN_LEN];
46
47 u32 dot11RSNAStatsCCMPFormatErrors;
48 u32 dot11RSNAStatsCCMPReplays;
49 u32 dot11RSNAStatsCCMPDecryptErrors;
50
51 int key_idx;
52
53 struct crypto_tfm *tfm;
54
55 /* scratch buffers for virt_to_page() (crypto API) */
56 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
57 tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
58 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
59};
60
61static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
62 const u8 pt[16], u8 ct[16])
63{
64 struct scatterlist src, dst;
65
66 src.page = virt_to_page(pt);
67 src.offset = offset_in_page(pt);
68 src.length = AES_BLOCK_LEN;
69
70 dst.page = virt_to_page(ct);
71 dst.offset = offset_in_page(ct);
72 dst.length = AES_BLOCK_LEN;
73
74 crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
75}
76
77static void *ieee80211_ccmp_init(int key_idx)
78{
79 struct ieee80211_ccmp_data *priv;
80
81 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
82 if (priv == NULL)
83 goto fail;
84 memset(priv, 0, sizeof(*priv));
85 priv->key_idx = key_idx;
86
87 priv->tfm = crypto_alloc_tfm("aes", 0);
88 if (priv->tfm == NULL) {
89 printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
90 "crypto API aes\n");
91 goto fail;
92 }
93
94 return priv;
95
96 fail:
97 if (priv) {
98 if (priv->tfm)
99 crypto_free_tfm(priv->tfm);
100 kfree(priv);
101 }
102
103 return NULL;
104}
105
106static void ieee80211_ccmp_deinit(void *priv)
107{
108 struct ieee80211_ccmp_data *_priv = priv;
109 if (_priv && _priv->tfm)
110 crypto_free_tfm(_priv->tfm);
111 kfree(priv);
112}
113
114static inline void xor_block(u8 * b, u8 * a, size_t len)
115{
116 int i;
117 for (i = 0; i < len; i++)
118 b[i] ^= a[i];
119}
120
121static void ccmp_init_blocks(struct crypto_tfm *tfm,
122 struct ieee80211_hdr *hdr,
123 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
124{
125 u8 *pos, qc = 0;
126 size_t aad_len;
127 u16 fc;
128 int a4_included, qc_included;
129 u8 aad[2 * AES_BLOCK_LEN];
130
131 fc = le16_to_cpu(hdr->frame_ctl);
132 a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
133 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
134 qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
135 (WLAN_FC_GET_STYPE(fc) & 0x08));
136 aad_len = 22;
137 if (a4_included)
138 aad_len += 6;
139 if (qc_included) {
140 pos = (u8 *) & hdr->addr4;
141 if (a4_included)
142 pos += 6;
143 qc = *pos & 0x0f;
144 aad_len += 2;
145 }
146
147 /* CCM Initial Block:
148 * Flag (Include authentication header, M=3 (8-octet MIC),
149 * L=1 (2-octet Dlen))
150 * Nonce: 0x00 | A2 | PN
151 * Dlen */
152 b0[0] = 0x59;
153 b0[1] = qc;
154 memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
155 memcpy(b0 + 8, pn, CCMP_PN_LEN);
156 b0[14] = (dlen >> 8) & 0xff;
157 b0[15] = dlen & 0xff;
158
159 /* AAD:
160 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
161 * A1 | A2 | A3
162 * SC with bits 4..15 (seq#) masked to zero
163 * A4 (if present)
164 * QC (if present)
165 */
166 pos = (u8 *) hdr;
167 aad[0] = 0; /* aad_len >> 8 */
168 aad[1] = aad_len & 0xff;
169 aad[2] = pos[0] & 0x8f;
170 aad[3] = pos[1] & 0xc7;
171 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
172 pos = (u8 *) & hdr->seq_ctl;
173 aad[22] = pos[0] & 0x0f;
174 aad[23] = 0; /* all bits masked */
175 memset(aad + 24, 0, 8);
176 if (a4_included)
177 memcpy(aad + 24, hdr->addr4, ETH_ALEN);
178 if (qc_included) {
179 aad[a4_included ? 30 : 24] = qc;
180 /* rest of QC masked */
181 }
182
183 /* Start with the first block and AAD */
184 ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
185 xor_block(auth, aad, AES_BLOCK_LEN);
186 ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
187 xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
188 ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
189 b0[0] &= 0x07;
190 b0[14] = b0[15] = 0;
191 ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
192}
193
194static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
195{
196 struct ieee80211_ccmp_data *key = priv;
197 int data_len, i, blocks, last, len;
198 u8 *pos, *mic;
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
205 if (skb_headroom(skb) < CCMP_HDR_LEN ||
206 skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
207 return -1;
208
209 data_len = skb->len - hdr_len;
210 pos = skb_push(skb, CCMP_HDR_LEN);
211 memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
212 pos += hdr_len;
213 mic = skb_put(skb, CCMP_MIC_LEN);
214
215 i = CCMP_PN_LEN - 1;
216 while (i >= 0) {
217 key->tx_pn[i]++;
218 if (key->tx_pn[i] != 0)
219 break;
220 i--;
221 }
222
223 *pos++ = key->tx_pn[5];
224 *pos++ = key->tx_pn[4];
225 *pos++ = 0;
226 *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
227 *pos++ = key->tx_pn[3];
228 *pos++ = key->tx_pn[2];
229 *pos++ = key->tx_pn[1];
230 *pos++ = key->tx_pn[0];
231
232 hdr = (struct ieee80211_hdr *)skb->data;
233 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
234
235 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
236 last = data_len % AES_BLOCK_LEN;
237
238 for (i = 1; i <= blocks; i++) {
239 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
240 /* Authentication */
241 xor_block(b, pos, len);
242 ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
243 /* Encryption, with counter */
244 b0[14] = (i >> 8) & 0xff;
245 b0[15] = i & 0xff;
246 ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
247 xor_block(pos, e, len);
248 pos += len;
249 }
250
251 for (i = 0; i < CCMP_MIC_LEN; i++)
252 mic[i] = b[i] ^ s0[i];
253
254 return 0;
255}
256
257static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
258{
259 struct ieee80211_ccmp_data *key = priv;
260 u8 keyidx, *pos;
261 struct ieee80211_hdr *hdr;
262 u8 *b0 = key->rx_b0;
263 u8 *b = key->rx_b;
264 u8 *a = key->rx_a;
265 u8 pn[6];
266 int i, blocks, last, len;
267 size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
268 u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
269
270 if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
271 key->dot11RSNAStatsCCMPFormatErrors++;
272 return -1;
273 }
274
275 hdr = (struct ieee80211_hdr *)skb->data;
276 pos = skb->data + hdr_len;
277 keyidx = pos[3];
278 if (!(keyidx & (1 << 5))) {
279 if (net_ratelimit()) {
280 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
281 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
282 }
283 key->dot11RSNAStatsCCMPFormatErrors++;
284 return -2;
285 }
286 keyidx >>= 6;
287 if (key->key_idx != keyidx) {
288 printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
289 "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
290 return -6;
291 }
292 if (!key->key_set) {
293 if (net_ratelimit()) {
294 printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
295 " with keyid=%d that does not have a configured"
296 " key\n", MAC_ARG(hdr->addr2), keyidx);
297 }
298 return -3;
299 }
300
301 pn[0] = pos[7];
302 pn[1] = pos[6];
303 pn[2] = pos[5];
304 pn[3] = pos[4];
305 pn[4] = pos[1];
306 pn[5] = pos[0];
307 pos += 8;
308
309 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
310 if (net_ratelimit()) {
311 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
312 " previous PN %02x%02x%02x%02x%02x%02x "
313 "received PN %02x%02x%02x%02x%02x%02x\n",
314 MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
315 MAC_ARG(pn));
316 }
317 key->dot11RSNAStatsCCMPReplays++;
318 return -4;
319 }
320
321 ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
322 xor_block(mic, b, CCMP_MIC_LEN);
323
324 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
325 last = data_len % AES_BLOCK_LEN;
326
327 for (i = 1; i <= blocks; i++) {
328 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
329 /* Decrypt, with counter */
330 b0[14] = (i >> 8) & 0xff;
331 b0[15] = i & 0xff;
332 ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
333 xor_block(pos, b, len);
334 /* Authentication */
335 xor_block(a, pos, len);
336 ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
337 pos += len;
338 }
339
340 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
341 if (net_ratelimit()) {
342 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
343 MAC_FMT "\n", MAC_ARG(hdr->addr2));
344 }
345 key->dot11RSNAStatsCCMPDecryptErrors++;
346 return -5;
347 }
348
349 memcpy(key->rx_pn, pn, CCMP_PN_LEN);
350
351 /* Remove hdr and MIC */
352 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
353 skb_pull(skb, CCMP_HDR_LEN);
354 skb_trim(skb, skb->len - CCMP_MIC_LEN);
355
356 return keyidx;
357}
358
359static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
360{
361 struct ieee80211_ccmp_data *data = priv;
362 int keyidx;
363 struct crypto_tfm *tfm = data->tfm;
364
365 keyidx = data->key_idx;
366 memset(data, 0, sizeof(*data));
367 data->key_idx = keyidx;
368 data->tfm = tfm;
369 if (len == CCMP_TK_LEN) {
370 memcpy(data->key, key, CCMP_TK_LEN);
371 data->key_set = 1;
372 if (seq) {
373 data->rx_pn[0] = seq[5];
374 data->rx_pn[1] = seq[4];
375 data->rx_pn[2] = seq[3];
376 data->rx_pn[3] = seq[2];
377 data->rx_pn[4] = seq[1];
378 data->rx_pn[5] = seq[0];
379 }
380 crypto_cipher_setkey(data->tfm, data->key, CCMP_TK_LEN);
381 } else if (len == 0)
382 data->key_set = 0;
383 else
384 return -1;
385
386 return 0;
387}
388
389static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
390{
391 struct ieee80211_ccmp_data *data = priv;
392
393 if (len < CCMP_TK_LEN)
394 return -1;
395
396 if (!data->key_set)
397 return 0;
398 memcpy(key, data->key, CCMP_TK_LEN);
399
400 if (seq) {
401 seq[0] = data->tx_pn[5];
402 seq[1] = data->tx_pn[4];
403 seq[2] = data->tx_pn[3];
404 seq[3] = data->tx_pn[2];
405 seq[4] = data->tx_pn[1];
406 seq[5] = data->tx_pn[0];
407 }
408
409 return CCMP_TK_LEN;
410}
411
412static char *ieee80211_ccmp_print_stats(char *p, void *priv)
413{
414 struct ieee80211_ccmp_data *ccmp = priv;
415 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
416 "tx_pn=%02x%02x%02x%02x%02x%02x "
417 "rx_pn=%02x%02x%02x%02x%02x%02x "
418 "format_errors=%d replays=%d decrypt_errors=%d\n",
419 ccmp->key_idx, ccmp->key_set,
420 MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
421 ccmp->dot11RSNAStatsCCMPFormatErrors,
422 ccmp->dot11RSNAStatsCCMPReplays,
423 ccmp->dot11RSNAStatsCCMPDecryptErrors);
424
425 return p;
426}
427
428static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
429 .name = "CCMP",
430 .init = ieee80211_ccmp_init,
431 .deinit = ieee80211_ccmp_deinit,
432 .encrypt_mpdu = ieee80211_ccmp_encrypt,
433 .decrypt_mpdu = ieee80211_ccmp_decrypt,
434 .encrypt_msdu = NULL,
435 .decrypt_msdu = NULL,
436 .set_key = ieee80211_ccmp_set_key,
437 .get_key = ieee80211_ccmp_get_key,
438 .print_stats = ieee80211_ccmp_print_stats,
439 .extra_prefix_len = CCMP_HDR_LEN,
440 .extra_postfix_len = CCMP_MIC_LEN,
441 .owner = THIS_MODULE,
442};
443
444static int __init ieee80211_crypto_ccmp_init(void)
445{
446 return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
447}
448
449static void __exit ieee80211_crypto_ccmp_exit(void)
450{
451 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
452}
453
454module_init(ieee80211_crypto_ccmp_init);
455module_exit(ieee80211_crypto_ccmp_exit);
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
new file mode 100644
index 000000000000..d4f9164be1a1
--- /dev/null
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -0,0 +1,683 @@
1/*
2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <asm/string.h>
23
24#include <net/ieee80211.h>
25
26#include <linux/crypto.h>
27#include <asm/scatterlist.h>
28#include <linux/crc32.h>
29
30MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Host AP crypt: TKIP");
32MODULE_LICENSE("GPL");
33
34struct ieee80211_tkip_data {
35#define TKIP_KEY_LEN 32
36 u8 key[TKIP_KEY_LEN];
37 int key_set;
38
39 u32 tx_iv32;
40 u16 tx_iv16;
41 u16 tx_ttak[5];
42 int tx_phase1_done;
43
44 u32 rx_iv32;
45 u16 rx_iv16;
46 u16 rx_ttak[5];
47 int rx_phase1_done;
48 u32 rx_iv32_new;
49 u16 rx_iv16_new;
50
51 u32 dot11RSNAStatsTKIPReplays;
52 u32 dot11RSNAStatsTKIPICVErrors;
53 u32 dot11RSNAStatsTKIPLocalMICFailures;
54
55 int key_idx;
56
57 struct crypto_tfm *tfm_arc4;
58 struct crypto_tfm *tfm_michael;
59
60 /* scratch buffers for virt_to_page() (crypto API) */
61 u8 rx_hdr[16], tx_hdr[16];
62};
63
64static void *ieee80211_tkip_init(int key_idx)
65{
66 struct ieee80211_tkip_data *priv;
67
68 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
69 if (priv == NULL)
70 goto fail;
71 memset(priv, 0, sizeof(*priv));
72 priv->key_idx = key_idx;
73
74 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
75 if (priv->tfm_arc4 == NULL) {
76 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
77 "crypto API arc4\n");
78 goto fail;
79 }
80
81 priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
82 if (priv->tfm_michael == NULL) {
83 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
84 "crypto API michael_mic\n");
85 goto fail;
86 }
87
88 return priv;
89
90 fail:
91 if (priv) {
92 if (priv->tfm_michael)
93 crypto_free_tfm(priv->tfm_michael);
94 if (priv->tfm_arc4)
95 crypto_free_tfm(priv->tfm_arc4);
96 kfree(priv);
97 }
98
99 return NULL;
100}
101
102static void ieee80211_tkip_deinit(void *priv)
103{
104 struct ieee80211_tkip_data *_priv = priv;
105 if (_priv && _priv->tfm_michael)
106 crypto_free_tfm(_priv->tfm_michael);
107 if (_priv && _priv->tfm_arc4)
108 crypto_free_tfm(_priv->tfm_arc4);
109 kfree(priv);
110}
111
112static inline u16 RotR1(u16 val)
113{
114 return (val >> 1) | (val << 15);
115}
116
117static inline u8 Lo8(u16 val)
118{
119 return val & 0xff;
120}
121
122static inline u8 Hi8(u16 val)
123{
124 return val >> 8;
125}
126
127static inline u16 Lo16(u32 val)
128{
129 return val & 0xffff;
130}
131
132static inline u16 Hi16(u32 val)
133{
134 return val >> 16;
135}
136
137static inline u16 Mk16(u8 hi, u8 lo)
138{
139 return lo | (((u16) hi) << 8);
140}
141
142static inline u16 Mk16_le(u16 * v)
143{
144 return le16_to_cpu(*v);
145}
146
147static const u16 Sbox[256] = {
148 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
149 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
150 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
151 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
152 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
153 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
154 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
155 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
156 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
157 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
158 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
159 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
160 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
161 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
162 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
163 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
164 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
165 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
166 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
167 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
168 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
169 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
170 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
171 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
172 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
173 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
174 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
175 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
176 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
177 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
178 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
179 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
180};
181
182static inline u16 _S_(u16 v)
183{
184 u16 t = Sbox[Hi8(v)];
185 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
186}
187
188#define PHASE1_LOOP_COUNT 8
189
190static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
191 u32 IV32)
192{
193 int i, j;
194
195 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
196 TTAK[0] = Lo16(IV32);
197 TTAK[1] = Hi16(IV32);
198 TTAK[2] = Mk16(TA[1], TA[0]);
199 TTAK[3] = Mk16(TA[3], TA[2]);
200 TTAK[4] = Mk16(TA[5], TA[4]);
201
202 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
203 j = 2 * (i & 1);
204 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
205 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
206 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
207 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
208 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
209 }
210}
211
212static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
213 u16 IV16)
214{
215 /* Make temporary area overlap WEP seed so that the final copy can be
216 * avoided on little endian hosts. */
217 u16 *PPK = (u16 *) & WEPSeed[4];
218
219 /* Step 1 - make copy of TTAK and bring in TSC */
220 PPK[0] = TTAK[0];
221 PPK[1] = TTAK[1];
222 PPK[2] = TTAK[2];
223 PPK[3] = TTAK[3];
224 PPK[4] = TTAK[4];
225 PPK[5] = TTAK[4] + IV16;
226
227 /* Step 2 - 96-bit bijective mixing using S-box */
228 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) & TK[0]));
229 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) & TK[2]));
230 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) & TK[4]));
231 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) & TK[6]));
232 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) & TK[8]));
233 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) & TK[10]));
234
235 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) & TK[12]));
236 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) & TK[14]));
237 PPK[2] += RotR1(PPK[1]);
238 PPK[3] += RotR1(PPK[2]);
239 PPK[4] += RotR1(PPK[3]);
240 PPK[5] += RotR1(PPK[4]);
241
242 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
243 * WEPSeed[0..2] is transmitted as WEP IV */
244 WEPSeed[0] = Hi8(IV16);
245 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
246 WEPSeed[2] = Lo8(IV16);
247 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) & TK[0])) >> 1);
248
249#ifdef __BIG_ENDIAN
250 {
251 int i;
252 for (i = 0; i < 6; i++)
253 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
254 }
255#endif
256}
257
258static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
259{
260 struct ieee80211_tkip_data *tkey = priv;
261 int len;
262 u8 rc4key[16], *pos, *icv;
263 struct ieee80211_hdr *hdr;
264 u32 crc;
265 struct scatterlist sg;
266
267 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
268 skb->len < hdr_len)
269 return -1;
270
271 hdr = (struct ieee80211_hdr *)skb->data;
272 if (!tkey->tx_phase1_done) {
273 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
274 tkey->tx_iv32);
275 tkey->tx_phase1_done = 1;
276 }
277 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
278
279 len = skb->len - hdr_len;
280 pos = skb_push(skb, 8);
281 memmove(pos, pos + 8, hdr_len);
282 pos += hdr_len;
283 icv = skb_put(skb, 4);
284
285 *pos++ = rc4key[0];
286 *pos++ = rc4key[1];
287 *pos++ = rc4key[2];
288 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
289 *pos++ = tkey->tx_iv32 & 0xff;
290 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
291 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
292 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
293
294 crc = ~crc32_le(~0, pos, len);
295 icv[0] = crc;
296 icv[1] = crc >> 8;
297 icv[2] = crc >> 16;
298 icv[3] = crc >> 24;
299
300 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
301 sg.page = virt_to_page(pos);
302 sg.offset = offset_in_page(pos);
303 sg.length = len + 4;
304 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
305
306 tkey->tx_iv16++;
307 if (tkey->tx_iv16 == 0) {
308 tkey->tx_phase1_done = 0;
309 tkey->tx_iv32++;
310 }
311
312 return 0;
313}
314
315static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
316{
317 struct ieee80211_tkip_data *tkey = priv;
318 u8 rc4key[16];
319 u8 keyidx, *pos;
320 u32 iv32;
321 u16 iv16;
322 struct ieee80211_hdr *hdr;
323 u8 icv[4];
324 u32 crc;
325 struct scatterlist sg;
326 int plen;
327
328 if (skb->len < hdr_len + 8 + 4)
329 return -1;
330
331 hdr = (struct ieee80211_hdr *)skb->data;
332 pos = skb->data + hdr_len;
333 keyidx = pos[3];
334 if (!(keyidx & (1 << 5))) {
335 if (net_ratelimit()) {
336 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
337 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
338 }
339 return -2;
340 }
341 keyidx >>= 6;
342 if (tkey->key_idx != keyidx) {
343 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
344 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
345 return -6;
346 }
347 if (!tkey->key_set) {
348 if (net_ratelimit()) {
349 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
350 " with keyid=%d that does not have a configured"
351 " key\n", MAC_ARG(hdr->addr2), keyidx);
352 }
353 return -3;
354 }
355 iv16 = (pos[0] << 8) | pos[2];
356 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
357 pos += 8;
358
359 if (iv32 < tkey->rx_iv32 ||
360 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
361 if (net_ratelimit()) {
362 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
363 " previous TSC %08x%04x received TSC "
364 "%08x%04x\n", MAC_ARG(hdr->addr2),
365 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
366 }
367 tkey->dot11RSNAStatsTKIPReplays++;
368 return -4;
369 }
370
371 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
372 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
373 tkey->rx_phase1_done = 1;
374 }
375 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
376
377 plen = skb->len - hdr_len - 12;
378
379 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
380 sg.page = virt_to_page(pos);
381 sg.offset = offset_in_page(pos);
382 sg.length = plen + 4;
383 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
384
385 crc = ~crc32_le(~0, pos, plen);
386 icv[0] = crc;
387 icv[1] = crc >> 8;
388 icv[2] = crc >> 16;
389 icv[3] = crc >> 24;
390 if (memcmp(icv, pos + plen, 4) != 0) {
391 if (iv32 != tkey->rx_iv32) {
392 /* Previously cached Phase1 result was already lost, so
393 * it needs to be recalculated for the next packet. */
394 tkey->rx_phase1_done = 0;
395 }
396 if (net_ratelimit()) {
397 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
398 MAC_FMT "\n", MAC_ARG(hdr->addr2));
399 }
400 tkey->dot11RSNAStatsTKIPICVErrors++;
401 return -5;
402 }
403
404 /* Update real counters only after Michael MIC verification has
405 * completed */
406 tkey->rx_iv32_new = iv32;
407 tkey->rx_iv16_new = iv16;
408
409 /* Remove IV and ICV */
410 memmove(skb->data + 8, skb->data, hdr_len);
411 skb_pull(skb, 8);
412 skb_trim(skb, skb->len - 4);
413
414 return keyidx;
415}
416
417static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
418 u8 * data, size_t data_len, u8 * mic)
419{
420 struct scatterlist sg[2];
421
422 if (tkey->tfm_michael == NULL) {
423 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
424 return -1;
425 }
426 sg[0].page = virt_to_page(hdr);
427 sg[0].offset = offset_in_page(hdr);
428 sg[0].length = 16;
429
430 sg[1].page = virt_to_page(data);
431 sg[1].offset = offset_in_page(data);
432 sg[1].length = data_len;
433
434 crypto_digest_init(tkey->tfm_michael);
435 crypto_digest_setkey(tkey->tfm_michael, key, 8);
436 crypto_digest_update(tkey->tfm_michael, sg, 2);
437 crypto_digest_final(tkey->tfm_michael, mic);
438
439 return 0;
440}
441
442static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
443{
444 struct ieee80211_hdr *hdr11;
445
446 hdr11 = (struct ieee80211_hdr *)skb->data;
447 switch (le16_to_cpu(hdr11->frame_ctl) &
448 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
449 case IEEE80211_FCTL_TODS:
450 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
451 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
452 break;
453 case IEEE80211_FCTL_FROMDS:
454 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
455 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
456 break;
457 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
458 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
459 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
460 break;
461 case 0:
462 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
463 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
464 break;
465 }
466
467 hdr[12] = 0; /* priority */
468 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
469}
470
471static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
472 void *priv)
473{
474 struct ieee80211_tkip_data *tkey = priv;
475 u8 *pos;
476
477 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
478 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
479 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
480 skb_tailroom(skb), hdr_len, skb->len);
481 return -1;
482 }
483
484 michael_mic_hdr(skb, tkey->tx_hdr);
485 pos = skb_put(skb, 8);
486 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
487 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
488 return -1;
489
490 return 0;
491}
492
493#if WIRELESS_EXT >= 18
494static void ieee80211_michael_mic_failure(struct net_device *dev,
495 struct ieee80211_hdr *hdr, int keyidx)
496{
497 union iwreq_data wrqu;
498 struct iw_michaelmicfailure ev;
499
500 /* TODO: needed parameters: count, keyid, key type, TSC */
501 memset(&ev, 0, sizeof(ev));
502 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
503 if (hdr->addr1[0] & 0x01)
504 ev.flags |= IW_MICFAILURE_GROUP;
505 else
506 ev.flags |= IW_MICFAILURE_PAIRWISE;
507 ev.src_addr.sa_family = ARPHRD_ETHER;
508 memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
509 memset(&wrqu, 0, sizeof(wrqu));
510 wrqu.data.length = sizeof(ev);
511 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
512}
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
536static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
537 int hdr_len, void *priv)
538{
539 struct ieee80211_tkip_data *tkey = priv;
540 u8 mic[8];
541
542 if (!tkey->key_set)
543 return -1;
544
545 michael_mic_hdr(skb, tkey->rx_hdr);
546 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
547 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
548 return -1;
549 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
550 struct ieee80211_hdr *hdr;
551 hdr = (struct ieee80211_hdr *)skb->data;
552 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
553 "MSDU from " MAC_FMT " keyidx=%d\n",
554 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
555 keyidx);
556 if (skb->dev)
557 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
558 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
559 return -1;
560 }
561
562 /* Update TSC counters for RX now that the packet verification has
563 * completed. */
564 tkey->rx_iv32 = tkey->rx_iv32_new;
565 tkey->rx_iv16 = tkey->rx_iv16_new;
566
567 skb_trim(skb, skb->len - 8);
568
569 return 0;
570}
571
572static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
573{
574 struct ieee80211_tkip_data *tkey = priv;
575 int keyidx;
576 struct crypto_tfm *tfm = tkey->tfm_michael;
577 struct crypto_tfm *tfm2 = tkey->tfm_arc4;
578
579 keyidx = tkey->key_idx;
580 memset(tkey, 0, sizeof(*tkey));
581 tkey->key_idx = keyidx;
582 tkey->tfm_michael = tfm;
583 tkey->tfm_arc4 = tfm2;
584 if (len == TKIP_KEY_LEN) {
585 memcpy(tkey->key, key, TKIP_KEY_LEN);
586 tkey->key_set = 1;
587 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
588 if (seq) {
589 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
590 (seq[3] << 8) | seq[2];
591 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
592 }
593 } else if (len == 0)
594 tkey->key_set = 0;
595 else
596 return -1;
597
598 return 0;
599}
600
601static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
602{
603 struct ieee80211_tkip_data *tkey = priv;
604
605 if (len < TKIP_KEY_LEN)
606 return -1;
607
608 if (!tkey->key_set)
609 return 0;
610 memcpy(key, tkey->key, TKIP_KEY_LEN);
611
612 if (seq) {
613 /* Return the sequence number of the last transmitted frame. */
614 u16 iv16 = tkey->tx_iv16;
615 u32 iv32 = tkey->tx_iv32;
616 if (iv16 == 0)
617 iv32--;
618 iv16--;
619 seq[0] = tkey->tx_iv16;
620 seq[1] = tkey->tx_iv16 >> 8;
621 seq[2] = tkey->tx_iv32;
622 seq[3] = tkey->tx_iv32 >> 8;
623 seq[4] = tkey->tx_iv32 >> 16;
624 seq[5] = tkey->tx_iv32 >> 24;
625 }
626
627 return TKIP_KEY_LEN;
628}
629
630static char *ieee80211_tkip_print_stats(char *p, void *priv)
631{
632 struct ieee80211_tkip_data *tkip = priv;
633 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
634 "tx_pn=%02x%02x%02x%02x%02x%02x "
635 "rx_pn=%02x%02x%02x%02x%02x%02x "
636 "replays=%d icv_errors=%d local_mic_failures=%d\n",
637 tkip->key_idx, tkip->key_set,
638 (tkip->tx_iv32 >> 24) & 0xff,
639 (tkip->tx_iv32 >> 16) & 0xff,
640 (tkip->tx_iv32 >> 8) & 0xff,
641 tkip->tx_iv32 & 0xff,
642 (tkip->tx_iv16 >> 8) & 0xff,
643 tkip->tx_iv16 & 0xff,
644 (tkip->rx_iv32 >> 24) & 0xff,
645 (tkip->rx_iv32 >> 16) & 0xff,
646 (tkip->rx_iv32 >> 8) & 0xff,
647 tkip->rx_iv32 & 0xff,
648 (tkip->rx_iv16 >> 8) & 0xff,
649 tkip->rx_iv16 & 0xff,
650 tkip->dot11RSNAStatsTKIPReplays,
651 tkip->dot11RSNAStatsTKIPICVErrors,
652 tkip->dot11RSNAStatsTKIPLocalMICFailures);
653 return p;
654}
655
656static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
657 .name = "TKIP",
658 .init = ieee80211_tkip_init,
659 .deinit = ieee80211_tkip_deinit,
660 .encrypt_mpdu = ieee80211_tkip_encrypt,
661 .decrypt_mpdu = ieee80211_tkip_decrypt,
662 .encrypt_msdu = ieee80211_michael_mic_add,
663 .decrypt_msdu = ieee80211_michael_mic_verify,
664 .set_key = ieee80211_tkip_set_key,
665 .get_key = ieee80211_tkip_get_key,
666 .print_stats = ieee80211_tkip_print_stats,
667 .extra_prefix_len = 4 + 4, /* IV + ExtIV */
668 .extra_postfix_len = 8 + 4, /* MIC + ICV */
669 .owner = THIS_MODULE,
670};
671
672static int __init ieee80211_crypto_tkip_init(void)
673{
674 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
675}
676
677static void __exit ieee80211_crypto_tkip_exit(void)
678{
679 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
680}
681
682module_init(ieee80211_crypto_tkip_init);
683module_exit(ieee80211_crypto_tkip_exit);
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
new file mode 100644
index 000000000000..b4d2514a0902
--- /dev/null
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -0,0 +1,258 @@
1/*
2 * Host AP crypt: host-based WEP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <asm/string.h>
20
21#include <net/ieee80211.h>
22
23#include <linux/crypto.h>
24#include <asm/scatterlist.h>
25#include <linux/crc32.h>
26
27MODULE_AUTHOR("Jouni Malinen");
28MODULE_DESCRIPTION("Host AP crypt: WEP");
29MODULE_LICENSE("GPL");
30
31struct prism2_wep_data {
32 u32 iv;
33#define WEP_KEY_LEN 13
34 u8 key[WEP_KEY_LEN + 1];
35 u8 key_len;
36 u8 key_idx;
37 struct crypto_tfm *tfm;
38};
39
40static void *prism2_wep_init(int keyidx)
41{
42 struct prism2_wep_data *priv;
43
44 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
45 if (priv == NULL)
46 goto fail;
47 memset(priv, 0, sizeof(*priv));
48 priv->key_idx = keyidx;
49
50 priv->tfm = crypto_alloc_tfm("arc4", 0);
51 if (priv->tfm == NULL) {
52 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
53 "crypto API arc4\n");
54 goto fail;
55 }
56
57 /* start WEP IV from a random value */
58 get_random_bytes(&priv->iv, 4);
59
60 return priv;
61
62 fail:
63 if (priv) {
64 if (priv->tfm)
65 crypto_free_tfm(priv->tfm);
66 kfree(priv);
67 }
68 return NULL;
69}
70
71static void prism2_wep_deinit(void *priv)
72{
73 struct prism2_wep_data *_priv = priv;
74 if (_priv && _priv->tfm)
75 crypto_free_tfm(_priv->tfm);
76 kfree(priv);
77}
78
79/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
80 * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
81 * so the payload length increases with 8 bytes.
82 *
83 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
84 */
85static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
86{
87 struct prism2_wep_data *wep = priv;
88 u32 crc, klen, len;
89 u8 key[WEP_KEY_LEN + 3];
90 u8 *pos, *icv;
91 struct scatterlist sg;
92
93 if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
94 skb->len < hdr_len)
95 return -1;
96
97 len = skb->len - hdr_len;
98 pos = skb_push(skb, 4);
99 memmove(pos, pos + 4, hdr_len);
100 pos += hdr_len;
101
102 klen = 3 + wep->key_len;
103
104 wep->iv++;
105
106 /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
107 * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
108 * can be used to speedup attacks, so avoid using them. */
109 if ((wep->iv & 0xff00) == 0xff00) {
110 u8 B = (wep->iv >> 16) & 0xff;
111 if (B >= 3 && B < klen)
112 wep->iv += 0x0100;
113 }
114
115 /* Prepend 24-bit IV to RC4 key and TX frame */
116 *pos++ = key[0] = (wep->iv >> 16) & 0xff;
117 *pos++ = key[1] = (wep->iv >> 8) & 0xff;
118 *pos++ = key[2] = wep->iv & 0xff;
119 *pos++ = wep->key_idx << 6;
120
121 /* Copy rest of the WEP key (the secret part) */
122 memcpy(key + 3, wep->key, wep->key_len);
123
124 /* Append little-endian CRC32 and encrypt it to produce ICV */
125 crc = ~crc32_le(~0, pos, len);
126 icv = skb_put(skb, 4);
127 icv[0] = crc;
128 icv[1] = crc >> 8;
129 icv[2] = crc >> 16;
130 icv[3] = crc >> 24;
131
132 crypto_cipher_setkey(wep->tfm, key, klen);
133 sg.page = virt_to_page(pos);
134 sg.offset = offset_in_page(pos);
135 sg.length = len + 4;
136 crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
137
138 return 0;
139}
140
141/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
142 * the frame: IV (4 bytes), encrypted payload (including SNAP header),
143 * ICV (4 bytes). len includes both IV and ICV.
144 *
145 * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
146 * failure. If frame is OK, IV and ICV will be removed.
147 */
148static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
149{
150 struct prism2_wep_data *wep = priv;
151 u32 crc, klen, plen;
152 u8 key[WEP_KEY_LEN + 3];
153 u8 keyidx, *pos, icv[4];
154 struct scatterlist sg;
155
156 if (skb->len < hdr_len + 8)
157 return -1;
158
159 pos = skb->data + hdr_len;
160 key[0] = *pos++;
161 key[1] = *pos++;
162 key[2] = *pos++;
163 keyidx = *pos++ >> 6;
164 if (keyidx != wep->key_idx)
165 return -1;
166
167 klen = 3 + wep->key_len;
168
169 /* Copy rest of the WEP key (the secret part) */
170 memcpy(key + 3, wep->key, wep->key_len);
171
172 /* Apply RC4 to data and compute CRC32 over decrypted data */
173 plen = skb->len - hdr_len - 8;
174
175 crypto_cipher_setkey(wep->tfm, key, klen);
176 sg.page = virt_to_page(pos);
177 sg.offset = offset_in_page(pos);
178 sg.length = plen + 4;
179 crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
180
181 crc = ~crc32_le(~0, pos, plen);
182 icv[0] = crc;
183 icv[1] = crc >> 8;
184 icv[2] = crc >> 16;
185 icv[3] = crc >> 24;
186 if (memcmp(icv, pos + plen, 4) != 0) {
187 /* ICV mismatch - drop frame */
188 return -2;
189 }
190
191 /* Remove IV and ICV */
192 memmove(skb->data + 4, skb->data, hdr_len);
193 skb_pull(skb, 4);
194 skb_trim(skb, skb->len - 4);
195
196 return 0;
197}
198
199static int prism2_wep_set_key(void *key, int len, u8 * seq, void *priv)
200{
201 struct prism2_wep_data *wep = priv;
202
203 if (len < 0 || len > WEP_KEY_LEN)
204 return -1;
205
206 memcpy(wep->key, key, len);
207 wep->key_len = len;
208
209 return 0;
210}
211
212static int prism2_wep_get_key(void *key, int len, u8 * seq, void *priv)
213{
214 struct prism2_wep_data *wep = priv;
215
216 if (len < wep->key_len)
217 return -1;
218
219 memcpy(key, wep->key, wep->key_len);
220
221 return wep->key_len;
222}
223
224static char *prism2_wep_print_stats(char *p, void *priv)
225{
226 struct prism2_wep_data *wep = priv;
227 p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
228 return p;
229}
230
231static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
232 .name = "WEP",
233 .init = prism2_wep_init,
234 .deinit = prism2_wep_deinit,
235 .encrypt_mpdu = prism2_wep_encrypt,
236 .decrypt_mpdu = prism2_wep_decrypt,
237 .encrypt_msdu = NULL,
238 .decrypt_msdu = NULL,
239 .set_key = prism2_wep_set_key,
240 .get_key = prism2_wep_get_key,
241 .print_stats = prism2_wep_print_stats,
242 .extra_prefix_len = 4, /* IV */
243 .extra_postfix_len = 4, /* ICV */
244 .owner = THIS_MODULE,
245};
246
247static int __init ieee80211_crypto_wep_init(void)
248{
249 return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
250}
251
252static void __exit ieee80211_crypto_wep_exit(void)
253{
254 ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
255}
256
257module_init(ieee80211_crypto_wep_init);
258module_exit(ieee80211_crypto_wep_exit);
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
new file mode 100644
index 000000000000..03a47343ddc7
--- /dev/null
+++ b/net/ieee80211/ieee80211_module.c
@@ -0,0 +1,297 @@
1/*******************************************************************************
2
3 Copyright(c) 2004 Intel Corporation. All rights reserved.
4
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <jkmaline@cc.hut.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31*******************************************************************************/
32
33#include <linux/compiler.h>
34#include <linux/config.h>
35#include <linux/errno.h>
36#include <linux/if_arp.h>
37#include <linux/in6.h>
38#include <linux/in.h>
39#include <linux/ip.h>
40#include <linux/kernel.h>
41#include <linux/module.h>
42#include <linux/netdevice.h>
43#include <linux/proc_fs.h>
44#include <linux/skbuff.h>
45#include <linux/slab.h>
46#include <linux/tcp.h>
47#include <linux/types.h>
48#include <linux/version.h>
49#include <linux/wireless.h>
50#include <linux/etherdevice.h>
51#include <asm/uaccess.h>
52#include <net/arp.h>
53
54#include <net/ieee80211.h>
55
56MODULE_DESCRIPTION("802.11 data/management/control stack");
57MODULE_AUTHOR
58 ("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
59MODULE_LICENSE("GPL");
60
61#define DRV_NAME "ieee80211"
62
63static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
64{
65 if (ieee->networks)
66 return 0;
67
68 ieee->networks =
69 kmalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
70 GFP_KERNEL);
71 if (!ieee->networks) {
72 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
73 ieee->dev->name);
74 return -ENOMEM;
75 }
76
77 memset(ieee->networks, 0,
78 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
79
80 return 0;
81}
82
83static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
84{
85 if (!ieee->networks)
86 return;
87 kfree(ieee->networks);
88 ieee->networks = NULL;
89}
90
91static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
92{
93 int i;
94
95 INIT_LIST_HEAD(&ieee->network_free_list);
96 INIT_LIST_HEAD(&ieee->network_list);
97 for (i = 0; i < MAX_NETWORK_COUNT; i++)
98 list_add_tail(&ieee->networks[i].list,
99 &ieee->network_free_list);
100}
101
102struct net_device *alloc_ieee80211(int sizeof_priv)
103{
104 struct ieee80211_device *ieee;
105 struct net_device *dev;
106 int err;
107
108 IEEE80211_DEBUG_INFO("Initializing...\n");
109
110 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
111 if (!dev) {
112 IEEE80211_ERROR("Unable to network device.\n");
113 goto failed;
114 }
115 ieee = netdev_priv(dev);
116 dev->hard_start_xmit = ieee80211_xmit;
117
118 ieee->dev = dev;
119
120 err = ieee80211_networks_allocate(ieee);
121 if (err) {
122 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
123 goto failed;
124 }
125 ieee80211_networks_initialize(ieee);
126
127 /* Default fragmentation threshold is maximum payload size */
128 ieee->fts = DEFAULT_FTS;
129 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
130 ieee->open_wep = 1;
131
132 /* Default to enabling full open WEP with host based encrypt/decrypt */
133 ieee->host_encrypt = 1;
134 ieee->host_decrypt = 1;
135 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
136
137 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
138 init_timer(&ieee->crypt_deinit_timer);
139 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
140 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
141
142 spin_lock_init(&ieee->lock);
143
144 ieee->wpa_enabled = 0;
145 ieee->tkip_countermeasures = 0;
146 ieee->drop_unencrypted = 0;
147 ieee->privacy_invoked = 0;
148 ieee->ieee802_1x = 1;
149
150 return dev;
151
152 failed:
153 if (dev)
154 free_netdev(dev);
155 return NULL;
156}
157
158void free_ieee80211(struct net_device *dev)
159{
160 struct ieee80211_device *ieee = netdev_priv(dev);
161
162 int i;
163
164 del_timer_sync(&ieee->crypt_deinit_timer);
165 ieee80211_crypt_deinit_entries(ieee, 1);
166
167 for (i = 0; i < WEP_KEYS; i++) {
168 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
169 if (crypt) {
170 if (crypt->ops) {
171 crypt->ops->deinit(crypt->priv);
172 module_put(crypt->ops->owner);
173 }
174 kfree(crypt);
175 ieee->crypt[i] = NULL;
176 }
177 }
178
179 ieee80211_networks_free(ieee);
180 free_netdev(dev);
181}
182
183#ifdef CONFIG_IEEE80211_DEBUG
184
185static int debug = 0;
186u32 ieee80211_debug_level = 0;
187struct proc_dir_entry *ieee80211_proc = NULL;
188
189static int show_debug_level(char *page, char **start, off_t offset,
190 int count, int *eof, void *data)
191{
192 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
193}
194
195static int store_debug_level(struct file *file, const char __user * buffer,
196 unsigned long count, void *data)
197{
198 char buf[] = "0x00000000";
199 char *p = (char *)buf;
200 unsigned long val;
201
202 if (count > sizeof(buf) - 1)
203 count = sizeof(buf) - 1;
204
205 if (copy_from_user(buf, buffer, count))
206 return count;
207 buf[count] = 0;
208 /*
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
221 ": %s is not in hex or decimal form.\n", buf);
222 else
223 ieee80211_debug_level = val;
224
225 return strlen(buf);
226}
227
228static int __init ieee80211_init(void)
229{
230 struct proc_dir_entry *e;
231
232 ieee80211_debug_level = debug;
233 ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
234 if (ieee80211_proc == NULL) {
235 IEEE80211_ERROR("Unable to create " DRV_NAME
236 " proc directory\n");
237 return -EIO;
238 }
239 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
240 ieee80211_proc);
241 if (!e) {
242 remove_proc_entry(DRV_NAME, proc_net);
243 ieee80211_proc = NULL;
244 return -EIO;
245 }
246 e->read_proc = show_debug_level;
247 e->write_proc = store_debug_level;
248 e->data = NULL;
249
250 return 0;
251}
252
253static void __exit ieee80211_exit(void)
254{
255 if (ieee80211_proc) {
256 remove_proc_entry("debug_level", ieee80211_proc);
257 remove_proc_entry(DRV_NAME, proc_net);
258 ieee80211_proc = NULL;
259 }
260}
261
262#include <linux/moduleparam.h>
263module_param(debug, int, 0444);
264MODULE_PARM_DESC(debug, "debug output mask");
265
266module_exit(ieee80211_exit);
267module_init(ieee80211_init);
268#endif
269
270const char *escape_essid(const char *essid, u8 essid_len)
271{
272 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
273 const char *s = essid;
274 char *d = escaped;
275
276 if (ieee80211_is_empty_essid(essid, essid_len)) {
277 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
278 return escaped;
279 }
280
281 essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
282 while (essid_len--) {
283 if (*s == '\0') {
284 *d++ = '\\';
285 *d++ = '0';
286 s++;
287 } else {
288 *d++ = *s++;
289 }
290 }
291 *d = '\0';
292 return escaped;
293}
294
295EXPORT_SYMBOL(alloc_ieee80211);
296EXPORT_SYMBOL(free_ieee80211);
297EXPORT_SYMBOL(escape_essid);
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
new file mode 100644
index 000000000000..f7dcd854139e
--- /dev/null
+++ b/net/ieee80211/ieee80211_rx.c
@@ -0,0 +1,1193 @@
1/*
2 * Original code based Host AP (software wireless LAN access point) driver
3 * for Intersil Prism2/2.5/3 - hostap.o module, common routines
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8 * Copyright (c) 2004, Intel Corporation
9 *
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
12 * published by the Free Software Foundation. See README and COPYING for
13 * more details.
14 */
15
16#include <linux/compiler.h>
17#include <linux/config.h>
18#include <linux/errno.h>
19#include <linux/if_arp.h>
20#include <linux/in6.h>
21#include <linux/in.h>
22#include <linux/ip.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/netdevice.h>
26#include <linux/proc_fs.h>
27#include <linux/skbuff.h>
28#include <linux/slab.h>
29#include <linux/tcp.h>
30#include <linux/types.h>
31#include <linux/version.h>
32#include <linux/wireless.h>
33#include <linux/etherdevice.h>
34#include <asm/uaccess.h>
35#include <linux/ctype.h>
36
37#include <net/ieee80211.h>
38
39static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
40 struct sk_buff *skb,
41 struct ieee80211_rx_stats *rx_stats)
42{
43 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
44 u16 fc = le16_to_cpu(hdr->frame_ctl);
45
46 skb->dev = ieee->dev;
47 skb->mac.raw = skb->data;
48 skb_pull(skb, ieee80211_get_hdrlen(fc));
49 skb->pkt_type = PACKET_OTHERHOST;
50 skb->protocol = __constant_htons(ETH_P_80211_RAW);
51 memset(skb->cb, 0, sizeof(skb->cb));
52 netif_rx(skb);
53}
54
55/* Called only as a tasklet (software IRQ) */
56static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
57 ieee80211_device
58 *ieee,
59 unsigned int seq,
60 unsigned int frag,
61 u8 * src,
62 u8 * dst)
63{
64 struct ieee80211_frag_entry *entry;
65 int i;
66
67 for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
68 entry = &ieee->frag_cache[i];
69 if (entry->skb != NULL &&
70 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
71 IEEE80211_DEBUG_FRAG("expiring fragment cache entry "
72 "seq=%u last_frag=%u\n",
73 entry->seq, entry->last_frag);
74 dev_kfree_skb_any(entry->skb);
75 entry->skb = NULL;
76 }
77
78 if (entry->skb != NULL && entry->seq == seq &&
79 (entry->last_frag + 1 == frag || frag == -1) &&
80 memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
81 memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
82 return entry;
83 }
84
85 return NULL;
86}
87
88/* Called only as a tasklet (software IRQ) */
89static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
90 struct ieee80211_hdr *hdr)
91{
92 struct sk_buff *skb = NULL;
93 u16 sc;
94 unsigned int frag, seq;
95 struct ieee80211_frag_entry *entry;
96
97 sc = le16_to_cpu(hdr->seq_ctl);
98 frag = WLAN_GET_SEQ_FRAG(sc);
99 seq = WLAN_GET_SEQ_SEQ(sc);
100
101 if (frag == 0) {
102 /* Reserve enough space to fit maximum frame length */
103 skb = dev_alloc_skb(ieee->dev->mtu +
104 sizeof(struct ieee80211_hdr) +
105 8 /* LLC */ +
106 2 /* alignment */ +
107 8 /* WEP */ + ETH_ALEN /* WDS */ );
108 if (skb == NULL)
109 return NULL;
110
111 entry = &ieee->frag_cache[ieee->frag_next_idx];
112 ieee->frag_next_idx++;
113 if (ieee->frag_next_idx >= IEEE80211_FRAG_CACHE_LEN)
114 ieee->frag_next_idx = 0;
115
116 if (entry->skb != NULL)
117 dev_kfree_skb_any(entry->skb);
118
119 entry->first_frag_time = jiffies;
120 entry->seq = seq;
121 entry->last_frag = frag;
122 entry->skb = skb;
123 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
124 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
125 } else {
126 /* received a fragment of a frame for which the head fragment
127 * should have already been received */
128 entry = ieee80211_frag_cache_find(ieee, seq, frag, hdr->addr2,
129 hdr->addr1);
130 if (entry != NULL) {
131 entry->last_frag = frag;
132 skb = entry->skb;
133 }
134 }
135
136 return skb;
137}
138
139/* Called only as a tasklet (software IRQ) */
140static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
141 struct ieee80211_hdr *hdr)
142{
143 u16 sc;
144 unsigned int seq;
145 struct ieee80211_frag_entry *entry;
146
147 sc = le16_to_cpu(hdr->seq_ctl);
148 seq = WLAN_GET_SEQ_SEQ(sc);
149
150 entry = ieee80211_frag_cache_find(ieee, seq, -1, hdr->addr2,
151 hdr->addr1);
152
153 if (entry == NULL) {
154 IEEE80211_DEBUG_FRAG("could not invalidate fragment cache "
155 "entry (seq=%u)\n", seq);
156 return -1;
157 }
158
159 entry->skb = NULL;
160 return 0;
161}
162
163#ifdef NOT_YET
164/* ieee80211_rx_frame_mgtmt
165 *
166 * Responsible for handling management control frames
167 *
168 * Called by ieee80211_rx */
169static inline int
170ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
171 struct ieee80211_rx_stats *rx_stats, u16 type,
172 u16 stype)
173{
174 if (ieee->iw_mode == IW_MODE_MASTER) {
175 printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
176 ieee->dev->name);
177 return 0;
178/*
179 hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
180 skb->data);*/
181 }
182
183 if (ieee->hostapd && type == WLAN_FC_TYPE_MGMT) {
184 if (stype == WLAN_FC_STYPE_BEACON &&
185 ieee->iw_mode == IW_MODE_MASTER) {
186 struct sk_buff *skb2;
187 /* Process beacon frames also in kernel driver to
188 * update STA(AP) table statistics */
189 skb2 = skb_clone(skb, GFP_ATOMIC);
190 if (skb2)
191 hostap_rx(skb2->dev, skb2, rx_stats);
192 }
193
194 /* send management frames to the user space daemon for
195 * processing */
196 ieee->apdevstats.rx_packets++;
197 ieee->apdevstats.rx_bytes += skb->len;
198 prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
199 return 0;
200 }
201
202 if (ieee->iw_mode == IW_MODE_MASTER) {
203 if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
204 printk(KERN_DEBUG "%s: unknown management frame "
205 "(type=0x%02x, stype=0x%02x) dropped\n",
206 skb->dev->name, type, stype);
207 return -1;
208 }
209
210 hostap_rx(skb->dev, skb, rx_stats);
211 return 0;
212 }
213
214 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
215 "received in non-Host AP mode\n", skb->dev->name);
216 return -1;
217}
218#endif
219
220/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
221/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
222static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
223
224/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
225static unsigned char bridge_tunnel_header[] =
226 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
227/* No encapsulation header if EtherType < 0x600 (=length) */
228
229/* Called by ieee80211_rx_frame_decrypt */
230static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
231 struct sk_buff *skb)
232{
233 struct net_device *dev = ieee->dev;
234 u16 fc, ethertype;
235 struct ieee80211_hdr *hdr;
236 u8 *pos;
237
238 if (skb->len < 24)
239 return 0;
240
241 hdr = (struct ieee80211_hdr *)skb->data;
242 fc = le16_to_cpu(hdr->frame_ctl);
243
244 /* check that the frame is unicast frame to us */
245 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
246 IEEE80211_FCTL_TODS &&
247 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
248 memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
249 /* ToDS frame with own addr BSSID and DA */
250 } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
251 IEEE80211_FCTL_FROMDS &&
252 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
253 /* FromDS frame with own addr as DA */
254 } else
255 return 0;
256
257 if (skb->len < 24 + 8)
258 return 0;
259
260 /* check for port access entity Ethernet type */
261 pos = skb->data + 24;
262 ethertype = (pos[6] << 8) | pos[7];
263 if (ethertype == ETH_P_PAE)
264 return 1;
265
266 return 0;
267}
268
269/* Called only as a tasklet (software IRQ), by ieee80211_rx */
270static inline int
271ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
272 struct ieee80211_crypt_data *crypt)
273{
274 struct ieee80211_hdr *hdr;
275 int res, hdrlen;
276
277 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
278 return 0;
279
280 hdr = (struct ieee80211_hdr *)skb->data;
281 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
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);
295 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
296 atomic_dec(&crypt->refcnt);
297 if (res < 0) {
298 IEEE80211_DEBUG_DROP("decryption failed (SA=" MAC_FMT
299 ") res=%d\n", MAC_ARG(hdr->addr2), res);
300 if (res == -2)
301 IEEE80211_DEBUG_DROP("Decryption failed ICV "
302 "mismatch (key %d)\n",
303 skb->data[hdrlen + 3] >> 6);
304 ieee->ieee_stats.rx_discards_undecryptable++;
305 return -1;
306 }
307
308 return res;
309}
310
311/* Called only as a tasklet (software IRQ), by ieee80211_rx */
312static inline int
313ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
314 struct sk_buff *skb, int keyidx,
315 struct ieee80211_crypt_data *crypt)
316{
317 struct ieee80211_hdr *hdr;
318 int res, hdrlen;
319
320 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
321 return 0;
322
323 hdr = (struct ieee80211_hdr *)skb->data;
324 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
325
326 atomic_inc(&crypt->refcnt);
327 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
328 atomic_dec(&crypt->refcnt);
329 if (res < 0) {
330 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
331 " (SA=" MAC_FMT " keyidx=%d)\n",
332 ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
333 return -1;
334 }
335
336 return 0;
337}
338
339/* All received frames are sent to this function. @skb contains the frame in
340 * IEEE 802.11 format, i.e., in the format it was sent over air.
341 * This function is called only as a tasklet (software IRQ). */
342int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
343 struct ieee80211_rx_stats *rx_stats)
344{
345 struct net_device *dev = ieee->dev;
346 struct ieee80211_hdr *hdr;
347 size_t hdrlen;
348 u16 fc, type, stype, sc;
349 struct net_device_stats *stats;
350 unsigned int frag;
351 u8 *payload;
352 u16 ethertype;
353#ifdef NOT_YET
354 struct net_device *wds = NULL;
355 struct sk_buff *skb2 = NULL;
356 struct net_device *wds = NULL;
357 int frame_authorized = 0;
358 int from_assoc_ap = 0;
359 void *sta = NULL;
360#endif
361 u8 dst[ETH_ALEN];
362 u8 src[ETH_ALEN];
363 struct ieee80211_crypt_data *crypt = NULL;
364 int keyidx = 0;
365
366 hdr = (struct ieee80211_hdr *)skb->data;
367 stats = &ieee->stats;
368
369 if (skb->len < 10) {
370 printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
371 goto rx_dropped;
372 }
373
374 fc = le16_to_cpu(hdr->frame_ctl);
375 type = WLAN_FC_GET_TYPE(fc);
376 stype = WLAN_FC_GET_STYPE(fc);
377 sc = le16_to_cpu(hdr->seq_ctl);
378 frag = WLAN_GET_SEQ_FRAG(sc);
379 hdrlen = ieee80211_get_hdrlen(fc);
380
381#ifdef NOT_YET
382#if WIRELESS_EXT > 15
383 /* Put this code here so that we avoid duplicating it in all
384 * Rx paths. - Jean II */
385#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
386 /* If spy monitoring on */
387 if (iface->spy_data.spy_number > 0) {
388 struct iw_quality wstats;
389 wstats.level = rx_stats->signal;
390 wstats.noise = rx_stats->noise;
391 wstats.updated = 6; /* No qual value */
392 /* Update spy records */
393 wireless_spy_update(dev, hdr->addr2, &wstats);
394 }
395#endif /* IW_WIRELESS_SPY */
396#endif /* WIRELESS_EXT > 15 */
397 hostap_update_rx_stats(local->ap, hdr, rx_stats);
398#endif
399
400#if WIRELESS_EXT > 15
401 if (ieee->iw_mode == IW_MODE_MONITOR) {
402 ieee80211_monitor_rx(ieee, skb, rx_stats);
403 stats->rx_packets++;
404 stats->rx_bytes += skb->len;
405 return 1;
406 }
407#endif
408
409 if (ieee->host_decrypt) {
410 int idx = 0;
411 if (skb->len >= hdrlen + 3)
412 idx = skb->data[hdrlen + 3] >> 6;
413 crypt = ieee->crypt[idx];
414#ifdef NOT_YET
415 sta = NULL;
416
417 /* Use station specific key to override default keys if the
418 * receiver address is a unicast address ("individual RA"). If
419 * bcrx_sta_key parameter is set, station specific key is used
420 * even with broad/multicast targets (this is against IEEE
421 * 802.11, but makes it easier to use different keys with
422 * stations that do not support WEP key mapping). */
423
424 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
425 (void)hostap_handle_sta_crypto(local, hdr, &crypt,
426 &sta);
427#endif
428
429 /* allow NULL decrypt to indicate an station specific override
430 * for default encryption */
431 if (crypt && (crypt->ops == NULL ||
432 crypt->ops->decrypt_mpdu == NULL))
433 crypt = NULL;
434
435 if (!crypt && (fc & IEEE80211_FCTL_PROTECTED)) {
436 /* This seems to be triggered by some (multicast?)
437 * frames from other than current BSS, so just drop the
438 * frames silently instead of filling system log with
439 * these reports. */
440 IEEE80211_DEBUG_DROP("Decryption failed (not set)"
441 " (SA=" MAC_FMT ")\n",
442 MAC_ARG(hdr->addr2));
443 ieee->ieee_stats.rx_discards_undecryptable++;
444 goto rx_dropped;
445 }
446 }
447#ifdef NOT_YET
448 if (type != WLAN_FC_TYPE_DATA) {
449 if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_AUTH &&
450 fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt &&
451 (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
452 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
453 "from " MAC_FMT "\n", dev->name,
454 MAC_ARG(hdr->addr2));
455 /* TODO: could inform hostapd about this so that it
456 * could send auth failure report */
457 goto rx_dropped;
458 }
459
460 if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
461 goto rx_dropped;
462 else
463 goto rx_exit;
464 }
465#endif
466
467 /* Data frame - extract src/dst addresses */
468 if (skb->len < IEEE80211_3ADDR_LEN)
469 goto rx_dropped;
470
471 switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
472 case IEEE80211_FCTL_FROMDS:
473 memcpy(dst, hdr->addr1, ETH_ALEN);
474 memcpy(src, hdr->addr3, ETH_ALEN);
475 break;
476 case IEEE80211_FCTL_TODS:
477 memcpy(dst, hdr->addr3, ETH_ALEN);
478 memcpy(src, hdr->addr2, ETH_ALEN);
479 break;
480 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
481 if (skb->len < IEEE80211_4ADDR_LEN)
482 goto rx_dropped;
483 memcpy(dst, hdr->addr3, ETH_ALEN);
484 memcpy(src, hdr->addr4, ETH_ALEN);
485 break;
486 case 0:
487 memcpy(dst, hdr->addr1, ETH_ALEN);
488 memcpy(src, hdr->addr2, ETH_ALEN);
489 break;
490 }
491
492#ifdef NOT_YET
493 if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
494 goto rx_dropped;
495 if (wds) {
496 skb->dev = dev = wds;
497 stats = hostap_get_stats(dev);
498 }
499
500 if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
501 (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
502 IEEE80211_FCTL_FROMDS && ieee->stadev
503 && memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
504 /* Frame from BSSID of the AP for which we are a client */
505 skb->dev = dev = ieee->stadev;
506 stats = hostap_get_stats(dev);
507 from_assoc_ap = 1;
508 }
509#endif
510
511 dev->last_rx = jiffies;
512
513#ifdef NOT_YET
514 if ((ieee->iw_mode == IW_MODE_MASTER ||
515 ieee->iw_mode == IW_MODE_REPEAT) && !from_assoc_ap) {
516 switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
517 wds != NULL)) {
518 case AP_RX_CONTINUE_NOT_AUTHORIZED:
519 frame_authorized = 0;
520 break;
521 case AP_RX_CONTINUE:
522 frame_authorized = 1;
523 break;
524 case AP_RX_DROP:
525 goto rx_dropped;
526 case AP_RX_EXIT:
527 goto rx_exit;
528 }
529 }
530#endif
531
532 /* Nullfunc frames may have PS-bit set, so they must be passed to
533 * hostap_handle_sta_rx() before being dropped here. */
534 if (stype != IEEE80211_STYPE_DATA &&
535 stype != IEEE80211_STYPE_DATA_CFACK &&
536 stype != IEEE80211_STYPE_DATA_CFPOLL &&
537 stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
538 if (stype != IEEE80211_STYPE_NULLFUNC)
539 IEEE80211_DEBUG_DROP("RX: dropped data frame "
540 "with no data (type=0x%02x, "
541 "subtype=0x%02x, len=%d)\n",
542 type, stype, skb->len);
543 goto rx_dropped;
544 }
545
546 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
547
548 if (ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
549 (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
550 goto rx_dropped;
551
552 hdr = (struct ieee80211_hdr *)skb->data;
553
554 /* skb: hdr + (possibly fragmented) plaintext payload */
555 // PR: FIXME: hostap has additional conditions in the "if" below:
556 // ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
557 if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
558 int flen;
559 struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
560 IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
561
562 if (!frag_skb) {
563 IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
564 "Rx cannot get skb from fragment "
565 "cache (morefrag=%d seq=%u frag=%u)\n",
566 (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
567 WLAN_GET_SEQ_SEQ(sc), frag);
568 goto rx_dropped;
569 }
570
571 flen = skb->len;
572 if (frag != 0)
573 flen -= hdrlen;
574
575 if (frag_skb->tail + flen > frag_skb->end) {
576 printk(KERN_WARNING "%s: host decrypted and "
577 "reassembled frame did not fit skb\n",
578 dev->name);
579 ieee80211_frag_cache_invalidate(ieee, hdr);
580 goto rx_dropped;
581 }
582
583 if (frag == 0) {
584 /* copy first fragment (including full headers) into
585 * beginning of the fragment cache skb */
586 memcpy(skb_put(frag_skb, flen), skb->data, flen);
587 } else {
588 /* append frame payload to the end of the fragment
589 * cache skb */
590 memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
591 flen);
592 }
593 dev_kfree_skb_any(skb);
594 skb = NULL;
595
596 if (fc & IEEE80211_FCTL_MOREFRAGS) {
597 /* more fragments expected - leave the skb in fragment
598 * cache for now; it will be delivered to upper layers
599 * after all fragments have been received */
600 goto rx_exit;
601 }
602
603 /* this was the last fragment and the frame will be
604 * delivered, so remove skb from fragment cache */
605 skb = frag_skb;
606 hdr = (struct ieee80211_hdr *)skb->data;
607 ieee80211_frag_cache_invalidate(ieee, hdr);
608 }
609
610 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
611 * encrypted/authenticated */
612 if (ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
613 ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
614 goto rx_dropped;
615
616 hdr = (struct ieee80211_hdr *)skb->data;
617 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
618 if ( /*ieee->ieee802_1x && */
619 ieee80211_is_eapol_frame(ieee, skb)) {
620 /* pass unencrypted EAPOL frames even if encryption is
621 * configured */
622 } else {
623 IEEE80211_DEBUG_DROP("encryption configured, but RX "
624 "frame not encrypted (SA=" MAC_FMT
625 ")\n", MAC_ARG(hdr->addr2));
626 goto rx_dropped;
627 }
628 }
629
630 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
631 !ieee80211_is_eapol_frame(ieee, skb)) {
632 IEEE80211_DEBUG_DROP("dropped unencrypted RX data "
633 "frame from " MAC_FMT
634 " (drop_unencrypted=1)\n",
635 MAC_ARG(hdr->addr2));
636 goto rx_dropped;
637 }
638
639 /* skb: hdr + (possible reassembled) full plaintext payload */
640
641 payload = skb->data + hdrlen;
642 ethertype = (payload[6] << 8) | payload[7];
643
644#ifdef NOT_YET
645 /* If IEEE 802.1X is used, check whether the port is authorized to send
646 * the received frame. */
647 if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
648 if (ethertype == ETH_P_PAE) {
649 printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
650 dev->name);
651 if (ieee->hostapd && ieee->apdev) {
652 /* Send IEEE 802.1X frames to the user
653 * space daemon for processing */
654 prism2_rx_80211(ieee->apdev, skb, rx_stats,
655 PRISM2_RX_MGMT);
656 ieee->apdevstats.rx_packets++;
657 ieee->apdevstats.rx_bytes += skb->len;
658 goto rx_exit;
659 }
660 } else if (!frame_authorized) {
661 printk(KERN_DEBUG "%s: dropped frame from "
662 "unauthorized port (IEEE 802.1X): "
663 "ethertype=0x%04x\n", dev->name, ethertype);
664 goto rx_dropped;
665 }
666 }
667#endif
668
669 /* convert hdr + possible LLC headers into Ethernet header */
670 if (skb->len - hdrlen >= 8 &&
671 ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
672 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
673 memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
674 /* remove RFC1042 or Bridge-Tunnel encapsulation and
675 * replace EtherType */
676 skb_pull(skb, hdrlen + SNAP_SIZE);
677 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
678 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
679 } else {
680 u16 len;
681 /* Leave Ethernet header part of hdr and full payload */
682 skb_pull(skb, hdrlen);
683 len = htons(skb->len);
684 memcpy(skb_push(skb, 2), &len, 2);
685 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
686 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
687 }
688
689#ifdef NOT_YET
690 if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
691 IEEE80211_FCTL_TODS) && skb->len >= ETH_HLEN + ETH_ALEN) {
692 /* Non-standard frame: get addr4 from its bogus location after
693 * the payload */
694 memcpy(skb->data + ETH_ALEN,
695 skb->data + skb->len - ETH_ALEN, ETH_ALEN);
696 skb_trim(skb, skb->len - ETH_ALEN);
697 }
698#endif
699
700 stats->rx_packets++;
701 stats->rx_bytes += skb->len;
702
703#ifdef NOT_YET
704 if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) {
705 if (dst[0] & 0x01) {
706 /* copy multicast frame both to the higher layers and
707 * to the wireless media */
708 ieee->ap->bridged_multicast++;
709 skb2 = skb_clone(skb, GFP_ATOMIC);
710 if (skb2 == NULL)
711 printk(KERN_DEBUG "%s: skb_clone failed for "
712 "multicast frame\n", dev->name);
713 } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
714 /* send frame directly to the associated STA using
715 * wireless media and not passing to higher layers */
716 ieee->ap->bridged_unicast++;
717 skb2 = skb;
718 skb = NULL;
719 }
720 }
721
722 if (skb2 != NULL) {
723 /* send to wireless media */
724 skb2->protocol = __constant_htons(ETH_P_802_3);
725 skb2->mac.raw = skb2->nh.raw = skb2->data;
726 /* skb2->nh.raw = skb2->data + ETH_HLEN; */
727 skb2->dev = dev;
728 dev_queue_xmit(skb2);
729 }
730#endif
731
732 if (skb) {
733 skb->protocol = eth_type_trans(skb, dev);
734 memset(skb->cb, 0, sizeof(skb->cb));
735 skb->dev = dev;
736 skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
737 netif_rx(skb);
738 }
739
740 rx_exit:
741#ifdef NOT_YET
742 if (sta)
743 hostap_handle_sta_release(sta);
744#endif
745 return 1;
746
747 rx_dropped:
748 stats->rx_dropped++;
749
750 /* Returning 0 indicates to caller that we have not handled the SKB--
751 * so it is still allocated and can be used again by underlying
752 * hardware as a DMA target */
753 return 0;
754}
755
756#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
757
758static inline int ieee80211_is_ofdm_rate(u8 rate)
759{
760 switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
761 case IEEE80211_OFDM_RATE_6MB:
762 case IEEE80211_OFDM_RATE_9MB:
763 case IEEE80211_OFDM_RATE_12MB:
764 case IEEE80211_OFDM_RATE_18MB:
765 case IEEE80211_OFDM_RATE_24MB:
766 case IEEE80211_OFDM_RATE_36MB:
767 case IEEE80211_OFDM_RATE_48MB:
768 case IEEE80211_OFDM_RATE_54MB:
769 return 1;
770 }
771 return 0;
772}
773
774static inline int ieee80211_network_init(struct ieee80211_device *ieee,
775 struct ieee80211_probe_response
776 *beacon,
777 struct ieee80211_network *network,
778 struct ieee80211_rx_stats *stats)
779{
780#ifdef CONFIG_IEEE80211_DEBUG
781 char rates_str[64];
782 char *p;
783#endif
784 struct ieee80211_info_element *info_element;
785 u16 left;
786 u8 i;
787
788 /* Pull out fixed field data */
789 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
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
803 if (stats->freq == IEEE80211_52GHZ_BAND) {
804 /* for A band (No DS info) */
805 network->channel = stats->received_channel;
806 } else
807 network->flags |= NETWORK_HAS_CCK;
808
809 network->wpa_ie_len = 0;
810 network->rsn_ie_len = 0;
811
812 info_element = &beacon->info_element;
813 left = stats->len - ((void *)info_element - (void *)beacon);
814 while (left >= sizeof(struct ieee80211_info_element_hdr)) {
815 if (sizeof(struct ieee80211_info_element_hdr) +
816 info_element->len > left) {
817 IEEE80211_DEBUG_SCAN
818 ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n",
819 info_element->len +
820 sizeof(struct ieee80211_info_element), left);
821 return 1;
822 }
823
824 switch (info_element->id) {
825 case MFIE_TYPE_SSID:
826 if (ieee80211_is_empty_essid(info_element->data,
827 info_element->len)) {
828 network->flags |= NETWORK_EMPTY_ESSID;
829 break;
830 }
831
832 network->ssid_len = min(info_element->len,
833 (u8) IW_ESSID_MAX_SIZE);
834 memcpy(network->ssid, info_element->data,
835 network->ssid_len);
836 if (network->ssid_len < IW_ESSID_MAX_SIZE)
837 memset(network->ssid + network->ssid_len, 0,
838 IW_ESSID_MAX_SIZE - network->ssid_len);
839
840 IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
841 network->ssid, network->ssid_len);
842 break;
843
844 case MFIE_TYPE_RATES:
845#ifdef CONFIG_IEEE80211_DEBUG
846 p = rates_str;
847#endif
848 network->rates_len =
849 min(info_element->len, MAX_RATES_LENGTH);
850 for (i = 0; i < network->rates_len; i++) {
851 network->rates[i] = info_element->data[i];
852#ifdef CONFIG_IEEE80211_DEBUG
853 p += snprintf(p,
854 sizeof(rates_str) - (p -
855 rates_str),
856 "%02X ", network->rates[i]);
857#endif
858 if (ieee80211_is_ofdm_rate
859 (info_element->data[i])) {
860 network->flags |= NETWORK_HAS_OFDM;
861 if (info_element->data[i] &
862 IEEE80211_BASIC_RATE_MASK)
863 network->flags &=
864 ~NETWORK_HAS_CCK;
865 }
866 }
867
868 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
869 rates_str, network->rates_len);
870 break;
871
872 case MFIE_TYPE_RATES_EX:
873#ifdef CONFIG_IEEE80211_DEBUG
874 p = rates_str;
875#endif
876 network->rates_ex_len =
877 min(info_element->len, MAX_RATES_EX_LENGTH);
878 for (i = 0; i < network->rates_ex_len; i++) {
879 network->rates_ex[i] = info_element->data[i];
880#ifdef CONFIG_IEEE80211_DEBUG
881 p += snprintf(p,
882 sizeof(rates_str) - (p -
883 rates_str),
884 "%02X ", network->rates[i]);
885#endif
886 if (ieee80211_is_ofdm_rate
887 (info_element->data[i])) {
888 network->flags |= NETWORK_HAS_OFDM;
889 if (info_element->data[i] &
890 IEEE80211_BASIC_RATE_MASK)
891 network->flags &=
892 ~NETWORK_HAS_CCK;
893 }
894 }
895
896 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
897 rates_str, network->rates_ex_len);
898 break;
899
900 case MFIE_TYPE_DS_SET:
901 IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
902 info_element->data[0]);
903 if (stats->freq == IEEE80211_24GHZ_BAND)
904 network->channel = info_element->data[0];
905 break;
906
907 case MFIE_TYPE_FH_SET:
908 IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
909 break;
910
911 case MFIE_TYPE_CF_SET:
912 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
913 break;
914
915 case MFIE_TYPE_TIM:
916 IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n");
917 break;
918
919 case MFIE_TYPE_IBSS_SET:
920 IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
921 break;
922
923 case MFIE_TYPE_CHALLENGE:
924 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
925 break;
926
927 case MFIE_TYPE_GENERIC:
928 IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
929 info_element->len);
930 if (info_element->len >= 4 &&
931 info_element->data[0] == 0x00 &&
932 info_element->data[1] == 0x50 &&
933 info_element->data[2] == 0xf2 &&
934 info_element->data[3] == 0x01) {
935 network->wpa_ie_len = min(info_element->len + 2,
936 MAX_WPA_IE_LEN);
937 memcpy(network->wpa_ie, info_element,
938 network->wpa_ie_len);
939 }
940 break;
941
942 case MFIE_TYPE_RSN:
943 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
944 info_element->len);
945 network->rsn_ie_len = min(info_element->len + 2,
946 MAX_WPA_IE_LEN);
947 memcpy(network->rsn_ie, info_element,
948 network->rsn_ie_len);
949 break;
950
951 default:
952 IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
953 info_element->id);
954 break;
955 }
956
957 left -= sizeof(struct ieee80211_info_element_hdr) +
958 info_element->len;
959 info_element = (struct ieee80211_info_element *)
960 &info_element->data[info_element->len];
961 }
962
963 network->mode = 0;
964 if (stats->freq == IEEE80211_52GHZ_BAND)
965 network->mode = IEEE_A;
966 else {
967 if (network->flags & NETWORK_HAS_OFDM)
968 network->mode |= IEEE_G;
969 if (network->flags & NETWORK_HAS_CCK)
970 network->mode |= IEEE_B;
971 }
972
973 if (network->mode == 0) {
974 IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
975 "network.\n",
976 escape_essid(network->ssid,
977 network->ssid_len),
978 MAC_ARG(network->bssid));
979 return 1;
980 }
981
982 if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
983 network->flags |= NETWORK_EMPTY_ESSID;
984
985 memcpy(&network->stats, stats, sizeof(network->stats));
986
987 return 0;
988}
989
990static inline int is_same_network(struct ieee80211_network *src,
991 struct ieee80211_network *dst)
992{
993 /* A network is only a duplicate if the channel, BSSID, and ESSID
994 * all match. We treat all <hidden> with the same BSSID and channel
995 * as one network */
996 return ((src->ssid_len == dst->ssid_len) &&
997 (src->channel == dst->channel) &&
998 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
999 !memcmp(src->ssid, dst->ssid, src->ssid_len));
1000}
1001
1002static inline void update_network(struct ieee80211_network *dst,
1003 struct ieee80211_network *src)
1004{
1005 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
1006 dst->capability = src->capability;
1007 memcpy(dst->rates, src->rates, src->rates_len);
1008 dst->rates_len = src->rates_len;
1009 memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
1010 dst->rates_ex_len = src->rates_ex_len;
1011
1012 dst->mode = src->mode;
1013 dst->flags = src->flags;
1014 dst->time_stamp[0] = src->time_stamp[0];
1015 dst->time_stamp[1] = src->time_stamp[1];
1016
1017 dst->beacon_interval = src->beacon_interval;
1018 dst->listen_interval = src->listen_interval;
1019 dst->atim_window = src->atim_window;
1020
1021 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
1022 dst->wpa_ie_len = src->wpa_ie_len;
1023 memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
1024 dst->rsn_ie_len = src->rsn_ie_len;
1025
1026 dst->last_scanned = jiffies;
1027 /* dst->last_associate is not overwritten */
1028}
1029
1030static inline void ieee80211_process_probe_response(struct ieee80211_device
1031 *ieee,
1032 struct
1033 ieee80211_probe_response
1034 *beacon,
1035 struct ieee80211_rx_stats
1036 *stats)
1037{
1038 struct ieee80211_network network;
1039 struct ieee80211_network *target;
1040 struct ieee80211_network *oldest = NULL;
1041#ifdef CONFIG_IEEE80211_DEBUG
1042 struct ieee80211_info_element *info_element = &beacon->info_element;
1043#endif
1044 unsigned long flags;
1045
1046 IEEE80211_DEBUG_SCAN("'%s' (" MAC_FMT
1047 "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
1048 escape_essid(info_element->data,
1049 info_element->len),
1050 MAC_ARG(beacon->header.addr3),
1051 (beacon->capability & (1 << 0xf)) ? '1' : '0',
1052 (beacon->capability & (1 << 0xe)) ? '1' : '0',
1053 (beacon->capability & (1 << 0xd)) ? '1' : '0',
1054 (beacon->capability & (1 << 0xc)) ? '1' : '0',
1055 (beacon->capability & (1 << 0xb)) ? '1' : '0',
1056 (beacon->capability & (1 << 0xa)) ? '1' : '0',
1057 (beacon->capability & (1 << 0x9)) ? '1' : '0',
1058 (beacon->capability & (1 << 0x8)) ? '1' : '0',
1059 (beacon->capability & (1 << 0x7)) ? '1' : '0',
1060 (beacon->capability & (1 << 0x6)) ? '1' : '0',
1061 (beacon->capability & (1 << 0x5)) ? '1' : '0',
1062 (beacon->capability & (1 << 0x4)) ? '1' : '0',
1063 (beacon->capability & (1 << 0x3)) ? '1' : '0',
1064 (beacon->capability & (1 << 0x2)) ? '1' : '0',
1065 (beacon->capability & (1 << 0x1)) ? '1' : '0',
1066 (beacon->capability & (1 << 0x0)) ? '1' : '0');
1067
1068 if (ieee80211_network_init(ieee, beacon, &network, stats)) {
1069 IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
1070 escape_essid(info_element->data,
1071 info_element->len),
1072 MAC_ARG(beacon->header.addr3),
1073 WLAN_FC_GET_STYPE(beacon->header.
1074 frame_ctl) ==
1075 IEEE80211_STYPE_PROBE_RESP ?
1076 "PROBE RESPONSE" : "BEACON");
1077 return;
1078 }
1079
1080 /* The network parsed correctly -- so now we scan our known networks
1081 * to see if we can find it in our list.
1082 *
1083 * NOTE: This search is definitely not optimized. Once its doing
1084 * the "right thing" we'll optimize it for efficiency if
1085 * necessary */
1086
1087 /* Search for this entry in the list and update it if it is
1088 * already there. */
1089
1090 spin_lock_irqsave(&ieee->lock, flags);
1091
1092 list_for_each_entry(target, &ieee->network_list, list) {
1093 if (is_same_network(target, &network))
1094 break;
1095
1096 if ((oldest == NULL) ||
1097 (target->last_scanned < oldest->last_scanned))
1098 oldest = target;
1099 }
1100
1101 /* If we didn't find a match, then get a new network slot to initialize
1102 * with this beacon's information */
1103 if (&target->list == &ieee->network_list) {
1104 if (list_empty(&ieee->network_free_list)) {
1105 /* If there are no more slots, expire the oldest */
1106 list_del(&oldest->list);
1107 target = oldest;
1108 IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
1109 "network list.\n",
1110 escape_essid(target->ssid,
1111 target->ssid_len),
1112 MAC_ARG(target->bssid));
1113 } else {
1114 /* Otherwise just pull from the free list */
1115 target = list_entry(ieee->network_free_list.next,
1116 struct ieee80211_network, list);
1117 list_del(ieee->network_free_list.next);
1118 }
1119
1120#ifdef CONFIG_IEEE80211_DEBUG
1121 IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
1122 escape_essid(network.ssid,
1123 network.ssid_len),
1124 MAC_ARG(network.bssid),
1125 WLAN_FC_GET_STYPE(beacon->header.
1126 frame_ctl) ==
1127 IEEE80211_STYPE_PROBE_RESP ?
1128 "PROBE RESPONSE" : "BEACON");
1129#endif
1130 memcpy(target, &network, sizeof(*target));
1131 list_add_tail(&target->list, &ieee->network_list);
1132 } else {
1133 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
1134 escape_essid(target->ssid,
1135 target->ssid_len),
1136 MAC_ARG(target->bssid),
1137 WLAN_FC_GET_STYPE(beacon->header.
1138 frame_ctl) ==
1139 IEEE80211_STYPE_PROBE_RESP ?
1140 "PROBE RESPONSE" : "BEACON");
1141 update_network(target, &network);
1142 }
1143
1144 spin_unlock_irqrestore(&ieee->lock, flags);
1145}
1146
1147void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1148 struct ieee80211_hdr *header,
1149 struct ieee80211_rx_stats *stats)
1150{
1151 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1152 case IEEE80211_STYPE_ASSOC_RESP:
1153 IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
1154 WLAN_FC_GET_STYPE(header->frame_ctl));
1155 break;
1156
1157 case IEEE80211_STYPE_REASSOC_RESP:
1158 IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
1159 WLAN_FC_GET_STYPE(header->frame_ctl));
1160 break;
1161
1162 case IEEE80211_STYPE_PROBE_RESP:
1163 IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
1164 WLAN_FC_GET_STYPE(header->frame_ctl));
1165 IEEE80211_DEBUG_SCAN("Probe response\n");
1166 ieee80211_process_probe_response(ieee,
1167 (struct
1168 ieee80211_probe_response *)
1169 header, stats);
1170 break;
1171
1172 case IEEE80211_STYPE_BEACON:
1173 IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
1174 WLAN_FC_GET_STYPE(header->frame_ctl));
1175 IEEE80211_DEBUG_SCAN("Beacon\n");
1176 ieee80211_process_probe_response(ieee,
1177 (struct
1178 ieee80211_probe_response *)
1179 header, stats);
1180 break;
1181
1182 default:
1183 IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
1184 WLAN_FC_GET_STYPE(header->frame_ctl));
1185 IEEE80211_WARNING("%s: Unknown management packet: %d\n",
1186 ieee->dev->name,
1187 WLAN_FC_GET_STYPE(header->frame_ctl));
1188 break;
1189 }
1190}
1191
1192EXPORT_SYMBOL(ieee80211_rx_mgt);
1193EXPORT_SYMBOL(ieee80211_rx);
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
new file mode 100644
index 000000000000..c9aaff3fea1e
--- /dev/null
+++ b/net/ieee80211/ieee80211_tx.c
@@ -0,0 +1,428 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2004 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
48/*
49
50802.11 Data Frame
51
52 ,-------------------------------------------------------------------.
53Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
54 |------|------|---------|---------|---------|------|---------|------|
55Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
56 | | tion | (BSSID) | | | ence | data | |
57 `--------------------------------------------------| |------'
58Total: 28 non-data bytes `----.----'
59 |
60 .- 'Frame data' expands to <---------------------------'
61 |
62 V
63 ,---------------------------------------------------.
64Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
65 |------|------|---------|----------|------|---------|
66Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
67 | DSAP | SSAP | | | | Packet |
68 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
69 `-----------------------------------------| |
70Total: 8 non-data bytes `----.----'
71 |
72 .- 'IP Packet' expands, if WEP enabled, to <--'
73 |
74 V
75 ,-----------------------.
76Bytes | 4 | 0-2296 | 4 |
77 |-----|-----------|-----|
78Desc. | IV | Encrypted | ICV |
79 | | IP Packet | |
80 `-----------------------'
81Total: 8 non-data bytes
82
83802.3 Ethernet Data Frame
84
85 ,-----------------------------------------.
86Bytes | 6 | 6 | 2 | Variable | 4 |
87 |-------|-------|------|-----------|------|
88Desc. | Dest. | Source| Type | IP Packet | fcs |
89 | MAC | MAC | | | |
90 `-----------------------------------------'
91Total: 18 non-data bytes
92
93In the event that fragmentation is required, the incoming payload is split into
94N parts of size ieee->fts. The first fragment contains the SNAP header and the
95remaining packets are just data.
96
97If encryption is enabled, each fragment payload size is reduced by enough space
98to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
99So if you have 1500 bytes of payload with ieee->fts set to 500 without
100encryption it will take 3 frames. With WEP it will take 4 frames as the
101payload of each frame is reduced to 492 bytes.
102
103* SKB visualization
104*
105* ,- skb->data
106* |
107* | ETHERNET HEADER ,-<-- PAYLOAD
108* | | 14 bytes from skb->data
109* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
110* | | | |
111* |,-Dest.--. ,--Src.---. | | |
112* | 6 bytes| | 6 bytes | | | |
113* v | | | | | |
114* 0 | v 1 | v | v 2
115* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
116* ^ | ^ | ^ |
117* | | | | | |
118* | | | | `T' <---- 2 bytes for Type
119* | | | |
120* | | '---SNAP--' <-------- 6 bytes for SNAP
121* | |
122* `-IV--' <-------------------- 4 bytes for IV (WEP)
123*
124* SNAP HEADER
125*
126*/
127
128static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
129static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
130
131static inline int ieee80211_put_snap(u8 * data, u16 h_proto)
132{
133 struct ieee80211_snap_hdr *snap;
134 u8 *oui;
135
136 snap = (struct ieee80211_snap_hdr *)data;
137 snap->dsap = 0xaa;
138 snap->ssap = 0xaa;
139 snap->ctrl = 0x03;
140
141 if (h_proto == 0x8137 || h_proto == 0x80f3)
142 oui = P802_1H_OUI;
143 else
144 oui = RFC1042_OUI;
145 snap->oui[0] = oui[0];
146 snap->oui[1] = oui[1];
147 snap->oui[2] = oui[2];
148
149 *(u16 *) (data + SNAP_SIZE) = htons(h_proto);
150
151 return SNAP_SIZE + sizeof(u16);
152}
153
154static inline int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
155 struct sk_buff *frag, int hdr_len)
156{
157 struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
158 int res;
159
160#ifdef CONFIG_IEEE80211_CRYPT_TKIP
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;
172 }
173#endif
174 /* To encrypt, frame format is:
175 * 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);
181 res = 0;
182 if (crypt->ops->encrypt_msdu)
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);
186
187 atomic_dec(&crypt->refcnt);
188 if (res < 0) {
189 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
190 ieee->dev->name, frag->len);
191 ieee->ieee_stats.tx_discards++;
192 return -1;
193 }
194
195 return 0;
196}
197
198void ieee80211_txb_free(struct ieee80211_txb *txb)
199{
200 int i;
201 if (unlikely(!txb))
202 return;
203 for (i = 0; i < txb->nr_frags; i++)
204 if (txb->fragments[i])
205 dev_kfree_skb_any(txb->fragments[i]);
206 kfree(txb);
207}
208
209static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
210 int gfp_mask)
211{
212 struct ieee80211_txb *txb;
213 int i;
214 txb = kmalloc(sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
215 gfp_mask);
216 if (!txb)
217 return NULL;
218
219 memset(txb, 0, sizeof(struct ieee80211_txb));
220 txb->nr_frags = nr_frags;
221 txb->frag_size = txb_size;
222
223 for (i = 0; i < nr_frags; i++) {
224 txb->fragments[i] = dev_alloc_skb(txb_size);
225 if (unlikely(!txb->fragments[i])) {
226 i--;
227 break;
228 }
229 }
230 if (unlikely(i != nr_frags)) {
231 while (i >= 0)
232 dev_kfree_skb_any(txb->fragments[i--]);
233 kfree(txb);
234 return NULL;
235 }
236 return txb;
237}
238
239/* SKBs are added to the ieee->tx_queue. */
240int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
241{
242 struct ieee80211_device *ieee = netdev_priv(dev);
243 struct ieee80211_txb *txb = NULL;
244 struct ieee80211_hdr *frag_hdr;
245 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
246 unsigned long flags;
247 struct net_device_stats *stats = &ieee->stats;
248 int ether_type, encrypt;
249 int bytes, fc, hdr_len;
250 struct sk_buff *skb_frag;
251 struct ieee80211_hdr header = { /* Ensure zero initialized */
252 .duration_id = 0,
253 .seq_ctl = 0
254 };
255 u8 dest[ETH_ALEN], src[ETH_ALEN];
256
257 struct ieee80211_crypt_data *crypt;
258
259 spin_lock_irqsave(&ieee->lock, flags);
260
261 /* If there is no driver handler to take the TXB, dont' bother
262 * creating it... */
263 if (!ieee->hard_start_xmit) {
264 printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
265 goto success;
266 }
267
268 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
269 printk(KERN_WARNING "%s: skb too small (%d).\n",
270 ieee->dev->name, skb->len);
271 goto success;
272 }
273
274 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
275
276 crypt = ieee->crypt[ieee->tx_keyidx];
277
278 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
279 ieee->host_encrypt && crypt && crypt->ops;
280
281 if (!encrypt && ieee->ieee802_1x &&
282 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
283 stats->tx_dropped++;
284 goto success;
285 }
286
287 /* Save source and destination addresses */
288 memcpy(&dest, skb->data, ETH_ALEN);
289 memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN);
290
291 /* Advance the SKB to the start of the payload */
292 skb_pull(skb, sizeof(struct ethhdr));
293
294 /* Determine total amount of storage required for TXB packets */
295 bytes = skb->len + SNAP_SIZE + sizeof(u16);
296
297 if (encrypt)
298 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
299 IEEE80211_FCTL_PROTECTED;
300 else
301 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
302
303 if (ieee->iw_mode == IW_MODE_INFRA) {
304 fc |= IEEE80211_FCTL_TODS;
305 /* To DS: Addr1 = BSSID, Addr2 = SA,
306 Addr3 = DA */
307 memcpy(&header.addr1, ieee->bssid, ETH_ALEN);
308 memcpy(&header.addr2, &src, ETH_ALEN);
309 memcpy(&header.addr3, &dest, ETH_ALEN);
310 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
311 /* not From/To DS: Addr1 = DA, Addr2 = SA,
312 Addr3 = BSSID */
313 memcpy(&header.addr1, dest, ETH_ALEN);
314 memcpy(&header.addr2, src, ETH_ALEN);
315 memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
316 }
317 header.frame_ctl = cpu_to_le16(fc);
318 hdr_len = IEEE80211_3ADDR_LEN;
319
320 /* Determine fragmentation size based on destination (multicast
321 * and broadcast are not fragmented) */
322 if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest))
323 frag_size = MAX_FRAG_THRESHOLD;
324 else
325 frag_size = ieee->fts;
326
327 /* Determine amount of payload per fragment. Regardless of if
328 * this stack is providing the full 802.11 header, one will
329 * eventually be affixed to this fragment -- so we must account for
330 * it when determining the amount of payload space. */
331 bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
332 if (ieee->config &
333 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
334 bytes_per_frag -= IEEE80211_FCS_LEN;
335
336 /* Each fragment may need to have room for encryptiong pre/postfix */
337 if (encrypt)
338 bytes_per_frag -= crypt->ops->extra_prefix_len +
339 crypt->ops->extra_postfix_len;
340
341 /* Number of fragments is the total bytes_per_frag /
342 * payload_per_fragment */
343 nr_frags = bytes / bytes_per_frag;
344 bytes_last_frag = bytes % bytes_per_frag;
345 if (bytes_last_frag)
346 nr_frags++;
347 else
348 bytes_last_frag = bytes_per_frag;
349
350 /* When we allocate the TXB we allocate enough space for the reserve
351 * and full fragment bytes (bytes_per_frag doesn't include prefix,
352 * postfix, header, FCS, etc.) */
353 txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
354 if (unlikely(!txb)) {
355 printk(KERN_WARNING "%s: Could not allocate TXB\n",
356 ieee->dev->name);
357 goto failed;
358 }
359 txb->encrypted = encrypt;
360 txb->payload_size = bytes;
361
362 for (i = 0; i < nr_frags; i++) {
363 skb_frag = txb->fragments[i];
364
365 if (encrypt)
366 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
367
368 frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
369 memcpy(frag_hdr, &header, hdr_len);
370
371 /* If this is not the last fragment, then add the MOREFRAGS
372 * bit to the frame control */
373 if (i != nr_frags - 1) {
374 frag_hdr->frame_ctl =
375 cpu_to_le16(fc | IEEE80211_FCTL_MOREFRAGS);
376 bytes = bytes_per_frag;
377 } else {
378 /* The last fragment takes the remaining length */
379 bytes = bytes_last_frag;
380 }
381
382 /* Put a SNAP header on the first fragment */
383 if (i == 0) {
384 ieee80211_put_snap(skb_put
385 (skb_frag, SNAP_SIZE + sizeof(u16)),
386 ether_type);
387 bytes -= SNAP_SIZE + sizeof(u16);
388 }
389
390 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
391
392 /* Advance the SKB... */
393 skb_pull(skb, bytes);
394
395 /* Encryption routine will move the header forward in order
396 * to insert the IV between the header and the payload */
397 if (encrypt)
398 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
399 if (ieee->config &
400 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
401 skb_put(skb_frag, 4);
402 }
403
404 success:
405 spin_unlock_irqrestore(&ieee->lock, flags);
406
407 dev_kfree_skb_any(skb);
408
409 if (txb) {
410 if ((*ieee->hard_start_xmit) (txb, dev) == 0) {
411 stats->tx_packets++;
412 stats->tx_bytes += txb->payload_size;
413 return 0;
414 }
415 ieee80211_txb_free(txb);
416 }
417
418 return 0;
419
420 failed:
421 spin_unlock_irqrestore(&ieee->lock, flags);
422 netif_stop_queue(dev);
423 stats->tx_errors++;
424 return 1;
425
426}
427
428EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
new file mode 100644
index 000000000000..94882f39b072
--- /dev/null
+++ b/net/ieee80211/ieee80211_wx.c
@@ -0,0 +1,468 @@
1/******************************************************************************
2
3 Copyright(c) 2004 Intel Corporation. All rights reserved.
4
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <jkmaline@cc.hut.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31******************************************************************************/
32
33#include <linux/kmod.h>
34#include <linux/module.h>
35
36#include <net/ieee80211.h>
37#include <linux/wireless.h>
38
39static const char *ieee80211_modes[] = {
40 "?", "a", "b", "ab", "g", "ag", "bg", "abg"
41};
42
43#define MAX_CUSTOM_LEN 64
44static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
45 char *start, char *stop,
46 struct ieee80211_network *network)
47{
48 char custom[MAX_CUSTOM_LEN];
49 char *p;
50 struct iw_event iwe;
51 int i, j;
52 u8 max_rate, rate;
53
54 /* First entry *MUST* be the AP MAC address */
55 iwe.cmd = SIOCGIWAP;
56 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
57 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
58 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
59
60 /* Remaining entries will be displayed in the order we provide them */
61
62 /* Add the ESSID */
63 iwe.cmd = SIOCGIWESSID;
64 iwe.u.data.flags = 1;
65 if (network->flags & NETWORK_EMPTY_ESSID) {
66 iwe.u.data.length = sizeof("<hidden>");
67 start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
68 } else {
69 iwe.u.data.length = min(network->ssid_len, (u8) 32);
70 start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
71 }
72
73 /* Add the protocol name */
74 iwe.cmd = SIOCGIWNAME;
75 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
76 ieee80211_modes[network->mode]);
77 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
78
79 /* Add mode */
80 iwe.cmd = SIOCGIWMODE;
81 if (network->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
82 if (network->capability & WLAN_CAPABILITY_ESS)
83 iwe.u.mode = IW_MODE_MASTER;
84 else
85 iwe.u.mode = IW_MODE_ADHOC;
86
87 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
88 }
89
90 /* Add frequency/channel */
91 iwe.cmd = SIOCGIWFREQ;
92/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
93 iwe.u.freq.e = 3; */
94 iwe.u.freq.m = network->channel;
95 iwe.u.freq.e = 0;
96 iwe.u.freq.i = 0;
97 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
98
99 /* Add encryption capability */
100 iwe.cmd = SIOCGIWENCODE;
101 if (network->capability & WLAN_CAPABILITY_PRIVACY)
102 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
103 else
104 iwe.u.data.flags = IW_ENCODE_DISABLED;
105 iwe.u.data.length = 0;
106 start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
107
108 /* Add basic and extended rates */
109 max_rate = 0;
110 p = custom;
111 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
112 for (i = 0, j = 0; i < network->rates_len;) {
113 if (j < network->rates_ex_len &&
114 ((network->rates_ex[j] & 0x7F) <
115 (network->rates[i] & 0x7F)))
116 rate = network->rates_ex[j++] & 0x7F;
117 else
118 rate = network->rates[i++] & 0x7F;
119 if (rate > max_rate)
120 max_rate = rate;
121 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
122 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
123 }
124 for (; j < network->rates_ex_len; j++) {
125 rate = network->rates_ex[j] & 0x7F;
126 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
127 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
128 if (rate > max_rate)
129 max_rate = rate;
130 }
131
132 iwe.cmd = SIOCGIWRATE;
133 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
134 iwe.u.bitrate.value = max_rate * 500000;
135 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_PARAM_LEN);
136
137 iwe.cmd = IWEVCUSTOM;
138 iwe.u.data.length = p - custom;
139 if (iwe.u.data.length)
140 start = iwe_stream_add_point(start, stop, &iwe, custom);
141
142 /* Add quality statistics */
143 /* TODO: Fix these values... */
144 iwe.cmd = IWEVQUAL;
145 iwe.u.qual.qual = network->stats.signal;
146 iwe.u.qual.level = network->stats.rssi;
147 iwe.u.qual.noise = network->stats.noise;
148 iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
149 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
150 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
151 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
152 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
153 if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
154 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
155
156 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
157
158 iwe.cmd = IWEVCUSTOM;
159 p = custom;
160
161 iwe.u.data.length = p - custom;
162 if (iwe.u.data.length)
163 start = iwe_stream_add_point(start, stop, &iwe, custom);
164
165 if (ieee->wpa_enabled && network->wpa_ie_len) {
166 char buf[MAX_WPA_IE_LEN * 2 + 30];
167
168 u8 *p = buf;
169 p += sprintf(p, "wpa_ie=");
170 for (i = 0; i < network->wpa_ie_len; i++) {
171 p += sprintf(p, "%02x", network->wpa_ie[i]);
172 }
173
174 memset(&iwe, 0, sizeof(iwe));
175 iwe.cmd = IWEVCUSTOM;
176 iwe.u.data.length = strlen(buf);
177 start = iwe_stream_add_point(start, stop, &iwe, buf);
178 }
179
180 if (ieee->wpa_enabled && network->rsn_ie_len) {
181 char buf[MAX_WPA_IE_LEN * 2 + 30];
182
183 u8 *p = buf;
184 p += sprintf(p, "rsn_ie=");
185 for (i = 0; i < network->rsn_ie_len; i++) {
186 p += sprintf(p, "%02x", network->rsn_ie[i]);
187 }
188
189 memset(&iwe, 0, sizeof(iwe));
190 iwe.cmd = IWEVCUSTOM;
191 iwe.u.data.length = strlen(buf);
192 start = iwe_stream_add_point(start, stop, &iwe, buf);
193 }
194
195 /* Add EXTRA: Age to display seconds since last beacon/probe response
196 * for given network. */
197 iwe.cmd = IWEVCUSTOM;
198 p = custom;
199 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
200 " Last beacon: %lums ago",
201 (jiffies - network->last_scanned) / (HZ / 100));
202 iwe.u.data.length = p - custom;
203 if (iwe.u.data.length)
204 start = iwe_stream_add_point(start, stop, &iwe, custom);
205
206 return start;
207}
208
209int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
210 struct iw_request_info *info,
211 union iwreq_data *wrqu, char *extra)
212{
213 struct ieee80211_network *network;
214 unsigned long flags;
215
216 char *ev = extra;
217 char *stop = ev + IW_SCAN_MAX_DATA;
218 int i = 0;
219
220 IEEE80211_DEBUG_WX("Getting scan\n");
221
222 spin_lock_irqsave(&ieee->lock, flags);
223
224 list_for_each_entry(network, &ieee->network_list, list) {
225 i++;
226 if (ieee->scan_age == 0 ||
227 time_after(network->last_scanned + ieee->scan_age, jiffies))
228 ev = ipw2100_translate_scan(ieee, ev, stop, network);
229 else
230 IEEE80211_DEBUG_SCAN("Not showing network '%s ("
231 MAC_FMT ")' due to age (%lums).\n",
232 escape_essid(network->ssid,
233 network->ssid_len),
234 MAC_ARG(network->bssid),
235 (jiffies -
236 network->last_scanned) / (HZ /
237 100));
238 }
239
240 spin_unlock_irqrestore(&ieee->lock, flags);
241
242 wrqu->data.length = ev - extra;
243 wrqu->data.flags = 0;
244
245 IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
246
247 return 0;
248}
249
250int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
251 struct iw_request_info *info,
252 union iwreq_data *wrqu, char *keybuf)
253{
254 struct iw_point *erq = &(wrqu->encoding);
255 struct net_device *dev = ieee->dev;
256 struct ieee80211_security sec = {
257 .flags = 0
258 };
259 int i, key, key_provided, len;
260 struct ieee80211_crypt_data **crypt;
261
262 IEEE80211_DEBUG_WX("SET_ENCODE\n");
263
264 key = erq->flags & IW_ENCODE_INDEX;
265 if (key) {
266 if (key > WEP_KEYS)
267 return -EINVAL;
268 key--;
269 key_provided = 1;
270 } else {
271 key_provided = 0;
272 key = ieee->tx_keyidx;
273 }
274
275 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
276 "provided" : "default");
277
278 crypt = &ieee->crypt[key];
279
280 if (erq->flags & IW_ENCODE_DISABLED) {
281 if (key_provided && *crypt) {
282 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
283 key);
284 ieee80211_crypt_delayed_deinit(ieee, crypt);
285 } else
286 IEEE80211_DEBUG_WX("Disabling encryption.\n");
287
288 /* Check all the keys to see if any are still configured,
289 * and if no key index was provided, de-init them all */
290 for (i = 0; i < WEP_KEYS; i++) {
291 if (ieee->crypt[i] != NULL) {
292 if (key_provided)
293 break;
294 ieee80211_crypt_delayed_deinit(ieee,
295 &ieee->crypt[i]);
296 }
297 }
298
299 if (i == WEP_KEYS) {
300 sec.enabled = 0;
301 sec.level = SEC_LEVEL_0;
302 sec.flags |= SEC_ENABLED | SEC_LEVEL;
303 }
304
305 goto done;
306 }
307
308 sec.enabled = 1;
309 sec.flags |= SEC_ENABLED;
310
311 if (*crypt != NULL && (*crypt)->ops != NULL &&
312 strcmp((*crypt)->ops->name, "WEP") != 0) {
313 /* changing to use WEP; deinit previously used algorithm
314 * on this key */
315 ieee80211_crypt_delayed_deinit(ieee, crypt);
316 }
317
318 if (*crypt == NULL) {
319 struct ieee80211_crypt_data *new_crypt;
320
321 /* take WEP into use */
322 new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
323 GFP_KERNEL);
324 if (new_crypt == NULL)
325 return -ENOMEM;
326 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
327 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
328 if (!new_crypt->ops) {
329 request_module("ieee80211_crypt_wep");
330 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
331 }
332
333 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
334 new_crypt->priv = new_crypt->ops->init(key);
335
336 if (!new_crypt->ops || !new_crypt->priv) {
337 kfree(new_crypt);
338 new_crypt = NULL;
339
340 printk(KERN_WARNING "%s: could not initialize WEP: "
341 "load module ieee80211_crypt_wep\n", dev->name);
342 return -EOPNOTSUPP;
343 }
344 *crypt = new_crypt;
345 }
346
347 /* If a new key was provided, set it up */
348 if (erq->length > 0) {
349 len = erq->length <= 5 ? 5 : 13;
350 memcpy(sec.keys[key], keybuf, erq->length);
351 if (len > erq->length)
352 memset(sec.keys[key] + erq->length, 0,
353 len - erq->length);
354 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
355 key, escape_essid(sec.keys[key], len),
356 erq->length, len);
357 sec.key_sizes[key] = len;
358 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
359 (*crypt)->priv);
360 sec.flags |= (1 << key);
361 /* This ensures a key will be activated if no key is
362 * explicitely set */
363 if (key == sec.active_key)
364 sec.flags |= SEC_ACTIVE_KEY;
365 } else {
366 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
367 NULL, (*crypt)->priv);
368 if (len == 0) {
369 /* Set a default key of all 0 */
370 IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
371 key);
372 memset(sec.keys[key], 0, 13);
373 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
374 (*crypt)->priv);
375 sec.key_sizes[key] = 13;
376 sec.flags |= (1 << key);
377 }
378
379 /* No key data - just set the default TX key index */
380 if (key_provided) {
381 IEEE80211_DEBUG_WX
382 ("Setting key %d to default Tx key.\n", key);
383 ieee->tx_keyidx = key;
384 sec.active_key = key;
385 sec.flags |= SEC_ACTIVE_KEY;
386 }
387 }
388
389 done:
390 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
391 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
392 sec.flags |= SEC_AUTH_MODE;
393 IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
394 "OPEN" : "SHARED KEY");
395
396 /* 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 */
398 sec.flags |= SEC_LEVEL;
399 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
400
401 if (ieee->set_security)
402 ieee->set_security(dev, &sec);
403
404 /* Do not reset port if card is in Managed mode since resetting will
405 * generate new IEEE 802.11 authentication which may end up in looping
406 * with IEEE 802.1X. If your hardware requires a reset after WEP
407 * configuration (for example... Prism2), implement the reset_port in
408 * the callbacks structures used to initialize the 802.11 stack. */
409 if (ieee->reset_on_keychange &&
410 ieee->iw_mode != IW_MODE_INFRA &&
411 ieee->reset_port && ieee->reset_port(dev)) {
412 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
413 return -EINVAL;
414 }
415 return 0;
416}
417
418int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
419 struct iw_request_info *info,
420 union iwreq_data *wrqu, char *keybuf)
421{
422 struct iw_point *erq = &(wrqu->encoding);
423 int len, key;
424 struct ieee80211_crypt_data *crypt;
425
426 IEEE80211_DEBUG_WX("GET_ENCODE\n");
427
428 key = erq->flags & IW_ENCODE_INDEX;
429 if (key) {
430 if (key > WEP_KEYS)
431 return -EINVAL;
432 key--;
433 } else
434 key = ieee->tx_keyidx;
435
436 crypt = ieee->crypt[key];
437 erq->flags = key + 1;
438
439 if (crypt == NULL || crypt->ops == NULL) {
440 erq->length = 0;
441 erq->flags |= IW_ENCODE_DISABLED;
442 return 0;
443 }
444
445 if (strcmp(crypt->ops->name, "WEP") != 0) {
446 /* only WEP is supported with wireless extensions, so just
447 * report that encryption is used */
448 erq->length = 0;
449 erq->flags |= IW_ENCODE_ENABLED;
450 return 0;
451 }
452
453 len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
454 erq->length = (len >= 0 ? len : 0);
455
456 erq->flags |= IW_ENCODE_ENABLED;
457
458 if (ieee->open_wep)
459 erq->flags |= IW_ENCODE_OPEN;
460 else
461 erq->flags |= IW_ENCODE_RESTRICTED;
462
463 return 0;
464}
465
466EXPORT_SYMBOL(ieee80211_wx_get_scan);
467EXPORT_SYMBOL(ieee80211_wx_set_encode);
468EXPORT_SYMBOL(ieee80211_wx_get_encode);
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 514c85b2631a..035ad2c9e1ba 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -263,10 +263,8 @@ static int ah_init_state(struct xfrm_state *x)
263 263
264error: 264error:
265 if (ahp) { 265 if (ahp) {
266 if (ahp->work_icv) 266 kfree(ahp->work_icv);
267 kfree(ahp->work_icv); 267 crypto_free_tfm(ahp->tfm);
268 if (ahp->tfm)
269 crypto_free_tfm(ahp->tfm);
270 kfree(ahp); 268 kfree(ahp);
271 } 269 }
272 return -EINVAL; 270 return -EINVAL;
@@ -279,14 +277,10 @@ static void ah_destroy(struct xfrm_state *x)
279 if (!ahp) 277 if (!ahp)
280 return; 278 return;
281 279
282 if (ahp->work_icv) { 280 kfree(ahp->work_icv);
283 kfree(ahp->work_icv); 281 ahp->work_icv = NULL;
284 ahp->work_icv = NULL; 282 crypto_free_tfm(ahp->tfm);
285 } 283 ahp->tfm = NULL;
286 if (ahp->tfm) {
287 crypto_free_tfm(ahp->tfm);
288 ahp->tfm = NULL;
289 }
290 kfree(ahp); 284 kfree(ahp);
291} 285}
292 286
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index b31ffc5053d2..1b5a09d1b90b 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -343,22 +343,14 @@ static void esp_destroy(struct xfrm_state *x)
343 if (!esp) 343 if (!esp)
344 return; 344 return;
345 345
346 if (esp->conf.tfm) { 346 crypto_free_tfm(esp->conf.tfm);
347 crypto_free_tfm(esp->conf.tfm); 347 esp->conf.tfm = NULL;
348 esp->conf.tfm = NULL; 348 kfree(esp->conf.ivec);
349 } 349 esp->conf.ivec = NULL;
350 if (esp->conf.ivec) { 350 crypto_free_tfm(esp->auth.tfm);
351 kfree(esp->conf.ivec); 351 esp->auth.tfm = NULL;
352 esp->conf.ivec = NULL; 352 kfree(esp->auth.work_icv);
353 } 353 esp->auth.work_icv = NULL;
354 if (esp->auth.tfm) {
355 crypto_free_tfm(esp->auth.tfm);
356 esp->auth.tfm = NULL;
357 }
358 if (esp->auth.work_icv) {
359 kfree(esp->auth.work_icv);
360 esp->auth.work_icv = NULL;
361 }
362 kfree(esp); 354 kfree(esp);
363} 355}
364 356
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 9e6e683cc34d..e7d26d9943c2 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -457,7 +457,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
457 457
458 if (pskb_pull(skb, ihl) == NULL) 458 if (pskb_pull(skb, ihl) == NULL)
459 goto err; 459 goto err;
460 if (pskb_trim(skb, end-offset)) 460 if (pskb_trim_rcsum(skb, end-offset))
461 goto err; 461 goto err;
462 462
463 /* Find out which fragments are in front and at the back of us 463 /* Find out which fragments are in front and at the back of us
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index dcb7ee6c4858..fc718df17b40 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -345,8 +345,7 @@ static void ipcomp_free_tfms(struct crypto_tfm **tfms)
345 345
346 for_each_cpu(cpu) { 346 for_each_cpu(cpu) {
347 struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); 347 struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu);
348 if (tfm) 348 crypto_free_tfm(tfm);
349 crypto_free_tfm(tfm);
350 } 349 }
351 free_percpu(tfms); 350 free_percpu(tfms);
352} 351}
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 63e106605f28..953129d392d2 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -54,6 +54,7 @@
54#include <linux/major.h> 54#include <linux/major.h>
55#include <linux/root_dev.h> 55#include <linux/root_dev.h>
56#include <linux/delay.h> 56#include <linux/delay.h>
57#include <linux/nfs_fs.h>
57#include <net/arp.h> 58#include <net/arp.h>
58#include <net/ip.h> 59#include <net/ip.h>
59#include <net/ipconfig.h> 60#include <net/ipconfig.h>
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index e046f5521814..30aa8e2ee214 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -34,6 +34,7 @@ config IP_NF_CT_ACCT
34 34
35config IP_NF_CONNTRACK_MARK 35config IP_NF_CONNTRACK_MARK
36 bool 'Connection mark tracking support' 36 bool 'Connection mark tracking support'
37 depends on IP_NF_CONNTRACK
37 help 38 help
38 This option enables support for connection marks, used by the 39 This option enables support for connection marks, used by the
39 `CONNMARK' target and `connmark' match. Similar to the mark value 40 `CONNMARK' target and `connmark' match. Similar to the mark value
@@ -85,6 +86,25 @@ config IP_NF_IRC
85 86
86 To compile it as a module, choose M here. If unsure, say Y. 87 To compile it as a module, choose M here. If unsure, say Y.
87 88
89config IP_NF_NETBIOS_NS
90 tristate "NetBIOS name service protocol support (EXPERIMENTAL)"
91 depends on IP_NF_CONNTRACK && EXPERIMENTAL
92 help
93 NetBIOS name service requests are sent as broadcast messages from an
94 unprivileged port and responded to with unicast messages to the
95 same port. This make them hard to firewall properly because connection
96 tracking doesn't deal with broadcasts. This helper tracks locally
97 originating NetBIOS name service requests and the corresponding
98 responses. It relies on correct IP address configuration, specifically
99 netmask and broadcast address. When properly configured, the output
100 of "ip address show" should look similar to this:
101
102 $ ip -4 address show eth0
103 4: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
104 inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0
105
106 To compile it as a module, choose M here. If unsure, say N.
107
88config IP_NF_TFTP 108config IP_NF_TFTP
89 tristate "TFTP protocol support" 109 tristate "TFTP protocol support"
90 depends on IP_NF_CONNTRACK 110 depends on IP_NF_CONNTRACK
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index a7bd38f50522..1ba0db746817 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
21obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o 21obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
22obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o 22obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
23obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o 23obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
24obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
24 25
25# NAT helpers 26# NAT helpers
26obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o 27obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index be4c9eb3243f..dc20881004bc 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -108,6 +108,7 @@ static int help(struct sk_buff **pskb,
108 } 108 }
109 109
110 exp->expectfn = NULL; 110 exp->expectfn = NULL;
111 exp->flags = 0;
111 112
112 exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; 113 exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
113 exp->tuple.src.u.tcp.port = 0; 114 exp->tuple.src.u.tcp.port = 0;
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index a0648600190e..19cba16e6e1e 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -197,7 +197,7 @@ ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse,
197 197
198 198
199/* ip_conntrack_expect helper functions */ 199/* ip_conntrack_expect helper functions */
200static void unlink_expect(struct ip_conntrack_expect *exp) 200void ip_ct_unlink_expect(struct ip_conntrack_expect *exp)
201{ 201{
202 ASSERT_WRITE_LOCK(&ip_conntrack_lock); 202 ASSERT_WRITE_LOCK(&ip_conntrack_lock);
203 IP_NF_ASSERT(!timer_pending(&exp->timeout)); 203 IP_NF_ASSERT(!timer_pending(&exp->timeout));
@@ -207,18 +207,12 @@ static void unlink_expect(struct ip_conntrack_expect *exp)
207 ip_conntrack_expect_put(exp); 207 ip_conntrack_expect_put(exp);
208} 208}
209 209
210void __ip_ct_expect_unlink_destroy(struct ip_conntrack_expect *exp)
211{
212 unlink_expect(exp);
213 ip_conntrack_expect_put(exp);
214}
215
216static void expectation_timed_out(unsigned long ul_expect) 210static void expectation_timed_out(unsigned long ul_expect)
217{ 211{
218 struct ip_conntrack_expect *exp = (void *)ul_expect; 212 struct ip_conntrack_expect *exp = (void *)ul_expect;
219 213
220 write_lock_bh(&ip_conntrack_lock); 214 write_lock_bh(&ip_conntrack_lock);
221 unlink_expect(exp); 215 ip_ct_unlink_expect(exp);
222 write_unlock_bh(&ip_conntrack_lock); 216 write_unlock_bh(&ip_conntrack_lock);
223 ip_conntrack_expect_put(exp); 217 ip_conntrack_expect_put(exp);
224} 218}
@@ -264,10 +258,14 @@ find_expectation(const struct ip_conntrack_tuple *tuple)
264 master ct never got confirmed, we'd hold a reference to it 258 master ct never got confirmed, we'd hold a reference to it
265 and weird things would happen to future packets). */ 259 and weird things would happen to future packets). */
266 if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) 260 if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
267 && is_confirmed(i->master) 261 && is_confirmed(i->master)) {
268 && del_timer(&i->timeout)) { 262 if (i->flags & IP_CT_EXPECT_PERMANENT) {
269 unlink_expect(i); 263 atomic_inc(&i->use);
270 return i; 264 return i;
265 } else if (del_timer(&i->timeout)) {
266 ip_ct_unlink_expect(i);
267 return i;
268 }
271 } 269 }
272 } 270 }
273 return NULL; 271 return NULL;
@@ -284,7 +282,7 @@ void ip_ct_remove_expectations(struct ip_conntrack *ct)
284 282
285 list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) { 283 list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) {
286 if (i->master == ct && del_timer(&i->timeout)) { 284 if (i->master == ct && del_timer(&i->timeout)) {
287 unlink_expect(i); 285 ip_ct_unlink_expect(i);
288 ip_conntrack_expect_put(i); 286 ip_conntrack_expect_put(i);
289 } 287 }
290 } 288 }
@@ -925,7 +923,7 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
925 /* choose the the oldest expectation to evict */ 923 /* choose the the oldest expectation to evict */
926 list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) { 924 list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
927 if (expect_matches(i, exp) && del_timer(&i->timeout)) { 925 if (expect_matches(i, exp) && del_timer(&i->timeout)) {
928 unlink_expect(i); 926 ip_ct_unlink_expect(i);
929 write_unlock_bh(&ip_conntrack_lock); 927 write_unlock_bh(&ip_conntrack_lock);
930 ip_conntrack_expect_put(i); 928 ip_conntrack_expect_put(i);
931 return; 929 return;
@@ -934,6 +932,9 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
934 write_unlock_bh(&ip_conntrack_lock); 932 write_unlock_bh(&ip_conntrack_lock);
935} 933}
936 934
935/* We don't increase the master conntrack refcount for non-fulfilled
936 * conntracks. During the conntrack destruction, the expectations are
937 * always killed before the conntrack itself */
937struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me) 938struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me)
938{ 939{
939 struct ip_conntrack_expect *new; 940 struct ip_conntrack_expect *new;
@@ -944,17 +945,14 @@ struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me)
944 return NULL; 945 return NULL;
945 } 946 }
946 new->master = me; 947 new->master = me;
947 atomic_inc(&new->master->ct_general.use);
948 atomic_set(&new->use, 1); 948 atomic_set(&new->use, 1);
949 return new; 949 return new;
950} 950}
951 951
952void ip_conntrack_expect_put(struct ip_conntrack_expect *exp) 952void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
953{ 953{
954 if (atomic_dec_and_test(&exp->use)) { 954 if (atomic_dec_and_test(&exp->use))
955 ip_conntrack_put(exp->master);
956 kmem_cache_free(ip_conntrack_expect_cachep, exp); 955 kmem_cache_free(ip_conntrack_expect_cachep, exp);
957 }
958} 956}
959 957
960static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp) 958static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp)
@@ -982,7 +980,7 @@ static void evict_oldest_expect(struct ip_conntrack *master)
982 list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) { 980 list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
983 if (i->master == master) { 981 if (i->master == master) {
984 if (del_timer(&i->timeout)) { 982 if (del_timer(&i->timeout)) {
985 unlink_expect(i); 983 ip_ct_unlink_expect(i);
986 ip_conntrack_expect_put(i); 984 ip_conntrack_expect_put(i);
987 } 985 }
988 break; 986 break;
@@ -1099,7 +1097,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
1099 /* Get rid of expectations */ 1097 /* Get rid of expectations */
1100 list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) { 1098 list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) {
1101 if (exp->master->helper == me && del_timer(&exp->timeout)) { 1099 if (exp->master->helper == me && del_timer(&exp->timeout)) {
1102 unlink_expect(exp); 1100 ip_ct_unlink_expect(exp);
1103 ip_conntrack_expect_put(exp); 1101 ip_conntrack_expect_put(exp);
1104 } 1102 }
1105 } 1103 }
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 3a2627db1729..1b79ec36085f 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -421,6 +421,7 @@ static int help(struct sk_buff **pskb,
421 { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); 421 { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
422 422
423 exp->expectfn = NULL; 423 exp->expectfn = NULL;
424 exp->flags = 0;
424 425
425 /* Now, NAT might want to mangle the packet, and register the 426 /* Now, NAT might want to mangle the packet, and register the
426 * (possibly changed) expectation itself. */ 427 * (possibly changed) expectation itself. */
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index 25438eec21a1..d7a8a98c05e1 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -221,6 +221,7 @@ static int help(struct sk_buff **pskb,
221 { { 0, { 0 } }, 221 { { 0, { 0 } },
222 { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); 222 { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
223 exp->expectfn = NULL; 223 exp->expectfn = NULL;
224 exp->flags = 0;
224 if (ip_nat_irc_hook) 225 if (ip_nat_irc_hook)
225 ret = ip_nat_irc_hook(pskb, ctinfo, 226 ret = ip_nat_irc_hook(pskb, ctinfo,
226 addr_beg_p - ib_ptr, 227 addr_beg_p - ib_ptr,
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
new file mode 100644
index 000000000000..2b5cf9c51309
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -0,0 +1,131 @@
1/*
2 * NetBIOS name service broadcast connection tracking helper
3 *
4 * (c) 2005 Patrick McHardy <kaber@trash.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11/*
12 * This helper tracks locally originating NetBIOS name service
13 * requests by issuing permanent expectations (valid until
14 * timing out) matching all reply connections from the
15 * destination network. The only NetBIOS specific thing is
16 * actually the port number.
17 */
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/skbuff.h>
22#include <linux/netdevice.h>
23#include <linux/inetdevice.h>
24#include <linux/in.h>
25#include <linux/ip.h>
26#include <linux/udp.h>
27#include <net/route.h>
28
29#include <linux/netfilter.h>
30#include <linux/netfilter_ipv4.h>
31#include <linux/netfilter_ipv4/ip_conntrack.h>
32#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
33
34MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
35MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
36MODULE_LICENSE("GPL");
37
38static unsigned int timeout = 3;
39module_param(timeout, int, 0600);
40MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
41
42static int help(struct sk_buff **pskb,
43 struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
44{
45 struct ip_conntrack_expect *exp;
46 struct iphdr *iph = (*pskb)->nh.iph;
47 struct udphdr _uh, *uh;
48 struct rtable *rt = (struct rtable *)(*pskb)->dst;
49 struct in_device *in_dev;
50 u_int32_t mask = 0;
51
52 /* we're only interested in locally generated packets */
53 if ((*pskb)->sk == NULL)
54 goto out;
55 if (rt == NULL || !(rt->rt_flags & RTCF_BROADCAST))
56 goto out;
57 if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
58 goto out;
59
60 rcu_read_lock();
61 in_dev = __in_dev_get(rt->u.dst.dev);
62 if (in_dev != NULL) {
63 for_primary_ifa(in_dev) {
64 if (ifa->ifa_broadcast == iph->daddr) {
65 mask = ifa->ifa_mask;
66 break;
67 }
68 } endfor_ifa(in_dev);
69 }
70 rcu_read_unlock();
71
72 if (mask == 0)
73 goto out;
74
75 uh = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_uh), &_uh);
76 BUG_ON(uh == NULL);
77
78 exp = ip_conntrack_expect_alloc(ct);
79 if (exp == NULL)
80 goto out;
81 memset(&exp->tuple, 0, sizeof(exp->tuple));
82 exp->tuple.src.ip = iph->daddr & mask;
83 exp->tuple.dst.ip = iph->saddr;
84 exp->tuple.dst.u.udp.port = uh->source;
85 exp->tuple.dst.protonum = IPPROTO_UDP;
86
87 memset(&exp->mask, 0, sizeof(exp->mask));
88 exp->mask.src.ip = mask;
89 exp->mask.dst.ip = 0xFFFFFFFF;
90 exp->mask.dst.u.udp.port = 0xFFFF;
91 exp->mask.dst.protonum = 0xFF;
92
93 exp->expectfn = NULL;
94 exp->flags = IP_CT_EXPECT_PERMANENT;
95
96 ip_conntrack_expect_related(exp);
97 ip_conntrack_expect_put(exp);
98
99 ip_ct_refresh_acct(ct, ctinfo, NULL, timeout * HZ);
100out:
101 return NF_ACCEPT;
102}
103
104static struct ip_conntrack_helper helper = {
105 .name = "netbios-ns",
106 .tuple = {
107 .src.u.udp.port = __constant_htons(137),
108 .dst.protonum = IPPROTO_UDP,
109 },
110 .mask = {
111 .src.u.udp.port = 0xFFFF,
112 .dst.protonum = 0xFF,
113 },
114 .max_expected = 1,
115 .me = THIS_MODULE,
116 .help = help,
117};
118
119static int __init init(void)
120{
121 helper.timeout = timeout;
122 return ip_conntrack_helper_register(&helper);
123}
124
125static void __exit fini(void)
126{
127 ip_conntrack_helper_unregister(&helper);
128}
129
130module_init(init);
131module_exit(fini);
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index a4e9278db4ed..15aef3564742 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -1349,8 +1349,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1349 list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, 1349 list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list,
1350 list) { 1350 list) {
1351 if (exp->master->helper == h 1351 if (exp->master->helper == h
1352 && del_timer(&exp->timeout)) 1352 && del_timer(&exp->timeout)) {
1353 __ip_ct_expect_unlink_destroy(exp); 1353 ip_ct_unlink_expect(exp);
1354 ip_conntrack_expect_put(exp);
1355 }
1354 } 1356 }
1355 write_unlock(&ip_conntrack_lock); 1357 write_unlock(&ip_conntrack_lock);
1356 } else { 1358 } else {
@@ -1358,8 +1360,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1358 write_lock_bh(&ip_conntrack_lock); 1360 write_lock_bh(&ip_conntrack_lock);
1359 list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, 1361 list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list,
1360 list) { 1362 list) {
1361 if (del_timer(&exp->timeout)) 1363 if (del_timer(&exp->timeout)) {
1362 __ip_ct_expect_unlink_destroy(exp); 1364 ip_ct_unlink_expect(exp);
1365 ip_conntrack_expect_put(exp);
1366 }
1363 } 1367 }
1364 write_unlock_bh(&ip_conntrack_lock); 1368 write_unlock_bh(&ip_conntrack_lock);
1365 } 1369 }
@@ -1413,6 +1417,7 @@ ctnetlink_create_expect(struct nfattr *cda[])
1413 } 1417 }
1414 1418
1415 exp->expectfn = NULL; 1419 exp->expectfn = NULL;
1420 exp->flags = 0;
1416 exp->master = ct; 1421 exp->master = ct;
1417 memcpy(&exp->tuple, &tuple, sizeof(struct ip_conntrack_tuple)); 1422 memcpy(&exp->tuple, &tuple, sizeof(struct ip_conntrack_tuple));
1418 memcpy(&exp->mask, &mask, sizeof(struct ip_conntrack_tuple)); 1423 memcpy(&exp->mask, &mask, sizeof(struct ip_conntrack_tuple));
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index f23ef1f88c46..1985abc59d24 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -349,6 +349,7 @@ static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
349 return 0; 349 return 0;
350 350
351nfattr_failure: 351nfattr_failure:
352 read_unlock_bh(&tcp_lock);
352 return -1; 353 return -1;
353} 354}
354#endif 355#endif
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index ee5895afd0c3..ae3e3e655db5 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -998,7 +998,7 @@ EXPORT_SYMBOL(ip_conntrack_expect_related);
998EXPORT_SYMBOL(ip_conntrack_unexpect_related); 998EXPORT_SYMBOL(ip_conntrack_unexpect_related);
999EXPORT_SYMBOL_GPL(ip_conntrack_expect_list); 999EXPORT_SYMBOL_GPL(ip_conntrack_expect_list);
1000EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find); 1000EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find);
1001EXPORT_SYMBOL_GPL(__ip_ct_expect_unlink_destroy); 1001EXPORT_SYMBOL_GPL(ip_ct_unlink_expect);
1002 1002
1003EXPORT_SYMBOL(ip_conntrack_tuple_taken); 1003EXPORT_SYMBOL(ip_conntrack_tuple_taken);
1004EXPORT_SYMBOL(ip_ct_gather_frags); 1004EXPORT_SYMBOL(ip_ct_gather_frags);
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index f8ff170f390a..d2b590533452 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -75,6 +75,7 @@ static int tftp_help(struct sk_buff **pskb,
75 exp->mask.dst.u.udp.port = 0xffff; 75 exp->mask.dst.u.udp.port = 0xffff;
76 exp->mask.dst.protonum = 0xff; 76 exp->mask.dst.protonum = 0xff;
77 exp->expectfn = NULL; 77 exp->expectfn = NULL;
78 exp->flags = 0;
78 79
79 DEBUGP("expect: "); 80 DEBUGP("expect: ");
80 DUMP_TUPLE(&exp->tuple); 81 DUMP_TUPLE(&exp->tuple);
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
index 60d70fa41a15..cb66b8bddeb3 100644
--- a/net/ipv4/netfilter/ip_nat_rule.c
+++ b/net/ipv4/netfilter/ip_nat_rule.c
@@ -255,6 +255,27 @@ alloc_null_binding(struct ip_conntrack *conntrack,
255 return ip_nat_setup_info(conntrack, &range, hooknum); 255 return ip_nat_setup_info(conntrack, &range, hooknum);
256} 256}
257 257
258unsigned int
259alloc_null_binding_confirmed(struct ip_conntrack *conntrack,
260 struct ip_nat_info *info,
261 unsigned int hooknum)
262{
263 u_int32_t ip
264 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
265 ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip
266 : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
267 u_int16_t all
268 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
269 ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all
270 : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all);
271 struct ip_nat_range range
272 = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
273
274 DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
275 conntrack, NIPQUAD(ip));
276 return ip_nat_setup_info(conntrack, &range, hooknum);
277}
278
258int ip_nat_rule_find(struct sk_buff **pskb, 279int ip_nat_rule_find(struct sk_buff **pskb,
259 unsigned int hooknum, 280 unsigned int hooknum,
260 const struct net_device *in, 281 const struct net_device *in,
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 89db052add81..0ff368b131f6 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -123,8 +123,12 @@ ip_nat_fn(unsigned int hooknum,
123 if (!ip_nat_initialized(ct, maniptype)) { 123 if (!ip_nat_initialized(ct, maniptype)) {
124 unsigned int ret; 124 unsigned int ret;
125 125
126 /* LOCAL_IN hook doesn't have a chain! */ 126 if (unlikely(is_confirmed(ct)))
127 if (hooknum == NF_IP_LOCAL_IN) 127 /* NAT module was loaded late */
128 ret = alloc_null_binding_confirmed(ct, info,
129 hooknum);
130 else if (hooknum == NF_IP_LOCAL_IN)
131 /* LOCAL_IN hook doesn't have a chain! */
128 ret = alloc_null_binding(ct, info, hooknum); 132 ret = alloc_null_binding(ct, info, hooknum);
129 else 133 else
130 ret = ip_nat_rule_find(pskb, hooknum, 134 ret = ip_nat_rule_find(pskb, hooknum,
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 2d05cafec221..7d38913754b1 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -144,7 +144,7 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
144 memcpy(&c->clustermac, &i->clustermac, ETH_ALEN); 144 memcpy(&c->clustermac, &i->clustermac, ETH_ALEN);
145 c->num_total_nodes = i->num_total_nodes; 145 c->num_total_nodes = i->num_total_nodes;
146 c->num_local_nodes = i->num_local_nodes; 146 c->num_local_nodes = i->num_local_nodes;
147 memcpy(&c->local_nodes, &i->local_nodes, sizeof(&c->local_nodes)); 147 memcpy(&c->local_nodes, &i->local_nodes, sizeof(c->local_nodes));
148 c->hash_mode = i->hash_mode; 148 c->hash_mode = i->hash_mode;
149 c->hash_initval = i->hash_initval; 149 c->hash_initval = i->hash_initval;
150 atomic_set(&c->refcount, 1); 150 atomic_set(&c->refcount, 1);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 02fdda68718d..f3f0013a9580 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -552,8 +552,7 @@ new_segment:
552 tcp_mark_push(tp, skb); 552 tcp_mark_push(tp, skb);
553 goto new_segment; 553 goto new_segment;
554 } 554 }
555 if (sk->sk_forward_alloc < copy && 555 if (!sk_stream_wmem_schedule(sk, copy))
556 !sk_stream_mem_schedule(sk, copy, 0))
557 goto wait_for_memory; 556 goto wait_for_memory;
558 557
559 if (can_coalesce) { 558 if (can_coalesce) {
@@ -770,19 +769,23 @@ new_segment:
770 if (off == PAGE_SIZE) { 769 if (off == PAGE_SIZE) {
771 put_page(page); 770 put_page(page);
772 TCP_PAGE(sk) = page = NULL; 771 TCP_PAGE(sk) = page = NULL;
772 off = 0;
773 } 773 }
774 } 774 } else
775 off = 0;
776
777 if (copy > PAGE_SIZE - off)
778 copy = PAGE_SIZE - off;
779
780 if (!sk_stream_wmem_schedule(sk, copy))
781 goto wait_for_memory;
775 782
776 if (!page) { 783 if (!page) {
777 /* Allocate new cache page. */ 784 /* Allocate new cache page. */
778 if (!(page = sk_stream_alloc_page(sk))) 785 if (!(page = sk_stream_alloc_page(sk)))
779 goto wait_for_memory; 786 goto wait_for_memory;
780 off = 0;
781 } 787 }
782 788
783 if (copy > PAGE_SIZE - off)
784 copy = PAGE_SIZE - off;
785
786 /* Time to copy data. We are close to 789 /* Time to copy data. We are close to
787 * the end! */ 790 * the end! */
788 err = skb_copy_to_page(sk, from, skb, page, 791 err = skb_copy_to_page(sk, from, skb, page,
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 1afb080bdf0c..29222b964951 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -923,14 +923,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
923 int flag = 0; 923 int flag = 0;
924 int i; 924 int i;
925 925
926 /* So, SACKs for already sent large segments will be lost.
927 * Not good, but alternative is to resegment the queue. */
928 if (sk->sk_route_caps & NETIF_F_TSO) {
929 sk->sk_route_caps &= ~NETIF_F_TSO;
930 sock_set_flag(sk, SOCK_NO_LARGESEND);
931 tp->mss_cache = tp->mss_cache;
932 }
933
934 if (!tp->sacked_out) 926 if (!tp->sacked_out)
935 tp->fackets_out = 0; 927 tp->fackets_out = 0;
936 prior_fackets = tp->fackets_out; 928 prior_fackets = tp->fackets_out;
@@ -978,20 +970,40 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
978 flag |= FLAG_DATA_LOST; 970 flag |= FLAG_DATA_LOST;
979 971
980 sk_stream_for_retrans_queue(skb, sk) { 972 sk_stream_for_retrans_queue(skb, sk) {
981 u8 sacked = TCP_SKB_CB(skb)->sacked; 973 int in_sack, pcount;
982 int in_sack; 974 u8 sacked;
983 975
984 /* The retransmission queue is always in order, so 976 /* The retransmission queue is always in order, so
985 * we can short-circuit the walk early. 977 * we can short-circuit the walk early.
986 */ 978 */
987 if(!before(TCP_SKB_CB(skb)->seq, end_seq)) 979 if (!before(TCP_SKB_CB(skb)->seq, end_seq))
988 break; 980 break;
989 981
990 fack_count += tcp_skb_pcount(skb); 982 pcount = tcp_skb_pcount(skb);
983
984 if (pcount > 1 &&
985 (after(start_seq, TCP_SKB_CB(skb)->seq) ||
986 before(end_seq, TCP_SKB_CB(skb)->end_seq))) {
987 unsigned int pkt_len;
988
989 if (after(start_seq, TCP_SKB_CB(skb)->seq))
990 pkt_len = (start_seq -
991 TCP_SKB_CB(skb)->seq);
992 else
993 pkt_len = (end_seq -
994 TCP_SKB_CB(skb)->seq);
995 if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->tso_size))
996 break;
997 pcount = tcp_skb_pcount(skb);
998 }
999
1000 fack_count += pcount;
991 1001
992 in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) && 1002 in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) &&
993 !before(end_seq, TCP_SKB_CB(skb)->end_seq); 1003 !before(end_seq, TCP_SKB_CB(skb)->end_seq);
994 1004
1005 sacked = TCP_SKB_CB(skb)->sacked;
1006
995 /* Account D-SACK for retransmitted packet. */ 1007 /* Account D-SACK for retransmitted packet. */
996 if ((dup_sack && in_sack) && 1008 if ((dup_sack && in_sack) &&
997 (sacked & TCPCB_RETRANS) && 1009 (sacked & TCPCB_RETRANS) &&
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 75b68116682a..6094db5e11be 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -428,11 +428,11 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned
428 * packet to the list. This won't be called frequently, I hope. 428 * packet to the list. This won't be called frequently, I hope.
429 * Remember, these are still headerless SKBs at this point. 429 * Remember, these are still headerless SKBs at this point.
430 */ 430 */
431static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss_now) 431int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss_now)
432{ 432{
433 struct tcp_sock *tp = tcp_sk(sk); 433 struct tcp_sock *tp = tcp_sk(sk);
434 struct sk_buff *buff; 434 struct sk_buff *buff;
435 int nsize; 435 int nsize, old_factor;
436 u16 flags; 436 u16 flags;
437 437
438 nsize = skb_headlen(skb) - len; 438 nsize = skb_headlen(skb) - len;
@@ -490,18 +490,29 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned
490 tp->left_out -= tcp_skb_pcount(skb); 490 tp->left_out -= tcp_skb_pcount(skb);
491 } 491 }
492 492
493 old_factor = tcp_skb_pcount(skb);
494
493 /* Fix up tso_factor for both original and new SKB. */ 495 /* Fix up tso_factor for both original and new SKB. */
494 tcp_set_skb_tso_segs(sk, skb, mss_now); 496 tcp_set_skb_tso_segs(sk, skb, mss_now);
495 tcp_set_skb_tso_segs(sk, buff, mss_now); 497 tcp_set_skb_tso_segs(sk, buff, mss_now);
496 498
497 if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) { 499 /* If this packet has been sent out already, we must
498 tp->lost_out += tcp_skb_pcount(skb); 500 * adjust the various packet counters.
499 tp->left_out += tcp_skb_pcount(skb); 501 */
500 } 502 if (after(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) {
503 int diff = old_factor - tcp_skb_pcount(skb) -
504 tcp_skb_pcount(buff);
501 505
502 if (TCP_SKB_CB(buff)->sacked&TCPCB_LOST) { 506 tp->packets_out -= diff;
503 tp->lost_out += tcp_skb_pcount(buff); 507 if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
504 tp->left_out += tcp_skb_pcount(buff); 508 tp->lost_out -= diff;
509 tp->left_out -= diff;
510 }
511 if (diff > 0) {
512 tp->fackets_out -= diff;
513 if ((int)tp->fackets_out < 0)
514 tp->fackets_out = 0;
515 }
505 } 516 }
506 517
507 /* Link BUFF into the send queue. */ 518 /* Link BUFF into the send queue. */
@@ -1350,12 +1361,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
1350 if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) { 1361 if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) {
1351 if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una)) 1362 if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
1352 BUG(); 1363 BUG();
1353
1354 if (sk->sk_route_caps & NETIF_F_TSO) {
1355 sk->sk_route_caps &= ~NETIF_F_TSO;
1356 sock_set_flag(sk, SOCK_NO_LARGESEND);
1357 }
1358
1359 if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq)) 1364 if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq))
1360 return -ENOMEM; 1365 return -ENOMEM;
1361 } 1366 }
@@ -1370,22 +1375,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
1370 return -EAGAIN; 1375 return -EAGAIN;
1371 1376
1372 if (skb->len > cur_mss) { 1377 if (skb->len > cur_mss) {
1373 int old_factor = tcp_skb_pcount(skb);
1374 int diff;
1375
1376 if (tcp_fragment(sk, skb, cur_mss, cur_mss)) 1378 if (tcp_fragment(sk, skb, cur_mss, cur_mss))
1377 return -ENOMEM; /* We'll try again later. */ 1379 return -ENOMEM; /* We'll try again later. */
1378
1379 /* New SKB created, account for it. */
1380 diff = old_factor - tcp_skb_pcount(skb) -
1381 tcp_skb_pcount(skb->next);
1382 tp->packets_out -= diff;
1383
1384 if (diff > 0) {
1385 tp->fackets_out -= diff;
1386 if ((int)tp->fackets_out < 0)
1387 tp->fackets_out = 0;
1388 }
1389 } 1380 }
1390 1381
1391 /* Collapse two adjacent packets if worthwhile and we can. */ 1382 /* Collapse two adjacent packets if worthwhile and we can. */
@@ -1993,12 +1984,6 @@ int tcp_write_wakeup(struct sock *sk)
1993 TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; 1984 TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
1994 if (tcp_fragment(sk, skb, seg_size, mss)) 1985 if (tcp_fragment(sk, skb, seg_size, mss))
1995 return -1; 1986 return -1;
1996 /* SWS override triggered forced fragmentation.
1997 * Disable TSO, the connection is too sick. */
1998 if (sk->sk_route_caps & NETIF_F_TSO) {
1999 sock_set_flag(sk, SOCK_NO_LARGESEND);
2000 sk->sk_route_caps &= ~NETIF_F_TSO;
2001 }
2002 } else if (!tcp_skb_pcount(skb)) 1987 } else if (!tcp_skb_pcount(skb))
2003 tcp_set_skb_tso_segs(sk, skb, mss); 1988 tcp_set_skb_tso_segs(sk, skb, mss);
2004 1989
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 937ad32db77c..6d6fb74f3b52 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3593,10 +3593,8 @@ void __exit addrconf_cleanup(void)
3593 rtnl_unlock(); 3593 rtnl_unlock();
3594 3594
3595#ifdef CONFIG_IPV6_PRIVACY 3595#ifdef CONFIG_IPV6_PRIVACY
3596 if (likely(md5_tfm != NULL)) { 3596 crypto_free_tfm(md5_tfm);
3597 crypto_free_tfm(md5_tfm); 3597 md5_tfm = NULL;
3598 md5_tfm = NULL;
3599 }
3600#endif 3598#endif
3601 3599
3602#ifdef CONFIG_PROC_FS 3600#ifdef CONFIG_PROC_FS
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 0ebfad907a03..f3629730eb15 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -401,10 +401,8 @@ static int ah6_init_state(struct xfrm_state *x)
401 401
402error: 402error:
403 if (ahp) { 403 if (ahp) {
404 if (ahp->work_icv) 404 kfree(ahp->work_icv);
405 kfree(ahp->work_icv); 405 crypto_free_tfm(ahp->tfm);
406 if (ahp->tfm)
407 crypto_free_tfm(ahp->tfm);
408 kfree(ahp); 406 kfree(ahp);
409 } 407 }
410 return -EINVAL; 408 return -EINVAL;
@@ -417,14 +415,10 @@ static void ah6_destroy(struct xfrm_state *x)
417 if (!ahp) 415 if (!ahp)
418 return; 416 return;
419 417
420 if (ahp->work_icv) { 418 kfree(ahp->work_icv);
421 kfree(ahp->work_icv); 419 ahp->work_icv = NULL;
422 ahp->work_icv = NULL; 420 crypto_free_tfm(ahp->tfm);
423 } 421 ahp->tfm = NULL;
424 if (ahp->tfm) {
425 crypto_free_tfm(ahp->tfm);
426 ahp->tfm = NULL;
427 }
428 kfree(ahp); 422 kfree(ahp);
429} 423}
430 424
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index e8bff9d3d96c..9b27460f0cc7 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -276,22 +276,14 @@ static void esp6_destroy(struct xfrm_state *x)
276 if (!esp) 276 if (!esp)
277 return; 277 return;
278 278
279 if (esp->conf.tfm) { 279 crypto_free_tfm(esp->conf.tfm);
280 crypto_free_tfm(esp->conf.tfm); 280 esp->conf.tfm = NULL;
281 esp->conf.tfm = NULL; 281 kfree(esp->conf.ivec);
282 } 282 esp->conf.ivec = NULL;
283 if (esp->conf.ivec) { 283 crypto_free_tfm(esp->auth.tfm);
284 kfree(esp->conf.ivec); 284 esp->auth.tfm = NULL;
285 esp->conf.ivec = NULL; 285 kfree(esp->auth.work_icv);
286 } 286 esp->auth.work_icv = NULL;
287 if (esp->auth.tfm) {
288 crypto_free_tfm(esp->auth.tfm);
289 esp->auth.tfm = NULL;
290 }
291 if (esp->auth.work_icv) {
292 kfree(esp->auth.work_icv);
293 esp->auth.work_icv = NULL;
294 }
295 kfree(esp); 287 kfree(esp);
296} 288}
297 289
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 5176fc655ea9..fa8f1bb0aa52 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -549,7 +549,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
549 read_lock(&raw_v6_lock); 549 read_lock(&raw_v6_lock);
550 if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) { 550 if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
551 while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, 551 while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr,
552 skb->dev->ifindex))) { 552 IP6CB(skb)->iif))) {
553 rawv6_err(sk, skb, NULL, type, code, inner_offset, info); 553 rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
554 sk = sk_next(sk); 554 sk = sk_next(sk);
555 } 555 }
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 135383ef538f..85bfbc69b2c3 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -341,8 +341,7 @@ static void ipcomp6_free_tfms(struct crypto_tfm **tfms)
341 341
342 for_each_cpu(cpu) { 342 for_each_cpu(cpu) {
343 struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); 343 struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu);
344 if (tfm) 344 crypto_free_tfm(tfm);
345 crypto_free_tfm(tfm);
346 } 345 }
347 free_percpu(tfms); 346 free_percpu(tfms);
348} 347}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 7a5863298f3f..ed3a76b30fd9 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -166,7 +166,7 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
166 if (sk == NULL) 166 if (sk == NULL)
167 goto out; 167 goto out;
168 168
169 sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, skb->dev->ifindex); 169 sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif);
170 170
171 while (sk) { 171 while (sk) {
172 delivered = 1; 172 delivered = 1;
@@ -178,7 +178,7 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
178 rawv6_rcv(sk, clone); 178 rawv6_rcv(sk, clone);
179 } 179 }
180 sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr, 180 sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr,
181 skb->dev->ifindex); 181 IP6CB(skb)->iif);
182 } 182 }
183out: 183out:
184 read_unlock(&raw_v6_lock); 184 read_unlock(&raw_v6_lock);
diff --git a/net/irda/irlan/irlan_filter.c b/net/irda/irlan/irlan_filter.c
index 343c5d4a1a1d..ca7d358dab52 100644
--- a/net/irda/irlan/irlan_filter.c
+++ b/net/irda/irlan/irlan_filter.c
@@ -27,6 +27,7 @@
27#include <linux/seq_file.h> 27#include <linux/seq_file.h>
28 28
29#include <net/irda/irlan_common.h> 29#include <net/irda/irlan_common.h>
30#include <net/irda/irlan_filter.h>
30 31
31/* 32/*
32 * Function irlan_filter_request (self, skb) 33 * Function irlan_filter_request (self, skb)
diff --git a/net/irda/qos.c b/net/irda/qos.c
index df732d56cc57..ddfb5c502a90 100644
--- a/net/irda/qos.c
+++ b/net/irda/qos.c
@@ -37,6 +37,7 @@
37#include <net/irda/parameters.h> 37#include <net/irda/parameters.h>
38#include <net/irda/qos.h> 38#include <net/irda/qos.h>
39#include <net/irda/irlap.h> 39#include <net/irda/irlap.h>
40#include <net/irda/irlap_frame.h>
40 41
41/* 42/*
42 * Maximum values of the baud rate we negociate with the other end. 43 * Maximum values of the baud rate we negociate with the other end.
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index e089f17bb803..49a3900e3d32 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -344,14 +344,14 @@ static void nfnetlink_rcv(struct sock *sk, int len)
344 } while(nfnl && nfnl->sk_receive_queue.qlen); 344 } while(nfnl && nfnl->sk_receive_queue.qlen);
345} 345}
346 346
347void __exit nfnetlink_exit(void) 347static void __exit nfnetlink_exit(void)
348{ 348{
349 printk("Removing netfilter NETLINK layer.\n"); 349 printk("Removing netfilter NETLINK layer.\n");
350 sock_release(nfnl->sk_socket); 350 sock_release(nfnl->sk_socket);
351 return; 351 return;
352} 352}
353 353
354int __init nfnetlink_init(void) 354static int __init nfnetlink_init(void)
355{ 355{
356 printk("Netfilter messages via NETLINK v%s.\n", nfversion); 356 printk("Netfilter messages via NETLINK v%s.\n", nfversion);
357 357
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index e3a5285329af..f81fe8c52e99 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -76,17 +76,6 @@ typedef int (*nfqnl_cmpfn)(struct nfqnl_queue_entry *, unsigned long);
76 76
77static DEFINE_RWLOCK(instances_lock); 77static DEFINE_RWLOCK(instances_lock);
78 78
79u_int64_t htonll(u_int64_t in)
80{
81 u_int64_t out;
82 int i;
83
84 for (i = 0; i < sizeof(u_int64_t); i++)
85 ((u_int8_t *)&out)[sizeof(u_int64_t)-1] = ((u_int8_t *)&in)[i];
86
87 return out;
88}
89
90#define INSTANCE_BUCKETS 16 79#define INSTANCE_BUCKETS 16
91static struct hlist_head instance_table[INSTANCE_BUCKETS]; 80static struct hlist_head instance_table[INSTANCE_BUCKETS];
92 81
@@ -382,6 +371,12 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
382 break; 371 break;
383 372
384 case NFQNL_COPY_PACKET: 373 case NFQNL_COPY_PACKET:
374 if (entry->skb->ip_summed == CHECKSUM_HW &&
375 (*errp = skb_checksum_help(entry->skb,
376 entry->info->outdev == NULL))) {
377 spin_unlock_bh(&queue->lock);
378 return NULL;
379 }
385 if (queue->copy_range == 0 380 if (queue->copy_range == 0
386 || queue->copy_range > entry->skb->len) 381 || queue->copy_range > entry->skb->len)
387 data_len = entry->skb->len; 382 data_len = entry->skb->len;
@@ -497,8 +492,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
497 if (entry->skb->tstamp.off_sec) { 492 if (entry->skb->tstamp.off_sec) {
498 struct nfqnl_msg_packet_timestamp ts; 493 struct nfqnl_msg_packet_timestamp ts;
499 494
500 ts.sec = htonll(skb_tv_base.tv_sec + entry->skb->tstamp.off_sec); 495 ts.sec = cpu_to_be64(skb_tv_base.tv_sec + entry->skb->tstamp.off_sec);
501 ts.usec = htonll(skb_tv_base.tv_usec + entry->skb->tstamp.off_usec); 496 ts.usec = cpu_to_be64(skb_tv_base.tv_usec + entry->skb->tstamp.off_usec);
502 497
503 NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts); 498 NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
504 } 499 }
@@ -647,7 +642,7 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
647 if (!skb_make_writable(&e->skb, data_len)) 642 if (!skb_make_writable(&e->skb, data_len))
648 return -ENOMEM; 643 return -ENOMEM;
649 memcpy(e->skb->data, data, data_len); 644 memcpy(e->skb->data, data, data_len);
650 645 e->skb->ip_summed = CHECKSUM_NONE;
651 return 0; 646 return 0;
652} 647}
653 648
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 62435ffc6184..a64e1d5ce3ca 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -398,24 +398,13 @@ static int netlink_create(struct socket *sock, int protocol)
398 if (nl_table[protocol].registered && 398 if (nl_table[protocol].registered &&
399 try_module_get(nl_table[protocol].module)) 399 try_module_get(nl_table[protocol].module))
400 module = nl_table[protocol].module; 400 module = nl_table[protocol].module;
401 else
402 err = -EPROTONOSUPPORT;
403 groups = nl_table[protocol].groups; 401 groups = nl_table[protocol].groups;
404 netlink_unlock_table(); 402 netlink_unlock_table();
405 403
406 if (err || (err = __netlink_create(sock, protocol) < 0)) 404 if ((err = __netlink_create(sock, protocol) < 0))
407 goto out_module; 405 goto out_module;
408 406
409 nlk = nlk_sk(sock->sk); 407 nlk = nlk_sk(sock->sk);
410
411 nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL);
412 if (nlk->groups == NULL) {
413 err = -ENOMEM;
414 goto out_module;
415 }
416 memset(nlk->groups, 0, NLGRPSZ(groups));
417 nlk->ngroups = groups;
418
419 nlk->module = module; 408 nlk->module = module;
420out: 409out:
421 return err; 410 return err;
@@ -534,6 +523,29 @@ netlink_update_subscriptions(struct sock *sk, unsigned int subscriptions)
534 nlk->subscriptions = subscriptions; 523 nlk->subscriptions = subscriptions;
535} 524}
536 525
526static int netlink_alloc_groups(struct sock *sk)
527{
528 struct netlink_sock *nlk = nlk_sk(sk);
529 unsigned int groups;
530 int err = 0;
531
532 netlink_lock_table();
533 groups = nl_table[sk->sk_protocol].groups;
534 if (!nl_table[sk->sk_protocol].registered)
535 err = -ENOENT;
536 netlink_unlock_table();
537
538 if (err)
539 return err;
540
541 nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL);
542 if (nlk->groups == NULL)
543 return -ENOMEM;
544 memset(nlk->groups, 0, NLGRPSZ(groups));
545 nlk->ngroups = groups;
546 return 0;
547}
548
537static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len) 549static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
538{ 550{
539 struct sock *sk = sock->sk; 551 struct sock *sk = sock->sk;
@@ -545,8 +557,15 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len
545 return -EINVAL; 557 return -EINVAL;
546 558
547 /* Only superuser is allowed to listen multicasts */ 559 /* Only superuser is allowed to listen multicasts */
548 if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_RECV)) 560 if (nladdr->nl_groups) {
549 return -EPERM; 561 if (!netlink_capable(sock, NL_NONROOT_RECV))
562 return -EPERM;
563 if (nlk->groups == NULL) {
564 err = netlink_alloc_groups(sk);
565 if (err)
566 return err;
567 }
568 }
550 569
551 if (nlk->pid) { 570 if (nlk->pid) {
552 if (nladdr->nl_pid != nlk->pid) 571 if (nladdr->nl_pid != nlk->pid)
@@ -559,7 +578,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len
559 return err; 578 return err;
560 } 579 }
561 580
562 if (!nladdr->nl_groups && !(u32)nlk->groups[0]) 581 if (!nladdr->nl_groups && (nlk->groups == NULL || !(u32)nlk->groups[0]))
563 return 0; 582 return 0;
564 583
565 netlink_table_grab(); 584 netlink_table_grab();
@@ -620,7 +639,7 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr, int *addr
620 nladdr->nl_groups = netlink_group_mask(nlk->dst_group); 639 nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
621 } else { 640 } else {
622 nladdr->nl_pid = nlk->pid; 641 nladdr->nl_pid = nlk->pid;
623 nladdr->nl_groups = nlk->groups[0]; 642 nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
624 } 643 }
625 return 0; 644 return 0;
626} 645}
@@ -976,6 +995,11 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
976 995
977 if (!netlink_capable(sock, NL_NONROOT_RECV)) 996 if (!netlink_capable(sock, NL_NONROOT_RECV))
978 return -EPERM; 997 return -EPERM;
998 if (nlk->groups == NULL) {
999 err = netlink_alloc_groups(sk);
1000 if (err)
1001 return err;
1002 }
979 if (!val || val - 1 >= nlk->ngroups) 1003 if (!val || val - 1 >= nlk->ngroups)
980 return -EINVAL; 1004 return -EINVAL;
981 netlink_table_grab(); 1005 netlink_table_grab();
@@ -1483,8 +1507,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
1483 s, 1507 s,
1484 s->sk_protocol, 1508 s->sk_protocol,
1485 nlk->pid, 1509 nlk->pid,
1486 nlk->flags & NETLINK_KERNEL_SOCKET ? 1510 nlk->groups ? (u32)nlk->groups[0] : 0,
1487 0 : (unsigned int)nlk->groups[0],
1488 atomic_read(&s->sk_rmem_alloc), 1511 atomic_read(&s->sk_rmem_alloc),
1489 atomic_read(&s->sk_wmem_alloc), 1512 atomic_read(&s->sk_wmem_alloc),
1490 nlk->cb, 1513 nlk->cb,
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 4b53de982114..f4578c759ffc 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1261,6 +1261,7 @@ static int nr_info_show(struct seq_file *seq, void *v)
1261 struct net_device *dev; 1261 struct net_device *dev;
1262 struct nr_sock *nr; 1262 struct nr_sock *nr;
1263 const char *devname; 1263 const char *devname;
1264 char buf[11];
1264 1265
1265 if (v == SEQ_START_TOKEN) 1266 if (v == SEQ_START_TOKEN)
1266 seq_puts(seq, 1267 seq_puts(seq,
@@ -1276,11 +1277,11 @@ static int nr_info_show(struct seq_file *seq, void *v)
1276 else 1277 else
1277 devname = dev->name; 1278 devname = dev->name;
1278 1279
1279 seq_printf(seq, "%-9s ", ax2asc(&nr->user_addr)); 1280 seq_printf(seq, "%-9s ", ax2asc(buf, &nr->user_addr));
1280 seq_printf(seq, "%-9s ", ax2asc(&nr->dest_addr)); 1281 seq_printf(seq, "%-9s ", ax2asc(buf, &nr->dest_addr));
1281 seq_printf(seq, 1282 seq_printf(seq,
1282"%-9s %-3s %02X/%02X %02X/%02X %2d %3d %3d %3d %3lu/%03lu %2lu/%02lu %3lu/%03lu %3lu/%03lu %2d/%02d %3d %5d %5d %ld\n", 1283"%-9s %-3s %02X/%02X %02X/%02X %2d %3d %3d %3d %3lu/%03lu %2lu/%02lu %3lu/%03lu %3lu/%03lu %2d/%02d %3d %5d %5d %ld\n",
1283 ax2asc(&nr->source_addr), 1284 ax2asc(buf, &nr->source_addr),
1284 devname, 1285 devname,
1285 nr->my_index, 1286 nr->my_index,
1286 nr->my_id, 1287 nr->my_id,
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 7a86b36cba50..b3b9097c87c7 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -881,6 +881,7 @@ static void nr_node_stop(struct seq_file *seq, void *v)
881 881
882static int nr_node_show(struct seq_file *seq, void *v) 882static int nr_node_show(struct seq_file *seq, void *v)
883{ 883{
884 char buf[11];
884 int i; 885 int i;
885 886
886 if (v == SEQ_START_TOKEN) 887 if (v == SEQ_START_TOKEN)
@@ -890,7 +891,7 @@ static int nr_node_show(struct seq_file *seq, void *v)
890 struct nr_node *nr_node = v; 891 struct nr_node *nr_node = v;
891 nr_node_lock(nr_node); 892 nr_node_lock(nr_node);
892 seq_printf(seq, "%-9s %-7s %d %d", 893 seq_printf(seq, "%-9s %-7s %d %d",
893 ax2asc(&nr_node->callsign), 894 ax2asc(buf, &nr_node->callsign),
894 (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic, 895 (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
895 nr_node->which + 1, 896 nr_node->which + 1,
896 nr_node->count); 897 nr_node->count);
@@ -964,6 +965,7 @@ static void nr_neigh_stop(struct seq_file *seq, void *v)
964 965
965static int nr_neigh_show(struct seq_file *seq, void *v) 966static int nr_neigh_show(struct seq_file *seq, void *v)
966{ 967{
968 char buf[11];
967 int i; 969 int i;
968 970
969 if (v == SEQ_START_TOKEN) 971 if (v == SEQ_START_TOKEN)
@@ -973,7 +975,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
973 975
974 seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d", 976 seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d",
975 nr_neigh->number, 977 nr_neigh->number,
976 ax2asc(&nr_neigh->callsign), 978 ax2asc(buf, &nr_neigh->callsign),
977 nr_neigh->dev ? nr_neigh->dev->name : "???", 979 nr_neigh->dev ? nr_neigh->dev->name : "???",
978 nr_neigh->quality, 980 nr_neigh->quality,
979 nr_neigh->locked, 981 nr_neigh->locked,
@@ -983,7 +985,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
983 if (nr_neigh->digipeat != NULL) { 985 if (nr_neigh->digipeat != NULL) {
984 for (i = 0; i < nr_neigh->digipeat->ndigi; i++) 986 for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
985 seq_printf(seq, " %s", 987 seq_printf(seq, " %s",
986 ax2asc(&nr_neigh->digipeat->calls[i])); 988 ax2asc(buf, &nr_neigh->digipeat->calls[i]));
987 } 989 }
988 990
989 seq_puts(seq, "\n"); 991 seq_puts(seq, "\n");
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index ba997095f08f..8690f171c1ef 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1535,8 +1535,7 @@ static unsigned int packet_poll(struct file * file, struct socket *sock,
1535static void packet_mm_open(struct vm_area_struct *vma) 1535static void packet_mm_open(struct vm_area_struct *vma)
1536{ 1536{
1537 struct file *file = vma->vm_file; 1537 struct file *file = vma->vm_file;
1538 struct inode *inode = file->f_dentry->d_inode; 1538 struct socket * sock = file->private_data;
1539 struct socket * sock = SOCKET_I(inode);
1540 struct sock *sk = sock->sk; 1539 struct sock *sk = sock->sk;
1541 1540
1542 if (sk) 1541 if (sk)
@@ -1546,8 +1545,7 @@ static void packet_mm_open(struct vm_area_struct *vma)
1546static void packet_mm_close(struct vm_area_struct *vma) 1545static void packet_mm_close(struct vm_area_struct *vma)
1547{ 1546{
1548 struct file *file = vma->vm_file; 1547 struct file *file = vma->vm_file;
1549 struct inode *inode = file->f_dentry->d_inode; 1548 struct socket * sock = file->private_data;
1550 struct socket * sock = SOCKET_I(inode);
1551 struct sock *sk = sock->sk; 1549 struct sock *sk = sock->sk;
1552 1550
1553 if (sk) 1551 if (sk)
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index c6e59f84c3ae..3077878ed4f0 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1363,6 +1363,8 @@ static void rose_info_stop(struct seq_file *seq, void *v)
1363 1363
1364static int rose_info_show(struct seq_file *seq, void *v) 1364static int rose_info_show(struct seq_file *seq, void *v)
1365{ 1365{
1366 char buf[11];
1367
1366 if (v == SEQ_START_TOKEN) 1368 if (v == SEQ_START_TOKEN)
1367 seq_puts(seq, 1369 seq_puts(seq,
1368 "dest_addr dest_call src_addr src_call dev lci neigh st vs vr va t t1 t2 t3 hb idle Snd-Q Rcv-Q inode\n"); 1370 "dest_addr dest_call src_addr src_call dev lci neigh st vs vr va t t1 t2 t3 hb idle Snd-Q Rcv-Q inode\n");
@@ -1380,12 +1382,12 @@ static int rose_info_show(struct seq_file *seq, void *v)
1380 1382
1381 seq_printf(seq, "%-10s %-9s ", 1383 seq_printf(seq, "%-10s %-9s ",
1382 rose2asc(&rose->dest_addr), 1384 rose2asc(&rose->dest_addr),
1383 ax2asc(&rose->dest_call)); 1385 ax2asc(buf, &rose->dest_call));
1384 1386
1385 if (ax25cmp(&rose->source_call, &null_ax25_address) == 0) 1387 if (ax25cmp(&rose->source_call, &null_ax25_address) == 0)
1386 callsign = "??????-?"; 1388 callsign = "??????-?";
1387 else 1389 else
1388 callsign = ax2asc(&rose->source_call); 1390 callsign = ax2asc(buf, &rose->source_call);
1389 1391
1390 seq_printf(seq, 1392 seq_printf(seq,
1391 "%-10s %-9s %-5s %3.3X %05d %d %d %d %d %3lu %3lu %3lu %3lu %3lu %3lu/%03lu %5d %5d %ld\n", 1393 "%-10s %-9s %-5s %3.3X %05d %d %d %d %d %3lu %3lu %3lu %3lu %3lu %3lu/%03lu %5d %5d %ld\n",
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 4510cd7613ec..e556d92c0bc4 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -851,6 +851,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
851 unsigned char cause, diagnostic; 851 unsigned char cause, diagnostic;
852 struct net_device *dev; 852 struct net_device *dev;
853 int len, res = 0; 853 int len, res = 0;
854 char buf[11];
854 855
855#if 0 856#if 0
856 if (call_in_firewall(PF_ROSE, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT) 857 if (call_in_firewall(PF_ROSE, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT)
@@ -876,7 +877,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
876 877
877 if (rose_neigh == NULL) { 878 if (rose_neigh == NULL) {
878 printk("rose_route : unknown neighbour or device %s\n", 879 printk("rose_route : unknown neighbour or device %s\n",
879 ax2asc(&ax25->dest_addr)); 880 ax2asc(buf, &ax25->dest_addr));
880 goto out; 881 goto out;
881 } 882 }
882 883
@@ -1178,6 +1179,7 @@ static void rose_neigh_stop(struct seq_file *seq, void *v)
1178 1179
1179static int rose_neigh_show(struct seq_file *seq, void *v) 1180static int rose_neigh_show(struct seq_file *seq, void *v)
1180{ 1181{
1182 char buf[11];
1181 int i; 1183 int i;
1182 1184
1183 if (v == SEQ_START_TOKEN) 1185 if (v == SEQ_START_TOKEN)
@@ -1189,7 +1191,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
1189 /* if (!rose_neigh->loopback) { */ 1191 /* if (!rose_neigh->loopback) { */
1190 seq_printf(seq, "%05d %-9s %-4s %3d %3d %3s %3s %3lu %3lu", 1192 seq_printf(seq, "%05d %-9s %-4s %3d %3d %3s %3s %3lu %3lu",
1191 rose_neigh->number, 1193 rose_neigh->number,
1192 (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(&rose_neigh->callsign), 1194 (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
1193 rose_neigh->dev ? rose_neigh->dev->name : "???", 1195 rose_neigh->dev ? rose_neigh->dev->name : "???",
1194 rose_neigh->count, 1196 rose_neigh->count,
1195 rose_neigh->use, 1197 rose_neigh->use,
@@ -1200,7 +1202,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
1200 1202
1201 if (rose_neigh->digipeat != NULL) { 1203 if (rose_neigh->digipeat != NULL) {
1202 for (i = 0; i < rose_neigh->digipeat->ndigi; i++) 1204 for (i = 0; i < rose_neigh->digipeat->ndigi; i++)
1203 seq_printf(seq, " %s", ax2asc(&rose_neigh->digipeat->calls[i])); 1205 seq_printf(seq, " %s", ax2asc(buf, &rose_neigh->digipeat->calls[i]));
1204 } 1206 }
1205 1207
1206 seq_puts(seq, "\n"); 1208 seq_puts(seq, "\n");
@@ -1260,6 +1262,8 @@ static void rose_route_stop(struct seq_file *seq, void *v)
1260 1262
1261static int rose_route_show(struct seq_file *seq, void *v) 1263static int rose_route_show(struct seq_file *seq, void *v)
1262{ 1264{
1265 char buf[11];
1266
1263 if (v == SEQ_START_TOKEN) 1267 if (v == SEQ_START_TOKEN)
1264 seq_puts(seq, 1268 seq_puts(seq,
1265 "lci address callsign neigh <-> lci address callsign neigh\n"); 1269 "lci address callsign neigh <-> lci address callsign neigh\n");
@@ -1271,7 +1275,7 @@ static int rose_route_show(struct seq_file *seq, void *v)
1271 "%3.3X %-10s %-9s %05d ", 1275 "%3.3X %-10s %-9s %05d ",
1272 rose_route->lci1, 1276 rose_route->lci1,
1273 rose2asc(&rose_route->src_addr), 1277 rose2asc(&rose_route->src_addr),
1274 ax2asc(&rose_route->src_call), 1278 ax2asc(buf, &rose_route->src_call),
1275 rose_route->neigh1->number); 1279 rose_route->neigh1->number);
1276 else 1280 else
1277 seq_puts(seq, 1281 seq_puts(seq,
@@ -1282,7 +1286,7 @@ static int rose_route_show(struct seq_file *seq, void *v)
1282 "%3.3X %-10s %-9s %05d\n", 1286 "%3.3X %-10s %-9s %05d\n",
1283 rose_route->lci2, 1287 rose_route->lci2,
1284 rose2asc(&rose_route->dest_addr), 1288 rose2asc(&rose_route->dest_addr),
1285 ax2asc(&rose_route->dest_call), 1289 ax2asc(buf, &rose_route->dest_call),
1286 rose_route->neigh2->number); 1290 rose_route->neigh2->number);
1287 else 1291 else
1288 seq_puts(seq, 1292 seq_puts(seq,
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index a29a3a960fd6..02891ce2db37 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -400,6 +400,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
400{ 400{
401 unsigned char *p = buffer + 1; 401 unsigned char *p = buffer + 1;
402 char *callsign; 402 char *callsign;
403 char buf[11];
403 int len, nb; 404 int len, nb;
404 405
405 /* National Facilities */ 406 /* National Facilities */
@@ -456,7 +457,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
456 457
457 *p++ = FAC_CCITT_DEST_NSAP; 458 *p++ = FAC_CCITT_DEST_NSAP;
458 459
459 callsign = ax2asc(&rose->dest_call); 460 callsign = ax2asc(buf, &rose->dest_call);
460 461
461 *p++ = strlen(callsign) + 10; 462 *p++ = strlen(callsign) + 10;
462 *p++ = (strlen(callsign) + 9) * 2; /* ??? */ 463 *p++ = (strlen(callsign) + 9) * 2; /* ??? */
@@ -471,7 +472,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
471 472
472 *p++ = FAC_CCITT_SRC_NSAP; 473 *p++ = FAC_CCITT_SRC_NSAP;
473 474
474 callsign = ax2asc(&rose->source_call); 475 callsign = ax2asc(buf, &rose->source_call);
475 476
476 *p++ = strlen(callsign) + 10; 477 *p++ = strlen(callsign) + 10;
477 *p++ = (strlen(callsign) + 9) * 2; /* ??? */ 478 *p++ = (strlen(callsign) + 9) * 2; /* ??? */
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index e47ac0d1a6d6..e22ccd655965 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -193,8 +193,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
193 sctp_unhash_endpoint(ep); 193 sctp_unhash_endpoint(ep);
194 194
195 /* Free up the HMAC transform. */ 195 /* Free up the HMAC transform. */
196 if (sctp_sk(ep->base.sk)->hmac) 196 sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac);
197 sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac);
198 197
199 /* Cleanup. */ 198 /* Cleanup. */
200 sctp_inq_free(&ep->base.inqueue); 199 sctp_inq_free(&ep->base.inqueue);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 4454afe4727e..91ec8c936913 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4194,8 +4194,7 @@ out:
4194 sctp_release_sock(sk); 4194 sctp_release_sock(sk);
4195 return err; 4195 return err;
4196cleanup: 4196cleanup:
4197 if (tfm) 4197 sctp_crypto_free_tfm(tfm);
4198 sctp_crypto_free_tfm(tfm);
4199 goto out; 4198 goto out;
4200} 4199}
4201 4200
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index dc4893474f18..75b28dd634fe 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -42,6 +42,7 @@
42 */ 42 */
43 43
44#include <net/sctp/structs.h> 44#include <net/sctp/structs.h>
45#include <net/sctp/sctp.h>
45#include <linux/sysctl.h> 46#include <linux/sysctl.h>
46 47
47static ctl_handler sctp_sysctl_jiffies_ms; 48static ctl_handler sctp_sysctl_jiffies_ms;
diff --git a/net/socket.c b/net/socket.c
index 94fe638b4d72..e1bd5d84d7bf 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -667,7 +667,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
667 } 667 }
668 iocb->private = x; 668 iocb->private = x;
669 x->kiocb = iocb; 669 x->kiocb = iocb;
670 sock = SOCKET_I(iocb->ki_filp->f_dentry->d_inode); 670 sock = iocb->ki_filp->private_data;
671 671
672 x->async_msg.msg_name = NULL; 672 x->async_msg.msg_name = NULL;
673 x->async_msg.msg_namelen = 0; 673 x->async_msg.msg_namelen = 0;
@@ -709,7 +709,7 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
709 } 709 }
710 iocb->private = x; 710 iocb->private = x;
711 x->kiocb = iocb; 711 x->kiocb = iocb;
712 sock = SOCKET_I(iocb->ki_filp->f_dentry->d_inode); 712 sock = iocb->ki_filp->private_data;
713 713
714 x->async_msg.msg_name = NULL; 714 x->async_msg.msg_name = NULL;
715 x->async_msg.msg_namelen = 0; 715 x->async_msg.msg_namelen = 0;
@@ -732,7 +732,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
732 struct socket *sock; 732 struct socket *sock;
733 int flags; 733 int flags;
734 734
735 sock = SOCKET_I(file->f_dentry->d_inode); 735 sock = file->private_data;
736 736
737 flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; 737 flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
738 if (more) 738 if (more)
@@ -741,14 +741,14 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
741 return sock->ops->sendpage(sock, page, offset, size, flags); 741 return sock->ops->sendpage(sock, page, offset, size, flags);
742} 742}
743 743
744static int sock_readv_writev(int type, struct inode * inode, 744static int sock_readv_writev(int type,
745 struct file * file, const struct iovec * iov, 745 struct file * file, const struct iovec * iov,
746 long count, size_t size) 746 long count, size_t size)
747{ 747{
748 struct msghdr msg; 748 struct msghdr msg;
749 struct socket *sock; 749 struct socket *sock;
750 750
751 sock = SOCKET_I(inode); 751 sock = file->private_data;
752 752
753 msg.msg_name = NULL; 753 msg.msg_name = NULL;
754 msg.msg_namelen = 0; 754 msg.msg_namelen = 0;
@@ -775,7 +775,7 @@ static ssize_t sock_readv(struct file *file, const struct iovec *vector,
775 int i; 775 int i;
776 for (i = 0 ; i < count ; i++) 776 for (i = 0 ; i < count ; i++)
777 tot_len += vector[i].iov_len; 777 tot_len += vector[i].iov_len;
778 return sock_readv_writev(VERIFY_WRITE, file->f_dentry->d_inode, 778 return sock_readv_writev(VERIFY_WRITE,
779 file, vector, count, tot_len); 779 file, vector, count, tot_len);
780} 780}
781 781
@@ -786,7 +786,7 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector,
786 int i; 786 int i;
787 for (i = 0 ; i < count ; i++) 787 for (i = 0 ; i < count ; i++)
788 tot_len += vector[i].iov_len; 788 tot_len += vector[i].iov_len;
789 return sock_readv_writev(VERIFY_READ, file->f_dentry->d_inode, 789 return sock_readv_writev(VERIFY_READ,
790 file, vector, count, tot_len); 790 file, vector, count, tot_len);
791} 791}
792 792
@@ -840,7 +840,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
840 void __user *argp = (void __user *)arg; 840 void __user *argp = (void __user *)arg;
841 int pid, err; 841 int pid, err;
842 842
843 sock = SOCKET_I(file->f_dentry->d_inode); 843 sock = file->private_data;
844 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { 844 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
845 err = dev_ioctl(cmd, argp); 845 err = dev_ioctl(cmd, argp);
846 } else 846 } else
@@ -939,13 +939,13 @@ static unsigned int sock_poll(struct file *file, poll_table * wait)
939 /* 939 /*
940 * We can't return errors to poll, so it's either yes or no. 940 * We can't return errors to poll, so it's either yes or no.
941 */ 941 */
942 sock = SOCKET_I(file->f_dentry->d_inode); 942 sock = file->private_data;
943 return sock->ops->poll(file, sock, wait); 943 return sock->ops->poll(file, sock, wait);
944} 944}
945 945
946static int sock_mmap(struct file * file, struct vm_area_struct * vma) 946static int sock_mmap(struct file * file, struct vm_area_struct * vma)
947{ 947{
948 struct socket *sock = SOCKET_I(file->f_dentry->d_inode); 948 struct socket *sock = file->private_data;
949 949
950 return sock->ops->mmap(file, sock, vma); 950 return sock->ops->mmap(file, sock, vma);
951} 951}
@@ -995,7 +995,7 @@ static int sock_fasync(int fd, struct file *filp, int on)
995 return -ENOMEM; 995 return -ENOMEM;
996 } 996 }
997 997
998 sock = SOCKET_I(filp->f_dentry->d_inode); 998 sock = filp->private_data;
999 999
1000 if ((sk=sock->sk) == NULL) { 1000 if ((sk=sock->sk) == NULL) {
1001 kfree(fna); 1001 kfree(fna);
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 5a7265aeaf83..ee6ae74cd1b2 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -160,7 +160,7 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
160 " unsupported checksum %d", cksumtype); 160 " unsupported checksum %d", cksumtype);
161 goto out; 161 goto out;
162 } 162 }
163 if (!(tfm = crypto_alloc_tfm(cksumname, 0))) 163 if (!(tfm = crypto_alloc_tfm(cksumname, CRYPTO_TFM_REQ_MAY_SLEEP)))
164 goto out; 164 goto out;
165 cksum->len = crypto_tfm_alg_digestsize(tfm); 165 cksum->len = crypto_tfm_alg_digestsize(tfm);
166 if ((cksum->data = kmalloc(cksum->len, GFP_KERNEL)) == NULL) 166 if ((cksum->data = kmalloc(cksum->len, GFP_KERNEL)) == NULL)
@@ -199,8 +199,7 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
199 crypto_digest_final(tfm, cksum->data); 199 crypto_digest_final(tfm, cksum->data);
200 code = 0; 200 code = 0;
201out: 201out:
202 if (tfm) 202 crypto_free_tfm(tfm);
203 crypto_free_tfm(tfm);
204 return code; 203 return code;
205} 204}
206 205
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index cf726510df8e..606a8a82cafb 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -185,12 +185,9 @@ static void
185gss_delete_sec_context_kerberos(void *internal_ctx) { 185gss_delete_sec_context_kerberos(void *internal_ctx) {
186 struct krb5_ctx *kctx = internal_ctx; 186 struct krb5_ctx *kctx = internal_ctx;
187 187
188 if (kctx->seq) 188 crypto_free_tfm(kctx->seq);
189 crypto_free_tfm(kctx->seq); 189 crypto_free_tfm(kctx->enc);
190 if (kctx->enc) 190 kfree(kctx->mech_used.data);
191 crypto_free_tfm(kctx->enc);
192 if (kctx->mech_used.data)
193 kfree(kctx->mech_used.data);
194 kfree(kctx); 191 kfree(kctx);
195} 192}
196 193
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index dad05994c3eb..6c97d61baa9b 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -214,14 +214,10 @@ static void
214gss_delete_sec_context_spkm3(void *internal_ctx) { 214gss_delete_sec_context_spkm3(void *internal_ctx) {
215 struct spkm3_ctx *sctx = internal_ctx; 215 struct spkm3_ctx *sctx = internal_ctx;
216 216
217 if(sctx->derived_integ_key) 217 crypto_free_tfm(sctx->derived_integ_key);
218 crypto_free_tfm(sctx->derived_integ_key); 218 crypto_free_tfm(sctx->derived_conf_key);
219 if(sctx->derived_conf_key) 219 kfree(sctx->share_key.data);
220 crypto_free_tfm(sctx->derived_conf_key); 220 kfree(sctx->mech_used.data);
221 if(sctx->share_key.data)
222 kfree(sctx->share_key.data);
223 if(sctx->mech_used.data)
224 kfree(sctx->mech_used.data);
225 kfree(sctx); 221 kfree(sctx);
226} 222}
227 223
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 5c8fe3bfc494..e3308195374e 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -250,6 +250,7 @@ out:
250} 250}
251 251
252static struct cache_detail rsi_cache = { 252static struct cache_detail rsi_cache = {
253 .owner = THIS_MODULE,
253 .hash_size = RSI_HASHMAX, 254 .hash_size = RSI_HASHMAX,
254 .hash_table = rsi_table, 255 .hash_table = rsi_table,
255 .name = "auth.rpcsec.init", 256 .name = "auth.rpcsec.init",
@@ -436,6 +437,7 @@ out:
436} 437}
437 438
438static struct cache_detail rsc_cache = { 439static struct cache_detail rsc_cache = {
440 .owner = THIS_MODULE,
439 .hash_size = RSC_HASHMAX, 441 .hash_size = RSC_HASHMAX,
440 .hash_table = rsc_table, 442 .hash_table = rsc_table,
441 .name = "auth.rpcsec.context", 443 .name = "auth.rpcsec.context",
@@ -1074,7 +1076,9 @@ gss_svc_init(void)
1074void 1076void
1075gss_svc_shutdown(void) 1077gss_svc_shutdown(void)
1076{ 1078{
1077 cache_unregister(&rsc_cache); 1079 if (cache_unregister(&rsc_cache))
1078 cache_unregister(&rsi_cache); 1080 printk(KERN_ERR "auth_rpcgss: failed to unregister rsc cache\n");
1081 if (cache_unregister(&rsi_cache))
1082 printk(KERN_ERR "auth_rpcgss: failed to unregister rsi cache\n");
1079 svc_auth_unregister(RPC_AUTH_GSS); 1083 svc_auth_unregister(RPC_AUTH_GSS);
1080} 1084}
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 900f5bc7e336..f509e9992767 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -177,7 +177,7 @@ void cache_register(struct cache_detail *cd)
177 cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc); 177 cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc);
178 if (cd->proc_ent) { 178 if (cd->proc_ent) {
179 struct proc_dir_entry *p; 179 struct proc_dir_entry *p;
180 cd->proc_ent->owner = THIS_MODULE; 180 cd->proc_ent->owner = cd->owner;
181 cd->channel_ent = cd->content_ent = NULL; 181 cd->channel_ent = cd->content_ent = NULL;
182 182
183 p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, 183 p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR,
@@ -185,7 +185,7 @@ void cache_register(struct cache_detail *cd)
185 cd->flush_ent = p; 185 cd->flush_ent = p;
186 if (p) { 186 if (p) {
187 p->proc_fops = &cache_flush_operations; 187 p->proc_fops = &cache_flush_operations;
188 p->owner = THIS_MODULE; 188 p->owner = cd->owner;
189 p->data = cd; 189 p->data = cd;
190 } 190 }
191 191
@@ -195,7 +195,7 @@ void cache_register(struct cache_detail *cd)
195 cd->channel_ent = p; 195 cd->channel_ent = p;
196 if (p) { 196 if (p) {
197 p->proc_fops = &cache_file_operations; 197 p->proc_fops = &cache_file_operations;
198 p->owner = THIS_MODULE; 198 p->owner = cd->owner;
199 p->data = cd; 199 p->data = cd;
200 } 200 }
201 } 201 }
@@ -205,7 +205,7 @@ void cache_register(struct cache_detail *cd)
205 cd->content_ent = p; 205 cd->content_ent = p;
206 if (p) { 206 if (p) {
207 p->proc_fops = &content_file_operations; 207 p->proc_fops = &content_file_operations;
208 p->owner = THIS_MODULE; 208 p->owner = cd->owner;
209 p->data = cd; 209 p->data = cd;
210 } 210 }
211 } 211 }
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index fe1a73ce6cff..ded6c63f11ec 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Userland/kernel interface for rpcauth_gss. 4 * Userland/kernel interface for rpcauth_gss.
5 * Code shamelessly plagiarized from fs/nfsd/nfsctl.c 5 * Code shamelessly plagiarized from fs/nfsd/nfsctl.c
6 * and fs/driverfs/inode.c 6 * and fs/sysfs/inode.c
7 * 7 *
8 * Copyright (c) 2002, Trond Myklebust <trond.myklebust@fys.uio.no> 8 * Copyright (c) 2002, Trond Myklebust <trond.myklebust@fys.uio.no>
9 * 9 *
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 9b67dc19944c..4979f226e285 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -35,13 +35,13 @@ static int rpc_proc_show(struct seq_file *seq, void *v) {
35 int i, j; 35 int i, j;
36 36
37 seq_printf(seq, 37 seq_printf(seq,
38 "net %d %d %d %d\n", 38 "net %u %u %u %u\n",
39 statp->netcnt, 39 statp->netcnt,
40 statp->netudpcnt, 40 statp->netudpcnt,
41 statp->nettcpcnt, 41 statp->nettcpcnt,
42 statp->nettcpconn); 42 statp->nettcpconn);
43 seq_printf(seq, 43 seq_printf(seq,
44 "rpc %d %d %d\n", 44 "rpc %u %u %u\n",
45 statp->rpccnt, 45 statp->rpccnt,
46 statp->rpcretrans, 46 statp->rpcretrans,
47 statp->rpcauthrefresh); 47 statp->rpcauthrefresh);
@@ -50,10 +50,10 @@ static int rpc_proc_show(struct seq_file *seq, void *v) {
50 const struct rpc_version *vers = prog->version[i]; 50 const struct rpc_version *vers = prog->version[i];
51 if (!vers) 51 if (!vers)
52 continue; 52 continue;
53 seq_printf(seq, "proc%d %d", 53 seq_printf(seq, "proc%u %u",
54 vers->number, vers->nrprocs); 54 vers->number, vers->nrprocs);
55 for (j = 0; j < vers->nrprocs; j++) 55 for (j = 0; j < vers->nrprocs; j++)
56 seq_printf(seq, " %d", 56 seq_printf(seq, " %u",
57 vers->procs[j].p_count); 57 vers->procs[j].p_count);
58 seq_putc(seq, '\n'); 58 seq_putc(seq, '\n');
59 } 59 }
@@ -83,13 +83,13 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) {
83 int i, j; 83 int i, j;
84 84
85 seq_printf(seq, 85 seq_printf(seq,
86 "net %d %d %d %d\n", 86 "net %u %u %u %u\n",
87 statp->netcnt, 87 statp->netcnt,
88 statp->netudpcnt, 88 statp->netudpcnt,
89 statp->nettcpcnt, 89 statp->nettcpcnt,
90 statp->nettcpconn); 90 statp->nettcpconn);
91 seq_printf(seq, 91 seq_printf(seq,
92 "rpc %d %d %d %d %d\n", 92 "rpc %u %u %u %u %u\n",
93 statp->rpccnt, 93 statp->rpccnt,
94 statp->rpcbadfmt+statp->rpcbadauth+statp->rpcbadclnt, 94 statp->rpcbadfmt+statp->rpcbadauth+statp->rpcbadclnt,
95 statp->rpcbadfmt, 95 statp->rpcbadfmt,
@@ -99,9 +99,9 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) {
99 for (i = 0; i < prog->pg_nvers; i++) { 99 for (i = 0; i < prog->pg_nvers; i++) {
100 if (!(vers = prog->pg_vers[i]) || !(proc = vers->vs_proc)) 100 if (!(vers = prog->pg_vers[i]) || !(proc = vers->vs_proc))
101 continue; 101 continue;
102 seq_printf(seq, "proc%d %d", i, vers->vs_nproc); 102 seq_printf(seq, "proc%d %u", i, vers->vs_nproc);
103 for (j = 0; j < vers->vs_nproc; j++, proc++) 103 for (j = 0; j < vers->vs_nproc; j++, proc++)
104 seq_printf(seq, " %d", proc->pc_count); 104 seq_printf(seq, " %u", proc->pc_count);
105 seq_putc(seq, '\n'); 105 seq_putc(seq, '\n');
106 } 106 }
107} 107}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 62a073495276..ed48ff022d35 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -176,8 +176,10 @@ cleanup_sunrpc(void)
176{ 176{
177 unregister_rpc_pipefs(); 177 unregister_rpc_pipefs();
178 rpc_destroy_mempool(); 178 rpc_destroy_mempool();
179 cache_unregister(&auth_domain_cache); 179 if (cache_unregister(&auth_domain_cache))
180 cache_unregister(&ip_map_cache); 180 printk(KERN_ERR "sunrpc: failed to unregister auth_domain cache\n");
181 if (cache_unregister(&ip_map_cache))
182 printk(KERN_ERR "sunrpc: failed to unregister ip_map cache\n");
181#ifdef RPC_DEBUG 183#ifdef RPC_DEBUG
182 rpc_unregister_sysctl(); 184 rpc_unregister_sysctl();
183#endif 185#endif
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index bde8147ef2db..dda4f0c63511 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -143,6 +143,7 @@ static void auth_domain_drop(struct cache_head *item, struct cache_detail *cd)
143 143
144 144
145struct cache_detail auth_domain_cache = { 145struct cache_detail auth_domain_cache = {
146 .owner = THIS_MODULE,
146 .hash_size = DN_HASHMAX, 147 .hash_size = DN_HASHMAX,
147 .hash_table = auth_domain_table, 148 .hash_table = auth_domain_table,
148 .name = "auth.domain", 149 .name = "auth.domain",
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index d6baf6fdf8a9..cac2e774dd81 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -242,6 +242,7 @@ static int ip_map_show(struct seq_file *m,
242 242
243 243
244struct cache_detail ip_map_cache = { 244struct cache_detail ip_map_cache = {
245 .owner = THIS_MODULE,
245 .hash_size = IP_HASHMAX, 246 .hash_size = IP_HASHMAX,
246 .hash_table = ip_table, 247 .hash_table = ip_table,
247 .name = "auth.unix.ip", 248 .name = "auth.unix.ip",