From: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> This patch adds a new .byteorder callback to expressions to allow infer the data byteorder that is placed in registers. Given that keys have a fixed datatype, this patch tracks register operations to obtain the data byteorder. This new infrastructure is internal and it is only used by the nftnl_rule_snprintf() function to make it portable regardless the endianess. A few examples after this patch running on x86_64: netdev [ meta load protocol => reg 1 ] [ cmp eq reg 1 0x00000008 ] [ immediate reg 1 0x01020304 ] [ payload write reg 1 => 4b @ network header + 12 csum_type 1 csum_off 10 csum_flags 0x1 ] root@salvia:/home/pablo/devel/scm/git-netfilter/libnftnl# nft --debug=netlink add rule netdev x z ip saddr 1.2.3.4 netdev [ meta load protocol => reg 1 ] [ cmp eq reg 1 0x00000008 ] [ payload load 4b @ network header + 12 => reg 1 ] [ cmp eq reg 1 0x01020304 ] Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> Signed-off-by: Phil Sutter <phil@xxxxxx> --- Changes since v1: - Fix calls to changed nftnl_data_reg_snprintf(). - Add more byteorder callbacks - expr/xfrm: Fix SPI endianness, was recently corrected in nftables - ct helper: Strings are always "big endian" - expr/cmp: Boundary comparisons are always Big Endian - expr/range: Ranges are always in network byte order --- include/common.h | 29 +++++++++++++++++++++++++ include/data_reg.h | 4 +++- include/expr.h | 2 +- include/expr_ops.h | 2 ++ src/expr.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ src/expr/bitwise.c | 30 +++++++++++++++++++------- src/expr/byteorder.c | 21 ++++++++++++++++++ src/expr/cmp.c | 21 +++++++++++++++++- src/expr/ct.c | 30 ++++++++++++++++++++++++++ src/expr/data_reg.c | 18 +++++++++++----- src/expr/dup.c | 14 ++++++++++++ src/expr/exthdr.c | 14 ++++++++++++ src/expr/fib.c | 18 ++++++++++++++++ src/expr/fwd.c | 14 ++++++++++++ src/expr/immediate.c | 17 ++++++++++++--- src/expr/masq.c | 16 ++++++++++++++ src/expr/meta.c | 28 ++++++++++++++++++++++++ src/expr/nat.c | 22 +++++++++++++++++++ src/expr/numgen.c | 12 +++++++++++ src/expr/osf.c | 12 +++++++++++ src/expr/payload.c | 14 ++++++++++++ src/expr/queue.c | 12 +++++++++++ src/expr/range.c | 11 ++++++++-- src/expr/redir.c | 16 ++++++++++++++ src/expr/rt.c | 19 +++++++++++++++++ src/expr/socket.c | 12 +++++++++++ src/expr/tproxy.c | 14 ++++++++++++ src/expr/tunnel.c | 12 +++++++++++ src/expr/xfrm.c | 18 ++++++++++++++++ src/rule.c | 7 ++++++ src/set_elem.c | 9 +++++--- 31 files changed, 495 insertions(+), 24 deletions(-) diff --git a/include/common.h b/include/common.h index d05a81ad542c1..13d709b247f92 100644 --- a/include/common.h +++ b/include/common.h @@ -18,4 +18,33 @@ enum nftnl_parse_input { NFTNL_PARSE_FILE, }; +enum nftnl_byteorder { + NFTNL_BYTEORDER_UNKNOWN = 0, + NFTNL_BYTEORDER_HOST, + NFTNL_BYTEORDER_NETWORK, +}; + +#define NFTNL_CTX_BYTEORDER_MAX_EXPRS 16 + +struct nftnl_byteorder_ctx { + struct { + const struct nftnl_expr *expr; + enum nftnl_byteorder byteorder; + } expr[NFT_REG32_15 + 1]; + struct { + uint32_t reg; + struct nftnl_expr *expr; + } pending[NFTNL_CTX_BYTEORDER_MAX_EXPRS]; + uint32_t num_pending; +}; + +void nftnl_reg_byteorder_set(struct nftnl_byteorder_ctx *ctx, uint32_t reg, + enum nftnl_byteorder byteorder); +enum nftnl_byteorder nftnl_reg_byteorder_get(struct nftnl_byteorder_ctx *ctx, + uint32_t reg); +void nftnl_reg_byteorder_unknown(struct nftnl_byteorder_ctx *ctx, uint32_t reg, + struct nftnl_expr *expr); +void nftnl_reg_byteorder_resolve(struct nftnl_byteorder_ctx *ctx, uint32_t reg, + enum nftnl_byteorder byteorder); + #endif diff --git a/include/data_reg.h b/include/data_reg.h index 6d2dc66858bf8..3f24b6725e148 100644 --- a/include/data_reg.h +++ b/include/data_reg.h @@ -5,6 +5,7 @@ #include <stdint.h> #include <stdbool.h> #include <unistd.h> +#include "common.h" enum { DATA_NONE, @@ -31,7 +32,8 @@ union nftnl_data_reg { int nftnl_data_reg_snprintf(char *buf, size_t size, const union nftnl_data_reg *reg, - uint32_t flags, int reg_type); + uint32_t flags, int reg_type, + enum nftnl_byteorder byteorder); struct nlattr; int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type); diff --git a/include/expr.h b/include/expr.h index be45e954df5b6..50959724492e7 100644 --- a/include/expr.h +++ b/include/expr.h @@ -6,6 +6,7 @@ struct expr_ops; struct nftnl_expr { struct list_head head; uint32_t flags; + uint32_t byteorder; struct expr_ops *ops; uint8_t data[]; }; @@ -15,5 +16,4 @@ struct nlmsghdr; void nftnl_expr_build_payload(struct nlmsghdr *nlh, struct nftnl_expr *expr); struct nftnl_expr *nftnl_expr_parse(struct nlattr *attr); - #endif diff --git a/include/expr_ops.h b/include/expr_ops.h index 7a6aa23f9bd1d..161babdade596 100644 --- a/include/expr_ops.h +++ b/include/expr_ops.h @@ -7,6 +7,7 @@ struct nlattr; struct nlmsghdr; struct nftnl_expr; +struct nftnl_print_ctx; struct expr_ops { const char *name; @@ -18,6 +19,7 @@ struct expr_ops { 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); + void (*byteorder)(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e); int (*snprintf)(char *buf, size_t len, uint32_t flags, const struct nftnl_expr *e); }; diff --git a/src/expr.c b/src/expr.c index 277bbdeeb5d02..d958bab98e925 100644 --- a/src/expr.c +++ b/src/expr.c @@ -301,3 +301,54 @@ int nftnl_expr_fprintf(FILE *fp, const struct nftnl_expr *expr, uint32_t type, return nftnl_fprintf(fp, expr, NFTNL_CMD_UNSPEC, type, flags, nftnl_expr_do_snprintf); } + +void nftnl_reg_byteorder_set(struct nftnl_byteorder_ctx *ctx, uint32_t reg, + enum nftnl_byteorder byteorder) +{ + if (reg > NFT_REG32_15) + return; + + ctx->expr[reg].byteorder = byteorder; +} + +enum nftnl_byteorder nftnl_reg_byteorder_get(struct nftnl_byteorder_ctx *ctx, + uint32_t reg) +{ + if (reg > NFT_REG32_15) + return NFTNL_BYTEORDER_UNKNOWN; + + return ctx->expr[reg].byteorder; +} + +void nftnl_reg_byteorder_unknown(struct nftnl_byteorder_ctx *ctx, uint32_t reg, + struct nftnl_expr *expr) +{ + int k; + + if (reg > NFT_REG32_15) + return; + + k = ctx->num_pending++; + if (k >= NFTNL_CTX_BYTEORDER_MAX_EXPRS) + return; + + ctx->pending[k].reg = reg; + ctx->pending[k].expr = expr; +} + +void nftnl_reg_byteorder_resolve(struct nftnl_byteorder_ctx *ctx, uint32_t reg, + enum nftnl_byteorder byteorder) +{ + struct nftnl_expr *expr; + int i; + + for (i = 0; i < ctx->num_pending; i++) { + if (!ctx->pending[i].expr) + continue; + if (ctx->pending[i].reg == reg) { + expr = ctx->pending[i].expr; + expr->byteorder = byteorder; + ctx->pending[i].expr = NULL; + } + } +} diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c index d0c7827eacec9..a21dec01d286f 100644 --- a/src/expr/bitwise.c +++ b/src/expr/bitwise.c @@ -209,9 +209,18 @@ nftnl_expr_bitwise_parse(struct nftnl_expr *e, struct nlattr *attr) return ret; } +static void +nftnl_expr_bitwise_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_bitwise *bitwise = nftnl_expr_data(e); + + e->byteorder = nftnl_reg_byteorder_get(ctx, bitwise->sreg); +} + static int nftnl_expr_bitwise_snprintf_bool(char *buf, size_t remain, - const struct nftnl_expr_bitwise *bitwise) + const struct nftnl_expr_bitwise *bitwise, + enum nftnl_byteorder byteorder) { int offset = 0, ret; @@ -220,14 +229,14 @@ nftnl_expr_bitwise_snprintf_bool(char *buf, size_t remain, SNPRINTF_BUFFER_SIZE(ret, remain, offset); ret = nftnl_data_reg_snprintf(buf + offset, remain, &bitwise->mask, - 0, DATA_VALUE); + 0, DATA_VALUE, byteorder); 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, &bitwise->xor, - 0, DATA_VALUE); + 0, DATA_VALUE, byteorder); SNPRINTF_BUFFER_SIZE(ret, remain, offset); return offset; @@ -235,7 +244,8 @@ nftnl_expr_bitwise_snprintf_bool(char *buf, size_t remain, static int nftnl_expr_bitwise_snprintf_shift(char *buf, size_t remain, const char *op, - const struct nftnl_expr_bitwise *bitwise) + const struct nftnl_expr_bitwise *bitwise, + enum nftnl_byteorder byteorder) { int offset = 0, ret; ret = snprintf(buf, remain, "reg %u = ( reg %u %s ", @@ -243,7 +253,7 @@ nftnl_expr_bitwise_snprintf_shift(char *buf, size_t remain, const char *op, SNPRINTF_BUFFER_SIZE(ret, remain, offset); ret = nftnl_data_reg_snprintf(buf + offset, remain, &bitwise->data, - 0, DATA_VALUE); + 0, DATA_VALUE, byteorder); SNPRINTF_BUFFER_SIZE(ret, remain, offset); ret = snprintf(buf + offset, remain, ") "); @@ -261,13 +271,16 @@ nftnl_expr_bitwise_snprintf(char *buf, size_t size, switch (bitwise->op) { case NFT_BITWISE_BOOL: - err = nftnl_expr_bitwise_snprintf_bool(buf, size, bitwise); + err = nftnl_expr_bitwise_snprintf_bool(buf, size, bitwise, + e->byteorder); break; case NFT_BITWISE_LSHIFT: - err = nftnl_expr_bitwise_snprintf_shift(buf, size, "<<", bitwise); + err = nftnl_expr_bitwise_snprintf_shift(buf, size, "<<", + bitwise, e->byteorder); break; case NFT_BITWISE_RSHIFT: - err = nftnl_expr_bitwise_snprintf_shift(buf, size, ">>", bitwise); + err = nftnl_expr_bitwise_snprintf_shift(buf, size, ">>", + bitwise, e->byteorder); break; } @@ -282,5 +295,6 @@ struct expr_ops expr_ops_bitwise = { .get = nftnl_expr_bitwise_get, .parse = nftnl_expr_bitwise_parse, .build = nftnl_expr_bitwise_build, + .byteorder = nftnl_expr_bitwise_byteorder, .snprintf = nftnl_expr_bitwise_snprintf, }; diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c index d299745fc57b4..ae67ee6ef2b35 100644 --- a/src/expr/byteorder.c +++ b/src/expr/byteorder.c @@ -197,6 +197,26 @@ static inline int nftnl_str2ntoh(const char *op) } } +static void nftnl_expr_byteorder_byteorder(struct nftnl_byteorder_ctx *ctx, + struct nftnl_expr *e) +{ + struct nftnl_expr_byteorder *byteorder = nftnl_expr_data(e); + enum nftnl_byteorder bo; + + switch (byteorder->op) { + case NFT_BYTEORDER_NTOH: + bo = NFTNL_BYTEORDER_HOST; + break; + case NFT_BYTEORDER_HTON: + bo = NFTNL_BYTEORDER_NETWORK; + break; + default: + bo = NFTNL_BYTEORDER_UNKNOWN; + break; + } + nftnl_reg_byteorder_set(ctx, byteorder->dreg, bo); +} + static int nftnl_expr_byteorder_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -220,5 +240,6 @@ struct expr_ops expr_ops_byteorder = { .get = nftnl_expr_byteorder_get, .parse = nftnl_expr_byteorder_parse, .build = nftnl_expr_byteorder_build, + .byteorder = nftnl_expr_byteorder_byteorder, .snprintf = nftnl_expr_byteorder_snprintf, }; diff --git a/src/expr/cmp.c b/src/expr/cmp.c index 6030693f15d86..846a112a03231 100644 --- a/src/expr/cmp.c +++ b/src/expr/cmp.c @@ -176,6 +176,24 @@ static inline int nftnl_str2cmp(const char *op) } } +static void +nftnl_expr_cmp_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_cmp *cmp = nftnl_expr_data(e); + + switch (cmp->op) { + case NFT_CMP_LT: + case NFT_CMP_LTE: + case NFT_CMP_GT: + case NFT_CMP_GTE: + e->byteorder = NFTNL_BYTEORDER_NETWORK; + break; + default: + e->byteorder = nftnl_reg_byteorder_get(ctx, cmp->sreg); + break; + } +} + static int nftnl_expr_cmp_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -188,7 +206,7 @@ nftnl_expr_cmp_snprintf(char *buf, size_t remain, SNPRINTF_BUFFER_SIZE(ret, remain, offset); ret = nftnl_data_reg_snprintf(buf + offset, remain, &cmp->data, - 0, DATA_VALUE); + 0, DATA_VALUE, e->byteorder); SNPRINTF_BUFFER_SIZE(ret, remain, offset); return offset; @@ -202,5 +220,6 @@ struct expr_ops expr_ops_cmp = { .get = nftnl_expr_cmp_get, .parse = nftnl_expr_cmp_parse, .build = nftnl_expr_cmp_build, + .byteorder = nftnl_expr_cmp_byteorder, .snprintf = nftnl_expr_cmp_snprintf, }; diff --git a/src/expr/ct.c b/src/expr/ct.c index d5dfc81cfe0d1..fe4fc43688eb5 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -222,6 +222,35 @@ static inline int str2ctdir(const char *str, uint8_t *ctdir) return -1; } +static void +nftnl_expr_ct_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_ct *ct = nftnl_expr_data(e); + + switch (ct->key) { + case NFT_CT_HELPER: + case NFT_CT_SRC: + case NFT_CT_DST: + case NFT_CT_PROTOCOL: + case NFT_CT_PROTO_SRC: + case NFT_CT_PROTO_DST: + case NFT_CT_SRC_IP: + case NFT_CT_DST_IP: + case NFT_CT_SRC_IP6: + case NFT_CT_DST_IP6: + case NFT_CT_ID: + e->byteorder = NFTNL_BYTEORDER_NETWORK; + break; + default: + e->byteorder = NFTNL_BYTEORDER_HOST; + } + + if (e->flags & (1 << NFTNL_EXPR_CT_SREG)) + nftnl_reg_byteorder_resolve(ctx, ct->sreg, e->byteorder); + if (e->flags & (1 << NFTNL_EXPR_CT_DREG)) + nftnl_reg_byteorder_set(ctx, ct->dreg, e->byteorder); +} + static int nftnl_expr_ct_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -258,5 +287,6 @@ struct expr_ops expr_ops_ct = { .get = nftnl_expr_ct_get, .parse = nftnl_expr_ct_parse, .build = nftnl_expr_ct_build, + .byteorder = nftnl_expr_ct_byteorder, .snprintf = nftnl_expr_ct_snprintf, }; diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c index 2633a775c90cc..789958ea66c0d 100644 --- a/src/expr/data_reg.c +++ b/src/expr/data_reg.c @@ -27,16 +27,22 @@ static int nftnl_data_reg_value_snprintf_default(char *buf, size_t remain, const union nftnl_data_reg *reg, - uint32_t flags) + uint32_t flags, + enum nftnl_byteorder byteorder) { const char *pfx = flags & DATA_F_NOPFX ? "" : "0x"; int offset = 0, ret, i; + uint32_t value; for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) { - ret = snprintf(buf + offset, remain, - "%s%.8x ", pfx, reg->val[i]); + if (byteorder == NFTNL_BYTEORDER_NETWORK) + value = ntohl(reg->val[i]); + else + value = reg->val[i]; + + ret = snprintf(buf + offset, remain, "%s%.8x ", pfx, value); SNPRINTF_BUFFER_SIZE(ret, remain, offset); } @@ -63,12 +69,14 @@ nftnl_data_reg_verdict_snprintf_def(char *buf, size_t size, int nftnl_data_reg_snprintf(char *buf, size_t size, const union nftnl_data_reg *reg, - uint32_t flags, int reg_type) + uint32_t flags, int reg_type, + enum nftnl_byteorder byteorder) { switch(reg_type) { case DATA_VALUE: return nftnl_data_reg_value_snprintf_default(buf, size, - reg, flags); + reg, flags, + byteorder); case DATA_VERDICT: case DATA_CHAIN: return nftnl_data_reg_verdict_snprintf_def(buf, size, diff --git a/src/expr/dup.c b/src/expr/dup.c index f041b551a7e78..58c3fe6989e91 100644 --- a/src/expr/dup.c +++ b/src/expr/dup.c @@ -111,6 +111,19 @@ static int nftnl_expr_dup_parse(struct nftnl_expr *e, struct nlattr *attr) return ret; } +static void +nftnl_expr_dup_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_dup *dup = nftnl_expr_data(e); + + if (e->flags & (1 << NFTNL_EXPR_DUP_SREG_ADDR)) + nftnl_reg_byteorder_resolve(ctx, dup->sreg_addr, + NFTNL_BYTEORDER_NETWORK); + if (e->flags & (1 << NFTNL_EXPR_DUP_SREG_DEV)) + nftnl_reg_byteorder_resolve(ctx, dup->sreg_dev, + NFTNL_BYTEORDER_HOST); +} + static int nftnl_expr_dup_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) { @@ -138,5 +151,6 @@ struct expr_ops expr_ops_dup = { .get = nftnl_expr_dup_get, .parse = nftnl_expr_dup_parse, .build = nftnl_expr_dup_build, + .byteorder = nftnl_expr_dup_byteorder, .snprintf = nftnl_expr_dup_snprintf, }; diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c index 1b813b1e47c4d..280fe73f48041 100644 --- a/src/expr/exthdr.c +++ b/src/expr/exthdr.c @@ -235,6 +235,19 @@ static inline int str2exthdr_type(const char *str) return -1; } +static void +nftnl_expr_exthdr_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_exthdr *exthdr = nftnl_expr_data(e); + + e->byteorder = NFTNL_BYTEORDER_NETWORK; + + if (e->flags & (1 << NFTNL_EXPR_EXTHDR_DREG)) + nftnl_reg_byteorder_set(ctx, exthdr->dreg, e->byteorder); + if (e->flags & (1 << NFTNL_EXPR_EXTHDR_SREG)) + nftnl_reg_byteorder_resolve(ctx, exthdr->sreg, e->byteorder); +} + static int nftnl_expr_exthdr_snprintf(char *buf, size_t len, uint32_t flags, const struct nftnl_expr *e) @@ -262,5 +275,6 @@ struct expr_ops expr_ops_exthdr = { .get = nftnl_expr_exthdr_get, .parse = nftnl_expr_exthdr_parse, .build = nftnl_expr_exthdr_build, + .byteorder = nftnl_expr_exthdr_byteorder, .snprintf = nftnl_expr_exthdr_snprintf, }; diff --git a/src/expr/fib.c b/src/expr/fib.c index aaff52acabdbd..75194bff95f41 100644 --- a/src/expr/fib.c +++ b/src/expr/fib.c @@ -128,6 +128,23 @@ nftnl_expr_fib_parse(struct nftnl_expr *e, struct nlattr *attr) return ret; } +static void +nftnl_expr_fib_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_fib *fib = nftnl_expr_data(e); + + switch (fib->result) { + case NFT_FIB_RESULT_OIFNAME: + e->byteorder = NFTNL_BYTEORDER_NETWORK; + break; + default: + e->byteorder = NFTNL_BYTEORDER_HOST; + } + + if (e->flags & (1 << NFTNL_EXPR_FIB_DREG)) + nftnl_reg_byteorder_set(ctx, fib->dreg, e->byteorder); +} + static const char *fib_type[NFT_FIB_RESULT_MAX + 1] = { [NFT_FIB_RESULT_OIF] = "oif", [NFT_FIB_RESULT_OIFNAME] = "oifname", @@ -198,5 +215,6 @@ struct expr_ops expr_ops_fib = { .get = nftnl_expr_fib_get, .parse = nftnl_expr_fib_parse, .build = nftnl_expr_fib_build, + .byteorder = nftnl_expr_fib_byteorder, .snprintf = nftnl_expr_fib_snprintf, }; diff --git a/src/expr/fwd.c b/src/expr/fwd.c index 82e5a418bfae5..6875abfa80d19 100644 --- a/src/expr/fwd.c +++ b/src/expr/fwd.c @@ -125,6 +125,19 @@ static int nftnl_expr_fwd_parse(struct nftnl_expr *e, struct nlattr *attr) return ret; } +static void +nftnl_expr_fwd_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_fwd *fwd = nftnl_expr_data(e); + + if (e->flags & (1 << NFTNL_EXPR_FWD_SREG_DEV)) + nftnl_reg_byteorder_resolve(ctx, fwd->sreg_dev, + NFTNL_BYTEORDER_HOST); + if (e->flags & (1 << NFTNL_EXPR_FWD_SREG_ADDR)) + nftnl_reg_byteorder_resolve(ctx, fwd->sreg_addr, + NFTNL_BYTEORDER_NETWORK); +} + static int nftnl_expr_fwd_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) { @@ -158,5 +171,6 @@ struct expr_ops expr_ops_fwd = { .get = nftnl_expr_fwd_get, .parse = nftnl_expr_fwd_parse, .build = nftnl_expr_fwd_build, + .byteorder = nftnl_expr_fwd_byteorder, .snprintf = nftnl_expr_fwd_snprintf, }; diff --git a/src/expr/immediate.c b/src/expr/immediate.c index 94b043c0fc8ab..fb291c7606bab 100644 --- a/src/expr/immediate.c +++ b/src/expr/immediate.c @@ -183,6 +183,14 @@ nftnl_expr_immediate_parse(struct nftnl_expr *e, struct nlattr *attr) return ret; } +static void +nftnl_expr_immediate_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_immediate *imm = nftnl_expr_data(e); + + nftnl_reg_byteorder_unknown(ctx, imm->dreg, e); +} + static int nftnl_expr_immediate_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -195,17 +203,19 @@ nftnl_expr_immediate_snprintf(char *buf, size_t remain, if (e->flags & (1 << NFTNL_EXPR_IMM_DATA)) { ret = nftnl_data_reg_snprintf(buf + offset, remain, &imm->data, - flags, DATA_VALUE); + flags, DATA_VALUE, e->byteorder); SNPRINTF_BUFFER_SIZE(ret, remain, offset); } else if (e->flags & (1 << NFTNL_EXPR_IMM_VERDICT)) { ret = nftnl_data_reg_snprintf(buf + offset, remain, &imm->data, - flags, DATA_VERDICT); + flags, DATA_VERDICT, + NFTNL_BYTEORDER_UNKNOWN); SNPRINTF_BUFFER_SIZE(ret, remain, offset); } else if (e->flags & (1 << NFTNL_EXPR_IMM_CHAIN)) { ret = nftnl_data_reg_snprintf(buf + offset, remain, &imm->data, - flags, DATA_CHAIN); + flags, DATA_CHAIN, + NFTNL_BYTEORDER_UNKNOWN); SNPRINTF_BUFFER_SIZE(ret, remain, offset); } @@ -229,5 +239,6 @@ struct expr_ops expr_ops_immediate = { .get = nftnl_expr_immediate_get, .parse = nftnl_expr_immediate_parse, .build = nftnl_expr_immediate_build, + .byteorder = nftnl_expr_immediate_byteorder, .snprintf = nftnl_expr_immediate_snprintf, }; diff --git a/src/expr/masq.c b/src/expr/masq.c index 684708c758390..a964e3ae1a938 100644 --- a/src/expr/masq.c +++ b/src/expr/masq.c @@ -131,6 +131,21 @@ nftnl_expr_masq_parse(struct nftnl_expr *e, struct nlattr *attr) return 0; } +static void +nftnl_expr_masq_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_masq *masq = nftnl_expr_data(e); + + if (e->flags & (1 << NFTNL_EXPR_MASQ_REG_PROTO_MIN)) + nftnl_reg_byteorder_resolve(ctx, masq->sreg_proto_min, + NFTNL_BYTEORDER_NETWORK); + if (e->flags & (1 << NFTNL_EXPR_MASQ_REG_PROTO_MAX)) + nftnl_reg_byteorder_resolve(ctx, masq->sreg_proto_max, + NFTNL_BYTEORDER_NETWORK); + + e->byteorder = NFTNL_BYTEORDER_NETWORK; +} + static int nftnl_expr_masq_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) { @@ -163,5 +178,6 @@ struct expr_ops expr_ops_masq = { .get = nftnl_expr_masq_get, .parse = nftnl_expr_masq_parse, .build = nftnl_expr_masq_build, + .byteorder = nftnl_expr_masq_byteorder, .snprintf = nftnl_expr_masq_snprintf, }; diff --git a/src/expr/meta.c b/src/expr/meta.c index 34fbb9bb63c03..deb14e5cb054d 100644 --- a/src/expr/meta.c +++ b/src/expr/meta.c @@ -191,6 +191,33 @@ static inline int str2meta_key(const char *str) return -1; } +static void nftnl_expr_meta_byteorder(struct nftnl_byteorder_ctx *ctx, + struct nftnl_expr *e) +{ + struct nftnl_expr_meta *meta = nftnl_expr_data(e); + + + switch (meta->key) { + case NFT_META_PROTOCOL: + case NFT_META_IIFNAME: + case NFT_META_OIFNAME: + case NFT_META_BRI_IIFNAME: + case NFT_META_BRI_OIFNAME: + case NFT_META_PRANDOM: + case NFT_META_BRI_IIFVPROTO: + case NFT_META_SDIFNAME: + e->byteorder = NFTNL_BYTEORDER_NETWORK; + break; + default: + e->byteorder = NFTNL_BYTEORDER_HOST; + } + + if (e->flags & (1 << NFTNL_EXPR_META_SREG)) + nftnl_reg_byteorder_resolve(ctx, meta->sreg, e->byteorder); + if (e->flags & (1 << NFTNL_EXPR_META_DREG)) + nftnl_reg_byteorder_set(ctx, meta->dreg, e->byteorder); +} + static int nftnl_expr_meta_snprintf(char *buf, size_t len, uint32_t flags, const struct nftnl_expr *e) @@ -216,5 +243,6 @@ struct expr_ops expr_ops_meta = { .get = nftnl_expr_meta_get, .parse = nftnl_expr_meta_parse, .build = nftnl_expr_meta_build, + .byteorder = nftnl_expr_meta_byteorder, .snprintf = nftnl_expr_meta_snprintf, }; diff --git a/src/expr/nat.c b/src/expr/nat.c index 0a9cdd7f65f8f..785ceb20a92bf 100644 --- a/src/expr/nat.c +++ b/src/expr/nat.c @@ -220,6 +220,27 @@ static inline int nftnl_str2nat(const char *nat) } } +static void +nftnl_expr_nat_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_nat *nat = nftnl_expr_data(e); + + if (e->flags & (1 << NFTNL_EXPR_NAT_REG_ADDR_MIN)) + nftnl_reg_byteorder_resolve(ctx, nat->sreg_addr_min, + NFTNL_BYTEORDER_NETWORK); + if (e->flags & (1 << NFTNL_EXPR_NAT_REG_ADDR_MAX)) + nftnl_reg_byteorder_resolve(ctx, nat->sreg_addr_max, + NFTNL_BYTEORDER_NETWORK); + if (e->flags & (1 << NFTNL_EXPR_NAT_REG_PROTO_MIN)) + nftnl_reg_byteorder_resolve(ctx, nat->sreg_proto_min, + NFTNL_BYTEORDER_NETWORK); + if (e->flags & (1 << NFTNL_EXPR_NAT_REG_PROTO_MAX)) + nftnl_reg_byteorder_resolve(ctx, nat->sreg_proto_max, + NFTNL_BYTEORDER_NETWORK); + + e->byteorder = NFTNL_BYTEORDER_NETWORK; +} + static int nftnl_expr_nat_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -274,5 +295,6 @@ struct expr_ops expr_ops_nat = { .get = nftnl_expr_nat_get, .parse = nftnl_expr_nat_parse, .build = nftnl_expr_nat_build, + .byteorder = nftnl_expr_nat_byteorder, .snprintf = nftnl_expr_nat_snprintf, }; diff --git a/src/expr/numgen.c b/src/expr/numgen.c index 159dfeca3618b..dfbeeaf1b172a 100644 --- a/src/expr/numgen.c +++ b/src/expr/numgen.c @@ -142,6 +142,17 @@ nftnl_expr_ng_parse(struct nftnl_expr *e, struct nlattr *attr) return ret; } +static void +nftnl_expr_ng_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_ng *ng = nftnl_expr_data(e); + + e->byteorder = NFTNL_BYTEORDER_HOST; + + if (e->flags & (1 << NFTNL_EXPR_NG_DREG)) + nftnl_reg_byteorder_set(ctx, ng->dreg, e->byteorder); +} + static int nftnl_expr_ng_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -180,5 +191,6 @@ struct expr_ops expr_ops_ng = { .get = nftnl_expr_ng_get, .parse = nftnl_expr_ng_parse, .build = nftnl_expr_ng_build, + .byteorder = nftnl_expr_ng_byteorder, .snprintf = nftnl_expr_ng_snprintf, }; diff --git a/src/expr/osf.c b/src/expr/osf.c index 215a681a97aae..b2e4294877c05 100644 --- a/src/expr/osf.c +++ b/src/expr/osf.c @@ -124,6 +124,17 @@ nftnl_expr_osf_parse(struct nftnl_expr *e, struct nlattr *attr) return 0; } +static void +nftnl_expr_osf_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_osf *osf = nftnl_expr_data(e); + + e->byteorder = NFTNL_BYTEORDER_NETWORK; + + if (e->flags & (1 << NFTNL_EXPR_OSF_DREG)) + nftnl_reg_byteorder_set(ctx, osf->dreg, e->byteorder); +} + static int nftnl_expr_osf_snprintf(char *buf, size_t len, uint32_t flags, const struct nftnl_expr *e) @@ -147,5 +158,6 @@ struct expr_ops expr_ops_osf = { .get = nftnl_expr_osf_get, .parse = nftnl_expr_osf_parse, .build = nftnl_expr_osf_build, + .byteorder = nftnl_expr_osf_byteorder, .snprintf = nftnl_expr_osf_snprintf, }; diff --git a/src/expr/payload.c b/src/expr/payload.c index 82747ec8994f7..84764e837a965 100644 --- a/src/expr/payload.c +++ b/src/expr/payload.c @@ -232,6 +232,19 @@ static inline int nftnl_str2base(const char *base) } } +static void +nftnl_expr_payload_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_payload *payload = nftnl_expr_data(e); + + e->byteorder = NFTNL_BYTEORDER_NETWORK; + + if (payload->sreg) + nftnl_reg_byteorder_resolve(ctx, payload->sreg, e->byteorder); + else + nftnl_reg_byteorder_set(ctx, payload->dreg, e->byteorder); +} + static int nftnl_expr_payload_snprintf(char *buf, size_t len, uint32_t flags, const struct nftnl_expr *e) @@ -259,5 +272,6 @@ struct expr_ops expr_ops_payload = { .get = nftnl_expr_payload_get, .parse = nftnl_expr_payload_parse, .build = nftnl_expr_payload_build, + .byteorder = nftnl_expr_payload_byteorder, .snprintf = nftnl_expr_payload_snprintf, }; diff --git a/src/expr/queue.c b/src/expr/queue.c index 8f70977f7de85..1a65c8ad6484a 100644 --- a/src/expr/queue.c +++ b/src/expr/queue.c @@ -143,6 +143,17 @@ nftnl_expr_queue_parse(struct nftnl_expr *e, struct nlattr *attr) return 0; } +static void +nftnl_expr_queue_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_queue *queue = nftnl_expr_data(e); + + e->byteorder = NFTNL_BYTEORDER_HOST; + + if (e->flags & (1 << NFTNL_EXPR_QUEUE_SREG_QNUM)) + nftnl_reg_byteorder_resolve(ctx, queue->sreg_qnum, e->byteorder); +} + static int nftnl_expr_queue_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -193,5 +204,6 @@ struct expr_ops expr_ops_queue = { .get = nftnl_expr_queue_get, .parse = nftnl_expr_queue_parse, .build = nftnl_expr_queue_build, + .byteorder = nftnl_expr_queue_byteorder, .snprintf = nftnl_expr_queue_snprintf, }; diff --git a/src/expr/range.c b/src/expr/range.c index f76843a8afd0c..ab4e2e70d8d01 100644 --- a/src/expr/range.c +++ b/src/expr/range.c @@ -184,6 +184,12 @@ static inline int nftnl_str2range(const char *op) } } +static void nftnl_expr_range_byteorder(struct nftnl_byteorder_ctx *ctx, + struct nftnl_expr *e) +{ + e->byteorder = NFTNL_BYTEORDER_NETWORK; +} + static int nftnl_expr_range_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) { @@ -195,11 +201,11 @@ static int nftnl_expr_range_snprintf(char *buf, size_t remain, SNPRINTF_BUFFER_SIZE(ret, remain, offset); ret = nftnl_data_reg_snprintf(buf + offset, remain, &range->data_from, - 0, DATA_VALUE); + 0, DATA_VALUE, e->byteorder); SNPRINTF_BUFFER_SIZE(ret, remain, offset); ret = nftnl_data_reg_snprintf(buf + offset, remain, &range->data_to, - 0, DATA_VALUE); + 0, DATA_VALUE, e->byteorder); SNPRINTF_BUFFER_SIZE(ret, remain, offset); return offset; @@ -213,5 +219,6 @@ struct expr_ops expr_ops_range = { .get = nftnl_expr_range_get, .parse = nftnl_expr_range_parse, .build = nftnl_expr_range_build, + .byteorder = nftnl_expr_range_byteorder, .snprintf = nftnl_expr_range_snprintf, }; diff --git a/src/expr/redir.c b/src/expr/redir.c index 4f56cb4302b30..3c1ebc13909e5 100644 --- a/src/expr/redir.c +++ b/src/expr/redir.c @@ -131,6 +131,21 @@ nftnl_expr_redir_parse(struct nftnl_expr *e, struct nlattr *attr) return 0; } +static void +nftnl_expr_redir_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_redir *redir = nftnl_expr_data(e); + + if (e->flags & (1 << NFTNL_EXPR_REDIR_REG_PROTO_MIN)) + nftnl_reg_byteorder_resolve(ctx, redir->sreg_proto_min, + NFTNL_BYTEORDER_NETWORK); + if (e->flags & (1 << NFTNL_EXPR_REDIR_REG_PROTO_MAX)) + nftnl_reg_byteorder_resolve(ctx, redir->sreg_proto_max, + NFTNL_BYTEORDER_NETWORK); + + e->byteorder = NFTNL_BYTEORDER_NETWORK; +} + static int nftnl_expr_redir_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -167,5 +182,6 @@ struct expr_ops expr_ops_redir = { .get = nftnl_expr_redir_get, .parse = nftnl_expr_redir_parse, .build = nftnl_expr_redir_build, + .byteorder = nftnl_expr_redir_byteorder, .snprintf = nftnl_expr_redir_snprintf, }; diff --git a/src/expr/rt.c b/src/expr/rt.c index 1ad9b2ad4043f..bd8b2a91948ee 100644 --- a/src/expr/rt.c +++ b/src/expr/rt.c @@ -112,6 +112,24 @@ nftnl_expr_rt_parse(struct nftnl_expr *e, struct nlattr *attr) return 0; } +static void nftnl_expr_rt_byteorder(struct nftnl_byteorder_ctx *ctx, + struct nftnl_expr *e) +{ + struct nftnl_expr_rt *rt = nftnl_expr_data(e); + + switch (rt->key) { + case NFT_RT_NEXTHOP4: + case NFT_RT_NEXTHOP6: + e->byteorder = NFTNL_BYTEORDER_NETWORK; + break; + default: + e->byteorder = NFTNL_BYTEORDER_HOST; + } + + if (e->flags & (1 << NFTNL_EXPR_RT_DREG)) + nftnl_reg_byteorder_set(ctx, rt->dreg, e->byteorder); +} + static const char *rt_key2str_array[NFT_RT_MAX + 1] = { [NFT_RT_CLASSID] = "classid", [NFT_RT_NEXTHOP4] = "nexthop4", @@ -162,5 +180,6 @@ struct expr_ops expr_ops_rt = { .get = nftnl_expr_rt_get, .parse = nftnl_expr_rt_parse, .build = nftnl_expr_rt_build, + .byteorder = nftnl_expr_rt_byteorder, .snprintf = nftnl_expr_rt_snprintf, }; diff --git a/src/expr/socket.c b/src/expr/socket.c index 02d86f8ac57c0..dae9ea22bd24f 100644 --- a/src/expr/socket.c +++ b/src/expr/socket.c @@ -126,6 +126,17 @@ nftnl_expr_socket_parse(struct nftnl_expr *e, struct nlattr *attr) return 0; } +static void +nftnl_expr_socket_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_socket *socket = nftnl_expr_data(e); + + e->byteorder = NFTNL_BYTEORDER_HOST; + + if (e->flags & (1 << NFTNL_EXPR_SOCKET_DREG)) + nftnl_reg_byteorder_set(ctx, socket->dreg, e->byteorder); +} + static const char *socket_key2str_array[NFT_SOCKET_MAX + 1] = { [NFT_SOCKET_TRANSPARENT] = "transparent", [NFT_SOCKET_MARK] = "mark", @@ -165,5 +176,6 @@ struct expr_ops expr_ops_socket = { .get = nftnl_expr_socket_get, .parse = nftnl_expr_socket_parse, .build = nftnl_expr_socket_build, + .byteorder = nftnl_expr_socket_byteorder, .snprintf = nftnl_expr_socket_snprintf, }; diff --git a/src/expr/tproxy.c b/src/expr/tproxy.c index d3ee8f89b6db3..ef3e20569c1cf 100644 --- a/src/expr/tproxy.c +++ b/src/expr/tproxy.c @@ -134,6 +134,19 @@ nftnl_expr_tproxy_build(struct nlmsghdr *nlh, const struct nftnl_expr *e) htonl(tproxy->sreg_port)); } +static void nftnl_expr_tproxy_byteorder(struct nftnl_byteorder_ctx *ctx, + struct nftnl_expr *e) +{ + struct nftnl_expr_tproxy *t = nftnl_expr_data(e); + + e->byteorder = NFTNL_BYTEORDER_NETWORK; + + if (e->flags & (1 << NFTNL_EXPR_TPROXY_REG_ADDR)) + nftnl_reg_byteorder_resolve(ctx, t->sreg_addr, e->byteorder); + if (e->flags & (1 << NFTNL_EXPR_TPROXY_REG_PORT)) + nftnl_reg_byteorder_resolve(ctx, t->sreg_port, e->byteorder); +} + static int nftnl_expr_tproxy_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -170,5 +183,6 @@ struct expr_ops expr_ops_tproxy = { .get = nftnl_expr_tproxy_get, .parse = nftnl_expr_tproxy_parse, .build = nftnl_expr_tproxy_build, + .byteorder = nftnl_expr_tproxy_byteorder, .snprintf = nftnl_expr_tproxy_snprintf, }; diff --git a/src/expr/tunnel.c b/src/expr/tunnel.c index 1460fd26b0fbc..94a6c9bb4add2 100644 --- a/src/expr/tunnel.c +++ b/src/expr/tunnel.c @@ -111,6 +111,17 @@ nftnl_expr_tunnel_parse(struct nftnl_expr *e, struct nlattr *attr) return 0; } +static void +nftnl_expr_tunnel_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_tunnel *tunnel = nftnl_expr_data(e); + + e->byteorder = NFTNL_BYTEORDER_HOST; + + if (e->flags & (1 << NFTNL_EXPR_TUNNEL_DREG)) + nftnl_reg_byteorder_set(ctx, tunnel->dreg, e->byteorder); +} + static const char *tunnel_key2str_array[NFT_TUNNEL_MAX + 1] = { [NFT_TUNNEL_PATH] = "path", [NFT_TUNNEL_ID] = "id", @@ -145,5 +156,6 @@ struct expr_ops expr_ops_tunnel = { .get = nftnl_expr_tunnel_get, .parse = nftnl_expr_tunnel_parse, .build = nftnl_expr_tunnel_build, + .byteorder = nftnl_expr_tunnel_byteorder, .snprintf = nftnl_expr_tunnel_snprintf, }; diff --git a/src/expr/xfrm.c b/src/expr/xfrm.c index c81d14d638dcd..3134b076f042e 100644 --- a/src/expr/xfrm.c +++ b/src/expr/xfrm.c @@ -171,6 +171,23 @@ static const char *xfrmdir2str(uint8_t dir) return xfrmdir2str_array[dir]; } +static void +nftnl_expr_xfrm_byteorder(struct nftnl_byteorder_ctx *ctx, struct nftnl_expr *e) +{ + struct nftnl_expr_xfrm *x = nftnl_expr_data(e); + + switch (x->key) { + case NFT_XFRM_KEY_REQID: + e->byteorder = NFTNL_BYTEORDER_HOST; + break; + default: + e->byteorder = NFTNL_BYTEORDER_NETWORK; + } + + if (e->flags & (1 << NFTNL_EXPR_XFRM_DREG)) + nftnl_reg_byteorder_set(ctx, x->dreg, e->byteorder); +} + static int nftnl_expr_xfrm_snprintf(char *buf, size_t remain, uint32_t flags, const struct nftnl_expr *e) @@ -196,5 +213,6 @@ struct expr_ops expr_ops_xfrm = { .get = nftnl_expr_xfrm_get, .parse = nftnl_expr_xfrm_parse, .build = nftnl_expr_xfrm_build, + .byteorder = nftnl_expr_xfrm_byteorder, .snprintf = nftnl_expr_xfrm_snprintf, }; diff --git a/src/rule.c b/src/rule.c index 0bb1c2a0583c1..9f1caa6feb57e 100644 --- a/src/rule.c +++ b/src/rule.c @@ -549,6 +549,7 @@ static int nftnl_rule_snprintf_default(char *buf, size_t remain, const struct nftnl_rule *r, uint32_t type, uint32_t flags) { + struct nftnl_byteorder_ctx ctx = {}; struct nftnl_expr *expr; int ret, offset = 0, i; const char *sep = ""; @@ -603,6 +604,12 @@ static int nftnl_rule_snprintf_default(char *buf, size_t remain, ret = snprintf(buf + offset, remain, "\n"); SNPRINTF_BUFFER_SIZE(ret, remain, offset); + list_for_each_entry(expr, &r->expr_list, head) { + if (!expr->ops->byteorder) + continue; + expr->ops->byteorder(&ctx, expr); + } + list_for_each_entry(expr, &r->expr_list, head) { ret = snprintf(buf + offset, remain, " [ %s ", expr->ops->name); SNPRINTF_BUFFER_SIZE(ret, remain, offset); diff --git a/src/set_elem.c b/src/set_elem.c index 12eadce1f8e0c..9b18f4def6c47 100644 --- a/src/set_elem.c +++ b/src/set_elem.c @@ -708,7 +708,8 @@ int nftnl_set_elem_snprintf_default(char *buf, size_t remain, SNPRINTF_BUFFER_SIZE(ret, remain, offset); ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->key, - DATA_F_NOPFX, DATA_VALUE); + DATA_F_NOPFX, DATA_VALUE, + NFTNL_BYTEORDER_UNKNOWN); SNPRINTF_BUFFER_SIZE(ret, remain, offset); if (e->flags & (1 << NFTNL_SET_ELEM_KEY_END)) { @@ -716,7 +717,8 @@ int nftnl_set_elem_snprintf_default(char *buf, size_t remain, SNPRINTF_BUFFER_SIZE(ret, remain, offset); ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->key_end, - DATA_F_NOPFX, DATA_VALUE); + DATA_F_NOPFX, DATA_VALUE, + NFTNL_BYTEORDER_UNKNOWN); SNPRINTF_BUFFER_SIZE(ret, remain, offset); } @@ -727,7 +729,8 @@ int nftnl_set_elem_snprintf_default(char *buf, size_t remain, dregtype = DATA_VERDICT; ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->data, - DATA_F_NOPFX, dregtype); + DATA_F_NOPFX, dregtype, + NFTNL_BYTEORDER_UNKNOWN); SNPRINTF_BUFFER_SIZE(ret, remain, offset); ret = snprintf(buf + offset, remain, "%u [end]", e->set_elem_flags); -- 2.33.0