aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_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/ipv6/ip6_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/ipv6/ip6_tunnel.c')
-rw-r--r--net/ipv6/ip6_tunnel.c45
1 files changed, 10 insertions, 35 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 48597538db3f..ff9040c92556 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -44,7 +44,6 @@
44 44
45#include <net/ip.h> 45#include <net/ip.h>
46#include <net/ipv6.h> 46#include <net/ipv6.h>
47#include <net/protocol.h>
48#include <net/ip6_route.h> 47#include <net/ip6_route.h>
49#include <net/addrconf.h> 48#include <net/addrconf.h>
50#include <net/ip6_tunnel.h> 49#include <net/ip6_tunnel.h>
@@ -391,7 +390,7 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
391 * to the specifications in RFC 2473. 390 * to the specifications in RFC 2473.
392 **/ 391 **/
393 392
394static void 393static int
395ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 394ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
396 int type, int code, int offset, __u32 info) 395 int type, int code, int offset, __u32 info)
397{ 396{
@@ -402,6 +401,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
402 int rel_code = ICMPV6_ADDR_UNREACH; 401 int rel_code = ICMPV6_ADDR_UNREACH;
403 __u32 rel_info = 0; 402 __u32 rel_info = 0;
404 __u16 len; 403 __u16 len;
404 int err = -ENOENT;
405 405
406 /* If the packet doesn't contain the original IPv6 header we are 406 /* If the packet doesn't contain the original IPv6 header we are
407 in trouble since we might need the source address for further 407 in trouble since we might need the source address for further
@@ -411,6 +411,8 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
411 if ((t = ip6ip6_tnl_lookup(&ipv6h->daddr, &ipv6h->saddr)) == NULL) 411 if ((t = ip6ip6_tnl_lookup(&ipv6h->daddr, &ipv6h->saddr)) == NULL)
412 goto out; 412 goto out;
413 413
414 err = 0;
415
414 switch (type) { 416 switch (type) {
415 __u32 teli; 417 __u32 teli;
416 struct ipv6_tlv_tnl_enc_lim *tel; 418 struct ipv6_tlv_tnl_enc_lim *tel;
@@ -492,6 +494,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
492 } 494 }
493out: 495out:
494 read_unlock(&ip6ip6_lock); 496 read_unlock(&ip6ip6_lock);
497 return err;
495} 498}
496 499
497static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph, 500static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,
@@ -511,9 +514,8 @@ static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,
511 **/ 514 **/
512 515
513static int 516static int
514ip6ip6_rcv(struct sk_buff **pskb) 517ip6ip6_rcv(struct sk_buff *skb)
515{ 518{
516 struct sk_buff *skb = *pskb;
517 struct ipv6hdr *ipv6h; 519 struct ipv6hdr *ipv6h;
518 struct ip6_tnl *t; 520 struct ip6_tnl *t;
519 521
@@ -1112,39 +1114,12 @@ ip6ip6_fb_tnl_dev_init(struct net_device *dev)
1112 return 0; 1114 return 0;
1113} 1115}
1114 1116
1115#ifdef CONFIG_INET6_TUNNEL
1116static struct xfrm6_tunnel ip6ip6_handler = { 1117static struct xfrm6_tunnel ip6ip6_handler = {
1117 .handler = ip6ip6_rcv, 1118 .handler = ip6ip6_rcv,
1118 .err_handler = ip6ip6_err, 1119 .err_handler = ip6ip6_err,
1120 .priority = 1,
1119}; 1121};
1120 1122
1121static inline int ip6ip6_register(void)
1122{
1123 return xfrm6_tunnel_register(&ip6ip6_handler);
1124}
1125
1126static inline int ip6ip6_unregister(void)
1127{
1128 return xfrm6_tunnel_deregister(&ip6ip6_handler);
1129}
1130#else
1131static struct inet6_protocol xfrm6_tunnel_protocol = {
1132 .handler = ip6ip6_rcv,
1133 .err_handler = ip6ip6_err,
1134 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1135};
1136
1137static inline int ip6ip6_register(void)
1138{
1139 return inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6);
1140}
1141
1142static inline int ip6ip6_unregister(void)
1143{
1144 return inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6);
1145}
1146#endif
1147
1148/** 1123/**
1149 * ip6_tunnel_init - register protocol and reserve needed resources 1124 * ip6_tunnel_init - register protocol and reserve needed resources
1150 * 1125 *
@@ -1155,7 +1130,7 @@ static int __init ip6_tunnel_init(void)
1155{ 1130{
1156 int err; 1131 int err;
1157 1132
1158 if (ip6ip6_register() < 0) { 1133 if (xfrm6_tunnel_register(&ip6ip6_handler)) {
1159 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n"); 1134 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n");
1160 return -EAGAIN; 1135 return -EAGAIN;
1161 } 1136 }
@@ -1174,7 +1149,7 @@ static int __init ip6_tunnel_init(void)
1174 } 1149 }
1175 return 0; 1150 return 0;
1176fail: 1151fail:
1177 ip6ip6_unregister(); 1152 xfrm6_tunnel_deregister(&ip6ip6_handler);
1178 return err; 1153 return err;
1179} 1154}
1180 1155
@@ -1184,7 +1159,7 @@ fail:
1184 1159
1185static void __exit ip6_tunnel_cleanup(void) 1160static void __exit ip6_tunnel_cleanup(void)
1186{ 1161{
1187 if (ip6ip6_unregister() < 0) 1162 if (xfrm6_tunnel_deregister(&ip6ip6_handler))
1188 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); 1163 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
1189 1164
1190 unregister_netdev(ip6ip6_fb_tnl_dev); 1165 unregister_netdev(ip6ip6_fb_tnl_dev);