summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2025-05-22 15:51:15 +0200
committerFlorian Westphal <fw@strlen.de>2025-07-04 10:34:39 +0200
commit56e37303ed30a4f9b73ec1f90b53da7dda645748 (patch)
tree76bcf65358a469fce8a9763a34ad0caa8a6bf45d
parent81d19bc4a52cd0d4ec976c19d2320e102553c315 (diff)
trace: add support for TRACE_CT information
Decode direction/id/state/status information. This will be used by 'nftables monitor trace' to print a packets conntrack state. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/libnftnl/trace.h4
-rw-r--r--include/linux/netfilter/nf_tables.h8
-rw-r--r--src/trace.c46
3 files changed, 58 insertions, 0 deletions
diff --git a/include/libnftnl/trace.h b/include/libnftnl/trace.h
index 18ab0c3..5d66b50 100644
--- a/include/libnftnl/trace.h
+++ b/include/libnftnl/trace.h
@@ -28,6 +28,10 @@ enum nftnl_trace_attr {
NFTNL_TRACE_VERDICT,
NFTNL_TRACE_NFPROTO,
NFTNL_TRACE_POLICY,
+ NFTNL_TRACE_CT_DIRECTION,
+ NFTNL_TRACE_CT_ID,
+ NFTNL_TRACE_CT_STATE,
+ NFTNL_TRACE_CT_STATUS,
__NFTNL_TRACE_MAX,
};
#define NFTNL_TRACE_MAX (__NFTNL_TRACE_MAX - 1)
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 7d6bc19..2beb30b 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1841,6 +1841,10 @@ enum nft_xfrm_keys {
* @NFTA_TRACE_MARK: nfmark (NLA_U32)
* @NFTA_TRACE_NFPROTO: nf protocol processed (NLA_U32)
* @NFTA_TRACE_POLICY: policy that decided fate of packet (NLA_U32)
+ * @NFTA_TRACE_CT_ID: conntrack id (NLA_U32)
+ * @NFTA_TRACE_CT_DIRECTION: packets direction (NLA_U8)
+ * @NFTA_TRACE_CT_STATUS: conntrack status (NLA_U32)
+ * @NFTA_TRACE_CT_STATE: packet state (new, established, ...) (NLA_U32)
*/
enum nft_trace_attributes {
NFTA_TRACE_UNSPEC,
@@ -1861,6 +1865,10 @@ enum nft_trace_attributes {
NFTA_TRACE_NFPROTO,
NFTA_TRACE_POLICY,
NFTA_TRACE_PAD,
+ NFTA_TRACE_CT_ID,
+ NFTA_TRACE_CT_DIRECTION,
+ NFTA_TRACE_CT_STATUS,
+ NFTA_TRACE_CT_STATE,
__NFTA_TRACE_MAX
};
#define NFTA_TRACE_MAX (__NFTA_TRACE_MAX - 1)
diff --git a/src/trace.c b/src/trace.c
index f7eb45e..d67e114 100644
--- a/src/trace.c
+++ b/src/trace.c
@@ -44,6 +44,12 @@ struct nftnl_trace {
uint32_t policy;
uint16_t iiftype;
uint16_t oiftype;
+ struct {
+ uint16_t dir;
+ uint32_t id;
+ uint32_t state;
+ uint32_t status;
+ } ct;
uint32_t flags;
};
@@ -88,6 +94,10 @@ static int nftnl_trace_parse_attr_cb(const struct nlattr *attr, void *data)
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
abi_breakage();
break;
+ case NFTA_TRACE_CT_DIRECTION:
+ if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
+ abi_breakage();
+ break;
case NFTA_TRACE_IIFTYPE:
case NFTA_TRACE_OIFTYPE:
if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
@@ -100,6 +110,9 @@ static int nftnl_trace_parse_attr_cb(const struct nlattr *attr, void *data)
case NFTA_TRACE_POLICY:
case NFTA_TRACE_NFPROTO:
case NFTA_TRACE_TYPE:
+ case NFTA_TRACE_CT_ID:
+ case NFTA_TRACE_CT_STATE:
+ case NFTA_TRACE_CT_STATUS:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
@@ -190,6 +203,18 @@ const void *nftnl_trace_get_data(const struct nftnl_trace *trace,
case NFTNL_TRACE_POLICY:
*data_len = sizeof(uint32_t);
return &trace->policy;
+ case NFTNL_TRACE_CT_DIRECTION:
+ *data_len = sizeof(uint16_t);
+ return &trace->ct.dir;
+ case NFTNL_TRACE_CT_ID:
+ *data_len = sizeof(uint32_t);
+ return &trace->ct.id;
+ case NFTNL_TRACE_CT_STATE:
+ *data_len = sizeof(uint32_t);
+ return &trace->ct.state;
+ case NFTNL_TRACE_CT_STATUS:
+ *data_len = sizeof(uint32_t);
+ return &trace->ct.status;
case __NFTNL_TRACE_MAX:
break;
}
@@ -419,5 +444,26 @@ int nftnl_trace_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_trace *t)
t->flags |= (1 << NFTNL_TRACE_MARK);
}
+ if (tb[NFTA_TRACE_CT_DIRECTION]) {
+ t->ct.dir = mnl_attr_get_u8(tb[NFTA_TRACE_CT_DIRECTION]);
+ t->flags |= (1 << NFTNL_TRACE_CT_DIRECTION);
+ }
+
+ if (tb[NFTA_TRACE_CT_ID]) {
+ /* NFT_CT_ID is expected to be in big endian */
+ t->ct.id = mnl_attr_get_u32(tb[NFTA_TRACE_CT_ID]);
+ t->flags |= (1 << NFTNL_TRACE_CT_ID);
+ }
+
+ if (tb[NFTA_TRACE_CT_STATE]) {
+ t->ct.state = ntohl(mnl_attr_get_u32(tb[NFTA_TRACE_CT_STATE]));
+ t->flags |= (1 << NFTNL_TRACE_CT_STATE);
+ }
+
+ if (tb[NFTA_TRACE_CT_STATUS]) {
+ t->ct.status = ntohl(mnl_attr_get_u32(tb[NFTA_TRACE_CT_STATUS]));
+ t->flags |= (1 << NFTNL_TRACE_CT_STATUS);
+ }
+
return 0;
}