netfilter: use switch() to handle verdict cases from nf_hook_slow()
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 3 Nov 2016 09:56:30 +0000 (10:56 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 3 Nov 2016 10:52:57 +0000 (11:52 +0100)
Use switch() for verdict handling and add explicit handling for
NF_STOLEN and other non-conventional verdicts.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/core.c

index 14f97b6..6462337 100644 (file)
@@ -328,22 +328,32 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state)
 {
        struct nf_hook_entry *entry;
        unsigned int verdict;
 {
        struct nf_hook_entry *entry;
        unsigned int verdict;
-       int ret = 0;
+       int ret;
 
        entry = rcu_dereference(state->hook_entries);
 next_hook:
        verdict = nf_iterate(skb, state, &entry);
 
        entry = rcu_dereference(state->hook_entries);
 next_hook:
        verdict = nf_iterate(skb, state, &entry);
-       if (verdict == NF_ACCEPT) {
+       switch (verdict & NF_VERDICT_MASK) {
+       case NF_ACCEPT:
                ret = 1;
                ret = 1;
-       } else if ((verdict & NF_VERDICT_MASK) == NF_DROP) {
+               break;
+       case NF_DROP:
                kfree_skb(skb);
                ret = NF_DROP_GETERR(verdict);
                if (ret == 0)
                        ret = -EPERM;
                kfree_skb(skb);
                ret = NF_DROP_GETERR(verdict);
                if (ret == 0)
                        ret = -EPERM;
-       } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
+               break;
+       case NF_QUEUE:
                ret = nf_queue(skb, state, &entry, verdict);
                if (ret == 1 && entry)
                        goto next_hook;
                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;
 }
        }
        return ret;
 }