summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/datatype.h4
-rw-r--r--src/datatype.c48
-rw-r--r--src/evaluate.c17
-rw-r--r--src/rule.c1
4 files changed, 59 insertions, 11 deletions
diff --git a/include/datatype.h b/include/datatype.h
index 9f127f29..68fb2a6c 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -251,6 +251,10 @@ concat_subtype_lookup(uint32_t type, unsigned int n)
return datatype_lookup(concat_subtype_id(type, n));
}
+extern const struct datatype *
+set_keytype_alloc(const struct datatype *orig_dtype, unsigned int byteorder);
+extern void set_keytype_destroy(const struct datatype *dtype);
+
extern void time_print(uint64_t seconds);
extern struct error_record *time_parse(const struct location *loc,
const char *c, uint64_t *res);
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,
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;
diff --git a/src/rule.c b/src/rule.c
index 0d58073f..b47076f0 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -210,6 +210,7 @@ void set_free(struct set *set)
if (set->init != NULL)
expr_free(set->init);
handle_free(&set->handle);
+ set_keytype_destroy(set->keytype);
xfree(set);
}