aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/exthdrs.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/exthdrs.c')
-rw-r--r--net/ipv6/exthdrs.c118
1 files changed, 66 insertions, 52 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index fb39604c3d09..6d8e4ac7bdad 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -50,13 +50,14 @@
50 50
51int ipv6_find_tlv(struct sk_buff *skb, int offset, int type) 51int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
52{ 52{
53 int packet_len = skb->tail - skb->nh.raw; 53 const unsigned char *nh = skb_network_header(skb);
54 int packet_len = skb->tail - skb->network_header;
54 struct ipv6_opt_hdr *hdr; 55 struct ipv6_opt_hdr *hdr;
55 int len; 56 int len;
56 57
57 if (offset + 2 > packet_len) 58 if (offset + 2 > packet_len)
58 goto bad; 59 goto bad;
59 hdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); 60 hdr = (struct ipv6_opt_hdr *)(nh + offset);
60 len = ((hdr->hdrlen + 1) << 3); 61 len = ((hdr->hdrlen + 1) << 3);
61 62
62 if (offset + len > packet_len) 63 if (offset + len > packet_len)
@@ -66,7 +67,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
66 len -= 2; 67 len -= 2;
67 68
68 while (len > 0) { 69 while (len > 0) {
69 int opttype = skb->nh.raw[offset]; 70 int opttype = nh[offset];
70 int optlen; 71 int optlen;
71 72
72 if (opttype == type) 73 if (opttype == type)
@@ -77,7 +78,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
77 optlen = 1; 78 optlen = 1;
78 break; 79 break;
79 default: 80 default:
80 optlen = skb->nh.raw[offset + 1] + 2; 81 optlen = nh[offset + 1] + 2;
81 if (optlen > len) 82 if (optlen > len)
82 goto bad; 83 goto bad;
83 break; 84 break;
@@ -113,7 +114,7 @@ static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
113{ 114{
114 struct sk_buff *skb = *skbp; 115 struct sk_buff *skb = *skbp;
115 116
116 switch ((skb->nh.raw[optoff] & 0xC0) >> 6) { 117 switch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) {
117 case 0: /* ignore */ 118 case 0: /* ignore */
118 return 1; 119 return 1;
119 120
@@ -124,12 +125,12 @@ static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
124 /* Actually, it is redundant check. icmp_send 125 /* Actually, it is redundant check. icmp_send
125 will recheck in any case. 126 will recheck in any case.
126 */ 127 */
127 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) 128 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))
128 break; 129 break;
129 case 2: /* send ICMP PARM PROB regardless and drop packet */ 130 case 2: /* send ICMP PARM PROB regardless and drop packet */
130 icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff); 131 icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
131 return 0; 132 return 0;
132 }; 133 }
133 134
134 kfree_skb(skb); 135 kfree_skb(skb);
135 return 0; 136 return 0;
@@ -141,19 +142,20 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
141{ 142{
142 struct sk_buff *skb = *skbp; 143 struct sk_buff *skb = *skbp;
143 struct tlvtype_proc *curr; 144 struct tlvtype_proc *curr;
144 int off = skb->h.raw - skb->nh.raw; 145 const unsigned char *nh = skb_network_header(skb);
145 int len = ((skb->h.raw[1]+1)<<3); 146 int off = skb_network_header_len(skb);
147 int len = (skb_transport_header(skb)[1] + 1) << 3;
146 148
147 if ((skb->h.raw + len) - skb->data > skb_headlen(skb)) 149 if (skb_transport_offset(skb) + len > skb_headlen(skb))
148 goto bad; 150 goto bad;
149 151
150 off += 2; 152 off += 2;
151 len -= 2; 153 len -= 2;
152 154
153 while (len > 0) { 155 while (len > 0) {
154 int optlen = skb->nh.raw[off+1]+2; 156 int optlen = nh[off + 1] + 2;
155 157
156 switch (skb->nh.raw[off]) { 158 switch (nh[off]) {
157 case IPV6_TLV_PAD0: 159 case IPV6_TLV_PAD0:
158 optlen = 1; 160 optlen = 1;
159 break; 161 break;
@@ -165,7 +167,7 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
165 if (optlen > len) 167 if (optlen > len)
166 goto bad; 168 goto bad;
167 for (curr=procs; curr->type >= 0; curr++) { 169 for (curr=procs; curr->type >= 0; curr++) {
168 if (curr->type == skb->nh.raw[off]) { 170 if (curr->type == nh[off]) {
169 /* type specific length/alignment 171 /* type specific length/alignment
170 checks will be performed in the 172 checks will be performed in the
171 func(). */ 173 func(). */
@@ -200,7 +202,7 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
200 struct sk_buff *skb = *skbp; 202 struct sk_buff *skb = *skbp;
201 struct ipv6_destopt_hao *hao; 203 struct ipv6_destopt_hao *hao;
202 struct inet6_skb_parm *opt = IP6CB(skb); 204 struct inet6_skb_parm *opt = IP6CB(skb);
203 struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb->nh.raw; 205 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
204 struct in6_addr tmp_addr; 206 struct in6_addr tmp_addr;
205 int ret; 207 int ret;
206 208
@@ -211,7 +213,7 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
211 opt->dsthao = opt->dst1; 213 opt->dsthao = opt->dst1;
212 opt->dst1 = 0; 214 opt->dst1 = 0;
213 215
214 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + optoff); 216 hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) + optoff);
215 217
216 if (hao->length != 16) { 218 if (hao->length != 16) {
217 LIMIT_NETDEBUG( 219 LIMIT_NETDEBUG(
@@ -244,8 +246,9 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
244 246
245 /* update all variable using below by copied skbuff */ 247 /* update all variable using below by copied skbuff */
246 *skbp = skb = skb2; 248 *skbp = skb = skb2;
247 hao = (struct ipv6_destopt_hao *)(skb2->nh.raw + optoff); 249 hao = (struct ipv6_destopt_hao *)(skb_network_header(skb2) +
248 ipv6h = (struct ipv6hdr *)skb2->nh.raw; 250 optoff);
251 ipv6h = ipv6_hdr(skb2);
249 } 252 }
250 253
251 if (skb->ip_summed == CHECKSUM_COMPLETE) 254 if (skb->ip_summed == CHECKSUM_COMPLETE)
@@ -255,7 +258,7 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
255 ipv6_addr_copy(&ipv6h->saddr, &hao->addr); 258 ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
256 ipv6_addr_copy(&hao->addr, &tmp_addr); 259 ipv6_addr_copy(&hao->addr, &tmp_addr);
257 260
258 if (skb->tstamp.off_sec == 0) 261 if (skb->tstamp.tv64 == 0)
259 __net_timestamp(skb); 262 __net_timestamp(skb);
260 263
261 return 1; 264 return 1;
@@ -285,16 +288,16 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
285#endif 288#endif
286 struct dst_entry *dst; 289 struct dst_entry *dst;
287 290
288 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || 291 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
289 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { 292 !pskb_may_pull(skb, (skb_transport_offset(skb) +
293 ((skb_transport_header(skb)[1] + 1) << 3)))) {
290 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 294 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
291 IPSTATS_MIB_INHDRERRORS); 295 IPSTATS_MIB_INHDRERRORS);
292 kfree_skb(skb); 296 kfree_skb(skb);
293 return -1; 297 return -1;
294 } 298 }
295 299
296 opt->lastopt = skb->h.raw - skb->nh.raw; 300 opt->lastopt = opt->dst1 = skb_network_header_len(skb);
297 opt->dst1 = skb->h.raw - skb->nh.raw;
298#ifdef CONFIG_IPV6_MIP6 301#ifdef CONFIG_IPV6_MIP6
299 dstbuf = opt->dst1; 302 dstbuf = opt->dst1;
300#endif 303#endif
@@ -303,7 +306,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
303 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) { 306 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
304 dst_release(dst); 307 dst_release(dst);
305 skb = *skbp; 308 skb = *skbp;
306 skb->h.raw += ((skb->h.raw[1]+1)<<3); 309 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
307 opt = IP6CB(skb); 310 opt = IP6CB(skb);
308#ifdef CONFIG_IPV6_MIP6 311#ifdef CONFIG_IPV6_MIP6
309 opt->nhoff = dstbuf; 312 opt->nhoff = dstbuf;
@@ -384,18 +387,20 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
384 387
385 in6_dev_put(idev); 388 in6_dev_put(idev);
386 389
387 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || 390 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
388 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { 391 !pskb_may_pull(skb, (skb_transport_offset(skb) +
392 ((skb_transport_header(skb)[1] + 1) << 3)))) {
389 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 393 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
390 IPSTATS_MIB_INHDRERRORS); 394 IPSTATS_MIB_INHDRERRORS);
391 kfree_skb(skb); 395 kfree_skb(skb);
392 return -1; 396 return -1;
393 } 397 }
394 398
395 hdr = (struct ipv6_rt_hdr *) skb->h.raw; 399 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
396 400
397 switch (hdr->type) { 401 switch (hdr->type) {
398#ifdef CONFIG_IPV6_MIP6 402#ifdef CONFIG_IPV6_MIP6
403 case IPV6_SRCRT_TYPE_2:
399 break; 404 break;
400#endif 405#endif
401 case IPV6_SRCRT_TYPE_0: 406 case IPV6_SRCRT_TYPE_0:
@@ -406,11 +411,12 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
406 default: 411 default:
407 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 412 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
408 IPSTATS_MIB_INHDRERRORS); 413 IPSTATS_MIB_INHDRERRORS);
409 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); 414 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
415 (&hdr->type) - skb_network_header(skb));
410 return -1; 416 return -1;
411 } 417 }
412 418
413 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) || 419 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
414 skb->pkt_type != PACKET_HOST) { 420 skb->pkt_type != PACKET_HOST) {
415 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 421 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
416 IPSTATS_MIB_INADDRERRORS); 422 IPSTATS_MIB_INADDRERRORS);
@@ -438,12 +444,11 @@ looped_back:
438 break; 444 break;
439 } 445 }
440 446
441 opt->lastopt = skb->h.raw - skb->nh.raw; 447 opt->lastopt = opt->srcrt = skb_network_header_len(skb);
442 opt->srcrt = skb->h.raw - skb->nh.raw; 448 skb->transport_header += (hdr->hdrlen + 1) << 3;
443 skb->h.raw += (hdr->hdrlen + 1) << 3;
444 opt->dst0 = opt->dst1; 449 opt->dst0 = opt->dst1;
445 opt->dst1 = 0; 450 opt->dst1 = 0;
446 opt->nhoff = (&hdr->nexthdr) - skb->nh.raw; 451 opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
447 return 1; 452 return 1;
448 } 453 }
449 454
@@ -452,7 +457,9 @@ looped_back:
452 if (hdr->hdrlen & 0x01) { 457 if (hdr->hdrlen & 0x01) {
453 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 458 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
454 IPSTATS_MIB_INHDRERRORS); 459 IPSTATS_MIB_INHDRERRORS);
455 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); 460 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
461 ((&hdr->hdrlen) -
462 skb_network_header(skb)));
456 return -1; 463 return -1;
457 } 464 }
458 break; 465 break;
@@ -479,7 +486,9 @@ looped_back:
479 if (hdr->segments_left > n) { 486 if (hdr->segments_left > n) {
480 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 487 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
481 IPSTATS_MIB_INHDRERRORS); 488 IPSTATS_MIB_INHDRERRORS);
482 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw); 489 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
490 ((&hdr->segments_left) -
491 skb_network_header(skb)));
483 return -1; 492 return -1;
484 } 493 }
485 494
@@ -498,7 +507,7 @@ looped_back:
498 kfree_skb(skb); 507 kfree_skb(skb);
499 *skbp = skb = skb2; 508 *skbp = skb = skb2;
500 opt = IP6CB(skb2); 509 opt = IP6CB(skb2);
501 hdr = (struct ipv6_rt_hdr *) skb2->h.raw; 510 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb2);
502 } 511 }
503 512
504 if (skb->ip_summed == CHECKSUM_COMPLETE) 513 if (skb->ip_summed == CHECKSUM_COMPLETE)
@@ -514,7 +523,7 @@ looped_back:
514#ifdef CONFIG_IPV6_MIP6 523#ifdef CONFIG_IPV6_MIP6
515 case IPV6_SRCRT_TYPE_2: 524 case IPV6_SRCRT_TYPE_2:
516 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, 525 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
517 (xfrm_address_t *)&skb->nh.ipv6h->saddr, 526 (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
518 IPPROTO_ROUTING) < 0) { 527 IPPROTO_ROUTING) < 0) {
519 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 528 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
520 IPSTATS_MIB_INADDRERRORS); 529 IPSTATS_MIB_INADDRERRORS);
@@ -541,19 +550,19 @@ looped_back:
541 } 550 }
542 551
543 ipv6_addr_copy(&daddr, addr); 552 ipv6_addr_copy(&daddr, addr);
544 ipv6_addr_copy(addr, &skb->nh.ipv6h->daddr); 553 ipv6_addr_copy(addr, &ipv6_hdr(skb)->daddr);
545 ipv6_addr_copy(&skb->nh.ipv6h->daddr, &daddr); 554 ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &daddr);
546 555
547 dst_release(xchg(&skb->dst, NULL)); 556 dst_release(xchg(&skb->dst, NULL));
548 ip6_route_input(skb); 557 ip6_route_input(skb);
549 if (skb->dst->error) { 558 if (skb->dst->error) {
550 skb_push(skb, skb->data - skb->nh.raw); 559 skb_push(skb, skb->data - skb_network_header(skb));
551 dst_input(skb); 560 dst_input(skb);
552 return -1; 561 return -1;
553 } 562 }
554 563
555 if (skb->dst->dev->flags&IFF_LOOPBACK) { 564 if (skb->dst->dev->flags&IFF_LOOPBACK) {
556 if (skb->nh.ipv6h->hop_limit <= 1) { 565 if (ipv6_hdr(skb)->hop_limit <= 1) {
557 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 566 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
558 IPSTATS_MIB_INHDRERRORS); 567 IPSTATS_MIB_INHDRERRORS);
559 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 568 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
@@ -561,11 +570,11 @@ looped_back:
561 kfree_skb(skb); 570 kfree_skb(skb);
562 return -1; 571 return -1;
563 } 572 }
564 skb->nh.ipv6h->hop_limit--; 573 ipv6_hdr(skb)->hop_limit--;
565 goto looped_back; 574 goto looped_back;
566 } 575 }
567 576
568 skb_push(skb, skb->data - skb->nh.raw); 577 skb_push(skb, skb->data - skb_network_header(skb));
569 dst_input(skb); 578 dst_input(skb);
570 return -1; 579 return -1;
571} 580}
@@ -656,13 +665,14 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
656static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) 665static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
657{ 666{
658 struct sk_buff *skb = *skbp; 667 struct sk_buff *skb = *skbp;
668 const unsigned char *nh = skb_network_header(skb);
659 669
660 if (skb->nh.raw[optoff+1] == 2) { 670 if (nh[optoff + 1] == 2) {
661 IP6CB(skb)->ra = optoff; 671 IP6CB(skb)->ra = optoff;
662 return 1; 672 return 1;
663 } 673 }
664 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", 674 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
665 skb->nh.raw[optoff+1]); 675 nh[optoff + 1]);
666 kfree_skb(skb); 676 kfree_skb(skb);
667 return 0; 677 return 0;
668} 678}
@@ -672,23 +682,24 @@ static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
672static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) 682static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
673{ 683{
674 struct sk_buff *skb = *skbp; 684 struct sk_buff *skb = *skbp;
685 const unsigned char *nh = skb_network_header(skb);
675 u32 pkt_len; 686 u32 pkt_len;
676 687
677 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { 688 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
678 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", 689 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
679 skb->nh.raw[optoff+1]); 690 nh[optoff+1]);
680 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 691 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
681 IPSTATS_MIB_INHDRERRORS); 692 IPSTATS_MIB_INHDRERRORS);
682 goto drop; 693 goto drop;
683 } 694 }
684 695
685 pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2)); 696 pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
686 if (pkt_len <= IPV6_MAXPLEN) { 697 if (pkt_len <= IPV6_MAXPLEN) {
687 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); 698 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
688 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); 699 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
689 return 0; 700 return 0;
690 } 701 }
691 if (skb->nh.ipv6h->payload_len) { 702 if (ipv6_hdr(skb)->payload_len) {
692 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); 703 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
693 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); 704 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
694 return 0; 705 return 0;
@@ -727,13 +738,14 @@ int ipv6_parse_hopopts(struct sk_buff **skbp)
727 struct inet6_skb_parm *opt = IP6CB(skb); 738 struct inet6_skb_parm *opt = IP6CB(skb);
728 739
729 /* 740 /*
730 * skb->nh.raw is equal to skb->data, and 741 * skb_network_header(skb) is equal to skb->data, and
731 * skb->h.raw - skb->nh.raw is always equal to 742 * skb_network_header_len(skb) is always equal to
732 * sizeof(struct ipv6hdr) by definition of 743 * sizeof(struct ipv6hdr) by definition of
733 * hop-by-hop options. 744 * hop-by-hop options.
734 */ 745 */
735 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || 746 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
736 !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { 747 !pskb_may_pull(skb, (sizeof(struct ipv6hdr) +
748 ((skb_transport_header(skb)[1] + 1) << 3)))) {
737 kfree_skb(skb); 749 kfree_skb(skb);
738 return -1; 750 return -1;
739 } 751 }
@@ -741,7 +753,7 @@ int ipv6_parse_hopopts(struct sk_buff **skbp)
741 opt->hop = sizeof(struct ipv6hdr); 753 opt->hop = sizeof(struct ipv6hdr);
742 if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) { 754 if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) {
743 skb = *skbp; 755 skb = *skbp;
744 skb->h.raw += (skb->h.raw[1]+1)<<3; 756 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
745 opt = IP6CB(skb); 757 opt = IP6CB(skb);
746 opt->nhoff = sizeof(struct ipv6hdr); 758 opt->nhoff = sizeof(struct ipv6hdr);
747 return 1; 759 return 1;
@@ -810,6 +822,8 @@ void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
810 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt); 822 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
811} 823}
812 824
825EXPORT_SYMBOL(ipv6_push_nfrag_opts);
826
813void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto) 827void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
814{ 828{
815 if (opt->dst1opt) 829 if (opt->dst1opt)