Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 327775
b: refs/heads/master
c: 2b60af0
h: refs/heads/master
i:
  327773: 67cf035
  327771: 9e0d3d8
  327767: 9cf5c2f
  327759: 3e4a83b
  327743: 7a10dde
v: v3
  • Loading branch information
Patrick McHardy authored and Pablo Neira Ayuso committed Aug 30, 2012
1 parent 2df24e9 commit d0f1f8b
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 58 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4cdd34084d539c758d00c5dc7bf95db2e4f2bc70
refs/heads/master: 2b60af017880f7dc35d1fac65f48fc94f8a3c1ec
63 changes: 6 additions & 57 deletions trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,82 +64,31 @@ static int ipv6_print_tuple(struct seq_file *s,
tuple->src.u3.ip6, tuple->dst.u3.ip6);
}

/*
* Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c
*
* This function parses (probably truncated) exthdr set "hdr"
* of length "len". "nexthdrp" initially points to some place,
* where type of the first header can be found.
*
* It skips all well-known exthdrs, and returns pointer to the start
* of unparsable area i.e. the first header with unknown type.
* if success, *nexthdr is updated by type/protocol of this header.
*
* NOTES: - it may return pointer pointing beyond end of packet,
* if the last recognized header is truncated in the middle.
* - if packet is truncated, so that all parsed headers are skipped,
* it returns -1.
* - if packet is fragmented, return pointer of the fragment header.
* - ESP is unparsable for now and considered like
* normal payload protocol.
* - Note also special handling of AUTH header. Thanks to IPsec wizards.
*/

static int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
u8 *nexthdrp, int len)
{
u8 nexthdr = *nexthdrp;

while (ipv6_ext_hdr(nexthdr)) {
struct ipv6_opt_hdr hdr;
int hdrlen;

if (len < (int)sizeof(struct ipv6_opt_hdr))
return -1;
if (nexthdr == NEXTHDR_NONE)
break;
if (nexthdr == NEXTHDR_FRAGMENT)
break;
if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
BUG();
if (nexthdr == NEXTHDR_AUTH)
hdrlen = (hdr.hdrlen+2)<<2;
else
hdrlen = ipv6_optlen(&hdr);

nexthdr = hdr.nexthdr;
len -= hdrlen;
start += hdrlen;
}

*nexthdrp = nexthdr;
return start;
}

static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
unsigned int *dataoff, u_int8_t *protonum)
{
unsigned int extoff = nhoff + sizeof(struct ipv6hdr);
unsigned char pnum;
__be16 frag_off;
int protoff;
u8 nexthdr;

if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr),
&pnum, sizeof(pnum)) != 0) {
&nexthdr, sizeof(nexthdr)) != 0) {
pr_debug("ip6_conntrack_core: can't get nexthdr\n");
return -NF_ACCEPT;
}
protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, skb->len - extoff);
protoff = ipv6_skip_exthdr(skb, extoff, &nexthdr, &frag_off);
/*
* (protoff == skb->len) mean that the packet doesn't have no data
* except of IPv6 & ext headers. but it's tracked anyway. - YK
*/
if ((protoff < 0) || (protoff > skb->len)) {
if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
return -NF_ACCEPT;
}

*dataoff = protoff;
*protonum = pnum;
*protonum = nexthdr;
return NF_ACCEPT;
}

Expand Down

0 comments on commit d0f1f8b

Please sign in to comment.