* [libnftnl PATCH 1/9] set_elem: Review debug output
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
@ 2025-10-23 16:05 ` Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 2/9] expr: data_reg: Avoid extra whitespace Phil Sutter
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2025-10-23 16:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
* Do not print a colon if no data part is present
* Include the object's name for objmap elements
* Print flags only if non-zero, but prefixed by 'flags' keyword to avoid
confusion with data values
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
src/set_elem.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/src/set_elem.c b/src/set_elem.c
index 05220e7933242..6c1be44ce5073 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -687,7 +687,7 @@ int nftnl_set_elem_parse_file(struct nftnl_set_elem *e, enum nftnl_parse_type ty
int nftnl_set_elem_snprintf_default(char *buf, size_t remain,
const struct nftnl_set_elem *e)
{
- int ret, dregtype = DATA_VALUE, offset = 0, i;
+ int ret, dregtype = DATA_NONE, offset = 0, i;
ret = snprintf(buf, remain, "element ");
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
@@ -705,18 +705,29 @@ int nftnl_set_elem_snprintf_default(char *buf, size_t remain,
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
}
- ret = snprintf(buf + offset, remain, " : ");
- SNPRINTF_BUFFER_SIZE(ret, remain, offset);
-
- if (e->flags & (1 << NFTNL_SET_ELEM_VERDICT))
+ if (e->flags & (1 << NFTNL_SET_ELEM_DATA))
+ dregtype = DATA_VALUE;
+ else if (e->flags & (1 << NFTNL_SET_ELEM_CHAIN))
+ dregtype = DATA_CHAIN;
+ else if (e->flags & (1 << NFTNL_SET_ELEM_VERDICT))
dregtype = DATA_VERDICT;
- ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->data,
- DATA_F_NOPFX, dregtype);
- SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ if (dregtype != DATA_NONE) {
+ ret = snprintf(buf + offset, remain, " : ");
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
- ret = snprintf(buf + offset, remain, "%u [end]", e->set_elem_flags);
- SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->data,
+ DATA_F_NOPFX, dregtype);
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ } else if (e->flags & (1 << NFTNL_SET_ELEM_OBJREF)) {
+ ret = snprintf(buf + offset, remain, " : %s ", e->objref);
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ }
+
+ if (e->set_elem_flags) {
+ ret = snprintf(buf + offset, remain, "flags %u ", e->set_elem_flags);
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ }
if (e->user.len) {
ret = snprintf(buf + offset, remain, " userdata = { ");
--
2.51.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [libnftnl PATCH 2/9] expr: data_reg: Avoid extra whitespace
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 1/9] set_elem: Review debug output Phil Sutter
@ 2025-10-23 16:05 ` Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 3/9] expr: Pass byteorder to struct expr_ops::set callback Phil Sutter
` (7 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2025-10-23 16:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Do not append a space to data regs, they may appear at end of line or
followed by a tab. Have callers print the space if needed.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
src/expr/bitwise.c | 7 +++++--
src/expr/cmp.c | 3 +++
src/expr/data_reg.c | 11 +++++------
src/expr/immediate.c | 3 +++
src/expr/range.c | 6 ++++++
src/set_elem.c | 4 ++--
6 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c
index cac47a5500993..2da83b7ba0441 100644
--- a/src/expr/bitwise.c
+++ b/src/expr/bitwise.c
@@ -225,13 +225,16 @@ nftnl_expr_bitwise_snprintf_mask_xor(char *buf, size_t remain,
0, DATA_VALUE);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
- ret = snprintf(buf + offset, remain, ") ^ ");
+ ret = snprintf(buf + offset, remain, " ) ^ ");
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
ret = nftnl_data_reg_snprintf(buf + offset, remain, &bitwise->xor,
0, DATA_VALUE);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ ret = snprintf(buf + offset, remain, " ");
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+
return offset;
}
@@ -248,7 +251,7 @@ nftnl_expr_bitwise_snprintf_shift(char *buf, size_t remain, const char *op,
0, DATA_VALUE);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
- ret = snprintf(buf + offset, remain, ") ");
+ ret = snprintf(buf + offset, remain, " ) ");
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
return offset;
diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index 2908f56325b45..ec1dc31894771 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -163,6 +163,9 @@ nftnl_expr_cmp_snprintf(char *buf, size_t remain,
0, DATA_VALUE);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ ret = snprintf(buf + offset, remain, " ");
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+
return offset;
}
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index fd5e0d6e749e1..bf4153c072fd0 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -25,15 +25,14 @@ nftnl_data_reg_value_snprintf_default(char *buf, size_t remain,
const union nftnl_data_reg *reg,
uint32_t flags)
{
- const char *pfx = flags & DATA_F_NOPFX ? "" : "0x";
+ const char *pfx = flags & DATA_F_NOPFX ? "" : "0x", *sep = "";
int offset = 0, ret, i;
-
-
for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) {
ret = snprintf(buf + offset, remain,
- "%s%.8x ", pfx, reg->val[i]);
+ "%s%s%.8x", sep, pfx, reg->val[i]);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ sep = " ";
}
return offset;
@@ -46,11 +45,11 @@ nftnl_data_reg_verdict_snprintf_def(char *buf, size_t size,
{
int remain = size, offset = 0, ret = 0;
- ret = snprintf(buf, size, "%s ", nftnl_verdict2str(reg->verdict));
+ ret = snprintf(buf, size, "%s", nftnl_verdict2str(reg->verdict));
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
if (reg->chain != NULL) {
- ret = snprintf(buf + offset, remain, "-> %s ", reg->chain);
+ ret = snprintf(buf + offset, remain, " -> %s", reg->chain);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
}
diff --git a/src/expr/immediate.c b/src/expr/immediate.c
index f0e0a78d6b794..6dffaf9ce4ad9 100644
--- a/src/expr/immediate.c
+++ b/src/expr/immediate.c
@@ -201,6 +201,9 @@ nftnl_expr_immediate_snprintf(char *buf, size_t remain,
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
}
+ ret = snprintf(buf + offset, remain, " ");
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+
return offset;
}
diff --git a/src/expr/range.c b/src/expr/range.c
index 50a8ed092e38f..564d14f0edbbb 100644
--- a/src/expr/range.c
+++ b/src/expr/range.c
@@ -176,10 +176,16 @@ static int nftnl_expr_range_snprintf(char *buf, size_t remain,
0, DATA_VALUE);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ ret = snprintf(buf + offset, remain, " ");
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+
ret = nftnl_data_reg_snprintf(buf + offset, remain, &range->data_to,
0, DATA_VALUE);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ ret = snprintf(buf + offset, remain, " ");
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+
return offset;
}
diff --git a/src/set_elem.c b/src/set_elem.c
index 6c1be44ce5073..f567a28719d11 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -720,12 +720,12 @@ int nftnl_set_elem_snprintf_default(char *buf, size_t remain,
DATA_F_NOPFX, dregtype);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
} else if (e->flags & (1 << NFTNL_SET_ELEM_OBJREF)) {
- ret = snprintf(buf + offset, remain, " : %s ", e->objref);
+ ret = snprintf(buf + offset, remain, " : %s", e->objref);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
}
if (e->set_elem_flags) {
- ret = snprintf(buf + offset, remain, "flags %u ", e->set_elem_flags);
+ ret = snprintf(buf + offset, remain, " flags %u", e->set_elem_flags);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [libnftnl PATCH 3/9] expr: Pass byteorder to struct expr_ops::set callback
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 1/9] set_elem: Review debug output Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 2/9] expr: data_reg: Avoid extra whitespace Phil Sutter
@ 2025-10-23 16:05 ` Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 4/9] data_reg: Introduce struct nftnl_data_reg::byteorder field Phil Sutter
` (6 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2025-10-23 16:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Prepare for storing data reg byteorder, no functional change intended.
Note the odd case in expr/byteorder.c since there is a local variable
with same name already.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
include/expr_ops.h | 2 +-
src/expr.c | 15 +++++++++++----
src/expr/bitwise.c | 2 +-
src/expr/byteorder.c | 2 +-
src/expr/cmp.c | 2 +-
src/expr/connlimit.c | 2 +-
src/expr/counter.c | 2 +-
src/expr/ct.c | 2 +-
src/expr/dup.c | 5 +++--
src/expr/dynset.c | 2 +-
src/expr/exthdr.c | 2 +-
src/expr/fib.c | 2 +-
src/expr/flow_offload.c | 5 +++--
src/expr/fwd.c | 5 +++--
src/expr/hash.c | 2 +-
src/expr/immediate.c | 2 +-
src/expr/inner.c | 2 +-
src/expr/last.c | 5 +++--
src/expr/limit.c | 2 +-
src/expr/log.c | 5 +++--
src/expr/lookup.c | 2 +-
src/expr/masq.c | 2 +-
src/expr/match.c | 2 +-
src/expr/meta.c | 2 +-
src/expr/nat.c | 2 +-
src/expr/numgen.c | 2 +-
src/expr/objref.c | 5 +++--
src/expr/osf.c | 5 +++--
src/expr/payload.c | 2 +-
src/expr/queue.c | 5 +++--
src/expr/quota.c | 5 +++--
src/expr/range.c | 5 +++--
src/expr/redir.c | 2 +-
src/expr/reject.c | 5 +++--
src/expr/rt.c | 2 +-
src/expr/socket.c | 2 +-
src/expr/synproxy.c | 5 +++--
src/expr/target.c | 2 +-
src/expr/tproxy.c | 2 +-
src/expr/tunnel.c | 5 +++--
src/expr/xfrm.c | 2 +-
41 files changed, 77 insertions(+), 57 deletions(-)
diff --git a/include/expr_ops.h b/include/expr_ops.h
index 6cfb3b5832083..9c816c085719a 100644
--- a/include/expr_ops.h
+++ b/include/expr_ops.h
@@ -19,7 +19,7 @@ struct expr_ops {
struct attr_policy *attr_policy;
void (*init)(const struct nftnl_expr *e);
void (*free)(const struct nftnl_expr *e);
- int (*set)(struct nftnl_expr *e, uint16_t type, const void *data, uint32_t data_len);
+ int (*set)(struct nftnl_expr *e, uint16_t type, const void *data, uint32_t data_len, uint32_t byteorder);
const void *(*get)(const struct nftnl_expr *e, uint16_t type, uint32_t *data_len);
int (*parse)(struct nftnl_expr *e, struct nlattr *attr);
void (*build)(struct nlmsghdr *nlh, const struct nftnl_expr *e);
diff --git a/src/expr.c b/src/expr.c
index 65180d6849cd8..d07e7332efd78 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -59,9 +59,9 @@ bool nftnl_expr_is_set(const struct nftnl_expr *expr, uint16_t type)
return expr->flags & (1 << type);
}
-EXPORT_SYMBOL(nftnl_expr_set);
-int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type,
- const void *data, uint32_t data_len)
+static int __nftnl_expr_set(struct nftnl_expr *expr, uint16_t type,
+ const void *data, uint32_t data_len,
+ uint32_t byteorder)
{
switch(type) {
case NFTNL_EXPR_NAME: /* cannot be modified */
@@ -77,13 +77,20 @@ int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type,
expr->ops->attr_policy[type].maxlen < data_len)
return -1;
- if (expr->ops->set(expr, type, data, data_len) < 0)
+ if (expr->ops->set(expr, type, data, data_len, byteorder) < 0)
return -1;
}
expr->flags |= (1 << type);
return 0;
}
+EXPORT_SYMBOL(nftnl_expr_set);
+int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type,
+ const void *data, uint32_t data_len)
+{
+ return __nftnl_expr_set(expr, type, data, data_len, 0);
+}
+
EXPORT_SYMBOL(nftnl_expr_set_u8);
void
nftnl_expr_set_u8(struct nftnl_expr *expr, uint16_t type, uint8_t data)
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c
index 2da83b7ba0441..da2b6d2ee57ec 100644
--- a/src/expr/bitwise.c
+++ b/src/expr/bitwise.c
@@ -30,7 +30,7 @@ struct nftnl_expr_bitwise {
static int
nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_bitwise *bitwise = nftnl_expr_data(e);
diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c
index 4171d0633728c..baa11a1401019 100644
--- a/src/expr/byteorder.c
+++ b/src/expr/byteorder.c
@@ -27,7 +27,7 @@ struct nftnl_expr_byteorder {
static int
nftnl_expr_byteorder_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorderp)
{
struct nftnl_expr_byteorder *byteorder = nftnl_expr_data(e);
diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index ec1dc31894771..4bcf2e4bce83e 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -26,7 +26,7 @@ struct nftnl_expr_cmp {
static int
nftnl_expr_cmp_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_cmp *cmp = nftnl_expr_data(e);
diff --git a/src/expr/connlimit.c b/src/expr/connlimit.c
index 02b9ecc87d258..f45129d60486d 100644
--- a/src/expr/connlimit.c
+++ b/src/expr/connlimit.c
@@ -23,7 +23,7 @@ struct nftnl_expr_connlimit {
static int
nftnl_expr_connlimit_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_connlimit *connlimit = nftnl_expr_data(e);
diff --git a/src/expr/counter.c b/src/expr/counter.c
index 80f21d7a177ea..21e641b0b939a 100644
--- a/src/expr/counter.c
+++ b/src/expr/counter.c
@@ -25,7 +25,7 @@ struct nftnl_expr_counter {
static int
nftnl_expr_counter_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_counter *ctr = nftnl_expr_data(e);
diff --git a/src/expr/ct.c b/src/expr/ct.c
index 8f8c2a6e73713..4117eeeb93863 100644
--- a/src/expr/ct.c
+++ b/src/expr/ct.c
@@ -29,7 +29,7 @@ struct nftnl_expr_ct {
static int
nftnl_expr_ct_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_ct *ct = nftnl_expr_data(e);
diff --git a/src/expr/dup.c b/src/expr/dup.c
index d49cdb77c1081..bb0f9c6c0be7e 100644
--- a/src/expr/dup.c
+++ b/src/expr/dup.c
@@ -21,8 +21,9 @@ struct nftnl_expr_dup {
enum nft_registers sreg_dev;
};
-static int nftnl_expr_dup_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_dup_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_dup *dup = nftnl_expr_data(e);
diff --git a/src/expr/dynset.c b/src/expr/dynset.c
index dc74fbbe75b3c..f513b3736b43c 100644
--- a/src/expr/dynset.c
+++ b/src/expr/dynset.c
@@ -30,7 +30,7 @@ struct nftnl_expr_dynset {
static int
nftnl_expr_dynset_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
struct nftnl_expr *expr, *next;
diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c
index ddebe43eabf52..c936ac0928200 100644
--- a/src/expr/exthdr.c
+++ b/src/expr/exthdr.c
@@ -36,7 +36,7 @@ struct nftnl_expr_exthdr {
static int
nftnl_expr_exthdr_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_exthdr *exthdr = nftnl_expr_data(e);
diff --git a/src/expr/fib.c b/src/expr/fib.c
index c378f4f51bb11..31750da05fabe 100644
--- a/src/expr/fib.c
+++ b/src/expr/fib.c
@@ -25,7 +25,7 @@ struct nftnl_expr_fib {
static int
nftnl_expr_fib_set(struct nftnl_expr *e, uint16_t result,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_fib *fib = nftnl_expr_data(e);
diff --git a/src/expr/flow_offload.c b/src/expr/flow_offload.c
index ce22ec419a944..f9a999bd48432 100644
--- a/src/expr/flow_offload.c
+++ b/src/expr/flow_offload.c
@@ -14,8 +14,9 @@ struct nftnl_expr_flow {
char *table_name;
};
-static int nftnl_expr_flow_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_flow_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_flow *flow = nftnl_expr_data(e);
diff --git a/src/expr/fwd.c b/src/expr/fwd.c
index d543e2239af20..5f6a56c7e939c 100644
--- a/src/expr/fwd.c
+++ b/src/expr/fwd.c
@@ -22,8 +22,9 @@ struct nftnl_expr_fwd {
uint32_t nfproto;
};
-static int nftnl_expr_fwd_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_fwd_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_fwd *fwd = nftnl_expr_data(e);
diff --git a/src/expr/hash.c b/src/expr/hash.c
index 050e4b9b1c599..c0cf8d943ba50 100644
--- a/src/expr/hash.c
+++ b/src/expr/hash.c
@@ -27,7 +27,7 @@ struct nftnl_expr_hash {
static int
nftnl_expr_hash_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_hash *hash = nftnl_expr_data(e);
switch (type) {
diff --git a/src/expr/immediate.c b/src/expr/immediate.c
index 6dffaf9ce4ad9..27ee6003d3f08 100644
--- a/src/expr/immediate.c
+++ b/src/expr/immediate.c
@@ -23,7 +23,7 @@ struct nftnl_expr_immediate {
static int
nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_immediate *imm = nftnl_expr_data(e);
diff --git a/src/expr/inner.c b/src/expr/inner.c
index 8a56bb336cff5..516cda62985d8 100644
--- a/src/expr/inner.c
+++ b/src/expr/inner.c
@@ -35,7 +35,7 @@ static void nftnl_expr_inner_free(const struct nftnl_expr *e)
static int
nftnl_expr_inner_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_inner *inner = nftnl_expr_data(e);
diff --git a/src/expr/last.c b/src/expr/last.c
index 427d4b52a1aec..ebdaf2a75d40d 100644
--- a/src/expr/last.c
+++ b/src/expr/last.c
@@ -21,8 +21,9 @@ struct nftnl_expr_last {
uint32_t set;
};
-static int nftnl_expr_last_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_last_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_last *last = nftnl_expr_data(e);
diff --git a/src/expr/limit.c b/src/expr/limit.c
index b77b27e024acb..36444975db045 100644
--- a/src/expr/limit.c
+++ b/src/expr/limit.c
@@ -28,7 +28,7 @@ struct nftnl_expr_limit {
static int
nftnl_expr_limit_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_limit *limit = nftnl_expr_data(e);
diff --git a/src/expr/log.c b/src/expr/log.c
index ead243799863c..f8456bcce4bf1 100644
--- a/src/expr/log.c
+++ b/src/expr/log.c
@@ -27,8 +27,9 @@ struct nftnl_expr_log {
const char *prefix;
};
-static int nftnl_expr_log_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_log_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_log *log = nftnl_expr_data(e);
diff --git a/src/expr/lookup.c b/src/expr/lookup.c
index 4f76c5b71bb2b..c6a36a68d0b08 100644
--- a/src/expr/lookup.c
+++ b/src/expr/lookup.c
@@ -27,7 +27,7 @@ struct nftnl_expr_lookup {
static int
nftnl_expr_lookup_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_lookup *lookup = nftnl_expr_data(e);
diff --git a/src/expr/masq.c b/src/expr/masq.c
index da4f437f136c0..e0d9eb698bf80 100644
--- a/src/expr/masq.c
+++ b/src/expr/masq.c
@@ -24,7 +24,7 @@ struct nftnl_expr_masq {
static int
nftnl_expr_masq_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_masq *masq = nftnl_expr_data(e);
diff --git a/src/expr/match.c b/src/expr/match.c
index 2c5bd6bb74d19..b7e99b8869aff 100644
--- a/src/expr/match.c
+++ b/src/expr/match.c
@@ -32,7 +32,7 @@ struct nftnl_expr_match {
static int
nftnl_expr_match_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_match *mt = nftnl_expr_data(e);
diff --git a/src/expr/meta.c b/src/expr/meta.c
index 7c56fdca08451..753975d988187 100644
--- a/src/expr/meta.c
+++ b/src/expr/meta.c
@@ -29,7 +29,7 @@ struct nftnl_expr_meta {
static int
nftnl_expr_meta_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_meta *meta = nftnl_expr_data(e);
diff --git a/src/expr/nat.c b/src/expr/nat.c
index f7e24cb34d515..89e7f15d656c9 100644
--- a/src/expr/nat.c
+++ b/src/expr/nat.c
@@ -32,7 +32,7 @@ struct nftnl_expr_nat {
static int
nftnl_expr_nat_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_nat *nat = nftnl_expr_data(e);
diff --git a/src/expr/numgen.c b/src/expr/numgen.c
index e3af372410720..5243d9d996f7f 100644
--- a/src/expr/numgen.c
+++ b/src/expr/numgen.c
@@ -24,7 +24,7 @@ struct nftnl_expr_ng {
static int
nftnl_expr_ng_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_ng *ng = nftnl_expr_data(e);
diff --git a/src/expr/objref.c b/src/expr/objref.c
index 1b27e94a6fa2c..481103e7883c0 100644
--- a/src/expr/objref.c
+++ b/src/expr/objref.c
@@ -28,8 +28,9 @@ struct nftnl_expr_objref {
} set;
};
-static int nftnl_expr_objref_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_objref_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_objref *objref = nftnl_expr_data(e);
diff --git a/src/expr/osf.c b/src/expr/osf.c
index 293a81420a322..35a31cf13bd09 100644
--- a/src/expr/osf.c
+++ b/src/expr/osf.c
@@ -18,8 +18,9 @@ struct nftnl_expr_osf {
uint32_t flags;
};
-static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_osf *osf = nftnl_expr_data(e);
diff --git a/src/expr/payload.c b/src/expr/payload.c
index 593b8422c44e6..476eaab0afd14 100644
--- a/src/expr/payload.c
+++ b/src/expr/payload.c
@@ -33,7 +33,7 @@ struct nftnl_expr_payload {
static int
nftnl_expr_payload_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_payload *payload = nftnl_expr_data(e);
diff --git a/src/expr/queue.c b/src/expr/queue.c
index 0160d5e25f836..f5e3f3284de70 100644
--- a/src/expr/queue.c
+++ b/src/expr/queue.c
@@ -22,8 +22,9 @@ struct nftnl_expr_queue {
uint16_t flags;
};
-static int nftnl_expr_queue_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_queue_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_queue *queue = nftnl_expr_data(e);
diff --git a/src/expr/quota.c b/src/expr/quota.c
index 108c87c04530d..6a8dc948530cb 100644
--- a/src/expr/quota.c
+++ b/src/expr/quota.c
@@ -22,8 +22,9 @@ struct nftnl_expr_quota {
uint32_t flags;
};
-static int nftnl_expr_quota_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_quota_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_quota *quota = nftnl_expr_data(e);
diff --git a/src/expr/range.c b/src/expr/range.c
index 564d14f0edbbb..cd6d6fbeb4ea2 100644
--- a/src/expr/range.c
+++ b/src/expr/range.c
@@ -23,8 +23,9 @@ struct nftnl_expr_range {
enum nft_range_ops op;
};
-static int nftnl_expr_range_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_range_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_range *range = nftnl_expr_data(e);
diff --git a/src/expr/redir.c b/src/expr/redir.c
index be38f6257a8f1..3565d3ffa74e9 100644
--- a/src/expr/redir.c
+++ b/src/expr/redir.c
@@ -24,7 +24,7 @@ struct nftnl_expr_redir {
static int
nftnl_expr_redir_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_redir *redir = nftnl_expr_data(e);
diff --git a/src/expr/reject.c b/src/expr/reject.c
index 5d8763ebb5ef0..df8f92635ca44 100644
--- a/src/expr/reject.c
+++ b/src/expr/reject.c
@@ -22,8 +22,9 @@ struct nftnl_expr_reject {
uint8_t icmp_code;
};
-static int nftnl_expr_reject_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_reject_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_reject *reject = nftnl_expr_data(e);
diff --git a/src/expr/rt.c b/src/expr/rt.c
index 4f2e96b53cad4..c0d43110eaf8c 100644
--- a/src/expr/rt.c
+++ b/src/expr/rt.c
@@ -22,7 +22,7 @@ struct nftnl_expr_rt {
static int
nftnl_expr_rt_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_rt *rt = nftnl_expr_data(e);
diff --git a/src/expr/socket.c b/src/expr/socket.c
index 822ee8b9b832e..98a8565024df6 100644
--- a/src/expr/socket.c
+++ b/src/expr/socket.c
@@ -23,7 +23,7 @@ struct nftnl_expr_socket {
static int
nftnl_expr_socket_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_socket *socket = nftnl_expr_data(e);
diff --git a/src/expr/synproxy.c b/src/expr/synproxy.c
index b5a1fef9f4064..ad2f0f0d20305 100644
--- a/src/expr/synproxy.c
+++ b/src/expr/synproxy.c
@@ -16,8 +16,9 @@ struct nftnl_expr_synproxy {
uint32_t flags;
};
-static int nftnl_expr_synproxy_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_synproxy_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_synproxy *synproxy = nftnl_expr_data(e);
diff --git a/src/expr/target.c b/src/expr/target.c
index 3549456b430ff..6b590f5a4b767 100644
--- a/src/expr/target.c
+++ b/src/expr/target.c
@@ -32,7 +32,7 @@ struct nftnl_expr_target {
static int
nftnl_expr_target_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_target *tg = nftnl_expr_data(e);
diff --git a/src/expr/tproxy.c b/src/expr/tproxy.c
index 4cc9125f1de65..630dffe040c7d 100644
--- a/src/expr/tproxy.c
+++ b/src/expr/tproxy.c
@@ -24,7 +24,7 @@ struct nftnl_expr_tproxy {
static int
nftnl_expr_tproxy_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_tproxy *tproxy = nftnl_expr_data(e);
diff --git a/src/expr/tunnel.c b/src/expr/tunnel.c
index b51b6c7513086..bdfbc290a8872 100644
--- a/src/expr/tunnel.c
+++ b/src/expr/tunnel.c
@@ -20,8 +20,9 @@ struct nftnl_expr_tunnel {
enum nft_registers dreg;
};
-static int nftnl_expr_tunnel_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+static int
+nftnl_expr_tunnel_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_tunnel *tunnel = nftnl_expr_data(e);
diff --git a/src/expr/xfrm.c b/src/expr/xfrm.c
index ba2107d63c082..d247b74e01e22 100644
--- a/src/expr/xfrm.c
+++ b/src/expr/xfrm.c
@@ -22,7 +22,7 @@ struct nftnl_expr_xfrm {
static int
nftnl_expr_xfrm_set(struct nftnl_expr *e, uint16_t type,
- const void *data, uint32_t data_len)
+ const void *data, uint32_t data_len, uint32_t byteorder)
{
struct nftnl_expr_xfrm *x = nftnl_expr_data(e);
--
2.51.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [libnftnl PATCH 4/9] data_reg: Introduce struct nftnl_data_reg::byteorder field
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
` (2 preceding siblings ...)
2025-10-23 16:05 ` [libnftnl PATCH 3/9] expr: Pass byteorder to struct expr_ops::set callback Phil Sutter
@ 2025-10-23 16:05 ` Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 5/9] data_reg: Introduce struct nftnl_data_reg::sizes array Phil Sutter
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2025-10-23 16:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Expression setters populate it from the passed 'byteorder' parameter.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
include/data_reg.h | 4 +++-
src/expr/bitwise.c | 6 +++---
src/expr/cmp.c | 2 +-
src/expr/data_reg.c | 4 +++-
src/expr/immediate.c | 2 +-
src/expr/range.c | 6 ++++--
src/set_elem.c | 6 +++---
7 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/include/data_reg.h b/include/data_reg.h
index 946354dc9881c..e22acd1b9a290 100644
--- a/include/data_reg.h
+++ b/include/data_reg.h
@@ -21,6 +21,7 @@ union nftnl_data_reg {
struct {
uint32_t val[NFT_DATA_VALUE_MAXLEN / sizeof(uint32_t)];
uint32_t len;
+ uint32_t byteorder;
};
struct {
uint32_t verdict;
@@ -35,6 +36,7 @@ int nftnl_data_reg_snprintf(char *buf, size_t size,
struct nlattr;
int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type);
-int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, uint32_t len);
+int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src,
+ uint32_t len, uint32_t byteorder);
#endif
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c
index da2b6d2ee57ec..a7752856cf957 100644
--- a/src/expr/bitwise.c
+++ b/src/expr/bitwise.c
@@ -51,11 +51,11 @@ nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type,
memcpy(&bitwise->len, data, data_len);
break;
case NFTNL_EXPR_BITWISE_MASK:
- return nftnl_data_cpy(&bitwise->mask, data, data_len);
+ return nftnl_data_cpy(&bitwise->mask, data, data_len, byteorder);
case NFTNL_EXPR_BITWISE_XOR:
- return nftnl_data_cpy(&bitwise->xor, data, data_len);
+ return nftnl_data_cpy(&bitwise->xor, data, data_len, byteorder);
case NFTNL_EXPR_BITWISE_DATA:
- return nftnl_data_cpy(&bitwise->data, data, data_len);
+ return nftnl_data_cpy(&bitwise->data, data, data_len, byteorder);
}
return 0;
}
diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index 4bcf2e4bce83e..c88e06aee2356 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -38,7 +38,7 @@ nftnl_expr_cmp_set(struct nftnl_expr *e, uint16_t type,
memcpy(&cmp->op, data, data_len);
break;
case NFTNL_EXPR_CMP_DATA:
- return nftnl_data_cpy(&cmp->data, data, data_len);
+ return nftnl_data_cpy(&cmp->data, data, data_len, byteorder);
}
return 0;
}
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index bf4153c072fd0..45f2d94881c61 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -201,7 +201,8 @@ int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type)
return ret;
}
-int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, uint32_t len)
+int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src,
+ uint32_t len, uint32_t byteorder)
{
int ret = 0;
@@ -212,5 +213,6 @@ int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src, uint32_t len)
memcpy(dreg->val, src, len);
dreg->len = len;
+ dreg->byteorder = byteorder;
return ret;
}
diff --git a/src/expr/immediate.c b/src/expr/immediate.c
index 27ee6003d3f08..f27b6e6b08f57 100644
--- a/src/expr/immediate.c
+++ b/src/expr/immediate.c
@@ -32,7 +32,7 @@ nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type,
memcpy(&imm->dreg, data, data_len);
break;
case NFTNL_EXPR_IMM_DATA:
- return nftnl_data_cpy(&imm->data, data, data_len);
+ return nftnl_data_cpy(&imm->data, data, data_len, byteorder);
case NFTNL_EXPR_IMM_VERDICT:
memcpy(&imm->data.verdict, data, data_len);
break;
diff --git a/src/expr/range.c b/src/expr/range.c
index cd6d6fbeb4ea2..4b3101ee88efa 100644
--- a/src/expr/range.c
+++ b/src/expr/range.c
@@ -37,9 +37,11 @@ nftnl_expr_range_set(struct nftnl_expr *e, uint16_t type,
memcpy(&range->op, data, data_len);
break;
case NFTNL_EXPR_RANGE_FROM_DATA:
- return nftnl_data_cpy(&range->data_from, data, data_len);
+ return nftnl_data_cpy(&range->data_from, data,
+ data_len, byteorder);
case NFTNL_EXPR_RANGE_TO_DATA:
- return nftnl_data_cpy(&range->data_to, data, data_len);
+ return nftnl_data_cpy(&range->data_to, data,
+ data_len, byteorder);
}
return 0;
}
diff --git a/src/set_elem.c b/src/set_elem.c
index f567a28719d11..19fd14a1fa900 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -122,11 +122,11 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
memcpy(&s->set_elem_flags, data, sizeof(s->set_elem_flags));
break;
case NFTNL_SET_ELEM_KEY: /* NFTA_SET_ELEM_KEY */
- if (nftnl_data_cpy(&s->key, data, data_len) < 0)
+ if (nftnl_data_cpy(&s->key, data, data_len, 0) < 0)
return -1;
break;
case NFTNL_SET_ELEM_KEY_END: /* NFTA_SET_ELEM_KEY_END */
- if (nftnl_data_cpy(&s->key_end, data, data_len) < 0)
+ if (nftnl_data_cpy(&s->key_end, data, data_len, 0) < 0)
return -1;
break;
case NFTNL_SET_ELEM_VERDICT: /* NFTA_SET_ELEM_DATA */
@@ -141,7 +141,7 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
return -1;
break;
case NFTNL_SET_ELEM_DATA: /* NFTA_SET_ELEM_DATA */
- if (nftnl_data_cpy(&s->data, data, data_len) < 0)
+ if (nftnl_data_cpy(&s->data, data, data_len, 0) < 0)
return -1;
break;
case NFTNL_SET_ELEM_TIMEOUT: /* NFTA_SET_ELEM_TIMEOUT */
--
2.51.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [libnftnl PATCH 5/9] data_reg: Introduce struct nftnl_data_reg::sizes array
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
` (3 preceding siblings ...)
2025-10-23 16:05 ` [libnftnl PATCH 4/9] data_reg: Introduce struct nftnl_data_reg::byteorder field Phil Sutter
@ 2025-10-23 16:05 ` Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 6/9] Introduce nftnl_{expr,set_elem}_set_imm() Phil Sutter
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2025-10-23 16:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
This will hold the actual size of each component in concatenated data.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
include/data_reg.h | 3 ++-
src/expr/bitwise.c | 9 ++++++---
src/expr/cmp.c | 3 ++-
src/expr/data_reg.c | 6 +++++-
src/expr/immediate.c | 3 ++-
src/expr/range.c | 4 ++--
src/set_elem.c | 6 +++---
7 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/include/data_reg.h b/include/data_reg.h
index e22acd1b9a290..5cdeba07cb1e6 100644
--- a/include/data_reg.h
+++ b/include/data_reg.h
@@ -22,6 +22,7 @@ union nftnl_data_reg {
uint32_t val[NFT_DATA_VALUE_MAXLEN / sizeof(uint32_t)];
uint32_t len;
uint32_t byteorder;
+ uint8_t sizes[NFT_REG32_COUNT];
};
struct {
uint32_t verdict;
@@ -37,6 +38,6 @@ struct nlattr;
int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type);
int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src,
- uint32_t len, uint32_t byteorder);
+ uint32_t len, uint32_t byteorder, uint8_t *sizes);
#endif
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c
index a7752856cf957..a838e6cc1abf2 100644
--- a/src/expr/bitwise.c
+++ b/src/expr/bitwise.c
@@ -51,11 +51,14 @@ nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type,
memcpy(&bitwise->len, data, data_len);
break;
case NFTNL_EXPR_BITWISE_MASK:
- return nftnl_data_cpy(&bitwise->mask, data, data_len, byteorder);
+ return nftnl_data_cpy(&bitwise->mask, data,
+ data_len, byteorder, NULL);
case NFTNL_EXPR_BITWISE_XOR:
- return nftnl_data_cpy(&bitwise->xor, data, data_len, byteorder);
+ return nftnl_data_cpy(&bitwise->xor, data,
+ data_len, byteorder, NULL);
case NFTNL_EXPR_BITWISE_DATA:
- return nftnl_data_cpy(&bitwise->data, data, data_len, byteorder);
+ return nftnl_data_cpy(&bitwise->data, data,
+ data_len, byteorder, NULL);
}
return 0;
}
diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index c88e06aee2356..ec5dd62efdab3 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -38,7 +38,8 @@ nftnl_expr_cmp_set(struct nftnl_expr *e, uint16_t type,
memcpy(&cmp->op, data, data_len);
break;
case NFTNL_EXPR_CMP_DATA:
- return nftnl_data_cpy(&cmp->data, data, data_len, byteorder);
+ return nftnl_data_cpy(&cmp->data, data,
+ data_len, byteorder, NULL);
}
return 0;
}
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index 45f2d94881c61..d1aadcc257f3f 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -202,7 +202,7 @@ int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type)
}
int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src,
- uint32_t len, uint32_t byteorder)
+ uint32_t len, uint32_t byteorder, uint8_t *sizes)
{
int ret = 0;
@@ -214,5 +214,9 @@ int nftnl_data_cpy(union nftnl_data_reg *dreg, const void *src,
memcpy(dreg->val, src, len);
dreg->len = len;
dreg->byteorder = byteorder;
+ if (sizes)
+ memcpy(dreg->sizes, sizes, sizeof(dreg->sizes));
+ else
+ memset(dreg->sizes, 0, sizeof(dreg->sizes));
return ret;
}
diff --git a/src/expr/immediate.c b/src/expr/immediate.c
index f27b6e6b08f57..94531984bafc9 100644
--- a/src/expr/immediate.c
+++ b/src/expr/immediate.c
@@ -32,7 +32,8 @@ nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type,
memcpy(&imm->dreg, data, data_len);
break;
case NFTNL_EXPR_IMM_DATA:
- return nftnl_data_cpy(&imm->data, data, data_len, byteorder);
+ return nftnl_data_cpy(&imm->data, data,
+ data_len, byteorder, NULL);
case NFTNL_EXPR_IMM_VERDICT:
memcpy(&imm->data.verdict, data, data_len);
break;
diff --git a/src/expr/range.c b/src/expr/range.c
index 4b3101ee88efa..12c91e9e2f1fc 100644
--- a/src/expr/range.c
+++ b/src/expr/range.c
@@ -38,10 +38,10 @@ nftnl_expr_range_set(struct nftnl_expr *e, uint16_t type,
break;
case NFTNL_EXPR_RANGE_FROM_DATA:
return nftnl_data_cpy(&range->data_from, data,
- data_len, byteorder);
+ data_len, byteorder, NULL);
case NFTNL_EXPR_RANGE_TO_DATA:
return nftnl_data_cpy(&range->data_to, data,
- data_len, byteorder);
+ data_len, byteorder, NULL);
}
return 0;
}
diff --git a/src/set_elem.c b/src/set_elem.c
index 19fd14a1fa900..96dc4aafb606f 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -122,11 +122,11 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
memcpy(&s->set_elem_flags, data, sizeof(s->set_elem_flags));
break;
case NFTNL_SET_ELEM_KEY: /* NFTA_SET_ELEM_KEY */
- if (nftnl_data_cpy(&s->key, data, data_len, 0) < 0)
+ if (nftnl_data_cpy(&s->key, data, data_len, 0, NULL) < 0)
return -1;
break;
case NFTNL_SET_ELEM_KEY_END: /* NFTA_SET_ELEM_KEY_END */
- if (nftnl_data_cpy(&s->key_end, data, data_len, 0) < 0)
+ if (nftnl_data_cpy(&s->key_end, data, data_len, 0, NULL) < 0)
return -1;
break;
case NFTNL_SET_ELEM_VERDICT: /* NFTA_SET_ELEM_DATA */
@@ -141,7 +141,7 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
return -1;
break;
case NFTNL_SET_ELEM_DATA: /* NFTA_SET_ELEM_DATA */
- if (nftnl_data_cpy(&s->data, data, data_len, 0) < 0)
+ if (nftnl_data_cpy(&s->data, data, data_len, 0, NULL) < 0)
return -1;
break;
case NFTNL_SET_ELEM_TIMEOUT: /* NFTA_SET_ELEM_TIMEOUT */
--
2.51.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [libnftnl PATCH 6/9] Introduce nftnl_{expr,set_elem}_set_imm()
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
` (4 preceding siblings ...)
2025-10-23 16:05 ` [libnftnl PATCH 5/9] data_reg: Introduce struct nftnl_data_reg::sizes array Phil Sutter
@ 2025-10-23 16:05 ` Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 7/9] data_reg: Respect data byteorder when printing Phil Sutter
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2025-10-23 16:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
These are alternatives to nftnl_{expr,set_elem}_set() which accept
byteorder and concat component size information.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
include/libnftnl/expr.h | 1 +
include/libnftnl/set.h | 1 +
src/expr.c | 7 +++++++
src/libnftnl.map | 5 +++++
src/set_elem.c | 30 ++++++++++++++++++++++++------
5 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 1c07b54139a57..41e9f301d7487 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -21,6 +21,7 @@ void nftnl_expr_free(const struct nftnl_expr *expr);
bool nftnl_expr_is_set(const struct nftnl_expr *expr, uint16_t type);
int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, const void *data, uint32_t data_len);
+int nftnl_expr_set_imm(struct nftnl_expr *expr, uint16_t type, const void *data, uint32_t data_len, uint32_t byteorder);
#define nftnl_expr_set_data nftnl_expr_set
void nftnl_expr_set_u8(struct nftnl_expr *expr, uint16_t type, uint8_t data);
void nftnl_expr_set_u16(struct nftnl_expr *expr, uint16_t type, uint16_t data);
diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index cad5e8e81c7ab..f2edca20f9e07 100644
--- a/include/libnftnl/set.h
+++ b/include/libnftnl/set.h
@@ -131,6 +131,7 @@ void nftnl_set_elem_add(struct nftnl_set *s, struct nftnl_set_elem *elem);
void nftnl_set_elem_unset(struct nftnl_set_elem *s, uint16_t attr);
int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, const void *data, uint32_t data_len);
+int nftnl_set_elem_set_imm(struct nftnl_set_elem *s, uint16_t attr, const void *data, uint32_t data_len, uint32_t byteorder, uint8_t *sizes);
void nftnl_set_elem_set_u32(struct nftnl_set_elem *s, uint16_t attr, uint32_t val);
void nftnl_set_elem_set_u64(struct nftnl_set_elem *s, uint16_t attr, uint64_t val);
int nftnl_set_elem_set_str(struct nftnl_set_elem *s, uint16_t attr, const char *str);
diff --git a/src/expr.c b/src/expr.c
index d07e7332efd78..0fec358e74806 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -91,6 +91,13 @@ int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type,
return __nftnl_expr_set(expr, type, data, data_len, 0);
}
+EXPORT_SYMBOL(nftnl_expr_set_imm);
+int nftnl_expr_set_imm(struct nftnl_expr *expr, uint16_t type,
+ const void *data, uint32_t data_len, uint32_t byteorder)
+{
+ return __nftnl_expr_set(expr, type, data, data_len, byteorder);
+}
+
EXPORT_SYMBOL(nftnl_expr_set_u8);
void
nftnl_expr_set_u8(struct nftnl_expr *expr, uint16_t type, uint8_t data)
diff --git a/src/libnftnl.map b/src/libnftnl.map
index 10c0e7fcff4da..daca971338897 100644
--- a/src/libnftnl.map
+++ b/src/libnftnl.map
@@ -399,3 +399,8 @@ nftnl_obj_tunnel_opts_foreach;
nftnl_tunnel_opts_add;
nftnl_tunnel_opts_free;
} LIBNFTNL_17;
+
+LIBNFTNL_19 {
+ nftnl_expr_set_imm;
+ nftnl_set_elem_set_imm;
+} LIBNFTNL_18;
diff --git a/src/set_elem.c b/src/set_elem.c
index 96dc4aafb606f..d22643c44dd71 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -108,9 +108,9 @@ static uint32_t nftnl_set_elem_validate[NFTNL_SET_ELEM_MAX + 1] = {
[NFTNL_SET_ELEM_EXPIRATION] = sizeof(uint64_t),
};
-EXPORT_SYMBOL(nftnl_set_elem_set);
-int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
- const void *data, uint32_t data_len)
+static int
+__nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr, const void *data,
+ uint32_t data_len, uint32_t byteorder, uint8_t *sizes)
{
struct nftnl_expr *expr, *tmp;
@@ -122,11 +122,13 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
memcpy(&s->set_elem_flags, data, sizeof(s->set_elem_flags));
break;
case NFTNL_SET_ELEM_KEY: /* NFTA_SET_ELEM_KEY */
- if (nftnl_data_cpy(&s->key, data, data_len, 0, NULL) < 0)
+ if (nftnl_data_cpy(&s->key, data,
+ data_len, byteorder, sizes) < 0)
return -1;
break;
case NFTNL_SET_ELEM_KEY_END: /* NFTA_SET_ELEM_KEY_END */
- if (nftnl_data_cpy(&s->key_end, data, data_len, 0, NULL) < 0)
+ if (nftnl_data_cpy(&s->key_end, data,
+ data_len, byteorder, sizes) < 0)
return -1;
break;
case NFTNL_SET_ELEM_VERDICT: /* NFTA_SET_ELEM_DATA */
@@ -141,7 +143,8 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
return -1;
break;
case NFTNL_SET_ELEM_DATA: /* NFTA_SET_ELEM_DATA */
- if (nftnl_data_cpy(&s->data, data, data_len, 0, NULL) < 0)
+ if (nftnl_data_cpy(&s->data, data,
+ data_len, byteorder, sizes) < 0)
return -1;
break;
case NFTNL_SET_ELEM_TIMEOUT: /* NFTA_SET_ELEM_TIMEOUT */
@@ -180,6 +183,21 @@ int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
return 0;
}
+EXPORT_SYMBOL(nftnl_set_elem_set);
+int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
+ const void *data, uint32_t data_len)
+{
+ return __nftnl_set_elem_set(s, attr, data, data_len, 0, NULL);
+}
+
+EXPORT_SYMBOL(nftnl_set_elem_set_imm);
+int nftnl_set_elem_set_imm(struct nftnl_set_elem *s, uint16_t attr,
+ const void *data, uint32_t data_len,
+ uint32_t byteorder, uint8_t *sizes)
+{
+ return __nftnl_set_elem_set(s, attr, data, data_len, byteorder, sizes);
+}
+
EXPORT_SYMBOL(nftnl_set_elem_set_u32);
void nftnl_set_elem_set_u32(struct nftnl_set_elem *s, uint16_t attr, uint32_t val)
{
--
2.51.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [libnftnl PATCH 7/9] data_reg: Respect data byteorder when printing
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
` (5 preceding siblings ...)
2025-10-23 16:05 ` [libnftnl PATCH 6/9] Introduce nftnl_{expr,set_elem}_set_imm() Phil Sutter
@ 2025-10-23 16:05 ` Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 8/9] data_reg: Support concatenated data Phil Sutter
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2025-10-23 16:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Print data from most significant byte to least significant one. Also
print only reg->len bytes of data, not every non-empty u32. Still
separate four byte blocks by whitespace, though.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
src/expr/data_reg.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index d1aadcc257f3f..de5d23501c92d 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -20,19 +20,36 @@
#include <libnftnl/rule.h>
#include "internal.h"
+static bool big_endian_host(void)
+{
+ uint16_t v = 1;
+
+ return v == htons(v);
+}
+
static int
nftnl_data_reg_value_snprintf_default(char *buf, size_t remain,
const union nftnl_data_reg *reg,
uint32_t flags)
{
const char *pfx = flags & DATA_F_NOPFX ? "" : "0x", *sep = "";
- int offset = 0, ret, i;
-
- for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) {
- ret = snprintf(buf + offset, remain,
- "%s%s%.8x", sep, pfx, reg->val[i]);
+ bool reverse = reg->byteorder && !big_endian_host();
+ int offset = 0, ret, i, idx;
+
+ for (i = 0; i < reg->len; i++) {
+ if ((i % 4) == 0) {
+ ret = snprintf(buf + offset, remain, "%s%s", sep, pfx);
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ sep = " ";
+ }
+ if (reverse)
+ idx = reg->len - i - 1;
+ else
+ idx = i;
+
+ ret = snprintf(buf + offset, remain, "%.2x",
+ ((uint8_t *)reg->val)[idx]);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
- sep = " ";
}
return offset;
--
2.51.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [libnftnl PATCH 8/9] data_reg: Support concatenated data
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
` (6 preceding siblings ...)
2025-10-23 16:05 ` [libnftnl PATCH 7/9] data_reg: Respect data byteorder when printing Phil Sutter
@ 2025-10-23 16:05 ` Phil Sutter
2025-10-23 16:05 ` [libnftnl PATCH 9/9] udata: Store u32 udata values in Big Endian Phil Sutter
2026-01-27 22:04 ` [libnftnl PATCH 0/9] Fix for debug output on " Phil Sutter
9 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2025-10-23 16:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
If sizes array has non-zero field values, interpret byteorder field as
bitfield indicating each compontent's byteorder and print the components
separated by a dot.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
src/expr/data_reg.c | 48 +++++++++++++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 10 deletions(-)
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index de5d23501c92d..d01e0f7d9969e 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -27,34 +27,62 @@ static bool big_endian_host(void)
return v == htons(v);
}
-static int
-nftnl_data_reg_value_snprintf_default(char *buf, size_t remain,
- const union nftnl_data_reg *reg,
- uint32_t flags)
+static int __reg_value_snprintf(char *buf, size_t remain,
+ uint8_t *data, size_t datalen,
+ bool reverse, const char *pfx)
{
- const char *pfx = flags & DATA_F_NOPFX ? "" : "0x", *sep = "";
- bool reverse = reg->byteorder && !big_endian_host();
int offset = 0, ret, i, idx;
+ const char *sep = "";
- for (i = 0; i < reg->len; i++) {
+ for (i = 0; i < datalen; i++) {
if ((i % 4) == 0) {
ret = snprintf(buf + offset, remain, "%s%s", sep, pfx);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
sep = " ";
}
if (reverse)
- idx = reg->len - i - 1;
+ idx = datalen - i - 1;
else
idx = i;
- ret = snprintf(buf + offset, remain, "%.2x",
- ((uint8_t *)reg->val)[idx]);
+ ret = snprintf(buf + offset, remain, "%.2x", data[idx]);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
}
return offset;
}
+static int
+nftnl_data_reg_value_snprintf_default(char *buf, size_t remain,
+ const union nftnl_data_reg *reg,
+ uint32_t flags)
+{
+ uint32_t byteorder = big_endian_host() ? 0 : reg->byteorder;
+ const char *pfx = flags & DATA_F_NOPFX ? "" : "0x";
+ int offset = 0, ret, i, pos = 0;
+
+ for (i = 0; i < array_size(reg->sizes); i++) {
+ int curlen = reg->sizes[i] ?: reg->len;
+ bool reverse = byteorder & (1 << i);
+
+ if (i > 0) {
+ ret = snprintf(buf + offset, remain, " . ");
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ }
+
+ ret = __reg_value_snprintf(buf + offset, remain,
+ (void *)®->val[pos],
+ curlen, reverse, pfx);
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+
+ pos += div_round_up(curlen, sizeof(uint32_t));
+ if (pos >= reg->len / sizeof(uint32_t))
+ break;
+ }
+
+ return offset;
+}
+
static int
nftnl_data_reg_verdict_snprintf_def(char *buf, size_t size,
const union nftnl_data_reg *reg,
--
2.51.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [libnftnl PATCH 9/9] udata: Store u32 udata values in Big Endian
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
` (7 preceding siblings ...)
2025-10-23 16:05 ` [libnftnl PATCH 8/9] data_reg: Support concatenated data Phil Sutter
@ 2025-10-23 16:05 ` Phil Sutter
2026-01-27 23:39 ` Pablo Neira Ayuso
2026-01-27 22:04 ` [libnftnl PATCH 0/9] Fix for debug output on " Phil Sutter
9 siblings, 1 reply; 13+ messages in thread
From: Phil Sutter @ 2025-10-23 16:05 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Avoid deviation of this data in between different byte orders. Assume
that direct callers of nftnl_udata_put() know what they do.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
src/udata.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/udata.c b/src/udata.c
index a1956571ef5fd..8cf4e7ca61e2f 100644
--- a/src/udata.c
+++ b/src/udata.c
@@ -8,6 +8,7 @@
#include <udata.h>
#include <utils.h>
+#include <arpa/inet.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@@ -100,7 +101,9 @@ EXPORT_SYMBOL(nftnl_udata_put_u32);
bool nftnl_udata_put_u32(struct nftnl_udata_buf *buf, uint8_t type,
uint32_t data)
{
- return nftnl_udata_put(buf, type, sizeof(data), &data);
+ uint32_t data_be = htonl(data);
+
+ return nftnl_udata_put(buf, type, sizeof(data_be), &data_be);
}
EXPORT_SYMBOL(nftnl_udata_type);
@@ -128,7 +131,7 @@ uint32_t nftnl_udata_get_u32(const struct nftnl_udata *attr)
memcpy(&data, attr->value, sizeof(data));
- return data;
+ return ntohl(data);
}
EXPORT_SYMBOL(nftnl_udata_next);
--
2.51.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [libnftnl PATCH 9/9] udata: Store u32 udata values in Big Endian
2025-10-23 16:05 ` [libnftnl PATCH 9/9] udata: Store u32 udata values in Big Endian Phil Sutter
@ 2026-01-27 23:39 ` Pablo Neira Ayuso
2026-01-28 11:57 ` Phil Sutter
0 siblings, 1 reply; 13+ messages in thread
From: Pablo Neira Ayuso @ 2026-01-27 23:39 UTC (permalink / raw)
To: Phil Sutter; +Cc: netfilter-devel
On Thu, Oct 23, 2025 at 06:05:47PM +0200, Phil Sutter wrote:
> Avoid deviation of this data in between different byte orders. Assume
> that direct callers of nftnl_udata_put() know what they do.
How does this work after an update?
Load ruleset with nft version previous to this, then upgrade, then
list ruleset with new nft version.
> Signed-off-by: Phil Sutter <phil@nwl.cc>
> ---
> src/udata.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/src/udata.c b/src/udata.c
> index a1956571ef5fd..8cf4e7ca61e2f 100644
> --- a/src/udata.c
> +++ b/src/udata.c
> @@ -8,6 +8,7 @@
> #include <udata.h>
> #include <utils.h>
>
> +#include <arpa/inet.h>
> #include <stdlib.h>
> #include <stdint.h>
> #include <string.h>
> @@ -100,7 +101,9 @@ EXPORT_SYMBOL(nftnl_udata_put_u32);
> bool nftnl_udata_put_u32(struct nftnl_udata_buf *buf, uint8_t type,
> uint32_t data)
> {
> - return nftnl_udata_put(buf, type, sizeof(data), &data);
> + uint32_t data_be = htonl(data);
> +
> + return nftnl_udata_put(buf, type, sizeof(data_be), &data_be);
> }
>
> EXPORT_SYMBOL(nftnl_udata_type);
> @@ -128,7 +131,7 @@ uint32_t nftnl_udata_get_u32(const struct nftnl_udata *attr)
>
> memcpy(&data, attr->value, sizeof(data));
>
> - return data;
> + return ntohl(data);
> }
>
> EXPORT_SYMBOL(nftnl_udata_next);
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [libnftnl PATCH 9/9] udata: Store u32 udata values in Big Endian
2026-01-27 23:39 ` Pablo Neira Ayuso
@ 2026-01-28 11:57 ` Phil Sutter
0 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2026-01-28 11:57 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Hi Pablo,
On Wed, Jan 28, 2026 at 12:39:20AM +0100, Pablo Neira Ayuso wrote:
> On Thu, Oct 23, 2025 at 06:05:47PM +0200, Phil Sutter wrote:
> > Avoid deviation of this data in between different byte orders. Assume
> > that direct callers of nftnl_udata_put() know what they do.
>
> How does this work after an update?
>
> Load ruleset with nft version previous to this, then upgrade, then
> list ruleset with new nft version.
You're right, on LE systems this would interpret LE data as BE. Do we
support this scenario? I vaguely remember a discussion around this topic
with iptables-nft, but don't recall any details.
Without this patch, udata values are in host byteorder. In order to
correctly print them, libnftnl would need to know how data is
structured, which it doesn't and that is by design, right? So the only
alternative to this breakage that I see is to entirely omit userdata
from debug output.
Cheers, Phil
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [libnftnl PATCH 0/9] Fix for debug output on Big Endian
2025-10-23 16:05 [libnftnl PATCH 0/9] Fix for debug output on Big Endian Phil Sutter
` (8 preceding siblings ...)
2025-10-23 16:05 ` [libnftnl PATCH 9/9] udata: Store u32 udata values in Big Endian Phil Sutter
@ 2026-01-27 22:04 ` Phil Sutter
9 siblings, 0 replies; 13+ messages in thread
From: Phil Sutter @ 2026-01-27 22:04 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
On Thu, Oct 23, 2025 at 06:05:38PM +0200, Phil Sutter wrote:
> This series aims at providing identical netlink debug output in nftables
> on Big and Little Endian systems. Particularly problematic are all data
> regs in host byte order, worsened by the potential for byte order swaps
> within a single data reg (concatenated set elements).
>
> A bonus task is cropping data reg values to their actual size.
> Previously, every four-byte register containing data was printed which
> further reduces data expressiveness.
>
> This series introduces data attribute setters for expressions and set
> elements which accept a byteorder value (plus an array of component
> sizes in the latter case) and changes the data reg printer to:
>
> - Print only nftnl_data_reg::len bytes at max
> - Print data byte-by-byte, not four byte chunks as u32 values
> interpreted in host byte order
> - Print data in reverse if in host byte order on Little Endian
>
> If nftnl_data_reg::sizes array has non-zero fields, data is assumed to
> be concatenated and bits in nftnl_data_reg::byteorder signal host byte
> order in components. Each component is then printed as per the above
> rules and separated by a dot (".").
>
> Patches 3-8 implement the above. Since debug output changes
> significantly, use the occasion to:
> - Print a colon (":") and flags value only if relevant (patch 1)
> - Fix for missing object name in objmap elements (patch 1)
> - Avoid ambiguity between data and flags value by prefixing with 'flags'
> (patch 1)
> - Avoid trailing whitespace or space before tab (patch 2)
>
> Finally, patch 8 tries to avoid userdata values in host byte order by
> storing u32 values in Big Endian. Since nftnl_udata_put_u32() is the
> only typed attribute setter (apart from the unproblematic strz one),
> this may be good enough for the purpose.
>
> Phil Sutter (9):
> set_elem: Review debug output
> expr: data_reg: Avoid extra whitespace
> expr: Pass byteorder to struct expr_ops::set callback
> data_reg: Introduce struct nftnl_data_reg::byteorder field
> data_reg: Introduce struct nftnl_data_reg::sizes array
> Introduce nftnl_{expr,set_elem}_set_imm()
> data_reg: Respect data byteorder when printing
> data_reg: Support concatenated data
> udata: Store u32 udata values in Big Endian
Series applied.
^ permalink raw reply [flat|nested] 13+ messages in thread