[PATCH v1 2/6] netlink_netfilter: decode expressions

Mathis Marion Mathis.Marion at silabs.com
Thu Jun 12 09:56:02 UTC 2025


From: Mathis Marion <mathis.marion at silabs.com>

Signed-off-by: Mathis Marion <mathis.marion at silabs.com>
---
 src/netlink_netfilter.c         | 177 +++++++++++++++++++++++++++++++-
 src/xlat/nft_cmp_attrs.in       |   6 ++
 src/xlat/nft_data_attrs.in      |   5 +
 src/xlat/nft_expr_attrs.in      |   5 +
 src/xlat/nft_immediate_attrs.in |   5 +
 src/xlat/nft_list_attrs.in      |   4 +
 src/xlat/nft_lookup_attrs.in    |   8 ++
 src/xlat/nft_meta_attrs.in      |   6 ++
 src/xlat/nft_payload_attrs.in   |  11 ++
 src/xlat/nft_verdict_attrs.in   |   6 ++
 10 files changed, 229 insertions(+), 4 deletions(-)
 create mode 100644 src/xlat/nft_cmp_attrs.in
 create mode 100644 src/xlat/nft_data_attrs.in
 create mode 100644 src/xlat/nft_expr_attrs.in
 create mode 100644 src/xlat/nft_immediate_attrs.in
 create mode 100644 src/xlat/nft_list_attrs.in
 create mode 100644 src/xlat/nft_lookup_attrs.in
 create mode 100644 src/xlat/nft_meta_attrs.in
 create mode 100644 src/xlat/nft_payload_attrs.in
 create mode 100644 src/xlat/nft_verdict_attrs.in

diff --git a/src/netlink_netfilter.c b/src/netlink_netfilter.c
index 029a9bdf7..8e5d28f00 100644
--- a/src/netlink_netfilter.c
+++ b/src/netlink_netfilter.c
@@ -19,14 +19,183 @@
 #include "xlat/nl_netfilter_msg_types.h"
 #include "xlat/nl_netfilter_subsys_ids.h"
 #include "xlat/nft_chain_attrs.h"
+#include "xlat/nft_cmp_attrs.h"
+#include "xlat/nft_data_attrs.h"
+#include "xlat/nft_expr_attrs.h"
 #include "xlat/nft_flowtable_attrs.h"
 #include "xlat/nft_gen_attrs.h"
 #include "xlat/nft_obj_attrs.h"
+#include "xlat/nft_immediate_attrs.h"
+#include "xlat/nft_list_attrs.h"
+#include "xlat/nft_lookup_attrs.h"
+#include "xlat/nft_meta_attrs.h"
+#include "xlat/nft_payload_attrs.h"
 #include "xlat/nft_rule_attrs.h"
 #include "xlat/nft_set_attrs.h"
+#include "xlat/nft_set_elem_attrs.h"
 #include "xlat/nft_set_elem_list_attrs.h"
 #include "xlat/nft_table_attrs.h"
 #include "xlat/nft_trace_attrs.h"
+#include "xlat/nft_verdict_attrs.h"
+
+static bool decode_verdict(struct tcb *tcp, kernel_ulong_t addr,
+			   unsigned int len, const void *opaque_data)
+{
+	static const nla_decoder_t decoders[] = {
+		[NFTA_VERDICT_CODE]	= decode_nla_be32,
+		[NFTA_VERDICT_CHAIN]	= decode_nla_str,
+		[NFTA_VERDICT_CHAIN_ID]	= decode_nla_be32,
+	};
+
+	decode_nlattr(tcp, addr, len, nft_verdict_attrs, "NFTA_VERDICT_???",
+		      decoders, ARRAY_SIZE(decoders), opaque_data);
+	return true;
+}
+
+static bool decode_data(struct tcb *tcp, kernel_ulong_t addr,
+			unsigned int len, const void *opaque_data)
+{
+	static const nla_decoder_t decoders[] = {
+		[NFTA_DATA_VALUE]	= NULL,
+		[NFTA_DATA_VERDICT]	= decode_verdict,
+	};
+
+	decode_nlattr(tcp, addr, len, nft_data_attrs, "NFTA_DATA_???",
+		      decoders, ARRAY_SIZE(decoders), opaque_data);
+	return true;
+}
+
+static const nla_decoder_t nfta_cmp_decoders[] = {
+	[NFTA_CMP_SREG]	= decode_nla_be32,
+	[NFTA_CMP_OP]	= decode_nla_be32,
+	[NFTA_CMP_DATA]	= decode_data,
+};
+
+static const nla_decoder_t nfta_immediate_decoders[] = {
+	[NFTA_IMMEDIATE_DREG]	= decode_nla_be32,
+	[NFTA_IMMEDIATE_DATA]	= decode_data,
+};
+
+static const nla_decoder_t nfta_meta_decoders[] = {
+	[NFTA_META_DREG]	= decode_nla_be32,
+	[NFTA_META_KEY]		= decode_nla_be32,
+	[NFTA_META_SREG]	= decode_nla_be32,
+};
+
+static const nla_decoder_t nfta_lookup_decoders[] = {
+	[NFTA_LOOKUP_SET]	= decode_nla_str,
+	[NFTA_LOOKUP_SREG]	= decode_nla_be32,
+	[NFTA_LOOKUP_DREG]	= decode_nla_be32,
+	[NFTA_LOOKUP_SET_ID]	= decode_nla_be32,
+	[NFTA_LOOKUP_FLAGS]	= decode_nla_be32,
+};
+
+static const nla_decoder_t nfta_payload_decoders[] = {
+	[NFTA_PAYLOAD_DREG]		= decode_nla_be32,
+	[NFTA_PAYLOAD_BASE]		= decode_nla_be32,
+	[NFTA_PAYLOAD_OFFSET]		= decode_nla_be32,
+	[NFTA_PAYLOAD_LEN]		= decode_nla_be32,
+	[NFTA_PAYLOAD_SREG]		= decode_nla_be32,
+	[NFTA_PAYLOAD_CSUM_TYPE]	= decode_nla_be32,
+	[NFTA_PAYLOAD_CSUM_OFFSET]	= decode_nla_be32,
+	[NFTA_PAYLOAD_CSUM_FLAGS]	= decode_nla_be32,
+};
+
+struct nlta_expr_data_decoder {
+	const char *name;
+	const struct xlat *xlat;
+	const char *dflt;
+	const nla_decoder_t *decoders;
+	unsigned int size;
+};
+
+static const struct nlta_expr_data_decoder nlta_expr_data_decoders[] = {
+	{ "cmp",	nft_cmp_attrs,		"NFTA_CMP_???",
+	  nfta_cmp_decoders, ARRAY_SIZE(nfta_cmp_decoders) },
+	{ "immediate",	nft_immediate_attrs,	"NFTA_IMMEDIATE_???",
+	  nfta_immediate_decoders, ARRAY_SIZE(nfta_immediate_decoders) },
+	{ "lookup",	nft_lookup_attrs,	"NFTA_LOOKUP_???",
+	  nfta_lookup_decoders, ARRAY_SIZE(nfta_lookup_decoders) },
+	{ "meta",	nft_meta_attrs,		"NFTA_META_???",
+	  nfta_meta_decoders, ARRAY_SIZE(nfta_meta_decoders) },
+	{ "payload",	nft_payload_attrs,	"NFTA_PAYLOAD_???",
+	  nfta_payload_decoders, ARRAY_SIZE(nfta_payload_decoders) },
+	{ 0 },
+};
+
+static bool decode_expr_data(struct tcb *tcp, kernel_ulong_t addr,
+			     unsigned int len, const void *name)
+{
+	const struct nlta_expr_data_decoder *decoder;
+
+	for (decoder = nlta_expr_data_decoders; decoder->decoders; decoder++)
+		if (name && !strcmp(decoder->name, name))
+			break;
+	if (decoder)
+		decode_nlattr(tcp, addr, len, decoder->xlat, decoder->dflt,
+			      decoder->decoders, decoder->size, NULL);
+	else
+		decode_nlattr(tcp, addr, len, NULL, NULL, NULL, 0, NULL);
+	return true;
+}
+
+static kernel_ulong_t find_nla(struct tcb *tcp, kernel_ulong_t addr, unsigned int len,
+			       struct nlattr *nla, unsigned short type)
+{
+	while (len >= sizeof(struct nlattr) && tfetch_obj(tcp, addr, nla)) {
+		const unsigned int nla_len = NLA_ALIGN(nla->nla_len);
+
+		if (nla->nla_len < NLA_HDRLEN || nla->nla_len > len || addr + nla_len < addr)
+			return 0;
+		if (nla->nla_type == type)
+			return addr;
+		len -= nla_len;
+		addr += nla_len;
+	}
+	return 0;
+}
+
+static bool decode_expr(struct tcb *tcp, kernel_ulong_t addr,
+			unsigned int len, const void *opaque_data)
+{
+	static const nla_decoder_t decoders[] = {
+		[NFTA_EXPR_NAME]	= decode_nla_str,
+		[NFTA_EXPR_DATA]	= decode_expr_data,
+	};
+	kernel_ulong_t name_addr;
+	struct nlattr name_attr;
+	char *name = NULL;
+	int name_len;
+
+	name_addr = find_nla(tcp, addr, len, &name_attr, NFTA_EXPR_NAME);
+	if (name_addr) {
+		name = xmalloc(name_attr.nla_len - NLA_HDRLEN);
+		name_len = umovestr(tcp, name_addr + NLA_HDRLEN,
+				    name_attr.nla_len - NLA_HDRLEN, name);
+		if (!name_len) {
+			free(name);
+			name = NULL;
+		}
+	}
+
+	decode_nlattr(tcp, addr, len, nft_expr_attrs, "NFTA_EXPR_???",
+		      decoders, ARRAY_SIZE(decoders), name);
+
+	free(name);
+	return true;
+}
+
+static bool decode_exprs(struct tcb *tcp, kernel_ulong_t addr,
+			 unsigned int len, const void *opaque_data)
+{
+	static const nla_decoder_t decoders[] = {
+		[NFTA_LIST_ELEM]	= decode_expr,
+	};
+
+	decode_nlattr(tcp, addr, len, nft_list_attrs, "NFTA_LIST_???",
+		      decoders, ARRAY_SIZE(decoders), opaque_data);
+	return true;
+}
 
 struct nfta_decoder {
 	const struct xlat *xlat;
@@ -78,7 +247,7 @@ static const nla_decoder_t nfta_rule_decoders[] = {
 	[NFTA_RULE_TABLE]	= decode_nla_str,
 	[NFTA_RULE_CHAIN]	= decode_nla_str,
 	[NFTA_RULE_HANDLE]	= decode_nla_be64,
-	[NFTA_RULE_EXPRESSIONS]	= NULL, // TODO
+	[NFTA_RULE_EXPRESSIONS]	= decode_exprs,
 	[NFTA_RULE_COMPAT]	= NULL, // TODO
 	[NFTA_RULE_POSITION]	= decode_nla_be64,
 	[NFTA_RULE_USERDATA]	= NULL,
@@ -112,8 +281,8 @@ static const nla_decoder_t nfta_set_decoders[] = {
 	[NFTA_SET_PAD]		= NULL,
 	[NFTA_SET_OBJ_TYPE]	= decode_nla_be32,
 	[NFTA_SET_HANDLE]	= decode_nla_be64,
-	[NFTA_SET_EXPR]		= NULL, // TODO
-	[NFTA_SET_EXPRESSIONS]	= NULL, // TODO
+	[NFTA_SET_EXPR]		= decode_expr,
+	[NFTA_SET_EXPRESSIONS]	= decode_exprs,
 };
 
 static const struct nfta_decoder nfta_set_decoder = {
@@ -142,7 +311,7 @@ static const nla_decoder_t nfta_trace_decoders[] = {
 	[NFTA_TRACE_CHAIN]		= decode_nla_str,
 	[NFTA_TRACE_RULE_HANDLE]	= decode_nla_be64,
 	[NFTA_TRACE_TYPE]		= decode_nla_be32,
-	[NFTA_TRACE_VERDICT]		= NULL, // TODO
+	[NFTA_TRACE_VERDICT]		= decode_verdict,
 	[NFTA_TRACE_ID]			= decode_nla_u32,
 	[NFTA_TRACE_LL_HEADER]		= NULL,
 	[NFTA_TRACE_NETWORK_HEADER]	= NULL,
diff --git a/src/xlat/nft_cmp_attrs.in b/src/xlat/nft_cmp_attrs.in
new file mode 100644
index 000000000..1f15453cc
--- /dev/null
+++ b/src/xlat/nft_cmp_attrs.in
@@ -0,0 +1,6 @@
+#unconditional
+#value_indexed
+NFTA_CMP_UNSPEC
+NFTA_CMP_SREG
+NFTA_CMP_OP
+NFTA_CMP_DATA
diff --git a/src/xlat/nft_data_attrs.in b/src/xlat/nft_data_attrs.in
new file mode 100644
index 000000000..1d7f54f4c
--- /dev/null
+++ b/src/xlat/nft_data_attrs.in
@@ -0,0 +1,5 @@
+#unconditional
+#value_indexed
+NFTA_DATA_UNSPEC
+NFTA_DATA_VALUE
+NFTA_DATA_VERDICT
diff --git a/src/xlat/nft_expr_attrs.in b/src/xlat/nft_expr_attrs.in
new file mode 100644
index 000000000..e4ff8809a
--- /dev/null
+++ b/src/xlat/nft_expr_attrs.in
@@ -0,0 +1,5 @@
+#unconditional
+#value_indexed
+NFTA_EXPR_UNSPEC
+NFTA_EXPR_NAME
+NFTA_EXPR_DATA
diff --git a/src/xlat/nft_immediate_attrs.in b/src/xlat/nft_immediate_attrs.in
new file mode 100644
index 000000000..d01807ca3
--- /dev/null
+++ b/src/xlat/nft_immediate_attrs.in
@@ -0,0 +1,5 @@
+#unconditional
+#value_indexed
+NFTA_IMMEDIATE_UNSPEC
+NFTA_IMMEDIATE_DREG
+NFTA_IMMEDIATE_DATA
diff --git a/src/xlat/nft_list_attrs.in b/src/xlat/nft_list_attrs.in
new file mode 100644
index 000000000..2d61c52e4
--- /dev/null
+++ b/src/xlat/nft_list_attrs.in
@@ -0,0 +1,4 @@
+#unconditional
+#value_indexed
+NFTA_LIST_UNSPEC
+NFTA_LIST_ELEM
diff --git a/src/xlat/nft_lookup_attrs.in b/src/xlat/nft_lookup_attrs.in
new file mode 100644
index 000000000..18774214b
--- /dev/null
+++ b/src/xlat/nft_lookup_attrs.in
@@ -0,0 +1,8 @@
+#unconditional
+#value_indexed
+NFTA_LOOKUP_UNSPEC
+NFTA_LOOKUP_SET
+NFTA_LOOKUP_SREG
+NFTA_LOOKUP_DREG
+NFTA_LOOKUP_SET_ID
+NFTA_LOOKUP_FLAGS
diff --git a/src/xlat/nft_meta_attrs.in b/src/xlat/nft_meta_attrs.in
new file mode 100644
index 000000000..3ffbe9afe
--- /dev/null
+++ b/src/xlat/nft_meta_attrs.in
@@ -0,0 +1,6 @@
+#unconditional
+#value_indexed
+NFTA_META_UNSPEC
+NFTA_META_DREG
+NFTA_META_KEY
+NFTA_META_SREG
diff --git a/src/xlat/nft_payload_attrs.in b/src/xlat/nft_payload_attrs.in
new file mode 100644
index 000000000..bf439a0ec
--- /dev/null
+++ b/src/xlat/nft_payload_attrs.in
@@ -0,0 +1,11 @@
+#unconditional
+#value_indexed
+NFTA_PAYLOAD_UNSPEC
+NFTA_PAYLOAD_DREG
+NFTA_PAYLOAD_BASE
+NFTA_PAYLOAD_OFFSET
+NFTA_PAYLOAD_LEN
+NFTA_PAYLOAD_SREG
+NFTA_PAYLOAD_CSUM_TYPE
+NFTA_PAYLOAD_CSUM_OFFSET
+NFTA_PAYLOAD_CSUM_FLAGS
diff --git a/src/xlat/nft_verdict_attrs.in b/src/xlat/nft_verdict_attrs.in
new file mode 100644
index 000000000..05542f156
--- /dev/null
+++ b/src/xlat/nft_verdict_attrs.in
@@ -0,0 +1,6 @@
+#unconditional
+#value_indexed
+NFTA_VERDICT_UNSPEC
+NFTA_VERDICT_CODE
+NFTA_VERDICT_CHAIN
+NFTA_VERDICT_CHAIN_ID
-- 
2.47.2



More information about the Strace-devel mailing list