summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2025-10-14 15:56:26 +0200
committerPhil Sutter <phil@nwl.cc>2026-01-27 22:59:15 +0100
commit4562e2418575d58df36d214c242f5d04613f52dd (patch)
tree257f793a61bfe0295108c6bb9b22eab95f6314da
parent84b7adedf98fbf738632d07e585d621588d45500 (diff)
data_reg: Support concatenated data
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>
-rw-r--r--src/expr/data_reg.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index de5d235..d01e0f7 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -27,28 +27,25 @@ 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);
}
@@ -56,6 +53,37 @@ nftnl_data_reg_value_snprintf_default(char *buf, size_t remain,
}
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 *)&reg->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,
uint32_t flags)