[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