Merge tag 'nfc-next-4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo...
[deliverable/linux.git] / net / netfilter / nf_tables_core.c
index 3b90eb2b2c55453e989c891a3f815be6e1da22d1..ef4dfcbaf149f4c207f0096ceb6b8a6c1aa3d924 100644 (file)
@@ -8,6 +8,7 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_log.h>
 
+enum nft_trace {
+       NFT_TRACE_RULE,
+       NFT_TRACE_RETURN,
+       NFT_TRACE_POLICY,
+};
+
+static const char *const comments[] = {
+       [NFT_TRACE_RULE]        = "rule",
+       [NFT_TRACE_RETURN]      = "return",
+       [NFT_TRACE_POLICY]      = "policy",
+};
+
+static struct nf_loginfo trace_loginfo = {
+       .type = NF_LOG_TYPE_LOG,
+       .u = {
+               .log = {
+                       .level = LOGLEVEL_WARNING,
+                       .logflags = NF_LOG_MASK,
+               },
+       },
+};
+
+static void __nft_trace_packet(const struct nft_pktinfo *pkt,
+                              const struct nft_chain *chain,
+                              int rulenum, enum nft_trace type)
+{
+       struct net *net = dev_net(pkt->in ? pkt->in : pkt->out);
+
+       nf_log_trace(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in,
+                    pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ",
+                    chain->table->name, chain->name, comments[type],
+                    rulenum);
+}
+
+static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
+                                   const struct nft_chain *chain,
+                                   int rulenum, enum nft_trace type)
+{
+       if (unlikely(pkt->skb->nf_trace))
+               __nft_trace_packet(pkt, chain, rulenum, type);
+}
+
 static void nft_cmp_fast_eval(const struct nft_expr *expr,
                              struct nft_data data[NFT_REG_MAX + 1])
 {
@@ -66,44 +109,11 @@ struct nft_jumpstack {
        int                     rulenum;
 };
 
-enum nft_trace {
-       NFT_TRACE_RULE,
-       NFT_TRACE_RETURN,
-       NFT_TRACE_POLICY,
-};
-
-static const char *const comments[] = {
-       [NFT_TRACE_RULE]        = "rule",
-       [NFT_TRACE_RETURN]      = "return",
-       [NFT_TRACE_POLICY]      = "policy",
-};
-
-static struct nf_loginfo trace_loginfo = {
-       .type = NF_LOG_TYPE_LOG,
-       .u = {
-               .log = {
-                       .level = 4,
-                       .logflags = NF_LOG_MASK,
-               },
-       },
-};
-
-static void nft_trace_packet(const struct nft_pktinfo *pkt,
-                            const struct nft_chain *chain,
-                            int rulenum, enum nft_trace type)
-{
-       struct net *net = dev_net(pkt->in ? pkt->in : pkt->out);
-
-       nf_log_packet(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in,
-                     pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ",
-                     chain->table->name, chain->name, comments[type],
-                     rulenum);
-}
-
 unsigned int
 nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
 {
        const struct nft_chain *chain = ops->priv, *basechain = chain;
+       const struct net *net = read_pnet(&nft_base_chain(basechain)->pnet);
        const struct nft_rule *rule;
        const struct nft_expr *expr, *last;
        struct nft_data data[NFT_REG_MAX + 1];
@@ -111,11 +121,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
        struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE];
        struct nft_stats *stats;
        int rulenum;
-       /*
-        * Cache cursor to avoid problems in case that the cursor is updated
-        * while traversing the ruleset.
-        */
-       unsigned int gencursor = ACCESS_ONCE(chain->net->nft.gencursor);
+       unsigned int gencursor = nft_genmask_cur(net);
 
 do_chain:
        rulenum = 0;
@@ -146,8 +152,7 @@ next_rule:
                        data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
                        continue;
                case NFT_CONTINUE:
-                       if (unlikely(pkt->skb->nf_trace))
-                               nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
+                       nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
                        continue;
                }
                break;
@@ -157,37 +162,28 @@ next_rule:
        case NF_ACCEPT:
        case NF_DROP:
        case NF_QUEUE:
-               if (unlikely(pkt->skb->nf_trace))
-                       nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
-
+               nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
                return data[NFT_REG_VERDICT].verdict;
        }
 
        switch (data[NFT_REG_VERDICT].verdict) {
        case NFT_JUMP:
-               if (unlikely(pkt->skb->nf_trace))
-                       nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
-
                BUG_ON(stackptr >= NFT_JUMP_STACK_SIZE);
                jumpstack[stackptr].chain = chain;
                jumpstack[stackptr].rule  = rule;
                jumpstack[stackptr].rulenum = rulenum;
                stackptr++;
-               chain = data[NFT_REG_VERDICT].chain;
-               goto do_chain;
+               /* fall through */
        case NFT_GOTO:
-               if (unlikely(pkt->skb->nf_trace))
-                       nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
+               nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
 
                chain = data[NFT_REG_VERDICT].chain;
                goto do_chain;
-       case NFT_RETURN:
-               if (unlikely(pkt->skb->nf_trace))
-                       nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RETURN);
-               break;
        case NFT_CONTINUE:
-               if (unlikely(pkt->skb->nf_trace && !(chain->flags & NFT_BASE_CHAIN)))
-                       nft_trace_packet(pkt, chain, ++rulenum, NFT_TRACE_RETURN);
+               rulenum++;
+               /* fall through */
+       case NFT_RETURN:
+               nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RETURN);
                break;
        default:
                WARN_ON(1);
@@ -201,8 +197,7 @@ next_rule:
                goto next_rule;
        }
 
-       if (unlikely(pkt->skb->nf_trace))
-               nft_trace_packet(pkt, basechain, -1, NFT_TRACE_POLICY);
+       nft_trace_packet(pkt, basechain, -1, NFT_TRACE_POLICY);
 
        rcu_read_lock_bh();
        stats = this_cpu_ptr(rcu_dereference(nft_base_chain(basechain)->stats));
This page took 0.027153 seconds and 5 git commands to generate.