diff options
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r-- | net/ipv6/sit.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 4d3cf301e1fc..862ed7c52c38 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -216,7 +216,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | 218 | ||
219 | static void ipip6_err(struct sk_buff *skb, u32 info) | 219 | static int ipip6_err(struct sk_buff *skb, u32 info) |
220 | { | 220 | { |
221 | #ifndef I_WISH_WORLD_WERE_PERFECT | 221 | #ifndef I_WISH_WORLD_WERE_PERFECT |
222 | 222 | ||
@@ -228,21 +228,22 @@ static void ipip6_err(struct sk_buff *skb, u32 info) | |||
228 | int type = skb->h.icmph->type; | 228 | int type = skb->h.icmph->type; |
229 | int code = skb->h.icmph->code; | 229 | int code = skb->h.icmph->code; |
230 | struct ip_tunnel *t; | 230 | struct ip_tunnel *t; |
231 | int err; | ||
231 | 232 | ||
232 | switch (type) { | 233 | switch (type) { |
233 | default: | 234 | default: |
234 | case ICMP_PARAMETERPROB: | 235 | case ICMP_PARAMETERPROB: |
235 | return; | 236 | return 0; |
236 | 237 | ||
237 | case ICMP_DEST_UNREACH: | 238 | case ICMP_DEST_UNREACH: |
238 | switch (code) { | 239 | switch (code) { |
239 | case ICMP_SR_FAILED: | 240 | case ICMP_SR_FAILED: |
240 | case ICMP_PORT_UNREACH: | 241 | case ICMP_PORT_UNREACH: |
241 | /* Impossible event. */ | 242 | /* Impossible event. */ |
242 | return; | 243 | return 0; |
243 | case ICMP_FRAG_NEEDED: | 244 | case ICMP_FRAG_NEEDED: |
244 | /* Soft state for pmtu is maintained by IP core. */ | 245 | /* Soft state for pmtu is maintained by IP core. */ |
245 | return; | 246 | return 0; |
246 | default: | 247 | default: |
247 | /* All others are translated to HOST_UNREACH. | 248 | /* All others are translated to HOST_UNREACH. |
248 | rfc2003 contains "deep thoughts" about NET_UNREACH, | 249 | rfc2003 contains "deep thoughts" about NET_UNREACH, |
@@ -253,14 +254,18 @@ static void ipip6_err(struct sk_buff *skb, u32 info) | |||
253 | break; | 254 | break; |
254 | case ICMP_TIME_EXCEEDED: | 255 | case ICMP_TIME_EXCEEDED: |
255 | if (code != ICMP_EXC_TTL) | 256 | if (code != ICMP_EXC_TTL) |
256 | return; | 257 | return 0; |
257 | break; | 258 | break; |
258 | } | 259 | } |
259 | 260 | ||
261 | err = -ENOENT; | ||
262 | |||
260 | read_lock(&ipip6_lock); | 263 | read_lock(&ipip6_lock); |
261 | t = ipip6_tunnel_lookup(iph->daddr, iph->saddr); | 264 | t = ipip6_tunnel_lookup(iph->daddr, iph->saddr); |
262 | if (t == NULL || t->parms.iph.daddr == 0) | 265 | if (t == NULL || t->parms.iph.daddr == 0) |
263 | goto out; | 266 | goto out; |
267 | |||
268 | err = 0; | ||
264 | if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) | 269 | if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) |
265 | goto out; | 270 | goto out; |
266 | 271 | ||
@@ -271,7 +276,7 @@ static void ipip6_err(struct sk_buff *skb, u32 info) | |||
271 | t->err_time = jiffies; | 276 | t->err_time = jiffies; |
272 | out: | 277 | out: |
273 | read_unlock(&ipip6_lock); | 278 | read_unlock(&ipip6_lock); |
274 | return; | 279 | return err; |
275 | #else | 280 | #else |
276 | struct iphdr *iph = (struct iphdr*)dp; | 281 | struct iphdr *iph = (struct iphdr*)dp; |
277 | int hlen = iph->ihl<<2; | 282 | int hlen = iph->ihl<<2; |
@@ -332,7 +337,7 @@ out: | |||
332 | /* Prepare fake skb to feed it to icmpv6_send */ | 337 | /* Prepare fake skb to feed it to icmpv6_send */ |
333 | skb2 = skb_clone(skb, GFP_ATOMIC); | 338 | skb2 = skb_clone(skb, GFP_ATOMIC); |
334 | if (skb2 == NULL) | 339 | if (skb2 == NULL) |
335 | return; | 340 | return 0; |
336 | dst_release(skb2->dst); | 341 | dst_release(skb2->dst); |
337 | skb2->dst = NULL; | 342 | skb2->dst = NULL; |
338 | skb_pull(skb2, skb->data - (u8*)iph6); | 343 | skb_pull(skb2, skb->data - (u8*)iph6); |
@@ -355,7 +360,7 @@ out: | |||
355 | } | 360 | } |
356 | } | 361 | } |
357 | kfree_skb(skb2); | 362 | kfree_skb(skb2); |
358 | return; | 363 | return 0; |
359 | #endif | 364 | #endif |
360 | } | 365 | } |
361 | 366 | ||
@@ -791,9 +796,10 @@ static int __init ipip6_fb_tunnel_init(struct net_device *dev) | |||
791 | return 0; | 796 | return 0; |
792 | } | 797 | } |
793 | 798 | ||
794 | static struct net_protocol sit_protocol = { | 799 | static struct xfrm_tunnel sit_handler = { |
795 | .handler = ipip6_rcv, | 800 | .handler = ipip6_rcv, |
796 | .err_handler = ipip6_err, | 801 | .err_handler = ipip6_err, |
802 | .priority = 1, | ||
797 | }; | 803 | }; |
798 | 804 | ||
799 | static void __exit sit_destroy_tunnels(void) | 805 | static void __exit sit_destroy_tunnels(void) |
@@ -812,7 +818,7 @@ static void __exit sit_destroy_tunnels(void) | |||
812 | 818 | ||
813 | static void __exit sit_cleanup(void) | 819 | static void __exit sit_cleanup(void) |
814 | { | 820 | { |
815 | inet_del_protocol(&sit_protocol, IPPROTO_IPV6); | 821 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); |
816 | 822 | ||
817 | rtnl_lock(); | 823 | rtnl_lock(); |
818 | sit_destroy_tunnels(); | 824 | sit_destroy_tunnels(); |
@@ -826,7 +832,7 @@ static int __init sit_init(void) | |||
826 | 832 | ||
827 | printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); | 833 | printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); |
828 | 834 | ||
829 | if (inet_add_protocol(&sit_protocol, IPPROTO_IPV6) < 0) { | 835 | if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) { |
830 | printk(KERN_INFO "sit init: Can't add protocol\n"); | 836 | printk(KERN_INFO "sit init: Can't add protocol\n"); |
831 | return -EAGAIN; | 837 | return -EAGAIN; |
832 | } | 838 | } |
@@ -848,7 +854,7 @@ static int __init sit_init(void) | |||
848 | err2: | 854 | err2: |
849 | free_netdev(ipip6_fb_tunnel_dev); | 855 | free_netdev(ipip6_fb_tunnel_dev); |
850 | err1: | 856 | err1: |
851 | inet_del_protocol(&sit_protocol, IPPROTO_IPV6); | 857 | xfrm4_tunnel_deregister(&sit_handler, AF_INET6); |
852 | goto out; | 858 | goto out; |
853 | } | 859 | } |
854 | 860 | ||