]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink: Show the handles of unknown rules in "nft monitor trace"
authorLuis Ressel <aranea@aixah.de>
Thu, 26 Mar 2020 15:22:29 +0000 (15:22 +0000)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 1 Apr 2020 10:40:44 +0000 (12:40 +0200)
When "nft monitor trace" doesn't know a rule (because it was only added
to the ruleset after nft was invoked), that rule is silently omitted in
the trace output, which can come as a surprise when debugging issues.

Instead, we can at least show the information we got via netlink, i.e.
the family, table and chain name, rule handle and verdict.

Signed-off-by: Luis Ressel <aranea@aixah.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/netlink.c

index 24d746ca636b7da3123882fb848316770386afe2..7b7ef39e7807592a65400e1359ee54413ba744bf 100644 (file)
@@ -1449,38 +1449,50 @@ static void trace_print_policy(const struct nftnl_trace *nlt,
        expr_free(expr);
 }
 
-static void trace_print_rule(const struct nftnl_trace *nlt,
-                             struct output_ctx *octx, struct nft_cache *cache)
+static struct rule *trace_lookup_rule(const struct nftnl_trace *nlt,
+                                     uint64_t rule_handle,
+                                     struct nft_cache *cache)
 {
-       const struct table *table;
-       uint64_t rule_handle;
        struct chain *chain;
-       struct rule *rule;
+       struct table *table;
        struct handle h;
 
        h.family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
-       h.table.name  = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
-       h.chain.name  = nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN);
+       h.table.name = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
+       h.chain.name = nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN);
 
        if (!h.table.name)
-               return;
+               return NULL;
 
        table = table_lookup(&h, cache);
        if (!table)
-               return;
+               return NULL;
 
        chain = chain_lookup(table, &h);
        if (!chain)
-               return;
+               return NULL;
+
+       return rule_lookup(chain, rule_handle);
+}
+
+static void trace_print_rule(const struct nftnl_trace *nlt,
+                             struct output_ctx *octx, struct nft_cache *cache)
+{
+       uint64_t rule_handle;
+       struct rule *rule;
 
        rule_handle = nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE);
-       rule = rule_lookup(chain, rule_handle);
-       if (!rule)
-               return;
+       rule = trace_lookup_rule(nlt, rule_handle, cache);
 
        trace_print_hdr(nlt, octx);
-       nft_print(octx, "rule ");
-       rule_print(rule, octx);
+
+       if (rule) {
+               nft_print(octx, "rule ");
+               rule_print(rule, octx);
+       } else {
+               nft_print(octx, "unknown rule handle %" PRIu64, rule_handle);
+       }
+
        nft_print(octx, " (");
        trace_print_verdict(nlt, octx);
        nft_print(octx, ")\n");