aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorAl Viro <viro@ftp.linux.org.uk>2007-07-26 12:33:29 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-26 14:11:56 -0400
commit704eae1f32274c0435f7f3924077afdb811edd1d (patch)
tree211d333d6f50ea078b6f4f29f0734eadcecdc37b /net/ipv6
parenta34c45896a723ee7b13128ac8bf564ea42fcd1eb (diff)
ip6_tunnel - endianness annotations
Convert rel_info to host-endian before calling ip6_tnl_err(). The things become much more straightforward that way. The key observation (and the reason why that code actually worked) is that after ip6_tnl_err() we either immediately bailed out or had rel_info set to 0 or had it set to host-endian and guaranteed to hit (rel_type == ICMP_DEST_UNREACH && rel_code == ICMP_FRAG_NEEDED) case. So inconsistent endianness didn't really lead to bugs, but it had been subtle and prone to breakage. New variant is saner and obviously safe. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_tunnel.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index df30976f6dfd..ca774d8e3be3 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -385,7 +385,7 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
385 385
386static int 386static int
387ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt, 387ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
388 int *type, int *code, int *msg, __be32 *info, int offset) 388 int *type, int *code, int *msg, __u32 *info, int offset)
389{ 389{
390 struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data; 390 struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data;
391 struct ip6_tnl *t; 391 struct ip6_tnl *t;
@@ -435,7 +435,7 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
435 if ((*code) == ICMPV6_HDR_FIELD) 435 if ((*code) == ICMPV6_HDR_FIELD)
436 teli = parse_tlv_tnl_enc_lim(skb, skb->data); 436 teli = parse_tlv_tnl_enc_lim(skb, skb->data);
437 437
438 if (teli && teli == ntohl(*info) - 2) { 438 if (teli && teli == *info - 2) {
439 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli]; 439 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
440 if (tel->encap_limit == 0) { 440 if (tel->encap_limit == 0) {
441 if (net_ratelimit()) 441 if (net_ratelimit())
@@ -452,7 +452,7 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
452 } 452 }
453 break; 453 break;
454 case ICMPV6_PKT_TOOBIG: 454 case ICMPV6_PKT_TOOBIG:
455 mtu = ntohl(*info) - offset; 455 mtu = *info - offset;
456 if (mtu < IPV6_MIN_MTU) 456 if (mtu < IPV6_MIN_MTU)
457 mtu = IPV6_MIN_MTU; 457 mtu = IPV6_MIN_MTU;
458 t->dev->mtu = mtu; 458 t->dev->mtu = mtu;
@@ -478,12 +478,12 @@ out:
478 478
479static int 479static int
480ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 480ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
481 int type, int code, int offset, __u32 info) 481 int type, int code, int offset, __be32 info)
482{ 482{
483 int rel_msg = 0; 483 int rel_msg = 0;
484 int rel_type = type; 484 int rel_type = type;
485 int rel_code = code; 485 int rel_code = code;
486 __u32 rel_info = info; 486 __u32 rel_info = ntohl(info);
487 int err; 487 int err;
488 struct sk_buff *skb2; 488 struct sk_buff *skb2;
489 struct iphdr *eiph; 489 struct iphdr *eiph;
@@ -564,10 +564,9 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
564 goto out; 564 goto out;
565 565
566 skb2->dst->ops->update_pmtu(skb2->dst, rel_info); 566 skb2->dst->ops->update_pmtu(skb2->dst, rel_info);
567 rel_info = htonl(rel_info);
568 } 567 }
569 568
570 icmp_send(skb2, rel_type, rel_code, rel_info); 569 icmp_send(skb2, rel_type, rel_code, htonl(rel_info));
571 570
572out: 571out:
573 kfree_skb(skb2); 572 kfree_skb(skb2);
@@ -576,12 +575,12 @@ out:
576 575
577static int 576static int
578ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 577ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
579 int type, int code, int offset, __u32 info) 578 int type, int code, int offset, __be32 info)
580{ 579{
581 int rel_msg = 0; 580 int rel_msg = 0;
582 int rel_type = type; 581 int rel_type = type;
583 int rel_code = code; 582 int rel_code = code;
584 __u32 rel_info = info; 583 __u32 rel_info = ntohl(info);
585 int err; 584 int err;
586 585
587 err = ip6_tnl_err(skb, IPPROTO_IPV6, opt, &rel_type, &rel_code, 586 err = ip6_tnl_err(skb, IPPROTO_IPV6, opt, &rel_type, &rel_code,