From: Phil Sutter Date: Fri, 17 Oct 2025 15:06:10 +0000 (+0200) Subject: netlink: Introduce struct nft_data_linearize::sizes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d5937f52b7d7675a8f9b446a336317b0f36560a;p=thirdparty%2Fnftables.git netlink: Introduce struct nft_data_linearize::sizes This array holds each concat component's actual length in bytes. It is crucial because component data is padded to match register lengths and if libnftnl has to print data "in reverse" (to print Little Endian values byte-by-byte), it will print extra leading zeroes with odd data lengths and thus indicate number of printed bytes does no longer correctly reflect actual data length. Signed-off-by: Phil Sutter --- diff --git a/include/netlink.h b/include/netlink.h index a762cb48..aa25094d 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -107,6 +107,7 @@ struct nft_data_linearize { uint32_t chain_id; int verdict; uint32_t byteorder; + uint8_t sizes[NFT_REG32_COUNT]; }; struct nft_data_delinearize { diff --git a/src/netlink.c b/src/netlink.c index 3a512753..d81cfccb 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -382,7 +382,7 @@ static void netlink_gen_concat_key(const struct expr *expr, if (byteorder == BYTEORDER_HOST_ENDIAN && expr_basetype(i)->type != TYPE_STRING) nld->byteorder |= 1 << n; - n++; + nld->sizes[n++] = div_round_up(i->len, BITS_PER_BYTE); } nft_data_memcpy(nld, data, len); @@ -452,7 +452,7 @@ static void __netlink_gen_concat_expand(const struct expr *expr, if (i->byteorder == BYTEORDER_HOST_ENDIAN && expr_basetype(i)->type != TYPE_STRING) nld->byteorder |= 1 << n; - n++; + nld->sizes[n++] = div_round_up(i->len, BITS_PER_BYTE); } list_for_each_entry(i, &expr_concat(expr)->expressions, list) { @@ -460,7 +460,7 @@ static void __netlink_gen_concat_expand(const struct expr *expr, if (i->byteorder == BYTEORDER_HOST_ENDIAN && expr_basetype(i)->type != TYPE_STRING) nld->byteorder |= 1 << n; - n++; + nld->sizes[n++] = div_round_up(i->len, BITS_PER_BYTE); } nft_data_memcpy(nld, data, len); @@ -485,7 +485,7 @@ static void __netlink_gen_concat(const struct expr *expr, if (i->byteorder == BYTEORDER_HOST_ENDIAN && expr_basetype(i)->type != TYPE_STRING) nld->byteorder |= 1 << n; - n++; + nld->sizes[n++] = div_round_up(i->len, BITS_PER_BYTE); } nft_data_memcpy(nld, data, len); @@ -563,6 +563,8 @@ static void netlink_gen_range(const struct expr *expr, offset = netlink_export_pad(data, expr->left->value, expr->left); netlink_export_pad(data + offset, expr->right->value, expr->right); nft_data_memcpy(nld, data, len); + nld->sizes[0] = div_round_up(expr->left->len, BITS_PER_BYTE); + nld->sizes[1] = div_round_up(expr->right->len, BITS_PER_BYTE); } static void netlink_gen_range_value(const struct expr *expr, @@ -579,6 +581,8 @@ static void netlink_gen_range_value(const struct expr *expr, offset = netlink_export_pad(data, expr->range.low, expr); netlink_export_pad(data + offset, expr->range.high, expr); nft_data_memcpy(nld, data, len); + nld->sizes[0] = div_round_up(expr->len, BITS_PER_BYTE); + nld->sizes[1] = nld->sizes[0]; } static void netlink_gen_prefix(const struct expr *expr, @@ -599,6 +603,8 @@ static void netlink_gen_prefix(const struct expr *expr, mpz_clear(v); nft_data_memcpy(nld, data, len); + nld->sizes[0] = div_round_up(expr->prefix->len, BITS_PER_BYTE); + nld->sizes[1] = nld->sizes[0]; } static void netlink_gen_key(const struct expr *expr,