aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-09-01 18:02:01 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-01 18:02:01 -0400
commite3ee3b78f83688a0ae4315e8be71b2eac559904a (patch)
treedeb03bcdd020262af450ed23382d7c921263f5cf /net/ipv6
parent91cb70c1769d9b72dd1efe40c31f01005820b09e (diff)
parent6b39374a27eb4be7e9d82145ae270ba02ea90dc8 (diff)
/spare/repo/netdev-2.6 branch 'master'
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Makefile4
-rw-r--r--net/ipv6/addrconf.c32
-rw-r--r--net/ipv6/af_inet6.c62
-rw-r--r--net/ipv6/ah6.c13
-rw-r--r--net/ipv6/datagram.c5
-rw-r--r--net/ipv6/esp6.c3
-rw-r--r--net/ipv6/exthdrs.c8
-rw-r--r--net/ipv6/icmp.c25
-rw-r--r--net/ipv6/inet6_hashtables.c81
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_input.c6
-rw-r--r--net/ipv6/ip6_output.c54
-rw-r--r--net/ipv6/ipv6_sockglue.c25
-rw-r--r--net/ipv6/ipv6_syms.c3
-rw-r--r--net/ipv6/ndisc.c4
-rw-r--r--net/ipv6/netfilter.c104
-rw-r--r--net/ipv6/netfilter/Kconfig37
-rw-r--r--net/ipv6/netfilter/Makefile3
-rw-r--r--net/ipv6/netfilter/ip6_queue.c48
-rw-r--r--net/ipv6/netfilter/ip6_tables.c5
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c118
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c93
-rw-r--r--net/ipv6/netfilter/ip6t_MARK.c5
-rw-r--r--net/ipv6/netfilter/ip6t_NFQUEUE.c70
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c284
-rw-r--r--net/ipv6/netfilter/ip6t_owner.c90
-rw-r--r--net/ipv6/raw.c20
-rw-r--r--net/ipv6/reassembly.c4
-rw-r--r--net/ipv6/route.c14
-rw-r--r--net/ipv6/sit.c2
-rw-r--r--net/ipv6/sysctl_net_ipv6.c3
-rw-r--r--net/ipv6/tcp_ipv6.c437
-rw-r--r--net/ipv6/udp.c12
-rw-r--r--net/ipv6/xfrm6_tunnel.c2
34 files changed, 1040 insertions, 638 deletions
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index b39e04940590..6460eec834b7 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -8,7 +8,7 @@ ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \
8 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ 8 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
9 protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ 9 protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
10 exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ 10 exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
11 ip6_flowlabel.o ipv6_syms.o 11 ip6_flowlabel.o ipv6_syms.o netfilter.o
12 12
13ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \ 13ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
14 xfrm6_output.o 14 xfrm6_output.o
@@ -23,3 +23,5 @@ obj-$(CONFIG_NETFILTER) += netfilter/
23obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o 23obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
24 24
25obj-y += exthdrs_core.o 25obj-y += exthdrs_core.o
26
27obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 77004b9456c0..937ad32db77c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1041,9 +1041,9 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
1041 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; 1041 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
1042 const struct in6_addr *sk2_rcv_saddr6 = tcp_v6_rcv_saddr(sk2); 1042 const struct in6_addr *sk2_rcv_saddr6 = tcp_v6_rcv_saddr(sk2);
1043 u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr; 1043 u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
1044 u32 sk2_rcv_saddr = tcp_v4_rcv_saddr(sk2); 1044 u32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
1045 int sk_ipv6only = ipv6_only_sock(sk); 1045 int sk_ipv6only = ipv6_only_sock(sk);
1046 int sk2_ipv6only = tcp_v6_ipv6only(sk2); 1046 int sk2_ipv6only = inet_v6_ipv6only(sk2);
1047 int addr_type = ipv6_addr_type(sk_rcv_saddr6); 1047 int addr_type = ipv6_addr_type(sk_rcv_saddr6);
1048 int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED; 1048 int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
1049 1049
@@ -1126,7 +1126,7 @@ void addrconf_leave_solict(struct inet6_dev *idev, struct in6_addr *addr)
1126 __ipv6_dev_mc_dec(idev, &maddr); 1126 __ipv6_dev_mc_dec(idev, &maddr);
1127} 1127}
1128 1128
1129void addrconf_join_anycast(struct inet6_ifaddr *ifp) 1129static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
1130{ 1130{
1131 struct in6_addr addr; 1131 struct in6_addr addr;
1132 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); 1132 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
@@ -1135,7 +1135,7 @@ void addrconf_join_anycast(struct inet6_ifaddr *ifp)
1135 ipv6_dev_ac_inc(ifp->idev->dev, &addr); 1135 ipv6_dev_ac_inc(ifp->idev->dev, &addr);
1136} 1136}
1137 1137
1138void addrconf_leave_anycast(struct inet6_ifaddr *ifp) 1138static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
1139{ 1139{
1140 struct in6_addr addr; 1140 struct in6_addr addr;
1141 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); 1141 ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
@@ -2858,16 +2858,16 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
2858 2858
2859 skb = alloc_skb(size, GFP_ATOMIC); 2859 skb = alloc_skb(size, GFP_ATOMIC);
2860 if (!skb) { 2860 if (!skb) {
2861 netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, ENOBUFS); 2861 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_IFADDR, ENOBUFS);
2862 return; 2862 return;
2863 } 2863 }
2864 if (inet6_fill_ifaddr(skb, ifa, current->pid, 0, event, 0) < 0) { 2864 if (inet6_fill_ifaddr(skb, ifa, current->pid, 0, event, 0) < 0) {
2865 kfree_skb(skb); 2865 kfree_skb(skb);
2866 netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, EINVAL); 2866 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_IFADDR, EINVAL);
2867 return; 2867 return;
2868 } 2868 }
2869 NETLINK_CB(skb).dst_groups = RTMGRP_IPV6_IFADDR; 2869 NETLINK_CB(skb).dst_group = RTNLGRP_IPV6_IFADDR;
2870 netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_IFADDR, GFP_ATOMIC); 2870 netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFADDR, GFP_ATOMIC);
2871} 2871}
2872 2872
2873static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, 2873static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
@@ -2994,16 +2994,16 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
2994 2994
2995 skb = alloc_skb(size, GFP_ATOMIC); 2995 skb = alloc_skb(size, GFP_ATOMIC);
2996 if (!skb) { 2996 if (!skb) {
2997 netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, ENOBUFS); 2997 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_IFINFO, ENOBUFS);
2998 return; 2998 return;
2999 } 2999 }
3000 if (inet6_fill_ifinfo(skb, idev, current->pid, 0, event, 0) < 0) { 3000 if (inet6_fill_ifinfo(skb, idev, current->pid, 0, event, 0) < 0) {
3001 kfree_skb(skb); 3001 kfree_skb(skb);
3002 netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, EINVAL); 3002 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_IFINFO, EINVAL);
3003 return; 3003 return;
3004 } 3004 }
3005 NETLINK_CB(skb).dst_groups = RTMGRP_IPV6_IFINFO; 3005 NETLINK_CB(skb).dst_group = RTNLGRP_IPV6_IFINFO;
3006 netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_IFINFO, GFP_ATOMIC); 3006 netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFINFO, GFP_ATOMIC);
3007} 3007}
3008 3008
3009static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, 3009static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
@@ -3054,16 +3054,16 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
3054 3054
3055 skb = alloc_skb(size, GFP_ATOMIC); 3055 skb = alloc_skb(size, GFP_ATOMIC);
3056 if (!skb) { 3056 if (!skb) {
3057 netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, ENOBUFS); 3057 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_PREFIX, ENOBUFS);
3058 return; 3058 return;
3059 } 3059 }
3060 if (inet6_fill_prefix(skb, idev, pinfo, current->pid, 0, event, 0) < 0) { 3060 if (inet6_fill_prefix(skb, idev, pinfo, current->pid, 0, event, 0) < 0) {
3061 kfree_skb(skb); 3061 kfree_skb(skb);
3062 netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, EINVAL); 3062 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_PREFIX, EINVAL);
3063 return; 3063 return;
3064 } 3064 }
3065 NETLINK_CB(skb).dst_groups = RTMGRP_IPV6_PREFIX; 3065 NETLINK_CB(skb).dst_group = RTNLGRP_IPV6_PREFIX;
3066 netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); 3066 netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_PREFIX, GFP_ATOMIC);
3067} 3067}
3068 3068
3069static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = { 3069static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = {
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 28d9bcab0970..4f8795af2edb 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -44,6 +44,7 @@
44#include <linux/netdevice.h> 44#include <linux/netdevice.h>
45#include <linux/icmpv6.h> 45#include <linux/icmpv6.h>
46#include <linux/smp_lock.h> 46#include <linux/smp_lock.h>
47#include <linux/netfilter_ipv6.h>
47 48
48#include <net/ip.h> 49#include <net/ip.h>
49#include <net/ipv6.h> 50#include <net/ipv6.h>
@@ -66,45 +67,14 @@ MODULE_AUTHOR("Cast of dozens");
66MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); 67MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
67MODULE_LICENSE("GPL"); 68MODULE_LICENSE("GPL");
68 69
69/* IPv6 procfs goodies... */
70
71#ifdef CONFIG_PROC_FS
72extern int raw6_proc_init(void);
73extern void raw6_proc_exit(void);
74extern int tcp6_proc_init(void);
75extern void tcp6_proc_exit(void);
76extern int udp6_proc_init(void);
77extern void udp6_proc_exit(void);
78extern int ipv6_misc_proc_init(void);
79extern void ipv6_misc_proc_exit(void);
80extern int ac6_proc_init(void);
81extern void ac6_proc_exit(void);
82extern int if6_proc_init(void);
83extern void if6_proc_exit(void);
84#endif
85
86int sysctl_ipv6_bindv6only; 70int sysctl_ipv6_bindv6only;
87 71
88#ifdef INET_REFCNT_DEBUG
89atomic_t inet6_sock_nr;
90EXPORT_SYMBOL(inet6_sock_nr);
91#endif
92
93/* The inetsw table contains everything that inet_create needs to 72/* The inetsw table contains everything that inet_create needs to
94 * build a new socket. 73 * build a new socket.
95 */ 74 */
96static struct list_head inetsw6[SOCK_MAX]; 75static struct list_head inetsw6[SOCK_MAX];
97static DEFINE_SPINLOCK(inetsw6_lock); 76static DEFINE_SPINLOCK(inetsw6_lock);
98 77
99static void inet6_sock_destruct(struct sock *sk)
100{
101 inet_sock_destruct(sk);
102
103#ifdef INET_REFCNT_DEBUG
104 atomic_dec(&inet6_sock_nr);
105#endif
106}
107
108static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) 78static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
109{ 79{
110 const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo); 80 const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo);
@@ -185,7 +155,7 @@ static int inet6_create(struct socket *sock, int protocol)
185 inet->hdrincl = 1; 155 inet->hdrincl = 1;
186 } 156 }
187 157
188 sk->sk_destruct = inet6_sock_destruct; 158 sk->sk_destruct = inet_sock_destruct;
189 sk->sk_family = PF_INET6; 159 sk->sk_family = PF_INET6;
190 sk->sk_protocol = protocol; 160 sk->sk_protocol = protocol;
191 161
@@ -212,12 +182,17 @@ static int inet6_create(struct socket *sock, int protocol)
212 inet->pmtudisc = IP_PMTUDISC_DONT; 182 inet->pmtudisc = IP_PMTUDISC_DONT;
213 else 183 else
214 inet->pmtudisc = IP_PMTUDISC_WANT; 184 inet->pmtudisc = IP_PMTUDISC_WANT;
185 /*
186 * Increment only the relevant sk_prot->socks debug field, this changes
187 * the previous behaviour of incrementing both the equivalent to
188 * answer->prot->socks (inet6_sock_nr) and inet_sock_nr.
189 *
190 * This allows better debug granularity as we'll know exactly how many
191 * UDPv6, TCPv6, etc socks were allocated, not the sum of all IPv6
192 * transport protocol socks. -acme
193 */
194 sk_refcnt_debug_inc(sk);
215 195
216
217#ifdef INET_REFCNT_DEBUG
218 atomic_inc(&inet6_sock_nr);
219 atomic_inc(&inet_sock_nr);
220#endif
221 if (inet->num) { 196 if (inet->num) {
222 /* It assumes that any protocol which allows 197 /* It assumes that any protocol which allows
223 * the user to assign a number at socket 198 * the user to assign a number at socket
@@ -513,11 +488,6 @@ static struct net_proto_family inet6_family_ops = {
513 .owner = THIS_MODULE, 488 .owner = THIS_MODULE,
514}; 489};
515 490
516#ifdef CONFIG_SYSCTL
517extern void ipv6_sysctl_register(void);
518extern void ipv6_sysctl_unregister(void);
519#endif
520
521/* Same as inet6_dgram_ops, sans udp_poll. */ 491/* Same as inet6_dgram_ops, sans udp_poll. */
522static struct proto_ops inet6_sockraw_ops = { 492static struct proto_ops inet6_sockraw_ops = {
523 .family = PF_INET6, 493 .family = PF_INET6,
@@ -684,8 +654,6 @@ static void cleanup_ipv6_mibs(void)
684 snmp6_mib_free((void **)udp_stats_in6); 654 snmp6_mib_free((void **)udp_stats_in6);
685} 655}
686 656
687extern int ipv6_misc_proc_init(void);
688
689static int __init inet6_init(void) 657static int __init inet6_init(void)
690{ 658{
691 struct sk_buff *dummy_skb; 659 struct sk_buff *dummy_skb;
@@ -757,6 +725,9 @@ static int __init inet6_init(void)
757 err = igmp6_init(&inet6_family_ops); 725 err = igmp6_init(&inet6_family_ops);
758 if (err) 726 if (err)
759 goto igmp_fail; 727 goto igmp_fail;
728 err = ipv6_netfilter_init();
729 if (err)
730 goto netfilter_fail;
760 /* Create /proc/foo6 entries. */ 731 /* Create /proc/foo6 entries. */
761#ifdef CONFIG_PROC_FS 732#ifdef CONFIG_PROC_FS
762 err = -ENOMEM; 733 err = -ENOMEM;
@@ -813,6 +784,8 @@ proc_tcp6_fail:
813 raw6_proc_exit(); 784 raw6_proc_exit();
814proc_raw6_fail: 785proc_raw6_fail:
815#endif 786#endif
787 ipv6_netfilter_fini();
788netfilter_fail:
816 igmp6_cleanup(); 789 igmp6_cleanup();
817igmp_fail: 790igmp_fail:
818 ndisc_cleanup(); 791 ndisc_cleanup();
@@ -852,6 +825,7 @@ static void __exit inet6_exit(void)
852 ip6_route_cleanup(); 825 ip6_route_cleanup();
853 ipv6_packet_cleanup(); 826 ipv6_packet_cleanup();
854 igmp6_cleanup(); 827 igmp6_cleanup();
828 ipv6_netfilter_fini();
855 ndisc_cleanup(); 829 ndisc_cleanup();
856 icmpv6_cleanup(); 830 icmpv6_cleanup();
857#ifdef CONFIG_SYSCTL 831#ifdef CONFIG_SYSCTL
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 986fdfdccbcd..0ebfad907a03 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -131,10 +131,10 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len)
131 case NEXTHDR_HOP: 131 case NEXTHDR_HOP:
132 case NEXTHDR_DEST: 132 case NEXTHDR_DEST:
133 if (!zero_out_mutable_opts(exthdr.opth)) { 133 if (!zero_out_mutable_opts(exthdr.opth)) {
134 LIMIT_NETDEBUG(printk( 134 LIMIT_NETDEBUG(
135 KERN_WARNING "overrun %sopts\n", 135 KERN_WARNING "overrun %sopts\n",
136 nexthdr == NEXTHDR_HOP ? 136 nexthdr == NEXTHDR_HOP ?
137 "hop" : "dest")); 137 "hop" : "dest");
138 return -EINVAL; 138 return -EINVAL;
139 } 139 }
140 break; 140 break;
@@ -293,8 +293,7 @@ static int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc
293 skb_push(skb, skb->data - skb->nh.raw); 293 skb_push(skb, skb->data - skb->nh.raw);
294 ahp->icv(ahp, skb, ah->auth_data); 294 ahp->icv(ahp, skb, ah->auth_data);
295 if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { 295 if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {
296 LIMIT_NETDEBUG( 296 LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n");
297 printk(KERN_WARNING "ipsec ah authentication error\n"));
298 x->stats.integrity_failed++; 297 x->stats.integrity_failed++;
299 goto free_out; 298 goto free_out;
300 } 299 }
@@ -332,9 +331,9 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
332 if (!x) 331 if (!x)
333 return; 332 return;
334 333
335 NETDEBUG(printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/" 334 NETDEBUG(KERN_DEBUG "pmtu discovery on SA AH/%08x/"
336 "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", 335 "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
337 ntohl(ah->spi), NIP6(iph->daddr))); 336 ntohl(ah->spi), NIP6(iph->daddr));
338 337
339 xfrm_state_put(x); 338 xfrm_state_put(x);
340} 339}
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 5229365cd8b4..01468fab3d3d 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -29,6 +29,7 @@
29#include <net/addrconf.h> 29#include <net/addrconf.h>
30#include <net/transp_v6.h> 30#include <net/transp_v6.h>
31#include <net/ip6_route.h> 31#include <net/ip6_route.h>
32#include <net/tcp_states.h>
32 33
33#include <linux/errqueue.h> 34#include <linux/errqueue.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
@@ -588,8 +589,8 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
588 break; 589 break;
589 590
590 default: 591 default:
591 LIMIT_NETDEBUG( 592 LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",
592 printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type)); 593 cmsg->cmsg_type);
593 err = -EINVAL; 594 err = -EINVAL;
594 break; 595 break;
595 }; 596 };
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 324db62515a2..e8bff9d3d96c 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -212,8 +212,7 @@ static int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, stru
212 212
213 padlen = nexthdr[0]; 213 padlen = nexthdr[0];
214 if (padlen+2 >= elen) { 214 if (padlen+2 >= elen) {
215 LIMIT_NETDEBUG( 215 LIMIT_NETDEBUG(KERN_WARNING "ipsec esp packet is garbage padlen=%d, elen=%d\n", padlen+2, elen);
216 printk(KERN_WARNING "ipsec esp packet is garbage padlen=%d, elen=%d\n", padlen+2, elen));
217 ret = -EINVAL; 216 ret = -EINVAL;
218 goto out; 217 goto out;
219 } 218 }
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index e0839eafc3a9..5be6da2584ee 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -424,8 +424,8 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
424 IP6CB(skb)->ra = optoff; 424 IP6CB(skb)->ra = optoff;
425 return 1; 425 return 1;
426 } 426 }
427 LIMIT_NETDEBUG( 427 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
428 printk(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", skb->nh.raw[optoff+1])); 428 skb->nh.raw[optoff+1]);
429 kfree_skb(skb); 429 kfree_skb(skb);
430 return 0; 430 return 0;
431} 431}
@@ -437,8 +437,8 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
437 u32 pkt_len; 437 u32 pkt_len;
438 438
439 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { 439 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
440 LIMIT_NETDEBUG( 440 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
441 printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1])); 441 skb->nh.raw[optoff+1]);
442 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 442 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
443 goto drop; 443 goto drop;
444 } 444 }
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index ff3ec9822e36..5176fc655ea9 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -67,7 +67,7 @@
67#include <asm/uaccess.h> 67#include <asm/uaccess.h>
68#include <asm/system.h> 68#include <asm/system.h>
69 69
70DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); 70DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly;
71 71
72/* 72/*
73 * The ICMP socket(s). This is the most convenient way to flow control 73 * The ICMP socket(s). This is the most convenient way to flow control
@@ -332,8 +332,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
332 * for now we don't know that. 332 * for now we don't know that.
333 */ 333 */
334 if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { 334 if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
335 LIMIT_NETDEBUG( 335 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n");
336 printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n"));
337 return; 336 return;
338 } 337 }
339 338
@@ -341,8 +340,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
341 * Never answer to a ICMP packet. 340 * Never answer to a ICMP packet.
342 */ 341 */
343 if (is_ineligible(skb)) { 342 if (is_ineligible(skb)) {
344 LIMIT_NETDEBUG( 343 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: no reply to icmp error\n");
345 printk(KERN_DEBUG "icmpv6_send: no reply to icmp error\n"));
346 return; 344 return;
347 } 345 }
348 346
@@ -393,8 +391,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
393 len = skb->len - msg.offset; 391 len = skb->len - msg.offset;
394 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr)); 392 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr));
395 if (len < 0) { 393 if (len < 0) {
396 LIMIT_NETDEBUG( 394 LIMIT_NETDEBUG(KERN_DEBUG "icmp: len problem\n");
397 printk(KERN_DEBUG "icmp: len problem\n"));
398 goto out_dst_release; 395 goto out_dst_release;
399 } 396 }
400 397
@@ -551,7 +548,8 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
551 548
552 read_lock(&raw_v6_lock); 549 read_lock(&raw_v6_lock);
553 if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) { 550 if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
554 while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr))) { 551 while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr,
552 skb->dev->ifindex))) {
555 rawv6_err(sk, skb, NULL, type, code, inner_offset, info); 553 rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
556 sk = sk_next(sk); 554 sk = sk_next(sk);
557 } 555 }
@@ -583,17 +581,15 @@ static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
583 skb->ip_summed = CHECKSUM_UNNECESSARY; 581 skb->ip_summed = CHECKSUM_UNNECESSARY;
584 if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, 582 if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
585 skb->csum)) { 583 skb->csum)) {
586 LIMIT_NETDEBUG( 584 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 hw checksum failed\n");
587 printk(KERN_DEBUG "ICMPv6 hw checksum failed\n"));
588 skb->ip_summed = CHECKSUM_NONE; 585 skb->ip_summed = CHECKSUM_NONE;
589 } 586 }
590 } 587 }
591 if (skb->ip_summed == CHECKSUM_NONE) { 588 if (skb->ip_summed == CHECKSUM_NONE) {
592 if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, 589 if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
593 skb_checksum(skb, 0, skb->len, 0))) { 590 skb_checksum(skb, 0, skb->len, 0))) {
594 LIMIT_NETDEBUG( 591 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
595 printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n", 592 NIP6(*saddr), NIP6(*daddr));
596 NIP6(*saddr), NIP6(*daddr)));
597 goto discard_it; 593 goto discard_it;
598 } 594 }
599 } 595 }
@@ -669,8 +665,7 @@ static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
669 break; 665 break;
670 666
671 default: 667 default:
672 LIMIT_NETDEBUG( 668 LIMIT_NETDEBUG(KERN_DEBUG "icmpv6: msg of unknown type\n");
673 printk(KERN_DEBUG "icmpv6: msg of unknown type\n"));
674 669
675 /* informational */ 670 /* informational */
676 if (type & ICMPV6_INFOMSG_MASK) 671 if (type & ICMPV6_INFOMSG_MASK)
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
new file mode 100644
index 000000000000..01d5f46d4e40
--- /dev/null
+++ b/net/ipv6/inet6_hashtables.c
@@ -0,0 +1,81 @@
1/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * Generic INET6 transport hashtables
7 *
8 * Authors: Lotsa people, from code originally in tcp
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <linux/config.h>
17
18#include <linux/module.h>
19
20#include <net/inet_connection_sock.h>
21#include <net/inet_hashtables.h>
22#include <net/inet6_hashtables.h>
23
24struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
25 const struct in6_addr *daddr,
26 const unsigned short hnum, const int dif)
27{
28 struct sock *sk;
29 const struct hlist_node *node;
30 struct sock *result = NULL;
31 int score, hiscore = 0;
32
33 read_lock(&hashinfo->lhash_lock);
34 sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) {
35 if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) {
36 const struct ipv6_pinfo *np = inet6_sk(sk);
37
38 score = 1;
39 if (!ipv6_addr_any(&np->rcv_saddr)) {
40 if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
41 continue;
42 score++;
43 }
44 if (sk->sk_bound_dev_if) {
45 if (sk->sk_bound_dev_if != dif)
46 continue;
47 score++;
48 }
49 if (score == 3) {
50 result = sk;
51 break;
52 }
53 if (score > hiscore) {
54 hiscore = score;
55 result = sk;
56 }
57 }
58 }
59 if (result)
60 sock_hold(result);
61 read_unlock(&hashinfo->lhash_lock);
62 return result;
63}
64
65EXPORT_SYMBOL_GPL(inet6_lookup_listener);
66
67struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
68 const struct in6_addr *saddr, const u16 sport,
69 const struct in6_addr *daddr, const u16 dport,
70 const int dif)
71{
72 struct sock *sk;
73
74 local_bh_disable();
75 sk = __inet6_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);
76 local_bh_enable();
77
78 return sk;
79}
80
81EXPORT_SYMBOL_GPL(inet6_lookup);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 1b354aa97934..16af874c9e8f 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -49,7 +49,7 @@
49 49
50struct rt6_statistics rt6_stats; 50struct rt6_statistics rt6_stats;
51 51
52static kmem_cache_t * fib6_node_kmem; 52static kmem_cache_t * fib6_node_kmem __read_mostly;
53 53
54enum fib_walk_state_t 54enum fib_walk_state_t
55{ 55{
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 10fbb50daea4..6e3480426939 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -56,7 +56,7 @@ static inline int ip6_rcv_finish( struct sk_buff *skb)
56 return dst_input(skb); 56 return dst_input(skb);
57} 57}
58 58
59int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) 59int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
60{ 60{
61 struct ipv6hdr *hdr; 61 struct ipv6hdr *hdr;
62 u32 pkt_len; 62 u32 pkt_len;
@@ -166,8 +166,8 @@ resubmit:
166 nexthdr = skb->nh.raw[nhoff]; 166 nexthdr = skb->nh.raw[nhoff];
167 167
168 raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]); 168 raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
169 if (raw_sk) 169 if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
170 ipv6_raw_deliver(skb, nexthdr); 170 raw_sk = NULL;
171 171
172 hash = nexthdr & (MAX_INET_PROTOS - 1); 172 hash = nexthdr & (MAX_INET_PROTOS - 1);
173 if ((ipprot = rcu_dereference(inet6_protos[hash])) != NULL) { 173 if ((ipprot = rcu_dereference(inet6_protos[hash])) != NULL) {
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index ae652ca14bc9..01ef94f7c7f1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -153,51 +153,6 @@ int ip6_output(struct sk_buff *skb)
153 return ip6_output2(skb); 153 return ip6_output2(skb);
154} 154}
155 155
156#ifdef CONFIG_NETFILTER
157int ip6_route_me_harder(struct sk_buff *skb)
158{
159 struct ipv6hdr *iph = skb->nh.ipv6h;
160 struct dst_entry *dst;
161 struct flowi fl = {
162 .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
163 .nl_u =
164 { .ip6_u =
165 { .daddr = iph->daddr,
166 .saddr = iph->saddr, } },
167 .proto = iph->nexthdr,
168 };
169
170 dst = ip6_route_output(skb->sk, &fl);
171
172 if (dst->error) {
173 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
174 LIMIT_NETDEBUG(
175 printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n"));
176 dst_release(dst);
177 return -EINVAL;
178 }
179
180 /* Drop old route. */
181 dst_release(skb->dst);
182
183 skb->dst = dst;
184 return 0;
185}
186#endif
187
188static inline int ip6_maybe_reroute(struct sk_buff *skb)
189{
190#ifdef CONFIG_NETFILTER
191 if (skb->nfcache & NFC_ALTERED){
192 if (ip6_route_me_harder(skb) != 0){
193 kfree_skb(skb);
194 return -EINVAL;
195 }
196 }
197#endif /* CONFIG_NETFILTER */
198 return dst_output(skb);
199}
200
201/* 156/*
202 * xmit an sk_buff (used by TCP) 157 * xmit an sk_buff (used by TCP)
203 */ 158 */
@@ -266,7 +221,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
266 mtu = dst_mtu(dst); 221 mtu = dst_mtu(dst);
267 if ((skb->len <= mtu) || ipfragok) { 222 if ((skb->len <= mtu) || ipfragok) {
268 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 223 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
269 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute); 224 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
225 dst_output);
270 } 226 }
271 227
272 if (net_ratelimit()) 228 if (net_ratelimit())
@@ -321,7 +277,9 @@ static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
321 read_lock(&ip6_ra_lock); 277 read_lock(&ip6_ra_lock);
322 for (ra = ip6_ra_chain; ra; ra = ra->next) { 278 for (ra = ip6_ra_chain; ra; ra = ra->next) {
323 struct sock *sk = ra->sk; 279 struct sock *sk = ra->sk;
324 if (sk && ra->sel == sel) { 280 if (sk && ra->sel == sel &&
281 (!sk->sk_bound_dev_if ||
282 sk->sk_bound_dev_if == skb->dev->ifindex)) {
325 if (last) { 283 if (last) {
326 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 284 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
327 if (skb2) 285 if (skb2)
@@ -667,7 +625,7 @@ slow_path:
667 */ 625 */
668 626
669 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { 627 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
670 NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n")); 628 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
671 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); 629 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS);
672 err = -ENOMEM; 630 err = -ENOMEM;
673 goto fail; 631 goto fail;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 3bc144a79fa5..76466af8331e 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -55,7 +55,7 @@
55 55
56#include <asm/uaccess.h> 56#include <asm/uaccess.h>
57 57
58DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); 58DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics) __read_mostly;
59 59
60static struct packet_type ipv6_packet_type = { 60static struct packet_type ipv6_packet_type = {
61 .type = __constant_htons(ETH_P_IPV6), 61 .type = __constant_htons(ETH_P_IPV6),
@@ -109,13 +109,6 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
109 return 0; 109 return 0;
110} 110}
111 111
112extern int ip6_mc_source(int add, int omode, struct sock *sk,
113 struct group_source_req *pgsr);
114extern int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf);
115extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
116 struct group_filter __user *optval, int __user *optlen);
117
118
119int ipv6_setsockopt(struct sock *sk, int level, int optname, 112int ipv6_setsockopt(struct sock *sk, int level, int optname,
120 char __user *optval, int optlen) 113 char __user *optval, int optlen)
121{ 114{
@@ -163,6 +156,13 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
163 fl6_free_socklist(sk); 156 fl6_free_socklist(sk);
164 ipv6_sock_mc_close(sk); 157 ipv6_sock_mc_close(sk);
165 158
159 /*
160 * Sock is moving from IPv6 to IPv4 (sk_prot), so
161 * remove it from the refcnt debug socks count in the
162 * original family...
163 */
164 sk_refcnt_debug_dec(sk);
165
166 if (sk->sk_protocol == IPPROTO_TCP) { 166 if (sk->sk_protocol == IPPROTO_TCP) {
167 struct tcp_sock *tp = tcp_sk(sk); 167 struct tcp_sock *tp = tcp_sk(sk);
168 168
@@ -192,9 +192,11 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
192 kfree_skb(pktopt); 192 kfree_skb(pktopt);
193 193
194 sk->sk_destruct = inet_sock_destruct; 194 sk->sk_destruct = inet_sock_destruct;
195#ifdef INET_REFCNT_DEBUG 195 /*
196 atomic_dec(&inet6_sock_nr); 196 * ... and add it to the refcnt debug socks count
197#endif 197 * in the new family. -acme
198 */
199 sk_refcnt_debug_inc(sk);
198 module_put(THIS_MODULE); 200 module_put(THIS_MODULE);
199 retv = 0; 201 retv = 0;
200 break; 202 break;
@@ -437,7 +439,6 @@ done:
437 } 439 }
438 case MCAST_MSFILTER: 440 case MCAST_MSFILTER:
439 { 441 {
440 extern int sysctl_optmem_max;
441 extern int sysctl_mld_max_msf; 442 extern int sysctl_mld_max_msf;
442 struct group_filter *gsf; 443 struct group_filter *gsf;
443 444
diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
index 5ade5a5d1990..37a4a99c9fe9 100644
--- a/net/ipv6/ipv6_syms.c
+++ b/net/ipv6/ipv6_syms.c
@@ -15,9 +15,6 @@ EXPORT_SYMBOL(ndisc_mc_map);
15EXPORT_SYMBOL(register_inet6addr_notifier); 15EXPORT_SYMBOL(register_inet6addr_notifier);
16EXPORT_SYMBOL(unregister_inet6addr_notifier); 16EXPORT_SYMBOL(unregister_inet6addr_notifier);
17EXPORT_SYMBOL(ip6_route_output); 17EXPORT_SYMBOL(ip6_route_output);
18#ifdef CONFIG_NETFILTER
19EXPORT_SYMBOL(ip6_route_me_harder);
20#endif
21EXPORT_SYMBOL(addrconf_lock); 18EXPORT_SYMBOL(addrconf_lock);
22EXPORT_SYMBOL(ipv6_setsockopt); 19EXPORT_SYMBOL(ipv6_setsockopt);
23EXPORT_SYMBOL(ipv6_getsockopt); 20EXPORT_SYMBOL(ipv6_getsockopt);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 7ae72d4c9bd2..a7eae30f4554 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -812,7 +812,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
812 if (ipv6_chk_acast_addr(dev, &msg->target) || 812 if (ipv6_chk_acast_addr(dev, &msg->target) ||
813 (idev->cnf.forwarding && 813 (idev->cnf.forwarding &&
814 pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) { 814 pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) {
815 if (skb->stamp.tv_sec != LOCALLY_ENQUEUED && 815 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
816 skb->pkt_type != PACKET_HOST && 816 skb->pkt_type != PACKET_HOST &&
817 inc != 0 && 817 inc != 0 &&
818 idev->nd_parms->proxy_delay != 0) { 818 idev->nd_parms->proxy_delay != 0) {
@@ -1487,6 +1487,8 @@ int ndisc_rcv(struct sk_buff *skb)
1487 return 0; 1487 return 0;
1488 } 1488 }
1489 1489
1490 memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1491
1490 switch (msg->icmph.icmp6_type) { 1492 switch (msg->icmph.icmp6_type) {
1491 case NDISC_NEIGHBOUR_SOLICITATION: 1493 case NDISC_NEIGHBOUR_SOLICITATION:
1492 ndisc_recv_ns(skb); 1494 ndisc_recv_ns(skb);
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
new file mode 100644
index 000000000000..f8626ebf90fd
--- /dev/null
+++ b/net/ipv6/netfilter.c
@@ -0,0 +1,104 @@
1#include <linux/config.h>
2#include <linux/init.h>
3
4#ifdef CONFIG_NETFILTER
5
6#include <linux/kernel.h>
7#include <linux/ipv6.h>
8#include <linux/netfilter.h>
9#include <linux/netfilter_ipv6.h>
10#include <net/dst.h>
11#include <net/ipv6.h>
12#include <net/ip6_route.h>
13
14int ip6_route_me_harder(struct sk_buff *skb)
15{
16 struct ipv6hdr *iph = skb->nh.ipv6h;
17 struct dst_entry *dst;
18 struct flowi fl = {
19 .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
20 .nl_u =
21 { .ip6_u =
22 { .daddr = iph->daddr,
23 .saddr = iph->saddr, } },
24 .proto = iph->nexthdr,
25 };
26
27 dst = ip6_route_output(skb->sk, &fl);
28
29 if (dst->error) {
30 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
31 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
32 dst_release(dst);
33 return -EINVAL;
34 }
35
36 /* Drop old route. */
37 dst_release(skb->dst);
38
39 skb->dst = dst;
40 return 0;
41}
42EXPORT_SYMBOL(ip6_route_me_harder);
43
44/*
45 * Extra routing may needed on local out, as the QUEUE target never
46 * returns control to the table.
47 */
48
49struct ip6_rt_info {
50 struct in6_addr daddr;
51 struct in6_addr saddr;
52};
53
54static void save(const struct sk_buff *skb, struct nf_info *info)
55{
56 struct ip6_rt_info *rt_info = nf_info_reroute(info);
57
58 if (info->hook == NF_IP6_LOCAL_OUT) {
59 struct ipv6hdr *iph = skb->nh.ipv6h;
60
61 rt_info->daddr = iph->daddr;
62 rt_info->saddr = iph->saddr;
63 }
64}
65
66static int reroute(struct sk_buff **pskb, const struct nf_info *info)
67{
68 struct ip6_rt_info *rt_info = nf_info_reroute(info);
69
70 if (info->hook == NF_IP6_LOCAL_OUT) {
71 struct ipv6hdr *iph = (*pskb)->nh.ipv6h;
72 if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
73 !ipv6_addr_equal(&iph->saddr, &rt_info->saddr))
74 return ip6_route_me_harder(*pskb);
75 }
76 return 0;
77}
78
79static struct nf_queue_rerouter ip6_reroute = {
80 .rer_size = sizeof(struct ip6_rt_info),
81 .save = &save,
82 .reroute = &reroute,
83};
84
85int __init ipv6_netfilter_init(void)
86{
87 return nf_register_queue_rerouter(PF_INET6, &ip6_reroute);
88}
89
90void ipv6_netfilter_fini(void)
91{
92 nf_unregister_queue_rerouter(PF_INET6);
93}
94
95#else /* CONFIG_NETFILTER */
96int __init ipv6_netfilter_init(void)
97{
98 return 0;
99}
100
101void ipv6_netfilter_fini(void)
102{
103}
104#endif /* CONFIG_NETFILTER */
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 77ec704c9ee3..216fbe1ac65c 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -10,13 +10,16 @@ menu "IPv6: Netfilter Configuration (EXPERIMENTAL)"
10# dep_tristate ' FTP protocol support' CONFIG_IP6_NF_FTP $CONFIG_IP6_NF_CONNTRACK 10# dep_tristate ' FTP protocol support' CONFIG_IP6_NF_FTP $CONFIG_IP6_NF_CONNTRACK
11#fi 11#fi
12config IP6_NF_QUEUE 12config IP6_NF_QUEUE
13 tristate "Userspace queueing via NETLINK" 13 tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)"
14 ---help--- 14 ---help---
15 15
16 This option adds a queue handler to the kernel for IPv6 16 This option adds a queue handler to the kernel for IPv6
17 packets which lets us to receive the filtered packets 17 packets which enables users to receive the filtered packets
18 with QUEUE target using libiptc as we can do with 18 with QUEUE target using libipq.
19 the IPv4 now. 19
20 THis option enables the old IPv6-only "ip6_queue" implementation
21 which has been obsoleted by the new "nfnetlink_queue" code (see
22 CONFIG_NETFILTER_NETLINK_QUEUE).
20 23
21 (C) Fernando Anton 2001 24 (C) Fernando Anton 2001
22 IPv64 Project - Work based in IPv64 draft by Arturo Azcorra. 25 IPv64 Project - Work based in IPv64 draft by Arturo Azcorra.
@@ -196,6 +199,16 @@ config IP6_NF_TARGET_LOG
196 199
197 To compile it as a module, choose M here. If unsure, say N. 200 To compile it as a module, choose M here. If unsure, say N.
198 201
202config IP6_NF_TARGET_REJECT
203 tristate "REJECT target support"
204 depends on IP6_NF_FILTER
205 help
206 The REJECT target allows a filtering rule to specify that an ICMPv6
207 error should be issued in response to an incoming packet, rather
208 than silently being dropped.
209
210 To compile it as a module, choose M here. If unsure, say N.
211
199# if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then 212# if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then
200# dep_tristate ' REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER 213# dep_tristate ' REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER
201# if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then 214# if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -226,6 +239,22 @@ config IP6_NF_TARGET_MARK
226 239
227 To compile it as a module, choose M here. If unsure, say N. 240 To compile it as a module, choose M here. If unsure, say N.
228 241
242config IP6_NF_TARGET_HL
243 tristate 'HL (hoplimit) target support'
244 depends on IP6_NF_MANGLE
245 help
246 This option adds a `HL' target, which enables the user to decrement
247 the hoplimit value of the IPv6 header or set it to a given (lower)
248 value.
249
250 While it is safe to decrement the hoplimit value, this option also
251 enables functionality to increment and set the hoplimit value of the
252 IPv6 header to arbitrary values. This is EXTREMELY DANGEROUS since
253 you can easily create immortal packets that loop forever on the
254 network.
255
256 To compile it as a module, choose M here. If unsure, say N.
257
229#dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES 258#dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
230config IP6_NF_RAW 259config IP6_NF_RAW
231 tristate 'raw table support (required for TRACE)' 260 tristate 'raw table support (required for TRACE)'
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 2e51714953b6..bd9a16a5cbba 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -20,7 +20,10 @@ obj-$(CONFIG_IP6_NF_MATCH_PHYSDEV) += ip6t_physdev.o
20obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o 20obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
21obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o 21obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
22obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o 22obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
23obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
23obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o 24obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
24obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o 25obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
25obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o 26obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
26obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o 27obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
28obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
29obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += ip6t_NFQUEUE.o
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index a16df5b27c84..aa11cf366efa 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -47,16 +47,10 @@
47#define NET_IPQ_QMAX 2088 47#define NET_IPQ_QMAX 2088
48#define NET_IPQ_QMAX_NAME "ip6_queue_maxlen" 48#define NET_IPQ_QMAX_NAME "ip6_queue_maxlen"
49 49
50struct ipq_rt_info {
51 struct in6_addr daddr;
52 struct in6_addr saddr;
53};
54
55struct ipq_queue_entry { 50struct ipq_queue_entry {
56 struct list_head list; 51 struct list_head list;
57 struct nf_info *info; 52 struct nf_info *info;
58 struct sk_buff *skb; 53 struct sk_buff *skb;
59 struct ipq_rt_info rt_info;
60}; 54};
61 55
62typedef int (*ipq_cmpfn)(struct ipq_queue_entry *, unsigned long); 56typedef int (*ipq_cmpfn)(struct ipq_queue_entry *, unsigned long);
@@ -244,8 +238,8 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
244 238
245 pmsg->packet_id = (unsigned long )entry; 239 pmsg->packet_id = (unsigned long )entry;
246 pmsg->data_len = data_len; 240 pmsg->data_len = data_len;
247 pmsg->timestamp_sec = entry->skb->stamp.tv_sec; 241 pmsg->timestamp_sec = skb_tv_base.tv_sec + entry->skb->tstamp.off_sec;
248 pmsg->timestamp_usec = entry->skb->stamp.tv_usec; 242 pmsg->timestamp_usec = skb_tv_base.tv_usec + entry->skb->tstamp.off_usec;
249 pmsg->mark = entry->skb->nfmark; 243 pmsg->mark = entry->skb->nfmark;
250 pmsg->hook = entry->info->hook; 244 pmsg->hook = entry->info->hook;
251 pmsg->hw_protocol = entry->skb->protocol; 245 pmsg->hw_protocol = entry->skb->protocol;
@@ -284,7 +278,8 @@ nlmsg_failure:
284} 278}
285 279
286static int 280static int
287ipq_enqueue_packet(struct sk_buff *skb, struct nf_info *info, void *data) 281ipq_enqueue_packet(struct sk_buff *skb, struct nf_info *info,
282 unsigned int queuenum, void *data)
288{ 283{
289 int status = -EINVAL; 284 int status = -EINVAL;
290 struct sk_buff *nskb; 285 struct sk_buff *nskb;
@@ -302,13 +297,6 @@ ipq_enqueue_packet(struct sk_buff *skb, struct nf_info *info, void *data)
302 entry->info = info; 297 entry->info = info;
303 entry->skb = skb; 298 entry->skb = skb;
304 299
305 if (entry->info->hook == NF_IP_LOCAL_OUT) {
306 struct ipv6hdr *iph = skb->nh.ipv6h;
307
308 entry->rt_info.daddr = iph->daddr;
309 entry->rt_info.saddr = iph->saddr;
310 }
311
312 nskb = ipq_build_packet_message(entry, &status); 300 nskb = ipq_build_packet_message(entry, &status);
313 if (nskb == NULL) 301 if (nskb == NULL)
314 goto err_out_free; 302 goto err_out_free;
@@ -384,23 +372,11 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
384 } 372 }
385 skb_put(e->skb, diff); 373 skb_put(e->skb, diff);
386 } 374 }
387 if (!skb_ip_make_writable(&e->skb, v->data_len)) 375 if (!skb_make_writable(&e->skb, v->data_len))
388 return -ENOMEM; 376 return -ENOMEM;
389 memcpy(e->skb->data, v->payload, v->data_len); 377 memcpy(e->skb->data, v->payload, v->data_len);
390 e->skb->ip_summed = CHECKSUM_NONE; 378 e->skb->ip_summed = CHECKSUM_NONE;
391 e->skb->nfcache |= NFC_ALTERED; 379
392
393 /*
394 * Extra routing may needed on local out, as the QUEUE target never
395 * returns control to the table.
396 * Not a nice way to cmp, but works
397 */
398 if (e->info->hook == NF_IP_LOCAL_OUT) {
399 struct ipv6hdr *iph = e->skb->nh.ipv6h;
400 if (!ipv6_addr_equal(&iph->daddr, &e->rt_info.daddr) ||
401 !ipv6_addr_equal(&iph->saddr, &e->rt_info.saddr))
402 return ip6_route_me_harder(e->skb);
403 }
404 return 0; 380 return 0;
405} 381}
406 382
@@ -676,6 +652,11 @@ ipq_get_info(char *buffer, char **start, off_t offset, int length)
676 return len; 652 return len;
677} 653}
678 654
655static struct nf_queue_handler nfqh = {
656 .name = "ip6_queue",
657 .outfn = &ipq_enqueue_packet,
658};
659
679static int 660static int
680init_or_cleanup(int init) 661init_or_cleanup(int init)
681{ 662{
@@ -686,7 +667,8 @@ init_or_cleanup(int init)
686 goto cleanup; 667 goto cleanup;
687 668
688 netlink_register_notifier(&ipq_nl_notifier); 669 netlink_register_notifier(&ipq_nl_notifier);
689 ipqnl = netlink_kernel_create(NETLINK_IP6_FW, ipq_rcv_sk); 670 ipqnl = netlink_kernel_create(NETLINK_IP6_FW, 0, ipq_rcv_sk,
671 THIS_MODULE);
690 if (ipqnl == NULL) { 672 if (ipqnl == NULL) {
691 printk(KERN_ERR "ip6_queue: failed to create netlink socket\n"); 673 printk(KERN_ERR "ip6_queue: failed to create netlink socket\n");
692 goto cleanup_netlink_notifier; 674 goto cleanup_netlink_notifier;
@@ -703,7 +685,7 @@ init_or_cleanup(int init)
703 register_netdevice_notifier(&ipq_dev_notifier); 685 register_netdevice_notifier(&ipq_dev_notifier);
704 ipq_sysctl_header = register_sysctl_table(ipq_root_table, 0); 686 ipq_sysctl_header = register_sysctl_table(ipq_root_table, 0);
705 687
706 status = nf_register_queue_handler(PF_INET6, ipq_enqueue_packet, NULL); 688 status = nf_register_queue_handler(PF_INET6, &nfqh);
707 if (status < 0) { 689 if (status < 0) {
708 printk(KERN_ERR "ip6_queue: failed to register queue handler\n"); 690 printk(KERN_ERR "ip6_queue: failed to register queue handler\n");
709 goto cleanup_sysctl; 691 goto cleanup_sysctl;
@@ -711,7 +693,7 @@ init_or_cleanup(int init)
711 return status; 693 return status;
712 694
713cleanup: 695cleanup:
714 nf_unregister_queue_handler(PF_INET6); 696 nf_unregister_queue_handlers(&nfqh);
715 synchronize_net(); 697 synchronize_net();
716 ipq_flush(NF_DROP); 698 ipq_flush(NF_DROP);
717 699
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 73034511c8db..1cb8adb2787f 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -401,7 +401,6 @@ ip6t_do_table(struct sk_buff **pskb,
401 do { 401 do {
402 IP_NF_ASSERT(e); 402 IP_NF_ASSERT(e);
403 IP_NF_ASSERT(back); 403 IP_NF_ASSERT(back);
404 (*pskb)->nfcache |= e->nfcache;
405 if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, 404 if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6,
406 &protoff, &offset)) { 405 &protoff, &offset)) {
407 struct ip6t_entry_target *t; 406 struct ip6t_entry_target *t;
@@ -434,8 +433,8 @@ ip6t_do_table(struct sk_buff **pskb,
434 back->comefrom); 433 back->comefrom);
435 continue; 434 continue;
436 } 435 }
437 if (table_base + v 436 if (table_base + v != (void *)e + e->next_offset
438 != (void *)e + e->next_offset) { 437 && !(e->ipv6.flags & IP6T_F_GOTO)) {
439 /* Save old back ptr in next entry */ 438 /* Save old back ptr in next entry */
440 struct ip6t_entry *next 439 struct ip6t_entry *next
441 = (void *)e + e->next_offset; 440 = (void *)e + e->next_offset;
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
new file mode 100644
index 000000000000..8f5549b72720
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -0,0 +1,118 @@
1/*
2 * Hop Limit modification target for ip6tables
3 * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4 * Based on HW's TTL module
5 *
6 * This software is distributed under the terms of GNU GPL
7 */
8
9#include <linux/module.h>
10#include <linux/skbuff.h>
11#include <linux/ip.h>
12
13#include <linux/netfilter_ipv6/ip6_tables.h>
14#include <linux/netfilter_ipv6/ip6t_HL.h>
15
16MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
17MODULE_DESCRIPTION("IP tables Hop Limit modification module");
18MODULE_LICENSE("GPL");
19
20static unsigned int ip6t_hl_target(struct sk_buff **pskb,
21 const struct net_device *in,
22 const struct net_device *out,
23 unsigned int hooknum,
24 const void *targinfo, void *userinfo)
25{
26 struct ipv6hdr *ip6h;
27 const struct ip6t_HL_info *info = targinfo;
28 u_int16_t diffs[2];
29 int new_hl;
30
31 if (!skb_make_writable(pskb, (*pskb)->len))
32 return NF_DROP;
33
34 ip6h = (*pskb)->nh.ipv6h;
35
36 switch (info->mode) {
37 case IP6T_HL_SET:
38 new_hl = info->hop_limit;
39 break;
40 case IP6T_HL_INC:
41 new_hl = ip6h->hop_limit + info->hop_limit;
42 if (new_hl > 255)
43 new_hl = 255;
44 break;
45 case IP6T_HL_DEC:
46 new_hl = ip6h->hop_limit - info->hop_limit;
47 if (new_hl < 0)
48 new_hl = 0;
49 break;
50 default:
51 new_hl = ip6h->hop_limit;
52 break;
53 }
54
55 if (new_hl != ip6h->hop_limit) {
56 diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
57 ip6h->hop_limit = new_hl;
58 diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
59 }
60
61 return IP6T_CONTINUE;
62}
63
64static int ip6t_hl_checkentry(const char *tablename,
65 const struct ip6t_entry *e,
66 void *targinfo,
67 unsigned int targinfosize,
68 unsigned int hook_mask)
69{
70 struct ip6t_HL_info *info = targinfo;
71
72 if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
73 printk(KERN_WARNING "ip6t_HL: targinfosize %u != %Zu\n",
74 targinfosize,
75 IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
76 return 0;
77 }
78
79 if (strcmp(tablename, "mangle")) {
80 printk(KERN_WARNING "ip6t_HL: can only be called from "
81 "\"mangle\" table, not \"%s\"\n", tablename);
82 return 0;
83 }
84
85 if (info->mode > IP6T_HL_MAXMODE) {
86 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
87 info->mode);
88 return 0;
89 }
90
91 if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
92 printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't "
93 "make sense with value 0\n");
94 return 0;
95 }
96
97 return 1;
98}
99
100static struct ip6t_target ip6t_HL = {
101 .name = "HL",
102 .target = ip6t_hl_target,
103 .checkentry = ip6t_hl_checkentry,
104 .me = THIS_MODULE
105};
106
107static int __init init(void)
108{
109 return ip6t_register_target(&ip6t_HL);
110}
111
112static void __exit fini(void)
113{
114 ip6t_unregister_target(&ip6t_HL);
115}
116
117module_init(init);
118module_exit(fini);
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index a692e26a4fa3..0cd1d1bd9033 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -26,10 +26,6 @@ MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
26MODULE_DESCRIPTION("IP6 tables LOG target module"); 26MODULE_DESCRIPTION("IP6 tables LOG target module");
27MODULE_LICENSE("GPL"); 27MODULE_LICENSE("GPL");
28 28
29static unsigned int nflog = 1;
30module_param(nflog, int, 0400);
31MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
32
33struct in_device; 29struct in_device;
34#include <net/route.h> 30#include <net/route.h>
35#include <linux/netfilter_ipv6/ip6t_LOG.h> 31#include <linux/netfilter_ipv6/ip6t_LOG.h>
@@ -44,7 +40,7 @@ struct in_device;
44static DEFINE_SPINLOCK(log_lock); 40static DEFINE_SPINLOCK(log_lock);
45 41
46/* One level of recursion won't kill us */ 42/* One level of recursion won't kill us */
47static void dump_packet(const struct ip6t_log_info *info, 43static void dump_packet(const struct nf_loginfo *info,
48 const struct sk_buff *skb, unsigned int ip6hoff, 44 const struct sk_buff *skb, unsigned int ip6hoff,
49 int recurse) 45 int recurse)
50{ 46{
@@ -53,6 +49,12 @@ static void dump_packet(const struct ip6t_log_info *info,
53 struct ipv6hdr _ip6h, *ih; 49 struct ipv6hdr _ip6h, *ih;
54 unsigned int ptr; 50 unsigned int ptr;
55 unsigned int hdrlen = 0; 51 unsigned int hdrlen = 0;
52 unsigned int logflags;
53
54 if (info->type == NF_LOG_TYPE_LOG)
55 logflags = info->u.log.logflags;
56 else
57 logflags = NF_LOG_MASK;
56 58
57 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h); 59 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
58 if (ih == NULL) { 60 if (ih == NULL) {
@@ -84,7 +86,7 @@ static void dump_packet(const struct ip6t_log_info *info,
84 } 86 }
85 87
86 /* Max length: 48 "OPT (...) " */ 88 /* Max length: 48 "OPT (...) " */
87 if (info->logflags & IP6T_LOG_IPOPT) 89 if (logflags & IP6T_LOG_IPOPT)
88 printk("OPT ( "); 90 printk("OPT ( ");
89 91
90 switch (currenthdr) { 92 switch (currenthdr) {
@@ -119,7 +121,7 @@ static void dump_packet(const struct ip6t_log_info *info,
119 case IPPROTO_ROUTING: 121 case IPPROTO_ROUTING:
120 case IPPROTO_HOPOPTS: 122 case IPPROTO_HOPOPTS:
121 if (fragment) { 123 if (fragment) {
122 if (info->logflags & IP6T_LOG_IPOPT) 124 if (logflags & IP6T_LOG_IPOPT)
123 printk(")"); 125 printk(")");
124 return; 126 return;
125 } 127 }
@@ -127,7 +129,7 @@ static void dump_packet(const struct ip6t_log_info *info,
127 break; 129 break;
128 /* Max Length */ 130 /* Max Length */
129 case IPPROTO_AH: 131 case IPPROTO_AH:
130 if (info->logflags & IP6T_LOG_IPOPT) { 132 if (logflags & IP6T_LOG_IPOPT) {
131 struct ip_auth_hdr _ahdr, *ah; 133 struct ip_auth_hdr _ahdr, *ah;
132 134
133 /* Max length: 3 "AH " */ 135 /* Max length: 3 "AH " */
@@ -158,7 +160,7 @@ static void dump_packet(const struct ip6t_log_info *info,
158 hdrlen = (hp->hdrlen+2)<<2; 160 hdrlen = (hp->hdrlen+2)<<2;
159 break; 161 break;
160 case IPPROTO_ESP: 162 case IPPROTO_ESP:
161 if (info->logflags & IP6T_LOG_IPOPT) { 163 if (logflags & IP6T_LOG_IPOPT) {
162 struct ip_esp_hdr _esph, *eh; 164 struct ip_esp_hdr _esph, *eh;
163 165
164 /* Max length: 4 "ESP " */ 166 /* Max length: 4 "ESP " */
@@ -190,7 +192,7 @@ static void dump_packet(const struct ip6t_log_info *info,
190 printk("Unknown Ext Hdr %u", currenthdr); 192 printk("Unknown Ext Hdr %u", currenthdr);
191 return; 193 return;
192 } 194 }
193 if (info->logflags & IP6T_LOG_IPOPT) 195 if (logflags & IP6T_LOG_IPOPT)
194 printk(") "); 196 printk(") ");
195 197
196 currenthdr = hp->nexthdr; 198 currenthdr = hp->nexthdr;
@@ -218,7 +220,7 @@ static void dump_packet(const struct ip6t_log_info *info,
218 printk("SPT=%u DPT=%u ", 220 printk("SPT=%u DPT=%u ",
219 ntohs(th->source), ntohs(th->dest)); 221 ntohs(th->source), ntohs(th->dest));
220 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ 222 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
221 if (info->logflags & IP6T_LOG_TCPSEQ) 223 if (logflags & IP6T_LOG_TCPSEQ)
222 printk("SEQ=%u ACK=%u ", 224 printk("SEQ=%u ACK=%u ",
223 ntohl(th->seq), ntohl(th->ack_seq)); 225 ntohl(th->seq), ntohl(th->ack_seq));
224 /* Max length: 13 "WINDOW=65535 " */ 226 /* Max length: 13 "WINDOW=65535 " */
@@ -245,7 +247,7 @@ static void dump_packet(const struct ip6t_log_info *info,
245 /* Max length: 11 "URGP=65535 " */ 247 /* Max length: 11 "URGP=65535 " */
246 printk("URGP=%u ", ntohs(th->urg_ptr)); 248 printk("URGP=%u ", ntohs(th->urg_ptr));
247 249
248 if ((info->logflags & IP6T_LOG_TCPOPT) 250 if ((logflags & IP6T_LOG_TCPOPT)
249 && th->doff * 4 > sizeof(struct tcphdr)) { 251 && th->doff * 4 > sizeof(struct tcphdr)) {
250 u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 252 u_int8_t _opt[60 - sizeof(struct tcphdr)], *op;
251 unsigned int i; 253 unsigned int i;
@@ -349,7 +351,7 @@ static void dump_packet(const struct ip6t_log_info *info,
349 } 351 }
350 352
351 /* Max length: 15 "UID=4294967295 " */ 353 /* Max length: 15 "UID=4294967295 " */
352 if ((info->logflags & IP6T_LOG_UID) && recurse && skb->sk) { 354 if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) {
353 read_lock_bh(&skb->sk->sk_callback_lock); 355 read_lock_bh(&skb->sk->sk_callback_lock);
354 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 356 if (skb->sk->sk_socket && skb->sk->sk_socket->file)
355 printk("UID=%u ", skb->sk->sk_socket->file->f_uid); 357 printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
@@ -357,19 +359,31 @@ static void dump_packet(const struct ip6t_log_info *info,
357 } 359 }
358} 360}
359 361
362static struct nf_loginfo default_loginfo = {
363 .type = NF_LOG_TYPE_LOG,
364 .u = {
365 .log = {
366 .level = 0,
367 .logflags = NF_LOG_MASK,
368 },
369 },
370};
371
360static void 372static void
361ip6t_log_packet(unsigned int hooknum, 373ip6t_log_packet(unsigned int pf,
374 unsigned int hooknum,
362 const struct sk_buff *skb, 375 const struct sk_buff *skb,
363 const struct net_device *in, 376 const struct net_device *in,
364 const struct net_device *out, 377 const struct net_device *out,
365 const struct ip6t_log_info *loginfo, 378 const struct nf_loginfo *loginfo,
366 const char *level_string,
367 const char *prefix) 379 const char *prefix)
368{ 380{
381 if (!loginfo)
382 loginfo = &default_loginfo;
383
369 spin_lock_bh(&log_lock); 384 spin_lock_bh(&log_lock);
370 printk(level_string); 385 printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
371 printk("%sIN=%s OUT=%s ", 386 prefix,
372 prefix == NULL ? loginfo->prefix : prefix,
373 in ? in->name : "", 387 in ? in->name : "",
374 out ? out->name : ""); 388 out ? out->name : "");
375 if (in && !out) { 389 if (in && !out) {
@@ -416,29 +430,17 @@ ip6t_log_target(struct sk_buff **pskb,
416 void *userinfo) 430 void *userinfo)
417{ 431{
418 const struct ip6t_log_info *loginfo = targinfo; 432 const struct ip6t_log_info *loginfo = targinfo;
419 char level_string[4] = "< >"; 433 struct nf_loginfo li;
434
435 li.type = NF_LOG_TYPE_LOG;
436 li.u.log.level = loginfo->level;
437 li.u.log.logflags = loginfo->logflags;
420 438
421 level_string[1] = '0' + (loginfo->level % 8); 439 nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, loginfo->prefix);
422 ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
423 440
424 return IP6T_CONTINUE; 441 return IP6T_CONTINUE;
425} 442}
426 443
427static void
428ip6t_logfn(unsigned int hooknum,
429 const struct sk_buff *skb,
430 const struct net_device *in,
431 const struct net_device *out,
432 const char *prefix)
433{
434 struct ip6t_log_info loginfo = {
435 .level = 0,
436 .logflags = IP6T_LOG_MASK,
437 .prefix = ""
438 };
439
440 ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
441}
442 444
443static int ip6t_log_checkentry(const char *tablename, 445static int ip6t_log_checkentry(const char *tablename,
444 const struct ip6t_entry *e, 446 const struct ip6t_entry *e,
@@ -475,20 +477,29 @@ static struct ip6t_target ip6t_log_reg = {
475 .me = THIS_MODULE, 477 .me = THIS_MODULE,
476}; 478};
477 479
480static struct nf_logger ip6t_logger = {
481 .name = "ip6t_LOG",
482 .logfn = &ip6t_log_packet,
483 .me = THIS_MODULE,
484};
485
478static int __init init(void) 486static int __init init(void)
479{ 487{
480 if (ip6t_register_target(&ip6t_log_reg)) 488 if (ip6t_register_target(&ip6t_log_reg))
481 return -EINVAL; 489 return -EINVAL;
482 if (nflog) 490 if (nf_log_register(PF_INET6, &ip6t_logger) < 0) {
483 nf_log_register(PF_INET6, &ip6t_logfn); 491 printk(KERN_WARNING "ip6t_LOG: not logging via system console "
492 "since somebody else already registered for PF_INET6\n");
493 /* we cannot make module load fail here, since otherwise
494 * ip6tables userspace would abort */
495 }
484 496
485 return 0; 497 return 0;
486} 498}
487 499
488static void __exit fini(void) 500static void __exit fini(void)
489{ 501{
490 if (nflog) 502 nf_log_unregister_logger(&ip6t_logger);
491 nf_log_unregister(PF_INET6, &ip6t_logfn);
492 ip6t_unregister_target(&ip6t_log_reg); 503 ip6t_unregister_target(&ip6t_log_reg);
493} 504}
494 505
diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c
index d09ceb05013a..81924fcc5857 100644
--- a/net/ipv6/netfilter/ip6t_MARK.c
+++ b/net/ipv6/netfilter/ip6t_MARK.c
@@ -28,10 +28,9 @@ target(struct sk_buff **pskb,
28{ 28{
29 const struct ip6t_mark_target_info *markinfo = targinfo; 29 const struct ip6t_mark_target_info *markinfo = targinfo;
30 30
31 if((*pskb)->nfmark != markinfo->mark) { 31 if((*pskb)->nfmark != markinfo->mark)
32 (*pskb)->nfmark = markinfo->mark; 32 (*pskb)->nfmark = markinfo->mark;
33 (*pskb)->nfcache |= NFC_ALTERED; 33
34 }
35 return IP6T_CONTINUE; 34 return IP6T_CONTINUE;
36} 35}
37 36
diff --git a/net/ipv6/netfilter/ip6t_NFQUEUE.c b/net/ipv6/netfilter/ip6t_NFQUEUE.c
new file mode 100644
index 000000000000..c6e3730e7409
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_NFQUEUE.c
@@ -0,0 +1,70 @@
1/* ip6tables module for using new netfilter netlink queue
2 *
3 * (C) 2005 by Harald Welte <laforge@netfilter.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 */
10
11#include <linux/module.h>
12#include <linux/skbuff.h>
13
14#include <linux/netfilter.h>
15#include <linux/netfilter_ipv6/ip6_tables.h>
16#include <linux/netfilter_ipv4/ipt_NFQUEUE.h>
17
18MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
19MODULE_DESCRIPTION("ip6tables NFQUEUE target");
20MODULE_LICENSE("GPL");
21
22static unsigned int
23target(struct sk_buff **pskb,
24 const struct net_device *in,
25 const struct net_device *out,
26 unsigned int hooknum,
27 const void *targinfo,
28 void *userinfo)
29{
30 const struct ipt_NFQ_info *tinfo = targinfo;
31
32 return NF_QUEUE_NR(tinfo->queuenum);
33}
34
35static int
36checkentry(const char *tablename,
37 const struct ip6t_entry *e,
38 void *targinfo,
39 unsigned int targinfosize,
40 unsigned int hook_mask)
41{
42 if (targinfosize != IP6T_ALIGN(sizeof(struct ipt_NFQ_info))) {
43 printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n",
44 targinfosize,
45 IP6T_ALIGN(sizeof(struct ipt_NFQ_info)));
46 return 0;
47 }
48
49 return 1;
50}
51
52static struct ip6t_target ipt_NFQ_reg = {
53 .name = "NFQUEUE",
54 .target = target,
55 .checkentry = checkentry,
56 .me = THIS_MODULE,
57};
58
59static int __init init(void)
60{
61 return ip6t_register_target(&ipt_NFQ_reg);
62}
63
64static void __exit fini(void)
65{
66 ip6t_unregister_target(&ipt_NFQ_reg);
67}
68
69module_init(init);
70module_exit(fini);
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
new file mode 100644
index 000000000000..14316c3ebde4
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -0,0 +1,284 @@
1/*
2 * IP6 tables REJECT target module
3 * Linux INET6 implementation
4 *
5 * Copyright (C)2003 USAGI/WIDE Project
6 *
7 * Authors:
8 * Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
9 *
10 * Based on net/ipv4/netfilter/ipt_REJECT.c
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/skbuff.h>
21#include <linux/icmpv6.h>
22#include <linux/netdevice.h>
23#include <net/ipv6.h>
24#include <net/tcp.h>
25#include <net/icmp.h>
26#include <net/ip6_checksum.h>
27#include <net/ip6_fib.h>
28#include <net/ip6_route.h>
29#include <net/flow.h>
30#include <linux/netfilter_ipv6/ip6_tables.h>
31#include <linux/netfilter_ipv6/ip6t_REJECT.h>
32
33MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
34MODULE_DESCRIPTION("IP6 tables REJECT target module");
35MODULE_LICENSE("GPL");
36
37#if 0
38#define DEBUGP printk
39#else
40#define DEBUGP(format, args...)
41#endif
42
43/* Send RST reply */
44static void send_reset(struct sk_buff *oldskb)
45{
46 struct sk_buff *nskb;
47 struct tcphdr otcph, *tcph;
48 unsigned int otcplen, hh_len;
49 int tcphoff, needs_ack;
50 struct ipv6hdr *oip6h = oldskb->nh.ipv6h, *ip6h;
51 struct dst_entry *dst = NULL;
52 u8 proto;
53 struct flowi fl;
54
55 if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
56 (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
57 DEBUGP("ip6t_REJECT: addr is not unicast.\n");
58 return;
59 }
60
61 proto = oip6h->nexthdr;
62 tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto);
63
64 if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
65 DEBUGP("ip6t_REJECT: Can't get TCP header.\n");
66 return;
67 }
68
69 otcplen = oldskb->len - tcphoff;
70
71 /* IP header checks: fragment, too short. */
72 if ((proto != IPPROTO_TCP) || (otcplen < sizeof(struct tcphdr))) {
73 DEBUGP("ip6t_REJECT: proto(%d) != IPPROTO_TCP, or too short. otcplen = %d\n",
74 proto, otcplen);
75 return;
76 }
77
78 if (skb_copy_bits(oldskb, tcphoff, &otcph, sizeof(struct tcphdr)))
79 BUG();
80
81 /* No RST for RST. */
82 if (otcph.rst) {
83 DEBUGP("ip6t_REJECT: RST is set\n");
84 return;
85 }
86
87 /* Check checksum. */
88 if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
89 skb_checksum(oldskb, tcphoff, otcplen, 0))) {
90 DEBUGP("ip6t_REJECT: TCP checksum is invalid\n");
91 return;
92 }
93
94 memset(&fl, 0, sizeof(fl));
95 fl.proto = IPPROTO_TCP;
96 ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr);
97 ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
98 fl.fl_ip_sport = otcph.dest;
99 fl.fl_ip_dport = otcph.source;
100 dst = ip6_route_output(NULL, &fl);
101 if (dst == NULL)
102 return;
103 if (dst->error ||
104 xfrm_lookup(&dst, &fl, NULL, 0)) {
105 dst_release(dst);
106 return;
107 }
108
109 hh_len = (dst->dev->hard_header_len + 15)&~15;
110 nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
111 + sizeof(struct tcphdr) + dst->trailer_len,
112 GFP_ATOMIC);
113
114 if (!nskb) {
115 if (net_ratelimit())
116 printk("ip6t_REJECT: Can't alloc skb\n");
117 dst_release(dst);
118 return;
119 }
120
121 nskb->dst = dst;
122
123 skb_reserve(nskb, hh_len + dst->header_len);
124
125 ip6h = nskb->nh.ipv6h = (struct ipv6hdr *)
126 skb_put(nskb, sizeof(struct ipv6hdr));
127 ip6h->version = 6;
128 ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
129 ip6h->nexthdr = IPPROTO_TCP;
130 ip6h->payload_len = htons(sizeof(struct tcphdr));
131 ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr);
132 ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr);
133
134 tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
135 /* Truncate to length (no data) */
136 tcph->doff = sizeof(struct tcphdr)/4;
137 tcph->source = otcph.dest;
138 tcph->dest = otcph.source;
139
140 if (otcph.ack) {
141 needs_ack = 0;
142 tcph->seq = otcph.ack_seq;
143 tcph->ack_seq = 0;
144 } else {
145 needs_ack = 1;
146 tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
147 + otcplen - (otcph.doff<<2));
148 tcph->seq = 0;
149 }
150
151 /* Reset flags */
152 ((u_int8_t *)tcph)[13] = 0;
153 tcph->rst = 1;
154 tcph->ack = needs_ack;
155 tcph->window = 0;
156 tcph->urg_ptr = 0;
157 tcph->check = 0;
158
159 /* Adjust TCP checksum */
160 tcph->check = csum_ipv6_magic(&nskb->nh.ipv6h->saddr,
161 &nskb->nh.ipv6h->daddr,
162 sizeof(struct tcphdr), IPPROTO_TCP,
163 csum_partial((char *)tcph,
164 sizeof(struct tcphdr), 0));
165
166 NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
167 dst_output);
168}
169
170static inline void
171send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum)
172{
173 if (hooknum == NF_IP6_LOCAL_OUT && skb_in->dev == NULL)
174 skb_in->dev = &loopback_dev;
175
176 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
177}
178
179static unsigned int reject6_target(struct sk_buff **pskb,
180 const struct net_device *in,
181 const struct net_device *out,
182 unsigned int hooknum,
183 const void *targinfo,
184 void *userinfo)
185{
186 const struct ip6t_reject_info *reject = targinfo;
187
188 DEBUGP(KERN_DEBUG "%s: medium point\n", __FUNCTION__);
189 /* WARNING: This code causes reentry within ip6tables.
190 This means that the ip6tables jump stack is now crap. We
191 must return an absolute verdict. --RR */
192 switch (reject->with) {
193 case IP6T_ICMP6_NO_ROUTE:
194 send_unreach(*pskb, ICMPV6_NOROUTE, hooknum);
195 break;
196 case IP6T_ICMP6_ADM_PROHIBITED:
197 send_unreach(*pskb, ICMPV6_ADM_PROHIBITED, hooknum);
198 break;
199 case IP6T_ICMP6_NOT_NEIGHBOUR:
200 send_unreach(*pskb, ICMPV6_NOT_NEIGHBOUR, hooknum);
201 break;
202 case IP6T_ICMP6_ADDR_UNREACH:
203 send_unreach(*pskb, ICMPV6_ADDR_UNREACH, hooknum);
204 break;
205 case IP6T_ICMP6_PORT_UNREACH:
206 send_unreach(*pskb, ICMPV6_PORT_UNREACH, hooknum);
207 break;
208 case IP6T_ICMP6_ECHOREPLY:
209 /* Do nothing */
210 break;
211 case IP6T_TCP_RESET:
212 send_reset(*pskb);
213 break;
214 default:
215 if (net_ratelimit())
216 printk(KERN_WARNING "ip6t_REJECT: case %u not handled yet\n", reject->with);
217 break;
218 }
219
220 return NF_DROP;
221}
222
223static int check(const char *tablename,
224 const struct ip6t_entry *e,
225 void *targinfo,
226 unsigned int targinfosize,
227 unsigned int hook_mask)
228{
229 const struct ip6t_reject_info *rejinfo = targinfo;
230
231 if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
232 DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
233 return 0;
234 }
235
236 /* Only allow these for packet filtering. */
237 if (strcmp(tablename, "filter") != 0) {
238 DEBUGP("ip6t_REJECT: bad table `%s'.\n", tablename);
239 return 0;
240 }
241
242 if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
243 | (1 << NF_IP6_FORWARD)
244 | (1 << NF_IP6_LOCAL_OUT))) != 0) {
245 DEBUGP("ip6t_REJECT: bad hook mask %X\n", hook_mask);
246 return 0;
247 }
248
249 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
250 printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
251 return 0;
252 } else if (rejinfo->with == IP6T_TCP_RESET) {
253 /* Must specify that it's a TCP packet */
254 if (e->ipv6.proto != IPPROTO_TCP
255 || (e->ipv6.invflags & IP6T_INV_PROTO)) {
256 DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
257 return 0;
258 }
259 }
260
261 return 1;
262}
263
264static struct ip6t_target ip6t_reject_reg = {
265 .name = "REJECT",
266 .target = reject6_target,
267 .checkentry = check,
268 .me = THIS_MODULE
269};
270
271static int __init init(void)
272{
273 if (ip6t_register_target(&ip6t_reject_reg))
274 return -EINVAL;
275 return 0;
276}
277
278static void __exit fini(void)
279{
280 ip6t_unregister_target(&ip6t_reject_reg);
281}
282
283module_init(init);
284module_exit(fini);
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index ab0e32d3de46..9b91decbfddb 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -20,71 +20,6 @@ MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
20MODULE_DESCRIPTION("IP6 tables owner matching module"); 20MODULE_DESCRIPTION("IP6 tables owner matching module");
21MODULE_LICENSE("GPL"); 21MODULE_LICENSE("GPL");
22 22
23static int
24match_pid(const struct sk_buff *skb, pid_t pid)
25{
26 struct task_struct *p;
27 struct files_struct *files;
28 int i;
29
30 read_lock(&tasklist_lock);
31 p = find_task_by_pid(pid);
32 if (!p)
33 goto out;
34 task_lock(p);
35 files = p->files;
36 if(files) {
37 spin_lock(&files->file_lock);
38 for (i=0; i < files->max_fds; i++) {
39 if (fcheck_files(files, i) == skb->sk->sk_socket->file) {
40 spin_unlock(&files->file_lock);
41 task_unlock(p);
42 read_unlock(&tasklist_lock);
43 return 1;
44 }
45 }
46 spin_unlock(&files->file_lock);
47 }
48 task_unlock(p);
49out:
50 read_unlock(&tasklist_lock);
51 return 0;
52}
53
54static int
55match_sid(const struct sk_buff *skb, pid_t sid)
56{
57 struct task_struct *g, *p;
58 struct file *file = skb->sk->sk_socket->file;
59 int i, found=0;
60
61 read_lock(&tasklist_lock);
62 do_each_thread(g, p) {
63 struct files_struct *files;
64 if (p->signal->session != sid)
65 continue;
66
67 task_lock(p);
68 files = p->files;
69 if (files) {
70 spin_lock(&files->file_lock);
71 for (i=0; i < files->max_fds; i++) {
72 if (fcheck_files(files, i) == file) {
73 found = 1;
74 break;
75 }
76 }
77 spin_unlock(&files->file_lock);
78 }
79 task_unlock(p);
80 if (found)
81 goto out;
82 } while_each_thread(g, p);
83out:
84 read_unlock(&tasklist_lock);
85
86 return found;
87}
88 23
89static int 24static int
90match(const struct sk_buff *skb, 25match(const struct sk_buff *skb,
@@ -112,18 +47,6 @@ match(const struct sk_buff *skb,
112 return 0; 47 return 0;
113 } 48 }
114 49
115 if(info->match & IP6T_OWNER_PID) {
116 if (!match_pid(skb, info->pid) ^
117 !!(info->invert & IP6T_OWNER_PID))
118 return 0;
119 }
120
121 if(info->match & IP6T_OWNER_SID) {
122 if (!match_sid(skb, info->sid) ^
123 !!(info->invert & IP6T_OWNER_SID))
124 return 0;
125 }
126
127 return 1; 50 return 1;
128} 51}
129 52
@@ -134,6 +57,8 @@ checkentry(const char *tablename,
134 unsigned int matchsize, 57 unsigned int matchsize,
135 unsigned int hook_mask) 58 unsigned int hook_mask)
136{ 59{
60 const struct ip6t_owner_info *info = matchinfo;
61
137 if (hook_mask 62 if (hook_mask
138 & ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) { 63 & ~((1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING))) {
139 printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n"); 64 printk("ip6t_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
@@ -142,14 +67,13 @@ checkentry(const char *tablename,
142 67
143 if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info))) 68 if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info)))
144 return 0; 69 return 0;
145#ifdef CONFIG_SMP 70
146 /* files->file_lock can not be used in a BH */ 71 if (info->match & (IP6T_OWNER_PID|IP6T_OWNER_SID)) {
147 if (((struct ip6t_owner_info *)matchinfo)->match 72 printk("ipt_owner: pid and sid matching "
148 & (IP6T_OWNER_PID|IP6T_OWNER_SID)) { 73 "not supported anymore\n");
149 printk("ip6t_owner: pid and sid matching is broken on SMP.\n");
150 return 0; 74 return 0;
151 } 75 }
152#endif 76
153 return 1; 77 return 1;
154} 78}
155 79
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 1d4d75b34d32..7a5863298f3f 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -49,6 +49,7 @@
49#include <net/transp_v6.h> 49#include <net/transp_v6.h>
50#include <net/udp.h> 50#include <net/udp.h>
51#include <net/inet_common.h> 51#include <net/inet_common.h>
52#include <net/tcp_states.h>
52 53
53#include <net/rawv6.h> 54#include <net/rawv6.h>
54#include <net/xfrm.h> 55#include <net/xfrm.h>
@@ -81,7 +82,8 @@ static void raw_v6_unhash(struct sock *sk)
81 82
82/* Grumble... icmp and ip_input want to get at this... */ 83/* Grumble... icmp and ip_input want to get at this... */
83struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num, 84struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
84 struct in6_addr *loc_addr, struct in6_addr *rmt_addr) 85 struct in6_addr *loc_addr, struct in6_addr *rmt_addr,
86 int dif)
85{ 87{
86 struct hlist_node *node; 88 struct hlist_node *node;
87 int is_multicast = ipv6_addr_is_multicast(loc_addr); 89 int is_multicast = ipv6_addr_is_multicast(loc_addr);
@@ -94,6 +96,9 @@ struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
94 !ipv6_addr_equal(&np->daddr, rmt_addr)) 96 !ipv6_addr_equal(&np->daddr, rmt_addr))
95 continue; 97 continue;
96 98
99 if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)
100 continue;
101
97 if (!ipv6_addr_any(&np->rcv_saddr)) { 102 if (!ipv6_addr_any(&np->rcv_saddr)) {
98 if (ipv6_addr_equal(&np->rcv_saddr, loc_addr)) 103 if (ipv6_addr_equal(&np->rcv_saddr, loc_addr))
99 goto found; 104 goto found;
@@ -137,11 +142,12 @@ static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
137 * 142 *
138 * Caller owns SKB so we must make clones. 143 * Caller owns SKB so we must make clones.
139 */ 144 */
140void ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) 145int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
141{ 146{
142 struct in6_addr *saddr; 147 struct in6_addr *saddr;
143 struct in6_addr *daddr; 148 struct in6_addr *daddr;
144 struct sock *sk; 149 struct sock *sk;
150 int delivered = 0;
145 __u8 hash; 151 __u8 hash;
146 152
147 saddr = &skb->nh.ipv6h->saddr; 153 saddr = &skb->nh.ipv6h->saddr;
@@ -160,9 +166,10 @@ void ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
160 if (sk == NULL) 166 if (sk == NULL)
161 goto out; 167 goto out;
162 168
163 sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr); 169 sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, skb->dev->ifindex);
164 170
165 while (sk) { 171 while (sk) {
172 delivered = 1;
166 if (nexthdr != IPPROTO_ICMPV6 || !icmpv6_filter(sk, skb)) { 173 if (nexthdr != IPPROTO_ICMPV6 || !icmpv6_filter(sk, skb)) {
167 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); 174 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
168 175
@@ -170,10 +177,12 @@ void ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
170 if (clone) 177 if (clone)
171 rawv6_rcv(sk, clone); 178 rawv6_rcv(sk, clone);
172 } 179 }
173 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);
174 } 182 }
175out: 183out:
176 read_unlock(&raw_v6_lock); 184 read_unlock(&raw_v6_lock);
185 return delivered;
177} 186}
178 187
179/* This cleans up af_inet6 a bit. -DaveM */ 188/* This cleans up af_inet6 a bit. -DaveM */
@@ -334,8 +343,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
334 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, 343 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
335 &skb->nh.ipv6h->daddr, 344 &skb->nh.ipv6h->daddr,
336 skb->len, inet->num, skb->csum)) { 345 skb->len, inet->num, skb->csum)) {
337 LIMIT_NETDEBUG( 346 LIMIT_NETDEBUG(KERN_DEBUG "raw v6 hw csum failure.\n");
338 printk(KERN_DEBUG "raw v6 hw csum failure.\n"));
339 skb->ip_summed = CHECKSUM_NONE; 347 skb->ip_summed = CHECKSUM_NONE;
340 } 348 }
341 } 349 }
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 59e7c6317872..9d9e04344c77 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -562,7 +562,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
562 if (skb->dev) 562 if (skb->dev)
563 fq->iif = skb->dev->ifindex; 563 fq->iif = skb->dev->ifindex;
564 skb->dev = NULL; 564 skb->dev = NULL;
565 fq->stamp = skb->stamp; 565 skb_get_timestamp(skb, &fq->stamp);
566 fq->meat += skb->len; 566 fq->meat += skb->len;
567 atomic_add(skb->truesize, &ip6_frag_mem); 567 atomic_add(skb->truesize, &ip6_frag_mem);
568 568
@@ -664,7 +664,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
664 664
665 head->next = NULL; 665 head->next = NULL;
666 head->dev = dev; 666 head->dev = dev;
667 head->stamp = fq->stamp; 667 skb_set_timestamp(head, &fq->stamp);
668 head->nh.ipv6h->payload_len = htons(payload_len); 668 head->nh.ipv6h->payload_len = htons(payload_len);
669 669
670 *skb_in = head; 670 *skb_in = head;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 878789b3122d..5d5bbb49ec78 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1372,7 +1372,7 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
1372 * Drop the packet on the floor 1372 * Drop the packet on the floor
1373 */ 1373 */
1374 1374
1375int ip6_pkt_discard(struct sk_buff *skb) 1375static int ip6_pkt_discard(struct sk_buff *skb)
1376{ 1376{
1377 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 1377 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
1378 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev); 1378 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev);
@@ -1380,7 +1380,7 @@ int ip6_pkt_discard(struct sk_buff *skb)
1380 return 0; 1380 return 0;
1381} 1381}
1382 1382
1383int ip6_pkt_discard_out(struct sk_buff *skb) 1383static int ip6_pkt_discard_out(struct sk_buff *skb)
1384{ 1384{
1385 skb->dev = skb->dst->dev; 1385 skb->dev = skb->dst->dev;
1386 return ip6_pkt_discard(skb); 1386 return ip6_pkt_discard(skb);
@@ -1850,16 +1850,16 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh,
1850 1850
1851 skb = alloc_skb(size, gfp_any()); 1851 skb = alloc_skb(size, gfp_any());
1852 if (!skb) { 1852 if (!skb) {
1853 netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS); 1853 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_ROUTE, ENOBUFS);
1854 return; 1854 return;
1855 } 1855 }
1856 if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0) < 0) { 1856 if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0) < 0) {
1857 kfree_skb(skb); 1857 kfree_skb(skb);
1858 netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL); 1858 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_ROUTE, EINVAL);
1859 return; 1859 return;
1860 } 1860 }
1861 NETLINK_CB(skb).dst_groups = RTMGRP_IPV6_ROUTE; 1861 NETLINK_CB(skb).dst_group = RTNLGRP_IPV6_ROUTE;
1862 netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_ROUTE, gfp_any()); 1862 netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_ROUTE, gfp_any());
1863} 1863}
1864 1864
1865/* 1865/*
@@ -1960,8 +1960,6 @@ static int rt6_proc_info(char *buffer, char **start, off_t offset, int length)
1960 return arg.len; 1960 return arg.len;
1961} 1961}
1962 1962
1963extern struct rt6_statistics rt6_stats;
1964
1965static int rt6_stats_seq_show(struct seq_file *seq, void *v) 1963static int rt6_stats_seq_show(struct seq_file *seq, void *v)
1966{ 1964{
1967 seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n", 1965 seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index e553e5b80d6e..c3123c9e1a8e 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -770,7 +770,7 @@ static int ipip6_tunnel_init(struct net_device *dev)
770 return 0; 770 return 0;
771} 771}
772 772
773int __init ipip6_fb_tunnel_init(struct net_device *dev) 773static int __init ipip6_fb_tunnel_init(struct net_device *dev)
774{ 774{
775 struct ip_tunnel *tunnel = dev->priv; 775 struct ip_tunnel *tunnel = dev->priv;
776 struct iphdr *iph = &tunnel->parms.iph; 776 struct iphdr *iph = &tunnel->parms.iph;
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 3a18e0e6ffed..8eff9fa1e983 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -14,9 +14,6 @@
14#include <net/ipv6.h> 14#include <net/ipv6.h>
15#include <net/addrconf.h> 15#include <net/addrconf.h>
16 16
17extern ctl_table ipv6_route_table[];
18extern ctl_table ipv6_icmp_table[];
19
20#ifdef CONFIG_SYSCTL 17#ifdef CONFIG_SYSCTL
21 18
22static ctl_table ipv6_table[] = { 19static ctl_table ipv6_table[] = {
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index ef29cfd936d3..794734f1d230 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -47,6 +47,7 @@
47 47
48#include <net/tcp.h> 48#include <net/tcp.h>
49#include <net/ndisc.h> 49#include <net/ndisc.h>
50#include <net/inet6_hashtables.h>
50#include <net/ipv6.h> 51#include <net/ipv6.h>
51#include <net/transp_v6.h> 52#include <net/transp_v6.h>
52#include <net/addrconf.h> 53#include <net/addrconf.h>
@@ -75,34 +76,11 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok);
75static struct tcp_func ipv6_mapped; 76static struct tcp_func ipv6_mapped;
76static struct tcp_func ipv6_specific; 77static struct tcp_func ipv6_specific;
77 78
78/* I have no idea if this is a good hash for v6 or not. -DaveM */ 79static inline int tcp_v6_bind_conflict(const struct sock *sk,
79static __inline__ int tcp_v6_hashfn(struct in6_addr *laddr, u16 lport, 80 const struct inet_bind_bucket *tb)
80 struct in6_addr *faddr, u16 fport)
81{ 81{
82 int hashent = (lport ^ fport); 82 const struct sock *sk2;
83 83 const struct hlist_node *node;
84 hashent ^= (laddr->s6_addr32[3] ^ faddr->s6_addr32[3]);
85 hashent ^= hashent>>16;
86 hashent ^= hashent>>8;
87 return (hashent & (tcp_ehash_size - 1));
88}
89
90static __inline__ int tcp_v6_sk_hashfn(struct sock *sk)
91{
92 struct inet_sock *inet = inet_sk(sk);
93 struct ipv6_pinfo *np = inet6_sk(sk);
94 struct in6_addr *laddr = &np->rcv_saddr;
95 struct in6_addr *faddr = &np->daddr;
96 __u16 lport = inet->num;
97 __u16 fport = inet->dport;
98 return tcp_v6_hashfn(laddr, lport, faddr, fport);
99}
100
101static inline int tcp_v6_bind_conflict(struct sock *sk,
102 struct tcp_bind_bucket *tb)
103{
104 struct sock *sk2;
105 struct hlist_node *node;
106 84
107 /* We must walk the whole port owner list in this case. -DaveM */ 85 /* We must walk the whole port owner list in this case. -DaveM */
108 sk_for_each_bound(sk2, node, &tb->owners) { 86 sk_for_each_bound(sk2, node, &tb->owners) {
@@ -126,8 +104,8 @@ static inline int tcp_v6_bind_conflict(struct sock *sk,
126 */ 104 */
127static int tcp_v6_get_port(struct sock *sk, unsigned short snum) 105static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
128{ 106{
129 struct tcp_bind_hashbucket *head; 107 struct inet_bind_hashbucket *head;
130 struct tcp_bind_bucket *tb; 108 struct inet_bind_bucket *tb;
131 struct hlist_node *node; 109 struct hlist_node *node;
132 int ret; 110 int ret;
133 111
@@ -138,25 +116,25 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
138 int remaining = (high - low) + 1; 116 int remaining = (high - low) + 1;
139 int rover; 117 int rover;
140 118
141 spin_lock(&tcp_portalloc_lock); 119 spin_lock(&tcp_hashinfo.portalloc_lock);
142 if (tcp_port_rover < low) 120 if (tcp_hashinfo.port_rover < low)
143 rover = low; 121 rover = low;
144 else 122 else
145 rover = tcp_port_rover; 123 rover = tcp_hashinfo.port_rover;
146 do { rover++; 124 do { rover++;
147 if (rover > high) 125 if (rover > high)
148 rover = low; 126 rover = low;
149 head = &tcp_bhash[tcp_bhashfn(rover)]; 127 head = &tcp_hashinfo.bhash[inet_bhashfn(rover, tcp_hashinfo.bhash_size)];
150 spin_lock(&head->lock); 128 spin_lock(&head->lock);
151 tb_for_each(tb, node, &head->chain) 129 inet_bind_bucket_for_each(tb, node, &head->chain)
152 if (tb->port == rover) 130 if (tb->port == rover)
153 goto next; 131 goto next;
154 break; 132 break;
155 next: 133 next:
156 spin_unlock(&head->lock); 134 spin_unlock(&head->lock);
157 } while (--remaining > 0); 135 } while (--remaining > 0);
158 tcp_port_rover = rover; 136 tcp_hashinfo.port_rover = rover;
159 spin_unlock(&tcp_portalloc_lock); 137 spin_unlock(&tcp_hashinfo.portalloc_lock);
160 138
161 /* Exhausted local port range during search? It is not 139 /* Exhausted local port range during search? It is not
162 * possible for us to be holding one of the bind hash 140 * possible for us to be holding one of the bind hash
@@ -171,9 +149,9 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
171 /* OK, here is the one we will use. */ 149 /* OK, here is the one we will use. */
172 snum = rover; 150 snum = rover;
173 } else { 151 } else {
174 head = &tcp_bhash[tcp_bhashfn(snum)]; 152 head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
175 spin_lock(&head->lock); 153 spin_lock(&head->lock);
176 tb_for_each(tb, node, &head->chain) 154 inet_bind_bucket_for_each(tb, node, &head->chain)
177 if (tb->port == snum) 155 if (tb->port == snum)
178 goto tb_found; 156 goto tb_found;
179 } 157 }
@@ -192,8 +170,11 @@ tb_found:
192 } 170 }
193tb_not_found: 171tb_not_found:
194 ret = 1; 172 ret = 1;
195 if (!tb && (tb = tcp_bucket_create(head, snum)) == NULL) 173 if (tb == NULL) {
196 goto fail_unlock; 174 tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, snum);
175 if (tb == NULL)
176 goto fail_unlock;
177 }
197 if (hlist_empty(&tb->owners)) { 178 if (hlist_empty(&tb->owners)) {
198 if (sk->sk_reuse && sk->sk_state != TCP_LISTEN) 179 if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
199 tb->fastreuse = 1; 180 tb->fastreuse = 1;
@@ -204,9 +185,9 @@ tb_not_found:
204 tb->fastreuse = 0; 185 tb->fastreuse = 0;
205 186
206success: 187success:
207 if (!tcp_sk(sk)->bind_hash) 188 if (!inet_csk(sk)->icsk_bind_hash)
208 tcp_bind_hash(sk, tb, snum); 189 inet_bind_hash(sk, tb, snum);
209 BUG_TRAP(tcp_sk(sk)->bind_hash == tb); 190 BUG_TRAP(inet_csk(sk)->icsk_bind_hash == tb);
210 ret = 0; 191 ret = 0;
211 192
212fail_unlock: 193fail_unlock:
@@ -224,13 +205,13 @@ static __inline__ void __tcp_v6_hash(struct sock *sk)
224 BUG_TRAP(sk_unhashed(sk)); 205 BUG_TRAP(sk_unhashed(sk));
225 206
226 if (sk->sk_state == TCP_LISTEN) { 207 if (sk->sk_state == TCP_LISTEN) {
227 list = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)]; 208 list = &tcp_hashinfo.listening_hash[inet_sk_listen_hashfn(sk)];
228 lock = &tcp_lhash_lock; 209 lock = &tcp_hashinfo.lhash_lock;
229 tcp_listen_wlock(); 210 inet_listen_wlock(&tcp_hashinfo);
230 } else { 211 } else {
231 sk->sk_hashent = tcp_v6_sk_hashfn(sk); 212 sk->sk_hashent = inet6_sk_ehashfn(sk, tcp_hashinfo.ehash_size);
232 list = &tcp_ehash[sk->sk_hashent].chain; 213 list = &tcp_hashinfo.ehash[sk->sk_hashent].chain;
233 lock = &tcp_ehash[sk->sk_hashent].lock; 214 lock = &tcp_hashinfo.ehash[sk->sk_hashent].lock;
234 write_lock(lock); 215 write_lock(lock);
235 } 216 }
236 217
@@ -255,131 +236,11 @@ static void tcp_v6_hash(struct sock *sk)
255 } 236 }
256} 237}
257 238
258static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned short hnum, int dif)
259{
260 struct sock *sk;
261 struct hlist_node *node;
262 struct sock *result = NULL;
263 int score, hiscore;
264
265 hiscore=0;
266 read_lock(&tcp_lhash_lock);
267 sk_for_each(sk, node, &tcp_listening_hash[tcp_lhashfn(hnum)]) {
268 if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) {
269 struct ipv6_pinfo *np = inet6_sk(sk);
270
271 score = 1;
272 if (!ipv6_addr_any(&np->rcv_saddr)) {
273 if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
274 continue;
275 score++;
276 }
277 if (sk->sk_bound_dev_if) {
278 if (sk->sk_bound_dev_if != dif)
279 continue;
280 score++;
281 }
282 if (score == 3) {
283 result = sk;
284 break;
285 }
286 if (score > hiscore) {
287 hiscore = score;
288 result = sk;
289 }
290 }
291 }
292 if (result)
293 sock_hold(result);
294 read_unlock(&tcp_lhash_lock);
295 return result;
296}
297
298/* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
299 * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
300 *
301 * The sockhash lock must be held as a reader here.
302 */
303
304static inline struct sock *__tcp_v6_lookup_established(struct in6_addr *saddr, u16 sport,
305 struct in6_addr *daddr, u16 hnum,
306 int dif)
307{
308 struct tcp_ehash_bucket *head;
309 struct sock *sk;
310 struct hlist_node *node;
311 __u32 ports = TCP_COMBINED_PORTS(sport, hnum);
312 int hash;
313
314 /* Optimize here for direct hit, only listening connections can
315 * have wildcards anyways.
316 */
317 hash = tcp_v6_hashfn(daddr, hnum, saddr, sport);
318 head = &tcp_ehash[hash];
319 read_lock(&head->lock);
320 sk_for_each(sk, node, &head->chain) {
321 /* For IPV6 do the cheaper port and family tests first. */
322 if(TCP_IPV6_MATCH(sk, saddr, daddr, ports, dif))
323 goto hit; /* You sunk my battleship! */
324 }
325 /* Must check for a TIME_WAIT'er before going to listener hash. */
326 sk_for_each(sk, node, &(head + tcp_ehash_size)->chain) {
327 /* FIXME: acme: check this... */
328 struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk;
329
330 if(*((__u32 *)&(tw->tw_dport)) == ports &&
331 sk->sk_family == PF_INET6) {
332 if(ipv6_addr_equal(&tw->tw_v6_daddr, saddr) &&
333 ipv6_addr_equal(&tw->tw_v6_rcv_saddr, daddr) &&
334 (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif))
335 goto hit;
336 }
337 }
338 read_unlock(&head->lock);
339 return NULL;
340
341hit:
342 sock_hold(sk);
343 read_unlock(&head->lock);
344 return sk;
345}
346
347
348static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
349 struct in6_addr *daddr, u16 hnum,
350 int dif)
351{
352 struct sock *sk;
353
354 sk = __tcp_v6_lookup_established(saddr, sport, daddr, hnum, dif);
355
356 if (sk)
357 return sk;
358
359 return tcp_v6_lookup_listener(daddr, hnum, dif);
360}
361
362inline struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
363 struct in6_addr *daddr, u16 dport,
364 int dif)
365{
366 struct sock *sk;
367
368 local_bh_disable();
369 sk = __tcp_v6_lookup(saddr, sport, daddr, ntohs(dport), dif);
370 local_bh_enable();
371
372 return sk;
373}
374
375EXPORT_SYMBOL_GPL(tcp_v6_lookup);
376
377
378/* 239/*
379 * Open request hash tables. 240 * Open request hash tables.
380 */ 241 */
381 242
382static u32 tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport, u32 rnd) 243static u32 tcp_v6_synq_hash(const struct in6_addr *raddr, const u16 rport, const u32 rnd)
383{ 244{
384 u32 a, b, c; 245 u32 a, b, c;
385 246
@@ -399,14 +260,15 @@ static u32 tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport, u32 rnd)
399 return c & (TCP_SYNQ_HSIZE - 1); 260 return c & (TCP_SYNQ_HSIZE - 1);
400} 261}
401 262
402static struct request_sock *tcp_v6_search_req(struct tcp_sock *tp, 263static struct request_sock *tcp_v6_search_req(const struct sock *sk,
403 struct request_sock ***prevp, 264 struct request_sock ***prevp,
404 __u16 rport, 265 __u16 rport,
405 struct in6_addr *raddr, 266 struct in6_addr *raddr,
406 struct in6_addr *laddr, 267 struct in6_addr *laddr,
407 int iif) 268 int iif)
408{ 269{
409 struct listen_sock *lopt = tp->accept_queue.listen_opt; 270 const struct inet_connection_sock *icsk = inet_csk(sk);
271 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
410 struct request_sock *req, **prev; 272 struct request_sock *req, **prev;
411 273
412 for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)]; 274 for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
@@ -451,44 +313,48 @@ static __u32 tcp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
451 } 313 }
452} 314}
453 315
454static int __tcp_v6_check_established(struct sock *sk, __u16 lport, 316static int __tcp_v6_check_established(struct sock *sk, const __u16 lport,
455 struct tcp_tw_bucket **twp) 317 struct inet_timewait_sock **twp)
456{ 318{
457 struct inet_sock *inet = inet_sk(sk); 319 struct inet_sock *inet = inet_sk(sk);
458 struct ipv6_pinfo *np = inet6_sk(sk); 320 const struct ipv6_pinfo *np = inet6_sk(sk);
459 struct in6_addr *daddr = &np->rcv_saddr; 321 const struct in6_addr *daddr = &np->rcv_saddr;
460 struct in6_addr *saddr = &np->daddr; 322 const struct in6_addr *saddr = &np->daddr;
461 int dif = sk->sk_bound_dev_if; 323 const int dif = sk->sk_bound_dev_if;
462 u32 ports = TCP_COMBINED_PORTS(inet->dport, lport); 324 const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
463 int hash = tcp_v6_hashfn(daddr, inet->num, saddr, inet->dport); 325 const int hash = inet6_ehashfn(daddr, inet->num, saddr, inet->dport,
464 struct tcp_ehash_bucket *head = &tcp_ehash[hash]; 326 tcp_hashinfo.ehash_size);
327 struct inet_ehash_bucket *head = &tcp_hashinfo.ehash[hash];
465 struct sock *sk2; 328 struct sock *sk2;
466 struct hlist_node *node; 329 const struct hlist_node *node;
467 struct tcp_tw_bucket *tw; 330 struct inet_timewait_sock *tw;
468 331
469 write_lock(&head->lock); 332 write_lock(&head->lock);
470 333
471 /* Check TIME-WAIT sockets first. */ 334 /* Check TIME-WAIT sockets first. */
472 sk_for_each(sk2, node, &(head + tcp_ehash_size)->chain) { 335 sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) {
473 tw = (struct tcp_tw_bucket*)sk2; 336 const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk2);
337
338 tw = inet_twsk(sk2);
474 339
475 if(*((__u32 *)&(tw->tw_dport)) == ports && 340 if(*((__u32 *)&(tw->tw_dport)) == ports &&
476 sk2->sk_family == PF_INET6 && 341 sk2->sk_family == PF_INET6 &&
477 ipv6_addr_equal(&tw->tw_v6_daddr, saddr) && 342 ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr) &&
478 ipv6_addr_equal(&tw->tw_v6_rcv_saddr, daddr) && 343 ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr) &&
479 sk2->sk_bound_dev_if == sk->sk_bound_dev_if) { 344 sk2->sk_bound_dev_if == sk->sk_bound_dev_if) {
345 const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2);
480 struct tcp_sock *tp = tcp_sk(sk); 346 struct tcp_sock *tp = tcp_sk(sk);
481 347
482 if (tw->tw_ts_recent_stamp && 348 if (tcptw->tw_ts_recent_stamp &&
483 (!twp || (sysctl_tcp_tw_reuse && 349 (!twp ||
484 xtime.tv_sec - 350 (sysctl_tcp_tw_reuse &&
485 tw->tw_ts_recent_stamp > 1))) { 351 xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) {
486 /* See comment in tcp_ipv4.c */ 352 /* See comment in tcp_ipv4.c */
487 tp->write_seq = tw->tw_snd_nxt + 65535 + 2; 353 tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
488 if (!tp->write_seq) 354 if (!tp->write_seq)
489 tp->write_seq = 1; 355 tp->write_seq = 1;
490 tp->rx_opt.ts_recent = tw->tw_ts_recent; 356 tp->rx_opt.ts_recent = tcptw->tw_ts_recent;
491 tp->rx_opt.ts_recent_stamp = tw->tw_ts_recent_stamp; 357 tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
492 sock_hold(sk2); 358 sock_hold(sk2);
493 goto unique; 359 goto unique;
494 } else 360 } else
@@ -499,7 +365,7 @@ static int __tcp_v6_check_established(struct sock *sk, __u16 lport,
499 365
500 /* And established part... */ 366 /* And established part... */
501 sk_for_each(sk2, node, &head->chain) { 367 sk_for_each(sk2, node, &head->chain) {
502 if(TCP_IPV6_MATCH(sk2, saddr, daddr, ports, dif)) 368 if (INET6_MATCH(sk2, saddr, daddr, ports, dif))
503 goto not_unique; 369 goto not_unique;
504 } 370 }
505 371
@@ -515,10 +381,10 @@ unique:
515 NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); 381 NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
516 } else if (tw) { 382 } else if (tw) {
517 /* Silly. Should hash-dance instead... */ 383 /* Silly. Should hash-dance instead... */
518 tcp_tw_deschedule(tw); 384 inet_twsk_deschedule(tw, &tcp_death_row);
519 NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); 385 NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
520 386
521 tcp_tw_put(tw); 387 inet_twsk_put(tw);
522 } 388 }
523 return 0; 389 return 0;
524 390
@@ -540,8 +406,8 @@ static inline u32 tcpv6_port_offset(const struct sock *sk)
540static int tcp_v6_hash_connect(struct sock *sk) 406static int tcp_v6_hash_connect(struct sock *sk)
541{ 407{
542 unsigned short snum = inet_sk(sk)->num; 408 unsigned short snum = inet_sk(sk)->num;
543 struct tcp_bind_hashbucket *head; 409 struct inet_bind_hashbucket *head;
544 struct tcp_bind_bucket *tb; 410 struct inet_bind_bucket *tb;
545 int ret; 411 int ret;
546 412
547 if (!snum) { 413 if (!snum) {
@@ -553,19 +419,19 @@ static int tcp_v6_hash_connect(struct sock *sk)
553 static u32 hint; 419 static u32 hint;
554 u32 offset = hint + tcpv6_port_offset(sk); 420 u32 offset = hint + tcpv6_port_offset(sk);
555 struct hlist_node *node; 421 struct hlist_node *node;
556 struct tcp_tw_bucket *tw = NULL; 422 struct inet_timewait_sock *tw = NULL;
557 423
558 local_bh_disable(); 424 local_bh_disable();
559 for (i = 1; i <= range; i++) { 425 for (i = 1; i <= range; i++) {
560 port = low + (i + offset) % range; 426 port = low + (i + offset) % range;
561 head = &tcp_bhash[tcp_bhashfn(port)]; 427 head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)];
562 spin_lock(&head->lock); 428 spin_lock(&head->lock);
563 429
564 /* Does not bother with rcv_saddr checks, 430 /* Does not bother with rcv_saddr checks,
565 * because the established check is already 431 * because the established check is already
566 * unique enough. 432 * unique enough.
567 */ 433 */
568 tb_for_each(tb, node, &head->chain) { 434 inet_bind_bucket_for_each(tb, node, &head->chain) {
569 if (tb->port == port) { 435 if (tb->port == port) {
570 BUG_TRAP(!hlist_empty(&tb->owners)); 436 BUG_TRAP(!hlist_empty(&tb->owners));
571 if (tb->fastreuse >= 0) 437 if (tb->fastreuse >= 0)
@@ -578,7 +444,7 @@ static int tcp_v6_hash_connect(struct sock *sk)
578 } 444 }
579 } 445 }
580 446
581 tb = tcp_bucket_create(head, port); 447 tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port);
582 if (!tb) { 448 if (!tb) {
583 spin_unlock(&head->lock); 449 spin_unlock(&head->lock);
584 break; 450 break;
@@ -597,7 +463,7 @@ ok:
597 hint += i; 463 hint += i;
598 464
599 /* Head lock still held and bh's disabled */ 465 /* Head lock still held and bh's disabled */
600 tcp_bind_hash(sk, tb, port); 466 inet_bind_hash(sk, tb, port);
601 if (sk_unhashed(sk)) { 467 if (sk_unhashed(sk)) {
602 inet_sk(sk)->sport = htons(port); 468 inet_sk(sk)->sport = htons(port);
603 __tcp_v6_hash(sk); 469 __tcp_v6_hash(sk);
@@ -605,16 +471,16 @@ ok:
605 spin_unlock(&head->lock); 471 spin_unlock(&head->lock);
606 472
607 if (tw) { 473 if (tw) {
608 tcp_tw_deschedule(tw); 474 inet_twsk_deschedule(tw, &tcp_death_row);
609 tcp_tw_put(tw); 475 inet_twsk_put(tw);
610 } 476 }
611 477
612 ret = 0; 478 ret = 0;
613 goto out; 479 goto out;
614 } 480 }
615 481
616 head = &tcp_bhash[tcp_bhashfn(snum)]; 482 head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
617 tb = tcp_sk(sk)->bind_hash; 483 tb = inet_csk(sk)->icsk_bind_hash;
618 spin_lock_bh(&head->lock); 484 spin_lock_bh(&head->lock);
619 485
620 if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { 486 if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
@@ -631,11 +497,6 @@ out:
631 } 497 }
632} 498}
633 499
634static __inline__ int tcp_v6_iif(struct sk_buff *skb)
635{
636 return IP6CB(skb)->iif;
637}
638
639static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 500static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
640 int addr_len) 501 int addr_len)
641{ 502{
@@ -827,14 +688,15 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
827 int type, int code, int offset, __u32 info) 688 int type, int code, int offset, __u32 info)
828{ 689{
829 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; 690 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
830 struct tcphdr *th = (struct tcphdr *)(skb->data+offset); 691 const struct tcphdr *th = (struct tcphdr *)(skb->data+offset);
831 struct ipv6_pinfo *np; 692 struct ipv6_pinfo *np;
832 struct sock *sk; 693 struct sock *sk;
833 int err; 694 int err;
834 struct tcp_sock *tp; 695 struct tcp_sock *tp;
835 __u32 seq; 696 __u32 seq;
836 697
837 sk = tcp_v6_lookup(&hdr->daddr, th->dest, &hdr->saddr, th->source, skb->dev->ifindex); 698 sk = inet6_lookup(&tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr,
699 th->source, skb->dev->ifindex);
838 700
839 if (sk == NULL) { 701 if (sk == NULL) {
840 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); 702 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -842,7 +704,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
842 } 704 }
843 705
844 if (sk->sk_state == TCP_TIME_WAIT) { 706 if (sk->sk_state == TCP_TIME_WAIT) {
845 tcp_tw_put((struct tcp_tw_bucket*)sk); 707 inet_twsk_put((struct inet_timewait_sock *)sk);
846 return; 708 return;
847 } 709 }
848 710
@@ -920,8 +782,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
920 if (sock_owned_by_user(sk)) 782 if (sock_owned_by_user(sk))
921 goto out; 783 goto out;
922 784
923 req = tcp_v6_search_req(tp, &prev, th->dest, &hdr->daddr, 785 req = tcp_v6_search_req(sk, &prev, th->dest, &hdr->daddr,
924 &hdr->saddr, tcp_v6_iif(skb)); 786 &hdr->saddr, inet6_iif(skb));
925 if (!req) 787 if (!req)
926 goto out; 788 goto out;
927 789
@@ -935,7 +797,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
935 goto out; 797 goto out;
936 } 798 }
937 799
938 tcp_synq_drop(sk, req, prev); 800 inet_csk_reqsk_queue_drop(sk, req, prev);
939 goto out; 801 goto out;
940 802
941 case TCP_SYN_SENT: 803 case TCP_SYN_SENT:
@@ -1132,7 +994,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
1132 buff->csum); 994 buff->csum);
1133 995
1134 fl.proto = IPPROTO_TCP; 996 fl.proto = IPPROTO_TCP;
1135 fl.oif = tcp_v6_iif(skb); 997 fl.oif = inet6_iif(skb);
1136 fl.fl_ip_dport = t1->dest; 998 fl.fl_ip_dport = t1->dest;
1137 fl.fl_ip_sport = t1->source; 999 fl.fl_ip_sport = t1->source;
1138 1000
@@ -1201,7 +1063,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1201 buff->csum); 1063 buff->csum);
1202 1064
1203 fl.proto = IPPROTO_TCP; 1065 fl.proto = IPPROTO_TCP;
1204 fl.oif = tcp_v6_iif(skb); 1066 fl.oif = inet6_iif(skb);
1205 fl.fl_ip_dport = t1->dest; 1067 fl.fl_ip_dport = t1->dest;
1206 fl.fl_ip_sport = t1->source; 1068 fl.fl_ip_sport = t1->source;
1207 1069
@@ -1220,12 +1082,14 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1220 1082
1221static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) 1083static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1222{ 1084{
1223 struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk; 1085 struct inet_timewait_sock *tw = inet_twsk(sk);
1086 const struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
1224 1087
1225 tcp_v6_send_ack(skb, tw->tw_snd_nxt, tw->tw_rcv_nxt, 1088 tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
1226 tw->tw_rcv_wnd >> tw->tw_rcv_wscale, tw->tw_ts_recent); 1089 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
1090 tcptw->tw_ts_recent);
1227 1091
1228 tcp_tw_put(tw); 1092 inet_twsk_put(tw);
1229} 1093}
1230 1094
1231static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 1095static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
@@ -1237,28 +1101,25 @@ static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
1237static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) 1101static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
1238{ 1102{
1239 struct request_sock *req, **prev; 1103 struct request_sock *req, **prev;
1240 struct tcphdr *th = skb->h.th; 1104 const struct tcphdr *th = skb->h.th;
1241 struct tcp_sock *tp = tcp_sk(sk);
1242 struct sock *nsk; 1105 struct sock *nsk;
1243 1106
1244 /* Find possible connection requests. */ 1107 /* Find possible connection requests. */
1245 req = tcp_v6_search_req(tp, &prev, th->source, &skb->nh.ipv6h->saddr, 1108 req = tcp_v6_search_req(sk, &prev, th->source, &skb->nh.ipv6h->saddr,
1246 &skb->nh.ipv6h->daddr, tcp_v6_iif(skb)); 1109 &skb->nh.ipv6h->daddr, inet6_iif(skb));
1247 if (req) 1110 if (req)
1248 return tcp_check_req(sk, skb, req, prev); 1111 return tcp_check_req(sk, skb, req, prev);
1249 1112
1250 nsk = __tcp_v6_lookup_established(&skb->nh.ipv6h->saddr, 1113 nsk = __inet6_lookup_established(&tcp_hashinfo, &skb->nh.ipv6h->saddr,
1251 th->source, 1114 th->source, &skb->nh.ipv6h->daddr,
1252 &skb->nh.ipv6h->daddr, 1115 ntohs(th->dest), inet6_iif(skb));
1253 ntohs(th->dest),
1254 tcp_v6_iif(skb));
1255 1116
1256 if (nsk) { 1117 if (nsk) {
1257 if (nsk->sk_state != TCP_TIME_WAIT) { 1118 if (nsk->sk_state != TCP_TIME_WAIT) {
1258 bh_lock_sock(nsk); 1119 bh_lock_sock(nsk);
1259 return nsk; 1120 return nsk;
1260 } 1121 }
1261 tcp_tw_put((struct tcp_tw_bucket*)nsk); 1122 inet_twsk_put((struct inet_timewait_sock *)nsk);
1262 return NULL; 1123 return NULL;
1263 } 1124 }
1264 1125
@@ -1271,12 +1132,12 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
1271 1132
1272static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req) 1133static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req)
1273{ 1134{
1274 struct tcp_sock *tp = tcp_sk(sk); 1135 struct inet_connection_sock *icsk = inet_csk(sk);
1275 struct listen_sock *lopt = tp->accept_queue.listen_opt; 1136 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
1276 u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd); 1137 const u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
1277 1138
1278 reqsk_queue_hash_req(&tp->accept_queue, h, req, TCP_TIMEOUT_INIT); 1139 reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, TCP_TIMEOUT_INIT);
1279 tcp_synq_added(sk); 1140 inet_csk_reqsk_queue_added(sk, TCP_TIMEOUT_INIT);
1280} 1141}
1281 1142
1282 1143
@@ -1301,13 +1162,13 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1301 /* 1162 /*
1302 * There are no SYN attacks on IPv6, yet... 1163 * There are no SYN attacks on IPv6, yet...
1303 */ 1164 */
1304 if (tcp_synq_is_full(sk) && !isn) { 1165 if (inet_csk_reqsk_queue_is_full(sk) && !isn) {
1305 if (net_ratelimit()) 1166 if (net_ratelimit())
1306 printk(KERN_INFO "TCPv6: dropping request, synflood is possible\n"); 1167 printk(KERN_INFO "TCPv6: dropping request, synflood is possible\n");
1307 goto drop; 1168 goto drop;
1308 } 1169 }
1309 1170
1310 if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) 1171 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
1311 goto drop; 1172 goto drop;
1312 1173
1313 req = reqsk_alloc(&tcp6_request_sock_ops); 1174 req = reqsk_alloc(&tcp6_request_sock_ops);
@@ -1339,7 +1200,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1339 /* So that link locals have meaning */ 1200 /* So that link locals have meaning */
1340 if (!sk->sk_bound_dev_if && 1201 if (!sk->sk_bound_dev_if &&
1341 ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) 1202 ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
1342 treq->iif = tcp_v6_iif(skb); 1203 treq->iif = inet6_iif(skb);
1343 1204
1344 if (isn == 0) 1205 if (isn == 0)
1345 isn = tcp_v6_init_sequence(sk,skb); 1206 isn = tcp_v6_init_sequence(sk,skb);
@@ -1404,15 +1265,14 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1404 newsk->sk_backlog_rcv = tcp_v4_do_rcv; 1265 newsk->sk_backlog_rcv = tcp_v4_do_rcv;
1405 newnp->pktoptions = NULL; 1266 newnp->pktoptions = NULL;
1406 newnp->opt = NULL; 1267 newnp->opt = NULL;
1407 newnp->mcast_oif = tcp_v6_iif(skb); 1268 newnp->mcast_oif = inet6_iif(skb);
1408 newnp->mcast_hops = skb->nh.ipv6h->hop_limit; 1269 newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
1409 1270
1410 /* Charge newly allocated IPv6 socket. Though it is mapped, 1271 /*
1411 * it is IPv6 yet. 1272 * No need to charge this sock to the relevant IPv6 refcnt debug socks count
1273 * here, tcp_create_openreq_child now does this for us, see the comment in
1274 * that function for the gory details. -acme
1412 */ 1275 */
1413#ifdef INET_REFCNT_DEBUG
1414 atomic_inc(&inet6_sock_nr);
1415#endif
1416 1276
1417 /* It is tricky place. Until this moment IPv4 tcp 1277 /* It is tricky place. Until this moment IPv4 tcp
1418 worked with IPv6 af_tcp.af_specific. 1278 worked with IPv6 af_tcp.af_specific.
@@ -1467,10 +1327,11 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1467 if (newsk == NULL) 1327 if (newsk == NULL)
1468 goto out; 1328 goto out;
1469 1329
1470 /* Charge newly allocated IPv6 socket */ 1330 /*
1471#ifdef INET_REFCNT_DEBUG 1331 * No need to charge this sock to the relevant IPv6 refcnt debug socks
1472 atomic_inc(&inet6_sock_nr); 1332 * count here, tcp_create_openreq_child now does this for us, see the
1473#endif 1333 * comment in that function for the gory details. -acme
1334 */
1474 1335
1475 ip6_dst_store(newsk, dst, NULL); 1336 ip6_dst_store(newsk, dst, NULL);
1476 newsk->sk_route_caps = dst->dev->features & 1337 newsk->sk_route_caps = dst->dev->features &
@@ -1509,7 +1370,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1509 skb_set_owner_r(newnp->pktoptions, newsk); 1370 skb_set_owner_r(newnp->pktoptions, newsk);
1510 } 1371 }
1511 newnp->opt = NULL; 1372 newnp->opt = NULL;
1512 newnp->mcast_oif = tcp_v6_iif(skb); 1373 newnp->mcast_oif = inet6_iif(skb);
1513 newnp->mcast_hops = skb->nh.ipv6h->hop_limit; 1374 newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
1514 1375
1515 /* Clone native IPv6 options from listening socket (if any) 1376 /* Clone native IPv6 options from listening socket (if any)
@@ -1536,7 +1397,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1536 newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; 1397 newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
1537 1398
1538 __tcp_v6_hash(newsk); 1399 __tcp_v6_hash(newsk);
1539 tcp_inherit_port(sk, newsk); 1400 inet_inherit_port(&tcp_hashinfo, sk, newsk);
1540 1401
1541 return newsk; 1402 return newsk;
1542 1403
@@ -1557,7 +1418,7 @@ static int tcp_v6_checksum_init(struct sk_buff *skb)
1557 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, 1418 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1558 &skb->nh.ipv6h->daddr,skb->csum)) 1419 &skb->nh.ipv6h->daddr,skb->csum))
1559 return 0; 1420 return 0;
1560 LIMIT_NETDEBUG(printk(KERN_DEBUG "hw tcp v6 csum failed\n")); 1421 LIMIT_NETDEBUG(KERN_DEBUG "hw tcp v6 csum failed\n");
1561 } 1422 }
1562 if (skb->len <= 76) { 1423 if (skb->len <= 76) {
1563 if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, 1424 if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
@@ -1684,7 +1545,7 @@ ipv6_pktoptions:
1684 if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && 1545 if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt &&
1685 !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { 1546 !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
1686 if (np->rxopt.bits.rxinfo) 1547 if (np->rxopt.bits.rxinfo)
1687 np->mcast_oif = tcp_v6_iif(opt_skb); 1548 np->mcast_oif = inet6_iif(opt_skb);
1688 if (np->rxopt.bits.rxhlim) 1549 if (np->rxopt.bits.rxhlim)
1689 np->mcast_hops = opt_skb->nh.ipv6h->hop_limit; 1550 np->mcast_hops = opt_skb->nh.ipv6h->hop_limit;
1690 if (ipv6_opt_accepted(sk, opt_skb)) { 1551 if (ipv6_opt_accepted(sk, opt_skb)) {
@@ -1739,8 +1600,9 @@ static int tcp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
1739 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(skb->nh.ipv6h); 1600 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(skb->nh.ipv6h);
1740 TCP_SKB_CB(skb)->sacked = 0; 1601 TCP_SKB_CB(skb)->sacked = 0;
1741 1602
1742 sk = __tcp_v6_lookup(&skb->nh.ipv6h->saddr, th->source, 1603 sk = __inet6_lookup(&tcp_hashinfo, &skb->nh.ipv6h->saddr, th->source,
1743 &skb->nh.ipv6h->daddr, ntohs(th->dest), tcp_v6_iif(skb)); 1604 &skb->nh.ipv6h->daddr, ntohs(th->dest),
1605 inet6_iif(skb));
1744 1606
1745 if (!sk) 1607 if (!sk)
1746 goto no_tcp_socket; 1608 goto no_tcp_socket;
@@ -1795,26 +1657,29 @@ discard_and_relse:
1795 1657
1796do_time_wait: 1658do_time_wait:
1797 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 1659 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
1798 tcp_tw_put((struct tcp_tw_bucket *) sk); 1660 inet_twsk_put((struct inet_timewait_sock *)sk);
1799 goto discard_it; 1661 goto discard_it;
1800 } 1662 }
1801 1663
1802 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { 1664 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
1803 TCP_INC_STATS_BH(TCP_MIB_INERRS); 1665 TCP_INC_STATS_BH(TCP_MIB_INERRS);
1804 tcp_tw_put((struct tcp_tw_bucket *) sk); 1666 inet_twsk_put((struct inet_timewait_sock *)sk);
1805 goto discard_it; 1667 goto discard_it;
1806 } 1668 }
1807 1669
1808 switch(tcp_timewait_state_process((struct tcp_tw_bucket *)sk, 1670 switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk,
1809 skb, th, skb->len)) { 1671 skb, th)) {
1810 case TCP_TW_SYN: 1672 case TCP_TW_SYN:
1811 { 1673 {
1812 struct sock *sk2; 1674 struct sock *sk2;
1813 1675
1814 sk2 = tcp_v6_lookup_listener(&skb->nh.ipv6h->daddr, ntohs(th->dest), tcp_v6_iif(skb)); 1676 sk2 = inet6_lookup_listener(&tcp_hashinfo,
1677 &skb->nh.ipv6h->daddr,
1678 ntohs(th->dest), inet6_iif(skb));
1815 if (sk2 != NULL) { 1679 if (sk2 != NULL) {
1816 tcp_tw_deschedule((struct tcp_tw_bucket *)sk); 1680 struct inet_timewait_sock *tw = inet_twsk(sk);
1817 tcp_tw_put((struct tcp_tw_bucket *)sk); 1681 inet_twsk_deschedule(tw, &tcp_death_row);
1682 inet_twsk_put(tw);
1818 sk = sk2; 1683 sk = sk2;
1819 goto process; 1684 goto process;
1820 } 1685 }
@@ -1983,7 +1848,7 @@ static struct tcp_func ipv6_specific = {
1983static struct tcp_func ipv6_mapped = { 1848static struct tcp_func ipv6_mapped = {
1984 .queue_xmit = ip_queue_xmit, 1849 .queue_xmit = ip_queue_xmit,
1985 .send_check = tcp_v4_send_check, 1850 .send_check = tcp_v4_send_check,
1986 .rebuild_header = tcp_v4_rebuild_header, 1851 .rebuild_header = inet_sk_rebuild_header,
1987 .conn_request = tcp_v6_conn_request, 1852 .conn_request = tcp_v6_conn_request,
1988 .syn_recv_sock = tcp_v6_syn_recv_sock, 1853 .syn_recv_sock = tcp_v6_syn_recv_sock,
1989 .remember_stamp = tcp_v4_remember_stamp, 1854 .remember_stamp = tcp_v4_remember_stamp,
@@ -2002,13 +1867,14 @@ static struct tcp_func ipv6_mapped = {
2002 */ 1867 */
2003static int tcp_v6_init_sock(struct sock *sk) 1868static int tcp_v6_init_sock(struct sock *sk)
2004{ 1869{
1870 struct inet_connection_sock *icsk = inet_csk(sk);
2005 struct tcp_sock *tp = tcp_sk(sk); 1871 struct tcp_sock *tp = tcp_sk(sk);
2006 1872
2007 skb_queue_head_init(&tp->out_of_order_queue); 1873 skb_queue_head_init(&tp->out_of_order_queue);
2008 tcp_init_xmit_timers(sk); 1874 tcp_init_xmit_timers(sk);
2009 tcp_prequeue_init(tp); 1875 tcp_prequeue_init(tp);
2010 1876
2011 tp->rto = TCP_TIMEOUT_INIT; 1877 icsk->icsk_rto = TCP_TIMEOUT_INIT;
2012 tp->mdev = TCP_TIMEOUT_INIT; 1878 tp->mdev = TCP_TIMEOUT_INIT;
2013 1879
2014 /* So many TCP implementations out there (incorrectly) count the 1880 /* So many TCP implementations out there (incorrectly) count the
@@ -2030,7 +1896,7 @@ static int tcp_v6_init_sock(struct sock *sk)
2030 sk->sk_state = TCP_CLOSE; 1896 sk->sk_state = TCP_CLOSE;
2031 1897
2032 tp->af_specific = &ipv6_specific; 1898 tp->af_specific = &ipv6_specific;
2033 tp->ca_ops = &tcp_init_congestion_ops; 1899 icsk->icsk_ca_ops = &tcp_init_congestion_ops;
2034 sk->sk_write_space = sk_stream_write_space; 1900 sk->sk_write_space = sk_stream_write_space;
2035 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 1901 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
2036 1902
@@ -2044,8 +1910,6 @@ static int tcp_v6_init_sock(struct sock *sk)
2044 1910
2045static int tcp_v6_destroy_sock(struct sock *sk) 1911static int tcp_v6_destroy_sock(struct sock *sk)
2046{ 1912{
2047 extern int tcp_v4_destroy_sock(struct sock *sk);
2048
2049 tcp_v4_destroy_sock(sk); 1913 tcp_v4_destroy_sock(sk);
2050 return inet6_destroy_sock(sk); 1914 return inet6_destroy_sock(sk);
2051} 1915}
@@ -2091,18 +1955,20 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
2091 unsigned long timer_expires; 1955 unsigned long timer_expires;
2092 struct inet_sock *inet = inet_sk(sp); 1956 struct inet_sock *inet = inet_sk(sp);
2093 struct tcp_sock *tp = tcp_sk(sp); 1957 struct tcp_sock *tp = tcp_sk(sp);
1958 const struct inet_connection_sock *icsk = inet_csk(sp);
2094 struct ipv6_pinfo *np = inet6_sk(sp); 1959 struct ipv6_pinfo *np = inet6_sk(sp);
2095 1960
2096 dest = &np->daddr; 1961 dest = &np->daddr;
2097 src = &np->rcv_saddr; 1962 src = &np->rcv_saddr;
2098 destp = ntohs(inet->dport); 1963 destp = ntohs(inet->dport);
2099 srcp = ntohs(inet->sport); 1964 srcp = ntohs(inet->sport);
2100 if (tp->pending == TCP_TIME_RETRANS) { 1965
1966 if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
2101 timer_active = 1; 1967 timer_active = 1;
2102 timer_expires = tp->timeout; 1968 timer_expires = icsk->icsk_timeout;
2103 } else if (tp->pending == TCP_TIME_PROBE0) { 1969 } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
2104 timer_active = 4; 1970 timer_active = 4;
2105 timer_expires = tp->timeout; 1971 timer_expires = icsk->icsk_timeout;
2106 } else if (timer_pending(&sp->sk_timer)) { 1972 } else if (timer_pending(&sp->sk_timer)) {
2107 timer_active = 2; 1973 timer_active = 2;
2108 timer_expires = sp->sk_timer.expires; 1974 timer_expires = sp->sk_timer.expires;
@@ -2123,28 +1989,31 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
2123 tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq, 1989 tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq,
2124 timer_active, 1990 timer_active,
2125 jiffies_to_clock_t(timer_expires - jiffies), 1991 jiffies_to_clock_t(timer_expires - jiffies),
2126 tp->retransmits, 1992 icsk->icsk_retransmits,
2127 sock_i_uid(sp), 1993 sock_i_uid(sp),
2128 tp->probes_out, 1994 icsk->icsk_probes_out,
2129 sock_i_ino(sp), 1995 sock_i_ino(sp),
2130 atomic_read(&sp->sk_refcnt), sp, 1996 atomic_read(&sp->sk_refcnt), sp,
2131 tp->rto, tp->ack.ato, (tp->ack.quick<<1)|tp->ack.pingpong, 1997 icsk->icsk_rto,
1998 icsk->icsk_ack.ato,
1999 (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
2132 tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh 2000 tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh
2133 ); 2001 );
2134} 2002}
2135 2003
2136static void get_timewait6_sock(struct seq_file *seq, 2004static void get_timewait6_sock(struct seq_file *seq,
2137 struct tcp_tw_bucket *tw, int i) 2005 struct inet_timewait_sock *tw, int i)
2138{ 2006{
2139 struct in6_addr *dest, *src; 2007 struct in6_addr *dest, *src;
2140 __u16 destp, srcp; 2008 __u16 destp, srcp;
2009 struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw);
2141 int ttd = tw->tw_ttd - jiffies; 2010 int ttd = tw->tw_ttd - jiffies;
2142 2011
2143 if (ttd < 0) 2012 if (ttd < 0)
2144 ttd = 0; 2013 ttd = 0;
2145 2014
2146 dest = &tw->tw_v6_daddr; 2015 dest = &tcp6tw->tw_v6_daddr;
2147 src = &tw->tw_v6_rcv_saddr; 2016 src = &tcp6tw->tw_v6_rcv_saddr;
2148 destp = ntohs(tw->tw_dport); 2017 destp = ntohs(tw->tw_dport);
2149 srcp = ntohs(tw->tw_sport); 2018 srcp = ntohs(tw->tw_sport);
2150 2019
@@ -2219,7 +2088,7 @@ struct proto tcpv6_prot = {
2219 .close = tcp_close, 2088 .close = tcp_close,
2220 .connect = tcp_v6_connect, 2089 .connect = tcp_v6_connect,
2221 .disconnect = tcp_disconnect, 2090 .disconnect = tcp_disconnect,
2222 .accept = tcp_accept, 2091 .accept = inet_csk_accept,
2223 .ioctl = tcp_ioctl, 2092 .ioctl = tcp_ioctl,
2224 .init = tcp_v6_init_sock, 2093 .init = tcp_v6_init_sock,
2225 .destroy = tcp_v6_destroy_sock, 2094 .destroy = tcp_v6_destroy_sock,
@@ -2236,11 +2105,13 @@ struct proto tcpv6_prot = {
2236 .sockets_allocated = &tcp_sockets_allocated, 2105 .sockets_allocated = &tcp_sockets_allocated,
2237 .memory_allocated = &tcp_memory_allocated, 2106 .memory_allocated = &tcp_memory_allocated,
2238 .memory_pressure = &tcp_memory_pressure, 2107 .memory_pressure = &tcp_memory_pressure,
2108 .orphan_count = &tcp_orphan_count,
2239 .sysctl_mem = sysctl_tcp_mem, 2109 .sysctl_mem = sysctl_tcp_mem,
2240 .sysctl_wmem = sysctl_tcp_wmem, 2110 .sysctl_wmem = sysctl_tcp_wmem,
2241 .sysctl_rmem = sysctl_tcp_rmem, 2111 .sysctl_rmem = sysctl_tcp_rmem,
2242 .max_header = MAX_TCP_HEADER, 2112 .max_header = MAX_TCP_HEADER,
2243 .obj_size = sizeof(struct tcp6_sock), 2113 .obj_size = sizeof(struct tcp6_sock),
2114 .twsk_obj_size = sizeof(struct tcp6_timewait_sock),
2244 .rsk_prot = &tcp6_request_sock_ops, 2115 .rsk_prot = &tcp6_request_sock_ops,
2245}; 2116};
2246 2117
@@ -2250,8 +2121,6 @@ static struct inet6_protocol tcpv6_protocol = {
2250 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 2121 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
2251}; 2122};
2252 2123
2253extern struct proto_ops inet6_stream_ops;
2254
2255static struct inet_protosw tcpv6_protosw = { 2124static struct inet_protosw tcpv6_protosw = {
2256 .type = SOCK_STREAM, 2125 .type = SOCK_STREAM,
2257 .protocol = IPPROTO_TCP, 2126 .protocol = IPPROTO_TCP,
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index eff050ac7049..390d750449ce 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -51,6 +51,7 @@
51#include <net/udp.h> 51#include <net/udp.h>
52#include <net/raw.h> 52#include <net/raw.h>
53#include <net/inet_common.h> 53#include <net/inet_common.h>
54#include <net/tcp_states.h>
54 55
55#include <net/ip6_checksum.h> 56#include <net/ip6_checksum.h>
56#include <net/xfrm.h> 57#include <net/xfrm.h>
@@ -58,7 +59,7 @@
58#include <linux/proc_fs.h> 59#include <linux/proc_fs.h>
59#include <linux/seq_file.h> 60#include <linux/seq_file.h>
60 61
61DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6); 62DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
62 63
63/* Grrr, addr_type already calculated by caller, but I don't want 64/* Grrr, addr_type already calculated by caller, but I don't want
64 * to add some silly "cookie" argument to this method just for that. 65 * to add some silly "cookie" argument to this method just for that.
@@ -477,8 +478,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
477 /* RFC 2460 section 8.1 says that we SHOULD log 478 /* RFC 2460 section 8.1 says that we SHOULD log
478 this error. Well, it is reasonable. 479 this error. Well, it is reasonable.
479 */ 480 */
480 LIMIT_NETDEBUG( 481 LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0\n");
481 printk(KERN_INFO "IPv6: udp checksum is 0\n"));
482 goto discard; 482 goto discard;
483 } 483 }
484 484
@@ -493,7 +493,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
493 if (skb->ip_summed==CHECKSUM_HW) { 493 if (skb->ip_summed==CHECKSUM_HW) {
494 skb->ip_summed = CHECKSUM_UNNECESSARY; 494 skb->ip_summed = CHECKSUM_UNNECESSARY;
495 if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) { 495 if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) {
496 LIMIT_NETDEBUG(printk(KERN_DEBUG "udp v6 hw csum failure.\n")); 496 LIMIT_NETDEBUG(KERN_DEBUG "udp v6 hw csum failure.\n");
497 skb->ip_summed = CHECKSUM_NONE; 497 skb->ip_summed = CHECKSUM_NONE;
498 } 498 }
499 } 499 }
@@ -825,7 +825,7 @@ back_from_confirm:
825 /* ... which is an evident application bug. --ANK */ 825 /* ... which is an evident application bug. --ANK */
826 release_sock(sk); 826 release_sock(sk);
827 827
828 LIMIT_NETDEBUG(printk(KERN_DEBUG "udp cork app bug 2\n")); 828 LIMIT_NETDEBUG(KERN_DEBUG "udp cork app bug 2\n");
829 err = -EINVAL; 829 err = -EINVAL;
830 goto out; 830 goto out;
831 } 831 }
@@ -1054,8 +1054,6 @@ struct proto udpv6_prot = {
1054 .obj_size = sizeof(struct udp6_sock), 1054 .obj_size = sizeof(struct udp6_sock),
1055}; 1055};
1056 1056
1057extern struct proto_ops inet6_dgram_ops;
1058
1059static struct inet_protosw udpv6_protosw = { 1057static struct inet_protosw udpv6_protosw = {
1060 .type = SOCK_DGRAM, 1058 .type = SOCK_DGRAM,
1061 .protocol = IPPROTO_UDP, 1059 .protocol = IPPROTO_UDP,
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 60c26c87277e..fbef7826a74f 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -79,7 +79,7 @@ static u32 xfrm6_tunnel_spi;
79#define XFRM6_TUNNEL_SPI_MIN 1 79#define XFRM6_TUNNEL_SPI_MIN 1
80#define XFRM6_TUNNEL_SPI_MAX 0xffffffff 80#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
81 81
82static kmem_cache_t *xfrm6_tunnel_spi_kmem; 82static kmem_cache_t *xfrm6_tunnel_spi_kmem __read_mostly;
83 83
84#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256 84#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
85#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256 85#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256