]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
netfilter: nf_tables: prepare nft audit for set element compaction
authorFlorian Westphal <fw@strlen.de>
Wed, 13 Nov 2024 15:35:51 +0000 (16:35 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 14 Nov 2024 11:40:55 +0000 (12:40 +0100)
nftables audit log format emits the number of added/deleted rules, sets,
set elements and so on, to userspace:

    table=t1 family=2 entries=4 op=nft_register_set
                      ~~~~~~~~~

At this time, the 'entries' key is the number of transactions that will
be applied.

The upcoming set element compression will coalesce subsequent
adds/deletes to the same set requests in the same transaction
request to conseve memory.

Without this patch, we'd under-report the number of altered elements.

Increment the audit counter by the number of elements to keep the reported
entries value the same.

Without this, nft_audit.sh selftest fails because the recorded
(expected) entries key is smaller than the expected one.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_tables_api.c

index 0882f78c2204749953118a11c7f8b2ef69ce5e04..5b517884155386755480cde5b325a6403e28e805 100644 (file)
@@ -10398,9 +10398,24 @@ static void nf_tables_commit_audit_free(struct list_head *adl)
        }
 }
 
+/* nft audit emits the number of elements that get added/removed/updated,
+ * so NEW/DELSETELEM needs to increment based on the total elem count.
+ */
+static unsigned int nf_tables_commit_audit_entrycount(const struct nft_trans *trans)
+{
+       switch (trans->msg_type) {
+       case NFT_MSG_NEWSETELEM:
+       case NFT_MSG_DELSETELEM:
+               return nft_trans_container_elem(trans)->nelems;
+       }
+
+       return 1;
+}
+
 static void nf_tables_commit_audit_collect(struct list_head *adl,
-                                          struct nft_table *table, u32 op)
+                                          const struct nft_trans *trans, u32 op)
 {
+       const struct nft_table *table = trans->table;
        struct nft_audit_data *adp;
 
        list_for_each_entry(adp, adl, list) {
@@ -10410,7 +10425,7 @@ static void nf_tables_commit_audit_collect(struct list_head *adl,
        WARN_ONCE(1, "table=%s not expected in commit list", table->name);
        return;
 found:
-       adp->entries++;
+       adp->entries += nf_tables_commit_audit_entrycount(trans);
        if (!adp->op || adp->op > op)
                adp->op = op;
 }
@@ -10569,7 +10584,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
 
                nft_ctx_update(&ctx, trans);
 
-               nf_tables_commit_audit_collect(&adl, table, trans->msg_type);
+               nf_tables_commit_audit_collect(&adl, trans, trans->msg_type);
                switch (trans->msg_type) {
                case NFT_MSG_NEWTABLE:
                        if (nft_trans_table_update(trans)) {