aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Kconfig1
-rw-r--r--net/ipv6/addrconf.c10
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/anycast.c1
-rw-r--r--net/ipv6/datagram.c1
-rw-r--r--net/ipv6/exthdrs.c1
-rw-r--r--net/ipv6/icmp.c1
-rw-r--r--net/ipv6/inet6_hashtables.c2
-rw-r--r--net/ipv6/ip6_input.c1
-rw-r--r--net/ipv6/ip6_tunnel.c6
-rw-r--r--net/ipv6/ipv6_sockglue.c1
-rw-r--r--net/ipv6/netfilter/ip6_queue.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c1
-rw-r--r--net/ipv6/proc.c1
-rw-r--r--net/ipv6/protocol.c1
-rw-r--r--net/ipv6/raw.c1
-rw-r--r--net/ipv6/sit.c31
-rw-r--r--net/ipv6/sysctl_net_ipv6.c2
-rw-r--r--net/ipv6/tunnel6.c43
-rw-r--r--net/ipv6/udp.c1
-rw-r--r--net/ipv6/xfrm6_input.c3
-rw-r--r--net/ipv6/xfrm6_tunnel.c19
22 files changed, 84 insertions, 47 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index deb4101a2a81..79682efb14be 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -156,6 +156,7 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION
156config IPV6_SIT 156config IPV6_SIT
157 tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)" 157 tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)"
158 depends on IPV6 158 depends on IPV6
159 select INET_TUNNEL
159 default y 160 default y
160 ---help--- 161 ---help---
161 Tunneling means encapsulating data of one protocol type within 162 Tunneling means encapsulating data of one protocol type within
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index ea0755b09033..569a37d698f7 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -44,7 +44,6 @@
44#include <linux/types.h> 44#include <linux/types.h>
45#include <linux/socket.h> 45#include <linux/socket.h>
46#include <linux/sockios.h> 46#include <linux/sockios.h>
47#include <linux/sched.h>
48#include <linux/net.h> 47#include <linux/net.h>
49#include <linux/in6.h> 48#include <linux/in6.h>
50#include <linux/netdevice.h> 49#include <linux/netdevice.h>
@@ -3999,7 +3998,6 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
3999 return; 3998 return;
4000 for (i=0; t->addrconf_vars[i].data; i++) { 3999 for (i=0; t->addrconf_vars[i].data; i++) {
4001 t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf; 4000 t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
4002 t->addrconf_vars[i].de = NULL;
4003 t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */ 4001 t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
4004 } 4002 }
4005 if (dev) { 4003 if (dev) {
@@ -4022,15 +4020,11 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
4022 t->addrconf_dev[0].procname = dev_name; 4020 t->addrconf_dev[0].procname = dev_name;
4023 4021
4024 t->addrconf_dev[0].child = t->addrconf_vars; 4022 t->addrconf_dev[0].child = t->addrconf_vars;
4025 t->addrconf_dev[0].de = NULL;
4026 t->addrconf_conf_dir[0].child = t->addrconf_dev; 4023 t->addrconf_conf_dir[0].child = t->addrconf_dev;
4027 t->addrconf_conf_dir[0].de = NULL;
4028 t->addrconf_proto_dir[0].child = t->addrconf_conf_dir; 4024 t->addrconf_proto_dir[0].child = t->addrconf_conf_dir;
4029 t->addrconf_proto_dir[0].de = NULL;
4030 t->addrconf_root_dir[0].child = t->addrconf_proto_dir; 4025 t->addrconf_root_dir[0].child = t->addrconf_proto_dir;
4031 t->addrconf_root_dir[0].de = NULL;
4032 4026
4033 t->sysctl_header = register_sysctl_table(t->addrconf_root_dir, 0); 4027 t->sysctl_header = register_sysctl_table(t->addrconf_root_dir);
4034 if (t->sysctl_header == NULL) 4028 if (t->sysctl_header == NULL)
4035 goto free_procname; 4029 goto free_procname;
4036 else 4030 else
@@ -4115,7 +4109,7 @@ int __init addrconf_init(void)
4115 rtnetlink_links[PF_INET6] = inet6_rtnetlink_table; 4109 rtnetlink_links[PF_INET6] = inet6_rtnetlink_table;
4116#ifdef CONFIG_SYSCTL 4110#ifdef CONFIG_SYSCTL
4117 addrconf_sysctl.sysctl_header = 4111 addrconf_sysctl.sysctl_header =
4118 register_sysctl_table(addrconf_sysctl.addrconf_root_dir, 0); 4112 register_sysctl_table(addrconf_sysctl.addrconf_root_dir);
4119 addrconf_sysctl_register(NULL, &ipv6_devconf_dflt); 4113 addrconf_sysctl_register(NULL, &ipv6_devconf_dflt);
4120#endif 4114#endif
4121 4115
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index a006d242be76..3585d8fa7f02 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -28,7 +28,6 @@
28#include <linux/socket.h> 28#include <linux/socket.h>
29#include <linux/in.h> 29#include <linux/in.h>
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/sched.h>
32#include <linux/timer.h> 31#include <linux/timer.h>
33#include <linux/string.h> 32#include <linux/string.h>
34#include <linux/sockios.h> 33#include <linux/sockios.h>
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 6fb2e9d716c0..e5ef5979ade4 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -21,7 +21,6 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/socket.h> 22#include <linux/socket.h>
23#include <linux/sockios.h> 23#include <linux/sockios.h>
24#include <linux/sched.h>
25#include <linux/net.h> 24#include <linux/net.h>
26#include <linux/in6.h> 25#include <linux/in6.h>
27#include <linux/netdevice.h> 26#include <linux/netdevice.h>
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 5f54dec3e205..3b4e8dcf4c86 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -17,7 +17,6 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/interrupt.h> 20#include <linux/interrupt.h>
22#include <linux/socket.h> 21#include <linux/socket.h>
23#include <linux/sockios.h> 22#include <linux/sockios.h>
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 08313efc48c8..28e0c6568272 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -27,7 +27,6 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/socket.h> 28#include <linux/socket.h>
29#include <linux/sockios.h> 29#include <linux/sockios.h>
30#include <linux/sched.h>
31#include <linux/net.h> 30#include <linux/net.h>
32#include <linux/netdevice.h> 31#include <linux/netdevice.h>
33#include <linux/in6.h> 32#include <linux/in6.h>
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 9377fea02682..edfe98bf64c3 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -37,7 +37,6 @@
37#include <linux/socket.h> 37#include <linux/socket.h>
38#include <linux/in.h> 38#include <linux/in.h>
39#include <linux/kernel.h> 39#include <linux/kernel.h>
40#include <linux/sched.h>
41#include <linux/sockios.h> 40#include <linux/sockios.h>
42#include <linux/net.h> 41#include <linux/net.h>
43#include <linux/skbuff.h> 42#include <linux/skbuff.h>
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 30b16da739c2..ae6b0e7eb488 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -172,7 +172,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
172 const struct in6_addr *saddr = &np->daddr; 172 const struct in6_addr *saddr = &np->daddr;
173 const int dif = sk->sk_bound_dev_if; 173 const int dif = sk->sk_bound_dev_if;
174 const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport); 174 const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
175 const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, 175 const unsigned int hash = inet6_ehashfn(daddr, lport, saddr,
176 inet->dport); 176 inet->dport);
177 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); 177 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
178 struct sock *sk2; 178 struct sock *sk2;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 4fdded0e545a..11bfc7c43182 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -25,7 +25,6 @@
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/socket.h> 26#include <linux/socket.h>
27#include <linux/sockios.h> 27#include <linux/sockios.h>
28#include <linux/sched.h>
29#include <linux/net.h> 28#include <linux/net.h>
30#include <linux/netdevice.h> 29#include <linux/netdevice.h>
31#include <linux/in6.h> 30#include <linux/in6.h>
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 367b74832986..662edb826899 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1128,7 +1128,7 @@ static int __init ip6_tunnel_init(void)
1128{ 1128{
1129 int err; 1129 int err;
1130 1130
1131 if (xfrm6_tunnel_register(&ip6ip6_handler)) { 1131 if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) {
1132 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n"); 1132 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n");
1133 return -EAGAIN; 1133 return -EAGAIN;
1134 } 1134 }
@@ -1147,7 +1147,7 @@ static int __init ip6_tunnel_init(void)
1147 } 1147 }
1148 return 0; 1148 return 0;
1149fail: 1149fail:
1150 xfrm6_tunnel_deregister(&ip6ip6_handler); 1150 xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
1151 return err; 1151 return err;
1152} 1152}
1153 1153
@@ -1171,7 +1171,7 @@ static void __exit ip6ip6_destroy_tunnels(void)
1171 1171
1172static void __exit ip6_tunnel_cleanup(void) 1172static void __exit ip6_tunnel_cleanup(void)
1173{ 1173{
1174 if (xfrm6_tunnel_deregister(&ip6ip6_handler)) 1174 if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6))
1175 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); 1175 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
1176 1176
1177 rtnl_lock(); 1177 rtnl_lock();
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 3f1e779ea5c5..286c86735aed 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -31,7 +31,6 @@
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/socket.h> 32#include <linux/socket.h>
33#include <linux/sockios.h> 33#include <linux/sockios.h>
34#include <linux/sched.h>
35#include <linux/net.h> 34#include <linux/net.h>
36#include <linux/in6.h> 35#include <linux/in6.h>
37#include <linux/netdevice.h> 36#include <linux/netdevice.h>
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 58847d3b61e5..fdb30a5916e5 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -683,7 +683,7 @@ static int __init ip6_queue_init(void)
683 } 683 }
684 684
685 register_netdevice_notifier(&ipq_dev_notifier); 685 register_netdevice_notifier(&ipq_dev_notifier);
686 ipq_sysctl_header = register_sysctl_table(ipq_root_table, 0); 686 ipq_sysctl_header = register_sysctl_table(ipq_root_table);
687 687
688 status = nf_register_queue_handler(PF_INET6, &nfqh); 688 status = nf_register_queue_handler(PF_INET6, &nfqh);
689 if (status < 0) { 689 if (status < 0) {
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 19bdb7cb8ff3..21f19cc719f3 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -17,7 +17,6 @@
17 */ 17 */
18 18
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/sched.h>
21#include <linux/timer.h> 20#include <linux/timer.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/netfilter.h> 22#include <linux/netfilter.h>
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index c82257dd04b6..fa3fb509f187 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -17,7 +17,6 @@
17 * as published by the Free Software Foundation; either version 17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version. 18 * 2 of the License, or (at your option) any later version.
19 */ 19 */
20#include <linux/sched.h>
21#include <linux/socket.h> 20#include <linux/socket.h>
22#include <linux/net.h> 21#include <linux/net.h>
23#include <linux/ipv6.h> 22#include <linux/ipv6.h>
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index ad0410c99675..ef43bd57baed 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -27,7 +27,6 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/socket.h> 28#include <linux/socket.h>
29#include <linux/sockios.h> 29#include <linux/sockios.h>
30#include <linux/sched.h>
31#include <linux/net.h> 30#include <linux/net.h>
32#include <linux/in6.h> 31#include <linux/in6.h>
33#include <linux/netdevice.h> 32#include <linux/netdevice.h>
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 1f8f6275a7e4..306d5d83c068 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -24,7 +24,6 @@
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/socket.h> 25#include <linux/socket.h>
26#include <linux/sockios.h> 26#include <linux/sockios.h>
27#include <linux/sched.h>
28#include <linux/net.h> 27#include <linux/net.h>
29#include <linux/in6.h> 28#include <linux/in6.h>
30#include <linux/netdevice.h> 29#include <linux/netdevice.h>
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 4d3cf301e1fc..08d6ed3396e4 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -24,7 +24,6 @@
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/socket.h> 25#include <linux/socket.h>
26#include <linux/sockios.h> 26#include <linux/sockios.h>
27#include <linux/sched.h>
28#include <linux/net.h> 27#include <linux/net.h>
29#include <linux/in6.h> 28#include <linux/in6.h>
30#include <linux/netdevice.h> 29#include <linux/netdevice.h>
@@ -216,7 +215,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
216} 215}
217 216
218 217
219static void ipip6_err(struct sk_buff *skb, u32 info) 218static int ipip6_err(struct sk_buff *skb, u32 info)
220{ 219{
221#ifndef I_WISH_WORLD_WERE_PERFECT 220#ifndef I_WISH_WORLD_WERE_PERFECT
222 221
@@ -228,21 +227,22 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
228 int type = skb->h.icmph->type; 227 int type = skb->h.icmph->type;
229 int code = skb->h.icmph->code; 228 int code = skb->h.icmph->code;
230 struct ip_tunnel *t; 229 struct ip_tunnel *t;
230 int err;
231 231
232 switch (type) { 232 switch (type) {
233 default: 233 default:
234 case ICMP_PARAMETERPROB: 234 case ICMP_PARAMETERPROB:
235 return; 235 return 0;
236 236
237 case ICMP_DEST_UNREACH: 237 case ICMP_DEST_UNREACH:
238 switch (code) { 238 switch (code) {
239 case ICMP_SR_FAILED: 239 case ICMP_SR_FAILED:
240 case ICMP_PORT_UNREACH: 240 case ICMP_PORT_UNREACH:
241 /* Impossible event. */ 241 /* Impossible event. */
242 return; 242 return 0;
243 case ICMP_FRAG_NEEDED: 243 case ICMP_FRAG_NEEDED:
244 /* Soft state for pmtu is maintained by IP core. */ 244 /* Soft state for pmtu is maintained by IP core. */
245 return; 245 return 0;
246 default: 246 default:
247 /* All others are translated to HOST_UNREACH. 247 /* All others are translated to HOST_UNREACH.
248 rfc2003 contains "deep thoughts" about NET_UNREACH, 248 rfc2003 contains "deep thoughts" about NET_UNREACH,
@@ -253,14 +253,18 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
253 break; 253 break;
254 case ICMP_TIME_EXCEEDED: 254 case ICMP_TIME_EXCEEDED:
255 if (code != ICMP_EXC_TTL) 255 if (code != ICMP_EXC_TTL)
256 return; 256 return 0;
257 break; 257 break;
258 } 258 }
259 259
260 err = -ENOENT;
261
260 read_lock(&ipip6_lock); 262 read_lock(&ipip6_lock);
261 t = ipip6_tunnel_lookup(iph->daddr, iph->saddr); 263 t = ipip6_tunnel_lookup(iph->daddr, iph->saddr);
262 if (t == NULL || t->parms.iph.daddr == 0) 264 if (t == NULL || t->parms.iph.daddr == 0)
263 goto out; 265 goto out;
266
267 err = 0;
264 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) 268 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
265 goto out; 269 goto out;
266 270
@@ -271,7 +275,7 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
271 t->err_time = jiffies; 275 t->err_time = jiffies;
272out: 276out:
273 read_unlock(&ipip6_lock); 277 read_unlock(&ipip6_lock);
274 return; 278 return err;
275#else 279#else
276 struct iphdr *iph = (struct iphdr*)dp; 280 struct iphdr *iph = (struct iphdr*)dp;
277 int hlen = iph->ihl<<2; 281 int hlen = iph->ihl<<2;
@@ -332,7 +336,7 @@ out:
332 /* Prepare fake skb to feed it to icmpv6_send */ 336 /* Prepare fake skb to feed it to icmpv6_send */
333 skb2 = skb_clone(skb, GFP_ATOMIC); 337 skb2 = skb_clone(skb, GFP_ATOMIC);
334 if (skb2 == NULL) 338 if (skb2 == NULL)
335 return; 339 return 0;
336 dst_release(skb2->dst); 340 dst_release(skb2->dst);
337 skb2->dst = NULL; 341 skb2->dst = NULL;
338 skb_pull(skb2, skb->data - (u8*)iph6); 342 skb_pull(skb2, skb->data - (u8*)iph6);
@@ -355,7 +359,7 @@ out:
355 } 359 }
356 } 360 }
357 kfree_skb(skb2); 361 kfree_skb(skb2);
358 return; 362 return 0;
359#endif 363#endif
360} 364}
361 365
@@ -791,9 +795,10 @@ static int __init ipip6_fb_tunnel_init(struct net_device *dev)
791 return 0; 795 return 0;
792} 796}
793 797
794static struct net_protocol sit_protocol = { 798static struct xfrm_tunnel sit_handler = {
795 .handler = ipip6_rcv, 799 .handler = ipip6_rcv,
796 .err_handler = ipip6_err, 800 .err_handler = ipip6_err,
801 .priority = 1,
797}; 802};
798 803
799static void __exit sit_destroy_tunnels(void) 804static void __exit sit_destroy_tunnels(void)
@@ -812,7 +817,7 @@ static void __exit sit_destroy_tunnels(void)
812 817
813static void __exit sit_cleanup(void) 818static void __exit sit_cleanup(void)
814{ 819{
815 inet_del_protocol(&sit_protocol, IPPROTO_IPV6); 820 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
816 821
817 rtnl_lock(); 822 rtnl_lock();
818 sit_destroy_tunnels(); 823 sit_destroy_tunnels();
@@ -826,7 +831,7 @@ static int __init sit_init(void)
826 831
827 printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); 832 printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n");
828 833
829 if (inet_add_protocol(&sit_protocol, IPPROTO_IPV6) < 0) { 834 if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) {
830 printk(KERN_INFO "sit init: Can't add protocol\n"); 835 printk(KERN_INFO "sit init: Can't add protocol\n");
831 return -EAGAIN; 836 return -EAGAIN;
832 } 837 }
@@ -848,7 +853,7 @@ static int __init sit_init(void)
848 err2: 853 err2:
849 free_netdev(ipip6_fb_tunnel_dev); 854 free_netdev(ipip6_fb_tunnel_dev);
850 err1: 855 err1:
851 inet_del_protocol(&sit_protocol, IPPROTO_IPV6); 856 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
852 goto out; 857 goto out;
853} 858}
854 859
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 25e8e7783fee..3fb44277207b 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -107,7 +107,7 @@ static ctl_table ipv6_root_table[] = {
107 107
108void ipv6_sysctl_register(void) 108void ipv6_sysctl_register(void)
109{ 109{
110 ipv6_sysctl_header = register_sysctl_table(ipv6_root_table, 0); 110 ipv6_sysctl_header = register_sysctl_table(ipv6_root_table);
111} 111}
112 112
113void ipv6_sysctl_unregister(void) 113void ipv6_sysctl_unregister(void)
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 918d07dd1219..23e2809878ae 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -30,9 +30,10 @@
30#include <net/xfrm.h> 30#include <net/xfrm.h>
31 31
32static struct xfrm6_tunnel *tunnel6_handlers; 32static struct xfrm6_tunnel *tunnel6_handlers;
33static struct xfrm6_tunnel *tunnel46_handlers;
33static DEFINE_MUTEX(tunnel6_mutex); 34static DEFINE_MUTEX(tunnel6_mutex);
34 35
35int xfrm6_tunnel_register(struct xfrm6_tunnel *handler) 36int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family)
36{ 37{
37 struct xfrm6_tunnel **pprev; 38 struct xfrm6_tunnel **pprev;
38 int ret = -EEXIST; 39 int ret = -EEXIST;
@@ -40,7 +41,8 @@ int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
40 41
41 mutex_lock(&tunnel6_mutex); 42 mutex_lock(&tunnel6_mutex);
42 43
43 for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) { 44 for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
45 *pprev; pprev = &(*pprev)->next) {
44 if ((*pprev)->priority > priority) 46 if ((*pprev)->priority > priority)
45 break; 47 break;
46 if ((*pprev)->priority == priority) 48 if ((*pprev)->priority == priority)
@@ -60,14 +62,15 @@ err:
60 62
61EXPORT_SYMBOL(xfrm6_tunnel_register); 63EXPORT_SYMBOL(xfrm6_tunnel_register);
62 64
63int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler) 65int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
64{ 66{
65 struct xfrm6_tunnel **pprev; 67 struct xfrm6_tunnel **pprev;
66 int ret = -ENOENT; 68 int ret = -ENOENT;
67 69
68 mutex_lock(&tunnel6_mutex); 70 mutex_lock(&tunnel6_mutex);
69 71
70 for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) { 72 for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
73 *pprev; pprev = &(*pprev)->next) {
71 if (*pprev == handler) { 74 if (*pprev == handler) {
72 *pprev = handler->next; 75 *pprev = handler->next;
73 ret = 0; 76 ret = 0;
@@ -103,6 +106,25 @@ drop:
103 return 0; 106 return 0;
104} 107}
105 108
109static int tunnel46_rcv(struct sk_buff **pskb)
110{
111 struct sk_buff *skb = *pskb;
112 struct xfrm6_tunnel *handler;
113
114 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
115 goto drop;
116
117 for (handler = tunnel46_handlers; handler; handler = handler->next)
118 if (!handler->handler(skb))
119 return 0;
120
121 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev);
122
123drop:
124 kfree_skb(skb);
125 return 0;
126}
127
106static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 128static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
107 int type, int code, int offset, __be32 info) 129 int type, int code, int offset, __be32 info)
108{ 130{
@@ -119,17 +141,30 @@ static struct inet6_protocol tunnel6_protocol = {
119 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 141 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
120}; 142};
121 143
144static struct inet6_protocol tunnel46_protocol = {
145 .handler = tunnel46_rcv,
146 .err_handler = tunnel6_err,
147 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
148};
149
122static int __init tunnel6_init(void) 150static int __init tunnel6_init(void)
123{ 151{
124 if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) { 152 if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) {
125 printk(KERN_ERR "tunnel6 init(): can't add protocol\n"); 153 printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
126 return -EAGAIN; 154 return -EAGAIN;
127 } 155 }
156 if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) {
157 printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
158 inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6);
159 return -EAGAIN;
160 }
128 return 0; 161 return 0;
129} 162}
130 163
131static void __exit tunnel6_fini(void) 164static void __exit tunnel6_fini(void)
132{ 165{
166 if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP))
167 printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
133 if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6)) 168 if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6))
134 printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); 169 printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
135} 170}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index ccf2f4d196be..0ad471909881 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -27,7 +27,6 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/socket.h> 28#include <linux/socket.h>
29#include <linux/sockios.h> 29#include <linux/sockios.h>
30#include <linux/sched.h>
31#include <linux/net.h> 30#include <linux/net.h>
32#include <linux/in6.h> 31#include <linux/in6.h>
33#include <linux/netdevice.h> 32#include <linux/netdevice.h>
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 25250147bdc3..31f651f95096 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -40,7 +40,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
40 if (xfrm_nr == XFRM_MAX_DEPTH) 40 if (xfrm_nr == XFRM_MAX_DEPTH)
41 goto drop; 41 goto drop;
42 42
43 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, nexthdr, AF_INET6); 43 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
44 nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6);
44 if (x == NULL) 45 if (x == NULL)
45 goto drop; 46 goto drop;
46 spin_lock(&x->lock); 47 spin_lock(&x->lock);
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index fb0228772f01..ee4b84a33ff4 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -339,17 +339,29 @@ static struct xfrm6_tunnel xfrm6_tunnel_handler = {
339 .priority = 2, 339 .priority = 2,
340}; 340};
341 341
342static struct xfrm6_tunnel xfrm46_tunnel_handler = {
343 .handler = xfrm6_tunnel_rcv,
344 .err_handler = xfrm6_tunnel_err,
345 .priority = 2,
346};
347
342static int __init xfrm6_tunnel_init(void) 348static int __init xfrm6_tunnel_init(void)
343{ 349{
344 if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) 350 if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
345 return -EAGAIN; 351 return -EAGAIN;
346 352
347 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) { 353 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) {
354 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
355 return -EAGAIN;
356 }
357 if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) {
358 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
348 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 359 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
349 return -EAGAIN; 360 return -EAGAIN;
350 } 361 }
351 if (xfrm6_tunnel_spi_init() < 0) { 362 if (xfrm6_tunnel_spi_init() < 0) {
352 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); 363 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
364 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
353 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 365 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
354 return -EAGAIN; 366 return -EAGAIN;
355 } 367 }
@@ -359,7 +371,8 @@ static int __init xfrm6_tunnel_init(void)
359static void __exit xfrm6_tunnel_fini(void) 371static void __exit xfrm6_tunnel_fini(void)
360{ 372{
361 xfrm6_tunnel_spi_fini(); 373 xfrm6_tunnel_spi_fini();
362 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); 374 xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
375 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
363 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 376 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
364} 377}
365 378