summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c14
-rw-r--r--src/mnl.c7
-rw-r--r--src/netlink.c11
-rw-r--r--src/rule.c2
4 files changed, 30 insertions, 4 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 09dd493f..55591f5f 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1217,6 +1217,8 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr,
struct expr *i, *next;
list_for_each_entry_safe(i, next, &(*expr)->expressions, list) {
+ unsigned dsize_bytes;
+
if (expr_is_constant(*expr) && dtype && off == 0)
return expr_binary_error(ctx->msgs, i, *expr,
"unexpected concat component, "
@@ -1241,6 +1243,9 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr,
i->dtype->name);
ntype = concat_subtype_add(ntype, i->dtype->type);
+
+ dsize_bytes = div_round_up(i->dtype->size, BITS_PER_BYTE);
+ (*expr)->field_len[(*expr)->field_count++] = dsize_bytes;
}
(*expr)->flags |= flags;
@@ -3345,9 +3350,12 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
return set_key_data_error(ctx, set,
set->key->dtype, type);
}
- if (set->flags & NFT_SET_INTERVAL &&
- set->key->etype == EXPR_CONCAT)
- return set_error(ctx, set, "concatenated types not supported in interval sets");
+
+ if (set->flags & NFT_SET_INTERVAL && set->key->etype == EXPR_CONCAT) {
+ memcpy(&set->desc.field_len, &set->key->field_len,
+ sizeof(set->desc.field_len));
+ set->desc.field_count = set->key->field_count;
+ }
if (set_is_datamap(set->flags)) {
if (set->data == NULL)
diff --git a/src/mnl.c b/src/mnl.c
index d5bdff29..340380ba 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -905,6 +905,13 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd,
if (set->data)
set_key_expression(ctx, set->data, set->flags, udbuf, NFTNL_UDATA_SET_DATA_TYPEOF);
+ if (set->desc.field_len[0]) {
+ nftnl_set_set_data(nls, NFTNL_SET_DESC_CONCAT,
+ set->desc.field_len,
+ set->desc.field_count *
+ sizeof(set->desc.field_len[0]));
+ }
+
nftnl_set_set_data(nls, NFTNL_SET_USERDATA, nftnl_udata_buf_data(udbuf),
nftnl_udata_buf_len(udbuf));
nftnl_udata_buf_free(udbuf);
diff --git a/src/netlink.c b/src/netlink.c
index a9ccebaf..791943b4 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -773,6 +773,17 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
if (nftnl_set_is_set(nls, NFTNL_SET_DESC_SIZE))
set->desc.size = nftnl_set_get_u32(nls, NFTNL_SET_DESC_SIZE);
+ if (nftnl_set_is_set(nls, NFTNL_SET_DESC_CONCAT)) {
+ uint32_t len = NFT_REG32_COUNT;
+ const uint8_t *data;
+
+ data = nftnl_set_get_data(nls, NFTNL_SET_DESC_CONCAT, &len);
+ if (data) {
+ memcpy(set->desc.field_len, data, len);
+ set->desc.field_count = len;
+ }
+ }
+
return set;
}
diff --git a/src/rule.c b/src/rule.c
index 883b0707..4853c4f3 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -337,7 +337,7 @@ struct set *set_clone(const struct set *set)
new_set->objtype = set->objtype;
new_set->policy = set->policy;
new_set->automerge = set->automerge;
- new_set->desc.size = set->desc.size;
+ new_set->desc = set->desc;
return new_set;
}