From b9b6092304aef17fea704c25b3d9d7dcdb3995a5 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 24 Feb 2017 20:47:49 +0100 Subject: evaluate: store byteorder for set keys Selectors that rely on the integer type and expect host endian byteorder don't work properly. We need to keep the byteorder around based on the left hand size expression that provides the context, so store the byteorder when evaluating the map. Before this patch. # nft --debug=netlink add rule x y meta mark set meta cpu map { 0 : 1, 1 : 2 } __map%d x b __map%d x 0 element 00000000 : 00000001 0 [end] element 01000000 : 00000002 0 [end] ^^^^^^^^ This is expressed in network byteorder, because the invalid byteorder defaults on this. After this patch: # nft --debug=netlink add rule x y meta mark set meta cpu map { 0 : 1, 1 : 2 } __map%d x b __map%d x 0 element 00000000 : 00000001 0 [end] element 00000001 : 00000002 0 [end] ^^^^^^^^ This is in host byteorder, as the key selector in the map mandates. Signed-off-by: Pablo Neira Ayuso --- src/datatype.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'src/datatype.c') diff --git a/src/datatype.c b/src/datatype.c index f1388dc5..bfc8817c 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -965,6 +965,28 @@ static struct datatype *dtype_alloc(void) return dtype; } +static struct datatype *dtype_clone(const struct datatype *orig_dtype) +{ + struct datatype *dtype; + + dtype = xzalloc(sizeof(*dtype)); + *dtype = *orig_dtype; + dtype->name = xstrdup(orig_dtype->name); + dtype->desc = xstrdup(orig_dtype->desc); + dtype->flags = DTYPE_F_ALLOC; + + return dtype; +} + +static void dtype_free(const struct datatype *dtype) +{ + if (dtype->flags & DTYPE_F_ALLOC) { + xfree(dtype->name); + xfree(dtype->desc); + xfree(dtype); + } +} + const struct datatype *concat_type_alloc(uint32_t type) { const struct datatype *i; @@ -1004,11 +1026,27 @@ const struct datatype *concat_type_alloc(uint32_t type) void concat_type_destroy(const struct datatype *dtype) { - if (dtype->flags & DTYPE_F_ALLOC) { - xfree(dtype->name); - xfree(dtype->desc); - xfree(dtype); - } + dtype_free(dtype); +} + +const struct datatype *set_keytype_alloc(const struct datatype *orig_dtype, + unsigned int byteorder) +{ + struct datatype *dtype; + + /* Restrict dynamic datatype allocation to generic integer datatype. */ + if (orig_dtype != &integer_type) + return orig_dtype; + + dtype = dtype_clone(orig_dtype); + dtype->byteorder = byteorder; + + return dtype; +} + +void set_keytype_destroy(const struct datatype *dtype) +{ + dtype_free(dtype); } static struct error_record *time_unit_parse(const struct location *loc, -- cgit v1.2.3