]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink: Introduce struct nft_data_linearize::sizes
authorPhil Sutter <phil@nwl.cc>
Fri, 17 Oct 2025 15:06:10 +0000 (17:06 +0200)
committerPhil Sutter <phil@nwl.cc>
Tue, 27 Jan 2026 22:01:54 +0000 (23:01 +0100)
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 <phil@nwl.cc>
include/netlink.h
src/netlink.c

index a762cb485784fbcb9fdaa322a8110ac3f3d912f0..aa25094dc7c1da9738ac0f11783d67bf36494c1f 100644 (file)
@@ -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 {
index 3a512753c762477c6abeb089be8d38f3f76e0209..d81cfccb6c6aa97ddd3183d752a100cd850efb96 100644 (file)
@@ -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,