diff options
Diffstat (limited to 'net/ipv6/exthdrs.c')
-rw-r--r-- | net/ipv6/exthdrs.c | 118 |
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 | ||
51 | int ipv6_find_tlv(struct sk_buff *skb, int offset, int type) | 51 | int 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); | |||
656 | static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) | 665 | static 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) | |||
672 | static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) | 682 | static 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 | ||
825 | EXPORT_SYMBOL(ipv6_push_nfrag_opts); | ||
826 | |||
813 | void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto) | 827 | void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto) |
814 | { | 828 | { |
815 | if (opt->dst1opt) | 829 | if (opt->dst1opt) |