aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c39
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;
210out:
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