aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/core.c
diff options
context:
space:
mode:
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);