aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/xfrm4_tunnel.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-03-28 04:12:13 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-28 20:02:46 -0500
commitd2acc3479cbccd5cfbca6c787be713ef1de12ec6 (patch)
treeaa348e19e15027db9abdd2da175a0c9055047858 /net/ipv4/xfrm4_tunnel.c
parentf0088a50e7c49d1ba285c88fe06345f223652fd3 (diff)
[INET]: Introduce tunnel4/tunnel6
Basically this patch moves the generic tunnel protocol stuff out of xfrm4_tunnel/xfrm6_tunnel and moves it into the new files of tunnel4.c and tunnel6 respectively. The reason for this is that the problem that Hugo uncovered is only the tip of the iceberg. The real problem is that when we removed the dependency of ipip on xfrm4_tunnel we didn't really consider the module case at all. For instance, as it is it's possible to build both ipip and xfrm4_tunnel as modules and if the latter is loaded then ipip simply won't load. After considering the alternatives I've decided that the best way out of this is to restore the dependency of ipip on the non-xfrm-specific part of xfrm4_tunnel. This is acceptable IMHO because the intention of the removal was really to be able to use ipip without the xfrm subsystem. This is still preserved by this patch. So now both ipip/xfrm4_tunnel depend on the new tunnel4.c which handles the arbitration between the two. The order of processing is determined by a simple integer which ensures that ipip gets processed before xfrm4_tunnel. The situation for ICMP handling is a little bit more complicated since we may not have enough information to determine who it's for. It's not a big deal at the moment since the xfrm ICMP handlers are basically no-ops. In future we can deal with this when we look at ICMP caching in general. The user-visible change to this is the removal of the TUNNEL Kconfig prompts. This makes sense because it can only be used through IPCOMP as it stands. The addition of the new modules shouldn't introduce any problems since module dependency will cause them to be loaded. Oh and I also turned some unnecessary pskb's in IPv6 related to this patch to skb's. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/xfrm4_tunnel.c')
-rw-r--r--net/ipv4/xfrm4_tunnel.c79
1 files changed, 13 insertions, 66 deletions
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index b08d56b117f8..2d670935c2b5 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -26,64 +26,6 @@ static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, s
26 return 0; 26 return 0;
27} 27}
28 28
29static struct xfrm_tunnel *ipip_handler;
30static DEFINE_MUTEX(xfrm4_tunnel_mutex);
31
32int xfrm4_tunnel_register(struct xfrm_tunnel *handler)
33{
34 int ret;
35
36 mutex_lock(&xfrm4_tunnel_mutex);
37 ret = 0;
38 if (ipip_handler != NULL)
39 ret = -EINVAL;
40 if (!ret)
41 ipip_handler = handler;
42 mutex_unlock(&xfrm4_tunnel_mutex);
43
44 return ret;
45}
46
47EXPORT_SYMBOL(xfrm4_tunnel_register);
48
49int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler)
50{
51 int ret;
52
53 mutex_lock(&xfrm4_tunnel_mutex);
54 ret = 0;
55 if (ipip_handler != handler)
56 ret = -EINVAL;
57 if (!ret)
58 ipip_handler = NULL;
59 mutex_unlock(&xfrm4_tunnel_mutex);
60
61 synchronize_net();
62
63 return ret;
64}
65
66EXPORT_SYMBOL(xfrm4_tunnel_deregister);
67
68static int ipip_rcv(struct sk_buff *skb)
69{
70 struct xfrm_tunnel *handler = ipip_handler;
71
72 /* Tunnel devices take precedence. */
73 if (handler && handler->handler(skb) == 0)
74 return 0;
75
76 return xfrm4_rcv(skb);
77}
78
79static void ipip_err(struct sk_buff *skb, u32 info)
80{
81 struct xfrm_tunnel *handler = ipip_handler;
82
83 if (handler)
84 handler->err_handler(skb, info);
85}
86
87static int ipip_init_state(struct xfrm_state *x) 29static int ipip_init_state(struct xfrm_state *x)
88{ 30{
89 if (!x->props.mode) 31 if (!x->props.mode)
@@ -111,10 +53,15 @@ static struct xfrm_type ipip_type = {
111 .output = ipip_output 53 .output = ipip_output
112}; 54};
113 55
114static struct net_protocol ipip_protocol = { 56static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
115 .handler = ipip_rcv, 57{
116 .err_handler = ipip_err, 58 return -ENOENT;
117 .no_policy = 1, 59}
60
61static struct xfrm_tunnel xfrm_tunnel_handler = {
62 .handler = xfrm4_rcv,
63 .err_handler = xfrm_tunnel_err,
64 .priority = 2,
118}; 65};
119 66
120static int __init ipip_init(void) 67static int __init ipip_init(void)
@@ -123,8 +70,8 @@ static int __init ipip_init(void)
123 printk(KERN_INFO "ipip init: can't add xfrm type\n"); 70 printk(KERN_INFO "ipip init: can't add xfrm type\n");
124 return -EAGAIN; 71 return -EAGAIN;
125 } 72 }
126 if (inet_add_protocol(&ipip_protocol, IPPROTO_IPIP) < 0) { 73 if (xfrm4_tunnel_register(&xfrm_tunnel_handler)) {
127 printk(KERN_INFO "ipip init: can't add protocol\n"); 74 printk(KERN_INFO "ipip init: can't add xfrm handler\n");
128 xfrm_unregister_type(&ipip_type, AF_INET); 75 xfrm_unregister_type(&ipip_type, AF_INET);
129 return -EAGAIN; 76 return -EAGAIN;
130 } 77 }
@@ -133,8 +80,8 @@ static int __init ipip_init(void)
133 80
134static void __exit ipip_fini(void) 81static void __exit ipip_fini(void)
135{ 82{
136 if (inet_del_protocol(&ipip_protocol, IPPROTO_IPIP) < 0) 83 if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler))
137 printk(KERN_INFO "ipip close: can't remove protocol\n"); 84 printk(KERN_INFO "ipip close: can't remove xfrm handler\n");
138 if (xfrm_unregister_type(&ipip_type, AF_INET) < 0) 85 if (xfrm_unregister_type(&ipip_type, AF_INET) < 0)
139 printk(KERN_INFO "ipip close: can't remove xfrm type\n"); 86 printk(KERN_INFO "ipip close: can't remove xfrm type\n");
140} 87}