aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/icmp.c
diff options
context:
space:
mode:
authorJesse Gross <jesse@nicira.com>2011-11-30 20:05:51 -0500
committerJesse Gross <jesse@nicira.com>2011-12-03 12:35:10 -0500
commit75f2811c6460ccc59d83c66059943ce9c9f81a18 (patch)
tree49373cf5f5b11358aeb587209ad270496f751609 /net/ipv6/icmp.c
parent396cf9430505cfba529a2f2a037d782719fa5844 (diff)
ipv6: Add fragment reporting to ipv6_skip_exthdr().
While parsing through IPv6 extension headers, fragment headers are skipped making them invisible to the caller. This reports the fragment offset of the last header in order to make it possible to determine whether the packet is fragmented and, if so whether it is a first or last fragment. Signed-off-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'net/ipv6/icmp.c')
-rw-r--r--net/ipv6/icmp.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 9e2bdccf9143..01d46bff63c3 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -135,11 +135,12 @@ static int is_ineligible(struct sk_buff *skb)
135 int ptr = (u8 *)(ipv6_hdr(skb) + 1) - skb->data; 135 int ptr = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
136 int len = skb->len - ptr; 136 int len = skb->len - ptr;
137 __u8 nexthdr = ipv6_hdr(skb)->nexthdr; 137 __u8 nexthdr = ipv6_hdr(skb)->nexthdr;
138 __be16 frag_off;
138 139
139 if (len < 0) 140 if (len < 0)
140 return 1; 141 return 1;
141 142
142 ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr); 143 ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, &frag_off);
143 if (ptr < 0) 144 if (ptr < 0)
144 return 0; 145 return 0;
145 if (nexthdr == IPPROTO_ICMPV6) { 146 if (nexthdr == IPPROTO_ICMPV6) {
@@ -596,6 +597,7 @@ static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
596 int inner_offset; 597 int inner_offset;
597 int hash; 598 int hash;
598 u8 nexthdr; 599 u8 nexthdr;
600 __be16 frag_off;
599 601
600 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 602 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
601 return; 603 return;
@@ -603,7 +605,8 @@ static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
603 nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr; 605 nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
604 if (ipv6_ext_hdr(nexthdr)) { 606 if (ipv6_ext_hdr(nexthdr)) {
605 /* now skip over extension headers */ 607 /* now skip over extension headers */
606 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr); 608 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
609 &nexthdr, &frag_off);
607 if (inner_offset<0) 610 if (inner_offset<0)
608 return; 611 return;
609 } else { 612 } else {