diff options
| author | Phil Sutter <phil@nwl.cc> | 2025-10-14 15:56:26 +0200 |
|---|---|---|
| committer | Phil Sutter <phil@nwl.cc> | 2026-01-27 22:59:15 +0100 |
| commit | 4562e2418575d58df36d214c242f5d04613f52dd (patch) | |
| tree | 257f793a61bfe0295108c6bb9b22eab95f6314da | |
| parent | 84b7adedf98fbf738632d07e585d621588d45500 (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.c | 48 |
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 *)®->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) |
