summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2017-02-24 20:47:49 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2017-02-25 13:40:34 +0100
commitb9b6092304aef17fea704c25b3d9d7dcdb3995a5 (patch)
tree38167a7fa655d2423f3d1e08b24c005813a3e54f /src/evaluate.c
parent261a3e61bab009982239de3c550299c50a60d902 (diff)
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 <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r--src/evaluate.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 4817a55c..87da2fd8 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -63,6 +63,7 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
const char *name,
const struct datatype *keytype,
unsigned int keylen,
+ unsigned int keybyteorder,
struct expr *expr)
{
struct cmd *cmd;
@@ -72,7 +73,7 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
set = set_alloc(&expr->location);
set->flags = NFT_SET_ANONYMOUS | expr->set_flags;
set->handle.set = xstrdup(name),
- set->keytype = keytype;
+ set->keytype = set_keytype_alloc(keytype, keybyteorder);
set->keylen = keylen;
set->init = expr;
@@ -1170,7 +1171,9 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
case EXPR_SET:
mappings = implicit_set_declaration(ctx, "__map%d",
ctx->ectx.dtype,
- ctx->ectx.len, mappings);
+ ctx->ectx.len,
+ ctx->ectx.byteorder,
+ mappings);
mappings->set->datatype = ectx.dtype;
mappings->set->datalen = ectx.len;
@@ -1505,8 +1508,8 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
if (right->ops->type == EXPR_SET)
right = rel->right =
implicit_set_declaration(ctx, "__set%d",
- left->dtype,
- left->len, right);
+ left->dtype, left->len,
+ left->byteorder, right);
else if (!datatype_equal(left->dtype, right->dtype))
return expr_binary_error(ctx->msgs, right, left,
"datatype mismatch, expected %s, "
@@ -1565,7 +1568,7 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
right = rel->right =
implicit_set_declaration(ctx, "__set%d",
left->dtype, left->len,
- right);
+ left->byteorder, right);
/* fall through */
case EXPR_SET_REF:
assert(rel->op == OP_NEQ);
@@ -1886,7 +1889,8 @@ static int stmt_evaluate_flow(struct eval_ctx *ctx, struct stmt *stmt)
set->set_flags |= NFT_SET_TIMEOUT;
setref = implicit_set_declaration(ctx, stmt->flow.table ?: "__ft%d",
- key->dtype, key->len, set);
+ key->dtype, key->len,
+ key->dtype->byteorder, set);
stmt->flow.set = setref;
@@ -2518,6 +2522,7 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt)
mappings = implicit_set_declaration(ctx, "__objmap%d",
ctx->ectx.dtype,
ctx->ectx.len,
+ ctx->ectx.byteorder,
mappings);
mappings->set->datatype = &string_type;
mappings->set->datalen = NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE;