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
config IPV6_SIT
tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)"
depends on IPV6
+ select INET_TUNNEL
default y
---help---
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 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/sched.h>
#include <linux/net.h>
#include <linux/in6.h>
#include <linux/netdevice.h>
@@ -3999,7 +3998,6 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
return;
for (i=0; t->addrconf_vars[i].data; i++) {
t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
- t->addrconf_vars[i].de = NULL;
t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
}
if (dev) {
@@ -4022,15 +4020,11 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
t->addrconf_dev[0].procname = dev_name;
t->addrconf_dev[0].child = t->addrconf_vars;
- t->addrconf_dev[0].de = NULL;
t->addrconf_conf_dir[0].child = t->addrconf_dev;
- t->addrconf_conf_dir[0].de = NULL;
t->addrconf_proto_dir[0].child = t->addrconf_conf_dir;
- t->addrconf_proto_dir[0].de = NULL;
t->addrconf_root_dir[0].child = t->addrconf_proto_dir;
- t->addrconf_root_dir[0].de = NULL;
- t->sysctl_header = register_sysctl_table(t->addrconf_root_dir, 0);
+ t->sysctl_header = register_sysctl_table(t->addrconf_root_dir);
if (t->sysctl_header == NULL)
goto free_procname;
else
@@ -4115,7 +4109,7 @@ int __init addrconf_init(void)
rtnetlink_links[PF_INET6] = inet6_rtnetlink_table;
#ifdef CONFIG_SYSCTL
addrconf_sysctl.sysctl_header =
- register_sysctl_table(addrconf_sysctl.addrconf_root_dir, 0);
+ register_sysctl_table(addrconf_sysctl.addrconf_root_dir);
addrconf_sysctl_register(NULL, &ipv6_devconf_dflt);
#endif
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 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
#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 @@
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/sched.h>
#include <linux/net.h>
#include <linux/in6.h>
#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 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/socket.h>
#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 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/sched.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#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 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/sockios.h>
#include <linux/net.h>
#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,
const struct in6_addr *saddr = &np->daddr;
const int dif = sk->sk_bound_dev_if;
const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
- const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr,
+ const unsigned int hash = inet6_ehashfn(daddr, lport, saddr,
inet->dport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
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 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/sched.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#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)
{
int err;
- if (xfrm6_tunnel_register(&ip6ip6_handler)) {
+ if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) {
printk(KERN_ERR "ip6ip6 init: can't register tunnel\n");
return -EAGAIN;
}
@@ -1147,7 +1147,7 @@ static int __init ip6_tunnel_init(void)
}
return 0;
fail:
- xfrm6_tunnel_deregister(&ip6ip6_handler);
+ xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
return err;
}
@@ -1171,7 +1171,7 @@ static void __exit ip6ip6_destroy_tunnels(void)
static void __exit ip6_tunnel_cleanup(void)
{
- if (xfrm6_tunnel_deregister(&ip6ip6_handler))
+ if (xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6))
printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
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 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/sched.h>
#include <linux/net.h>
#include <linux/in6.h>
#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)
}
register_netdevice_notifier(&ipq_dev_notifier);
- ipq_sysctl_header = register_sysctl_table(ipq_root_table, 0);
+ ipq_sysctl_header = register_sysctl_table(ipq_root_table);
status = nf_register_queue_handler(PF_INET6, &nfqh);
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 @@
*/
#include <linux/types.h>
-#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/module.h>
#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 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/sched.h>
#include <linux/socket.h>
#include <linux/net.h>
#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 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/sched.h>
#include <linux/net.h>
#include <linux/in6.h>
#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 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/sched.h>
#include <linux/net.h>
#include <linux/in6.h>
#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 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/sched.h>
#include <linux/net.h>
#include <linux/in6.h>
#include <linux/netdevice.h>
@@ -216,7 +215,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
}
-static void ipip6_err(struct sk_buff *skb, u32 info)
+static int ipip6_err(struct sk_buff *skb, u32 info)
{
#ifndef I_WISH_WORLD_WERE_PERFECT
@@ -228,21 +227,22 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
int type = skb->h.icmph->type;
int code = skb->h.icmph->code;
struct ip_tunnel *t;
+ int err;
switch (type) {
default:
case ICMP_PARAMETERPROB:
- return;
+ return 0;
case ICMP_DEST_UNREACH:
switch (code) {
case ICMP_SR_FAILED:
case ICMP_PORT_UNREACH:
/* Impossible event. */
- return;
+ return 0;
case ICMP_FRAG_NEEDED:
/* Soft state for pmtu is maintained by IP core. */
- return;
+ return 0;
default:
/* All others are translated to HOST_UNREACH.
rfc2003 contains "deep thoughts" about NET_UNREACH,
@@ -253,14 +253,18 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
break;
case ICMP_TIME_EXCEEDED:
if (code != ICMP_EXC_TTL)
- return;
+ return 0;
break;
}
+ err = -ENOENT;
+
read_lock(&ipip6_lock);
t = ipip6_tunnel_lookup(iph->daddr, iph->saddr);
if (t == NULL || t->parms.iph.daddr == 0)
goto out;
+
+ err = 0;
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
goto out;
@@ -271,7 +275,7 @@ static void ipip6_err(struct sk_buff *skb, u32 info)
t->err_time = jiffies;
out:
read_unlock(&ipip6_lock);
- return;
+ return err;
#else
struct iphdr *iph = (struct iphdr*)dp;
int hlen = iph->ihl<<2;
@@ -332,7 +336,7 @@ out:
/* Prepare fake skb to feed it to icmpv6_send */
skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2 == NULL)
- return;
+ return 0;
dst_release(skb2->dst);
skb2->dst = NULL;
skb_pull(skb2, skb->data - (u8*)iph6);
@@ -355,7 +359,7 @@ out:
}
}
kfree_skb(skb2);
- return;
+ return 0;
#endif
}
@@ -791,9 +795,10 @@ static int __init ipip6_fb_tunnel_init(struct net_device *dev)
return 0;
}
-static struct net_protocol sit_protocol = {
+static struct xfrm_tunnel sit_handler = {
.handler = ipip6_rcv,
.err_handler = ipip6_err,
+ .priority = 1,
};
static void __exit sit_destroy_tunnels(void)
@@ -812,7 +817,7 @@ static void __exit sit_destroy_tunnels(void)
static void __exit sit_cleanup(void)
{
- inet_del_protocol(&sit_protocol, IPPROTO_IPV6);
+ xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
rtnl_lock();
sit_destroy_tunnels();
@@ -826,7 +831,7 @@ static int __init sit_init(void)
printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n");
- if (inet_add_protocol(&sit_protocol, IPPROTO_IPV6) < 0) {
+ if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) {
printk(KERN_INFO "sit init: Can't add protocol\n");
return -EAGAIN;
}
@@ -848,7 +853,7 @@ static int __init sit_init(void)
err2:
free_netdev(ipip6_fb_tunnel_dev);
err1:
- inet_del_protocol(&sit_protocol, IPPROTO_IPV6);
+ xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
goto out;
}
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[] = {
void ipv6_sysctl_register(void)
{
- ipv6_sysctl_header = register_sysctl_table(ipv6_root_table, 0);
+ ipv6_sysctl_header = register_sysctl_table(ipv6_root_table);
}
void 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 @@
#include <net/xfrm.h>
static struct xfrm6_tunnel *tunnel6_handlers;
+static struct xfrm6_tunnel *tunnel46_handlers;
static DEFINE_MUTEX(tunnel6_mutex);
-int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
+int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family)
{
struct xfrm6_tunnel **pprev;
int ret = -EEXIST;
@@ -40,7 +41,8 @@ int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
mutex_lock(&tunnel6_mutex);
- for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) {
+ for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
+ *pprev; pprev = &(*pprev)->next) {
if ((*pprev)->priority > priority)
break;
if ((*pprev)->priority == priority)
@@ -60,14 +62,15 @@ err:
EXPORT_SYMBOL(xfrm6_tunnel_register);
-int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler)
+int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
{
struct xfrm6_tunnel **pprev;
int ret = -ENOENT;
mutex_lock(&tunnel6_mutex);
- for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) {
+ for (pprev = (family == AF_INET6) ? &tunnel6_handlers : &tunnel46_handlers;
+ *pprev; pprev = &(*pprev)->next) {
if (*pprev == handler) {
*pprev = handler->next;
ret = 0;
@@ -103,6 +106,25 @@ drop:
return 0;
}
+static int tunnel46_rcv(struct sk_buff **pskb)
+{
+ struct sk_buff *skb = *pskb;
+ struct xfrm6_tunnel *handler;
+
+ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+ goto drop;
+
+ for (handler = tunnel46_handlers; handler; handler = handler->next)
+ if (!handler->handler(skb))
+ return 0;
+
+ icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, skb->dev);
+
+drop:
+ kfree_skb(skb);
+ return 0;
+}
+
static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
int type, int code, int offset, __be32 info)
{
@@ -119,17 +141,30 @@ static struct inet6_protocol tunnel6_protocol = {
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};
+static struct inet6_protocol tunnel46_protocol = {
+ .handler = tunnel46_rcv,
+ .err_handler = tunnel6_err,
+ .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
+};
+
static int __init tunnel6_init(void)
{
if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) {
printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
return -EAGAIN;
}
+ if (inet6_add_protocol(&tunnel46_protocol, IPPROTO_IPIP)) {
+ printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
+ inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6);
+ return -EAGAIN;
+ }
return 0;
}
static void __exit tunnel6_fini(void)
{
+ if (inet6_del_protocol(&tunnel46_protocol, IPPROTO_IPIP))
+ printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6))
printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
}
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 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/sched.h>
#include <linux/net.h>
#include <linux/in6.h>
#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)
if (xfrm_nr == XFRM_MAX_DEPTH)
goto drop;
- x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, nexthdr, AF_INET6);
+ x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
+ nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6);
if (x == NULL)
goto drop;
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 = {
.priority = 2,
};
+static struct xfrm6_tunnel xfrm46_tunnel_handler = {
+ .handler = xfrm6_tunnel_rcv,
+ .err_handler = xfrm6_tunnel_err,
+ .priority = 2,
+};
+
static int __init xfrm6_tunnel_init(void)
{
if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
return -EAGAIN;
- if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) {
+ if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) {
+ xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
+ return -EAGAIN;
+ }
+ if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) {
+ xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
return -EAGAIN;
}
if (xfrm6_tunnel_spi_init() < 0) {
- xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
+ xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
+ xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
return -EAGAIN;
}
@@ -359,7 +371,8 @@ static int __init xfrm6_tunnel_init(void)
static void __exit xfrm6_tunnel_fini(void)
{
xfrm6_tunnel_spi_fini();
- xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
+ xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET);
+ xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6);
xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
}