Bits in this field indicate data is in host byte order and thus may need conversion when being printed "byte by byte" in libnftnl. With regular immediate values, this field's value may be treated as boolean (zero or not). Concatenations may contain components in different byteorder, so with them each bit (at pos N) indicates whether a component (at index N) is in host byte order. A follow-up patch collecting components' lengths will complete this. Signed-off-by: Phil Sutter --- include/netlink.h | 1 + src/netlink.c | 28 ++++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/netlink.h b/include/netlink.h index 2737d5708b295..a762cb485784f 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -106,6 +106,7 @@ struct nft_data_linearize { char chain[NFT_CHAIN_MAXNAMELEN]; uint32_t chain_id; int verdict; + uint32_t byteorder; }; struct nft_data_delinearize { diff --git a/src/netlink.c b/src/netlink.c index 3228747a74af8..2a4315c691059 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -248,6 +248,7 @@ void netlink_gen_raw_data(const mpz_t value, enum byteorder byteorder, assert(len > 0); mpz_export_data(data->value, value, byteorder, len); data->len = len; + data->byteorder = byteorder == BYTEORDER_HOST_ENDIAN ? UINT32_MAX : 0; } static int netlink_export_pad(unsigned char *data, const mpz_t v, @@ -353,14 +354,19 @@ static void netlink_gen_concat_key(const struct expr *expr, unsigned char data[NFT_MAX_EXPR_LEN_BYTES]; unsigned int offset = 0; const struct expr *i; + int n = 0; if (len > sizeof(data)) BUG("Value export of %u bytes would overflow", len); memset(data, 0, sizeof(data)); - list_for_each_entry(i, &expr_concat(expr)->expressions, list) + list_for_each_entry(i, &expr_concat(expr)->expressions, list) { offset += __netlink_gen_concat_key(expr->flags, i, data + offset); + if (i->byteorder == BYTEORDER_HOST_ENDIAN) + nld->byteorder |= 1 << n; + n++; + } nft_data_memcpy(nld, data, len); } @@ -417,17 +423,26 @@ static void __netlink_gen_concat_expand(const struct expr *expr, unsigned char data[NFT_MAX_EXPR_LEN_BYTES]; unsigned int offset = 0; const struct expr *i; + int n = 0; if (len > sizeof(data)) BUG("Value export of %u bytes would overflow", len); memset(data, 0, sizeof(data)); - list_for_each_entry(i, &expr_concat(expr)->expressions, list) + list_for_each_entry(i, &expr_concat(expr)->expressions, list) { offset += __netlink_gen_concat_data(false, i, data + offset); + if (i->byteorder == BYTEORDER_HOST_ENDIAN) + nld->byteorder |= 1 << n; + n++; + } - list_for_each_entry(i, &expr_concat(expr)->expressions, list) + list_for_each_entry(i, &expr_concat(expr)->expressions, list) { offset += __netlink_gen_concat_data(true, i, data + offset); + if (i->byteorder == BYTEORDER_HOST_ENDIAN) + nld->byteorder |= 1 << n; + n++; + } nft_data_memcpy(nld, data, len); } @@ -439,14 +454,19 @@ static void __netlink_gen_concat(const struct expr *expr, unsigned char data[NFT_MAX_EXPR_LEN_BYTES]; unsigned int offset = 0; const struct expr *i; + int n = 0; if (len > sizeof(data)) BUG("Value export of %u bytes would overflow", len); memset(data, 0, sizeof(data)); - list_for_each_entry(i, &expr_concat(expr)->expressions, list) + list_for_each_entry(i, &expr_concat(expr)->expressions, list) { offset += __netlink_gen_concat_data(expr->flags, i, data + offset); + if (i->byteorder == BYTEORDER_HOST_ENDIAN) + nld->byteorder |= 1 << n; + n++; + } nft_data_memcpy(nld, data, len); } -- 2.51.0