diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-11-03 10:56:39 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-11-03 11:52:59 +0100 |
commit | 26dfab7216291cee94d6012d06c255fcc15cd72a (patch) | |
tree | d22fdcd3cce7d329887f6c3fd49a965d57a239e4 /net/netfilter/core.c | |
parent | netfilter: remove hook_entries field from nf_hook_state (diff) | |
download | linux-dev-26dfab7216291cee94d6012d06c255fcc15cd72a.tar.xz linux-dev-26dfab7216291cee94d6012d06c255fcc15cd72a.zip |
netfilter: merge nf_iterate() into nf_hook_slow()
nf_iterate() has become rather simple, we can integrate this code into
nf_hook_slow() to reduce the amount of LOC in the core path.
However, we still need nf_iterate() around for nf_queue packet handling,
so move this function there where we only need it. I think it should be
possible to refactor nf_queue code to get rid of it definitely, but
given this is slow path anyway, let's have a look this later.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/core.c')
-rw-r--r-- | net/netfilter/core.c | 73 |
1 files changed, 28 insertions, 45 deletions
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index ebece48b8392..bd9272eeccb5 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -302,26 +302,6 @@ void _nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n) } EXPORT_SYMBOL(_nf_unregister_hooks); -unsigned int nf_iterate(struct sk_buff *skb, - struct nf_hook_state *state, - struct nf_hook_entry **entryp) -{ - unsigned int verdict; - - do { -repeat: - verdict = (*entryp)->ops.hook((*entryp)->ops.priv, skb, state); - if (verdict != NF_ACCEPT) { - if (verdict != NF_REPEAT) - return verdict; - goto repeat; - } - *entryp = rcu_dereference((*entryp)->next); - } while (*entryp); - return NF_ACCEPT; -} - - /* Returns 1 if okfn() needs to be executed by the caller, * -EPERM for NF_DROP, 0 otherwise. Caller must hold rcu_read_lock. */ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, @@ -330,31 +310,34 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, unsigned int verdict; int ret; -next_hook: - verdict = nf_iterate(skb, state, &entry); - switch (verdict & NF_VERDICT_MASK) { - case NF_ACCEPT: - ret = 1; - break; - case NF_DROP: - kfree_skb(skb); - ret = NF_DROP_GETERR(verdict); - if (ret == 0) - ret = -EPERM; - break; - case NF_QUEUE: - ret = nf_queue(skb, state, &entry, verdict); - if (ret == 1 && entry) - goto next_hook; - /* Fall through. */ - default: - /* Implicit handling for NF_STOLEN, as well as any other non - * conventional verdicts. - */ - ret = 0; - break; - } - return ret; + do { + verdict = entry->ops.hook(entry->ops.priv, skb, state); + switch (verdict & NF_VERDICT_MASK) { + case NF_ACCEPT: + entry = rcu_dereference(entry->next); + break; + case NF_DROP: + kfree_skb(skb); + ret = NF_DROP_GETERR(verdict); + if (ret == 0) + ret = -EPERM; + return ret; + case NF_REPEAT: + continue; + case NF_QUEUE: + ret = nf_queue(skb, state, &entry, verdict); + if (ret == 1 && entry) + continue; + return ret; + default: + /* Implicit handling for NF_STOLEN, as well as any other + * non conventional verdicts. + */ + return 0; + } + } while (entry); + + return 1; } EXPORT_SYMBOL(nf_hook_slow); |