diff options
Diffstat (limited to 'net/ipv6/exthdrs.c')
-rw-r--r-- | net/ipv6/exthdrs.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 1bda0299890e..f25ee773f52e 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -144,7 +144,7 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp) | |||
144 | struct tlvtype_proc *curr; | 144 | struct tlvtype_proc *curr; |
145 | const unsigned char *nh = skb_network_header(skb); | 145 | const unsigned char *nh = skb_network_header(skb); |
146 | int off = skb->h.raw - skb->nh.raw; | 146 | int off = skb->h.raw - skb->nh.raw; |
147 | int len = ((skb->h.raw[1]+1)<<3); | 147 | int len = (skb_transport_header(skb)[1] + 1) << 3; |
148 | 148 | ||
149 | if (skb_transport_offset(skb) + len > skb_headlen(skb)) | 149 | if (skb_transport_offset(skb) + len > skb_headlen(skb)) |
150 | goto bad; | 150 | goto bad; |
@@ -290,15 +290,14 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp) | |||
290 | 290 | ||
291 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || | 291 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || |
292 | !pskb_may_pull(skb, (skb_transport_offset(skb) + | 292 | !pskb_may_pull(skb, (skb_transport_offset(skb) + |
293 | ((skb->h.raw[1] + 1) << 3)))) { | 293 | ((skb_transport_header(skb)[1] + 1) << 3)))) { |
294 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 294 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), |
295 | IPSTATS_MIB_INHDRERRORS); | 295 | IPSTATS_MIB_INHDRERRORS); |
296 | kfree_skb(skb); | 296 | kfree_skb(skb); |
297 | return -1; | 297 | return -1; |
298 | } | 298 | } |
299 | 299 | ||
300 | opt->lastopt = skb->h.raw - skb->nh.raw; | 300 | opt->lastopt = opt->dst1 = skb->h.raw - skb->nh.raw; |
301 | opt->dst1 = skb->h.raw - skb->nh.raw; | ||
302 | #ifdef CONFIG_IPV6_MIP6 | 301 | #ifdef CONFIG_IPV6_MIP6 |
303 | dstbuf = opt->dst1; | 302 | dstbuf = opt->dst1; |
304 | #endif | 303 | #endif |
@@ -307,7 +306,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp) | |||
307 | if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) { | 306 | if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) { |
308 | dst_release(dst); | 307 | dst_release(dst); |
309 | skb = *skbp; | 308 | skb = *skbp; |
310 | skb->h.raw += ((skb->h.raw[1]+1)<<3); | 309 | skb->h.raw += (skb_transport_header(skb)[1] + 1) << 3; |
311 | opt = IP6CB(skb); | 310 | opt = IP6CB(skb); |
312 | #ifdef CONFIG_IPV6_MIP6 | 311 | #ifdef CONFIG_IPV6_MIP6 |
313 | opt->nhoff = dstbuf; | 312 | opt->nhoff = dstbuf; |
@@ -390,14 +389,14 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) | |||
390 | 389 | ||
391 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || | 390 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || |
392 | !pskb_may_pull(skb, (skb_transport_offset(skb) + | 391 | !pskb_may_pull(skb, (skb_transport_offset(skb) + |
393 | ((skb->h.raw[1] + 1) << 3)))) { | 392 | ((skb_transport_header(skb)[1] + 1) << 3)))) { |
394 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 393 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), |
395 | IPSTATS_MIB_INHDRERRORS); | 394 | IPSTATS_MIB_INHDRERRORS); |
396 | kfree_skb(skb); | 395 | kfree_skb(skb); |
397 | return -1; | 396 | return -1; |
398 | } | 397 | } |
399 | 398 | ||
400 | hdr = (struct ipv6_rt_hdr *) skb->h.raw; | 399 | hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb); |
401 | 400 | ||
402 | switch (hdr->type) { | 401 | switch (hdr->type) { |
403 | #ifdef CONFIG_IPV6_MIP6 | 402 | #ifdef CONFIG_IPV6_MIP6 |
@@ -444,8 +443,7 @@ looped_back: | |||
444 | break; | 443 | break; |
445 | } | 444 | } |
446 | 445 | ||
447 | opt->lastopt = skb->h.raw - skb->nh.raw; | 446 | opt->lastopt = opt->srcrt = skb->h.raw - skb->nh.raw; |
448 | opt->srcrt = skb->h.raw - skb->nh.raw; | ||
449 | skb->h.raw += (hdr->hdrlen + 1) << 3; | 447 | skb->h.raw += (hdr->hdrlen + 1) << 3; |
450 | opt->dst0 = opt->dst1; | 448 | opt->dst0 = opt->dst1; |
451 | opt->dst1 = 0; | 449 | opt->dst1 = 0; |
@@ -745,7 +743,8 @@ int ipv6_parse_hopopts(struct sk_buff **skbp) | |||
745 | * hop-by-hop options. | 743 | * hop-by-hop options. |
746 | */ | 744 | */ |
747 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || | 745 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || |
748 | !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { | 746 | !pskb_may_pull(skb, (sizeof(struct ipv6hdr) + |
747 | ((skb_transport_header(skb)[1] + 1) << 3)))) { | ||
749 | kfree_skb(skb); | 748 | kfree_skb(skb); |
750 | return -1; | 749 | return -1; |
751 | } | 750 | } |
@@ -753,7 +752,7 @@ int ipv6_parse_hopopts(struct sk_buff **skbp) | |||
753 | opt->hop = sizeof(struct ipv6hdr); | 752 | opt->hop = sizeof(struct ipv6hdr); |
754 | if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) { | 753 | if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) { |
755 | skb = *skbp; | 754 | skb = *skbp; |
756 | skb->h.raw += (skb->h.raw[1]+1)<<3; | 755 | skb->h.raw += (skb_transport_header(skb)[1] + 1) << 3; |
757 | opt = IP6CB(skb); | 756 | opt = IP6CB(skb); |
758 | opt->nhoff = sizeof(struct ipv6hdr); | 757 | opt->nhoff = sizeof(struct ipv6hdr); |
759 | return 1; | 758 | return 1; |