diff options
Diffstat (limited to 'net/ipv6/exthdrs.c')
| -rw-r--r-- | net/ipv6/exthdrs.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 2a1e7e45b890..a18d4256372c 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
| @@ -485,15 +485,27 @@ static struct tlvtype_proc tlvprochopopt_lst[] = { | |||
| 485 | { -1, } | 485 | { -1, } |
| 486 | }; | 486 | }; |
| 487 | 487 | ||
| 488 | int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) | 488 | int ipv6_parse_hopopts(struct sk_buff *skb) |
| 489 | { | 489 | { |
| 490 | struct inet6_skb_parm *opt = IP6CB(skb); | 490 | struct inet6_skb_parm *opt = IP6CB(skb); |
| 491 | 491 | ||
| 492 | /* | ||
| 493 | * skb->nh.raw is equal to skb->data, and | ||
| 494 | * skb->h.raw - skb->nh.raw is always equal to | ||
| 495 | * sizeof(struct ipv6hdr) by definition of | ||
| 496 | * hop-by-hop options. | ||
| 497 | */ | ||
| 498 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || | ||
| 499 | !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { | ||
| 500 | kfree_skb(skb); | ||
| 501 | return -1; | ||
| 502 | } | ||
| 503 | |||
| 492 | opt->hop = sizeof(struct ipv6hdr); | 504 | opt->hop = sizeof(struct ipv6hdr); |
| 493 | if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { | 505 | if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { |
| 494 | skb->h.raw += (skb->h.raw[1]+1)<<3; | 506 | skb->h.raw += (skb->h.raw[1]+1)<<3; |
| 495 | opt->nhoff = sizeof(struct ipv6hdr); | 507 | opt->nhoff = sizeof(struct ipv6hdr); |
| 496 | return sizeof(struct ipv6hdr); | 508 | return 1; |
| 497 | } | 509 | } |
| 498 | return -1; | 510 | return -1; |
| 499 | } | 511 | } |
