netfilter: nf_tables: consolidate rule verdict trace call
[platform/kernel/linux-rpi.git] / net / netfilter / nf_tables_core.c
index 866cfba..7defe5a 100644 (file)
@@ -67,6 +67,36 @@ static void nft_cmp_fast_eval(const struct nft_expr *expr,
        regs->verdict.code = NFT_BREAK;
 }
 
+static noinline void __nft_trace_verdict(struct nft_traceinfo *info,
+                                        const struct nft_chain *chain,
+                                        const struct nft_regs *regs)
+{
+       enum nft_trace_types type;
+
+       switch (regs->verdict.code) {
+       case NFT_CONTINUE:
+       case NFT_RETURN:
+               type = NFT_TRACETYPE_RETURN;
+               break;
+       default:
+               type = NFT_TRACETYPE_RULE;
+               break;
+       }
+
+       __nft_trace_packet(info, chain, type);
+}
+
+static inline void nft_trace_verdict(struct nft_traceinfo *info,
+                                    const struct nft_chain *chain,
+                                    const struct nft_rule *rule,
+                                    const struct nft_regs *regs)
+{
+       if (static_branch_unlikely(&nft_trace_enabled)) {
+               info->rule = rule;
+               __nft_trace_verdict(info, chain, regs);
+       }
+}
+
 static bool nft_payload_fast_eval(const struct nft_expr *expr,
                                  struct nft_regs *regs,
                                  const struct nft_pktinfo *pkt)
@@ -79,7 +109,7 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,
        if (priv->base == NFT_PAYLOAD_NETWORK_HEADER)
                ptr = skb_network_header(skb);
        else {
-               if (!pkt->tprot_set)
+               if (!(pkt->flags & NFT_PKTINFO_L4PROTO))
                        return false;
                ptr = skb_network_header(skb) + nft_thoff(pkt);
        }
@@ -162,7 +192,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
        struct nft_rule *const *rules;
        const struct nft_rule *rule;
        const struct nft_expr *expr, *last;
-       struct nft_regs regs;
+       struct nft_regs regs = {};
        unsigned int stackptr = 0;
        struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE];
        bool genbit = READ_ONCE(net->nft.gencursor);
@@ -207,13 +237,13 @@ next_rule:
                break;
        }
 
+       nft_trace_verdict(&info, chain, rule, &regs);
+
        switch (regs.verdict.code & NF_VERDICT_MASK) {
        case NF_ACCEPT:
        case NF_DROP:
        case NF_QUEUE:
        case NF_STOLEN:
-               nft_trace_packet(&info, chain, rule,
-                                NFT_TRACETYPE_RULE);
                return regs.verdict.code;
        }
 
@@ -226,15 +256,10 @@ next_rule:
                stackptr++;
                fallthrough;
        case NFT_GOTO:
-               nft_trace_packet(&info, chain, rule,
-                                NFT_TRACETYPE_RULE);
-
                chain = regs.verdict.chain;
                goto do_chain;
        case NFT_CONTINUE:
        case NFT_RETURN:
-               nft_trace_packet(&info, chain, rule,
-                                NFT_TRACETYPE_RETURN);
                break;
        default:
                WARN_ON(1);