aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/sit.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r--net/ipv6/sit.c31
1 files changed, 18 insertions, 13 deletions
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