* 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 --- 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 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 --- 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 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 --- 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 Expression setters populate it from the passed 'byteorder' parameter. Signed-off-by: Phil Sutter --- 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 This will hold the actual size of each component in concatenated data. Signed-off-by: Phil Sutter --- 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 These are alternatives to nftnl_{expr,set_elem}_set() which accept byteorder and concat component size information. Signed-off-by: Phil Sutter --- 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 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 --- 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 #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 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 --- 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 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 --- 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 #include +#include #include #include #include @@ -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