diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index ac702a29dd16..ac35f9526368 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -179,31 +179,36 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
179 | int (*okfn)(struct sk_buff *)) | 179 | int (*okfn)(struct sk_buff *)) |
180 | { | 180 | { |
181 | struct nf_conn *ct; | 181 | struct nf_conn *ct; |
182 | struct nf_conn_help *help; | ||
182 | enum ip_conntrack_info ctinfo; | 183 | enum ip_conntrack_info ctinfo; |
184 | unsigned int ret, protoff; | ||
185 | unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1) | ||
186 | - (*pskb)->data; | ||
187 | unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr; | ||
188 | |||
183 | 189 | ||
184 | /* This is where we call the helper: as the packet goes out. */ | 190 | /* This is where we call the helper: as the packet goes out. */ |
185 | ct = nf_ct_get(*pskb, &ctinfo); | 191 | ct = nf_ct_get(*pskb, &ctinfo); |
186 | if (ct && ct->helper) { | 192 | if (!ct) |
187 | unsigned int ret, protoff; | 193 | goto out; |
188 | unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1) | ||
189 | - (*pskb)->data; | ||
190 | unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr; | ||
191 | |||
192 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, | ||
193 | (*pskb)->len - extoff); | ||
194 | if (protoff < 0 || protoff > (*pskb)->len || | ||
195 | pnum == NEXTHDR_FRAGMENT) { | ||
196 | DEBUGP("proto header not found\n"); | ||
197 | return NF_ACCEPT; | ||
198 | } | ||
199 | 194 | ||
200 | ret = ct->helper->help(pskb, protoff, ct, ctinfo); | 195 | help = nfct_help(ct); |
201 | if (ret != NF_ACCEPT) | 196 | if (!help || !help->helper) |
202 | return ret; | 197 | goto out; |
198 | |||
199 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, | ||
200 | (*pskb)->len - extoff); | ||
201 | if (protoff < 0 || protoff > (*pskb)->len || | ||
202 | pnum == NEXTHDR_FRAGMENT) { | ||
203 | DEBUGP("proto header not found\n"); | ||
204 | return NF_ACCEPT; | ||
203 | } | 205 | } |
204 | 206 | ||
207 | ret = help->helper->help(pskb, protoff, ct, ctinfo); | ||
208 | if (ret != NF_ACCEPT) | ||
209 | return ret; | ||
210 | out: | ||
205 | /* We've seen it coming out the other side: confirm it */ | 211 | /* We've seen it coming out the other side: confirm it */ |
206 | |||
207 | return nf_conntrack_confirm(pskb); | 212 | return nf_conntrack_confirm(pskb); |
208 | } | 213 | } |
209 | 214 | ||