]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
netlink: pad constant concat sub-expressions
authorPatrick McHardy <kaber@trash.net>
Sun, 12 Apr 2015 20:10:42 +0000 (21:10 +0100)
committerPatrick McHardy <kaber@trash.net>
Tue, 2 Jun 2015 11:03:58 +0000 (13:03 +0200)
Pad all but the last sub-expressions of a concat expressions.

Signed-off-by: Patrick McHardy <kaber@trash.net>
include/netlink.h
src/datatype.c
src/netlink.c

index 9b42fdbd3f0de374fcb1392061510c805caa2a3b..185c43573e299ec465da8ce41f9d8efc5e303b09 100644 (file)
@@ -58,6 +58,16 @@ static inline unsigned int netlink_register_space(unsigned int size)
        return div_round_up(size, NFT_REG32_SIZE * BITS_PER_BYTE);
 }
 
+static inline unsigned int netlink_padded_len(unsigned int size)
+{
+       return netlink_register_space(size) * NFT_REG32_SIZE * BITS_PER_BYTE;
+}
+
+static inline unsigned int netlink_padding_len(unsigned int size)
+{
+       return netlink_padded_len(size) - size;
+}
+
 extern void netlink_gen_data(const struct expr *expr,
                             struct nft_data_linearize *data);
 extern void netlink_gen_raw_data(const mpz_t value, enum byteorder byteorder,
index f93337b135a486f9622b4200ed556379a7a1d785..a06a58e20abc5d5018541a70ae13691d0415aeb3 100644 (file)
@@ -23,6 +23,7 @@
 #include <expression.h>
 #include <gmputil.h>
 #include <erec.h>
+#include <netlink.h>
 
 #include <netinet/ip_icmp.h>
 #include <netinet/icmp6.h>
@@ -943,7 +944,7 @@ const struct datatype *concat_type_alloc(uint32_t type)
                strncat(desc, i->desc, sizeof(desc) - strlen(desc) - 1);
                strncat(name, i->name, sizeof(name) - strlen(name) - 1);
 
-               size += i->size;
+               size += netlink_padded_len(i->size);
                subtypes++;
        }
        strncat(desc, ")", sizeof(desc) - strlen(desc) - 1);
index d31387f823222ce339e5c6eb1bff52b76cf90153..3369d22312b91c7a6d0aa05617e8711adc2b53e0 100644 (file)
@@ -273,23 +273,21 @@ static void netlink_gen_concat_data(const struct expr *expr,
        const struct expr *i;
        unsigned int len, offset;
 
-       len = 0;
-       list_for_each_entry(i, &expr->expressions, list)
-               len += i->len;
-
+       len = expr->len / BITS_PER_BYTE;
        if (1) {
-               unsigned char data[len / BITS_PER_BYTE];
+               unsigned char data[len];
 
+               memset(data, 0, sizeof(data));
                offset = 0;
                list_for_each_entry(i, &expr->expressions, list) {
                        assert(i->ops->type == EXPR_VALUE);
                        mpz_export_data(data + offset, i->value, i->byteorder,
                                        i->len / BITS_PER_BYTE);
-                       offset += i->len / BITS_PER_BYTE;
+                       offset += netlink_padded_len(i->len) / BITS_PER_BYTE;
                }
 
-               memcpy(nld->value, data, len / BITS_PER_BYTE);
-               nld->len = len / BITS_PER_BYTE;
+               memcpy(nld->value, data, len);
+               nld->len = len;
        }
 }