On 2021-11-24, at 18:22:36 +0100, Phil Sutter wrote: > 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; > + This doesn't look right: > + k = ctx->num_pending++; > + if (k >= NFTNL_CTX_BYTEORDER_MAX_EXPRS) > + return; Shouldn't it be? if (ctx->num_pending >= NFTNL_CTX_BYTEORDER_MAX_EXPRS) return; k = ctx->num_pending++; Otherwise ... > + 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; ... we can run off the end of `ctx->pending` here: > + 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)) Spaces instead of tabs here: > + 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 Spaces instead of tabs here: > + 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); How about this? @@ -604,6 +605,9 @@ static int nftnl_rule_snprintf_default(char *buf, size_t remain, SNPRINTF_BUFFER_SIZE(ret, remain, offset); list_for_each_entry(expr, &r->expr_list, head) { + if (expr->ops->byteorder) + expr->ops->byteorder(&ctx, expr); + 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 > >
Attachment:
signature.asc
Description: PGP signature