diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index b5c4bb54691e..9b7eaaadc67e 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -86,7 +86,7 @@ static int ipv6_print_conntrack(struct seq_file *s, | |||
86 | * - Note also special handling of AUTH header. Thanks to IPsec wizards. | 86 | * - Note also special handling of AUTH header. Thanks to IPsec wizards. |
87 | */ | 87 | */ |
88 | 88 | ||
89 | int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp, | 89 | int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, |
90 | int len) | 90 | int len) |
91 | { | 91 | { |
92 | u8 nexthdr = *nexthdrp; | 92 | u8 nexthdr = *nexthdrp; |
@@ -117,19 +117,24 @@ int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp, | |||
117 | return start; | 117 | return start; |
118 | } | 118 | } |
119 | 119 | ||
120 | static int | 120 | static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, |
121 | ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff, | 121 | unsigned int *dataoff, u_int8_t *protonum) |
122 | u_int8_t *protonum) | ||
123 | { | 122 | { |
124 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; | 123 | unsigned int extoff = nhoff + sizeof(struct ipv6hdr); |
125 | unsigned char pnum = ipv6_hdr(*pskb)->nexthdr; | 124 | unsigned char pnum; |
126 | int protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, | 125 | int protoff; |
127 | (*pskb)->len - extoff); | 126 | |
127 | if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr), | ||
128 | &pnum, sizeof(pnum)) != 0) { | ||
129 | pr_debug("ip6_conntrack_core: can't get nexthdr\n"); | ||
130 | return -NF_ACCEPT; | ||
131 | } | ||
132 | protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, skb->len - extoff); | ||
128 | /* | 133 | /* |
129 | * (protoff == (*pskb)->len) mean that the packet doesn't have no data | 134 | * (protoff == skb->len) mean that the packet doesn't have no data |
130 | * except of IPv6 & ext headers. but it's tracked anyway. - YK | 135 | * except of IPv6 & ext headers. but it's tracked anyway. - YK |
131 | */ | 136 | */ |
132 | if ((protoff < 0) || (protoff > (*pskb)->len)) { | 137 | if ((protoff < 0) || (protoff > skb->len)) { |
133 | pr_debug("ip6_conntrack_core: can't find proto in pkt\n"); | 138 | pr_debug("ip6_conntrack_core: can't find proto in pkt\n"); |
134 | return -NF_ACCEPT; | 139 | return -NF_ACCEPT; |
135 | } | 140 | } |
@@ -375,7 +380,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = { | |||
375 | .invert_tuple = ipv6_invert_tuple, | 380 | .invert_tuple = ipv6_invert_tuple, |
376 | .print_tuple = ipv6_print_tuple, | 381 | .print_tuple = ipv6_print_tuple, |
377 | .print_conntrack = ipv6_print_conntrack, | 382 | .print_conntrack = ipv6_print_conntrack, |
378 | .prepare = ipv6_prepare, | 383 | .get_l4proto = ipv6_get_l4proto, |
379 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | 384 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) |
380 | .tuple_to_nfattr = ipv6_tuple_to_nfattr, | 385 | .tuple_to_nfattr = ipv6_tuple_to_nfattr, |
381 | .nfattr_to_tuple = ipv6_nfattr_to_tuple, | 386 | .nfattr_to_tuple = ipv6_nfattr_to_tuple, |