aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/core.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-11-03 10:56:39 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2016-11-03 11:52:59 +0100
commit26dfab7216291cee94d6012d06c255fcc15cd72a (patch)
treed22fdcd3cce7d329887f6c3fd49a965d57a239e4 /net/netfilter/core.c
parentnetfilter: remove hook_entries field from nf_hook_state (diff)
downloadlinux-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.c73
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);