summaryrefslogtreecommitdiffstats
path: root/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
diff options
context:
space:
mode:
authorFlorian Westphal2015-11-18 23:32:40 +0100
committerPablo Neira Ayuso2015-11-23 17:54:45 +0100
commitdaaa7d647f81f3f1494d9a9029d611b666d63181 (patch)
treebc0ecf36c021ae09c845364acbd918afbd0a693e /net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
parentnetfilter: ipv6: nf_defrag: avoid/free clone operations (diff)
downloadkernel-qcow2-linux-daaa7d647f81f3f1494d9a9029d611b666d63181.tar.gz
kernel-qcow2-linux-daaa7d647f81f3f1494d9a9029d611b666d63181.tar.xz
kernel-qcow2-linux-daaa7d647f81f3f1494d9a9029d611b666d63181.zip
netfilter: ipv6: avoid nf_iterate recursion
The previous patch changed nf_ct_frag6_gather() to morph reassembled skb with the previous one. This means that the return value is always NULL or the skb argument. So change it to an err value. Instead of invoking NF_HOOK recursively with threshold to skip already-called hooks we can now just return NF_ACCEPT to move on to the next hook except for -EINPROGRESS (which means skb has been queued for reassembly), in which case we return NF_STOLEN. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/ipv6/netfilter/nf_defrag_ipv6_hooks.c')
-rw-r--r--net/ipv6/netfilter/nf_defrag_ipv6_hooks.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
index fb96b1018884..f7aab5ab93a5 100644
--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -55,7 +55,7 @@ static unsigned int ipv6_defrag(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
- struct sk_buff *reasm;
+ int err;
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
/* Previously seen (loopback)? */
@@ -63,17 +63,13 @@ static unsigned int ipv6_defrag(void *priv,
return NF_ACCEPT;
#endif
- reasm = nf_ct_frag6_gather(state->net, skb,
- nf_ct6_defrag_user(state->hook, skb));
+ err = nf_ct_frag6_gather(state->net, skb,
+ nf_ct6_defrag_user(state->hook, skb));
/* queued */
- if (reasm == NULL)
+ if (err == -EINPROGRESS)
return NF_STOLEN;
- NF_HOOK_THRESH(NFPROTO_IPV6, state->hook, state->net, state->sk, reasm,
- state->in, state->out,
- state->okfn, NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
-
- return NF_STOLEN;
+ return NF_ACCEPT;
}
static struct nf_hook_ops ipv6_defrag_ops[] = {