|
|
f1d1c0 |
From c8a5da2f527c85ab7c392cd293ff37d02a3f93a7 Mon Sep 17 00:00:00 2001
|
|
|
f1d1c0 |
From: Phil Sutter <psutter@redhat.com>
|
|
|
f1d1c0 |
Date: Thu, 13 Feb 2020 17:48:18 +0100
|
|
|
f1d1c0 |
Subject: [PATCH] src: Add support for NFTNL_SET_DESC_CONCAT
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1795224
|
|
|
f1d1c0 |
Upstream Status: nftables commit 6156ba34018dd
|
|
|
f1d1c0 |
Conflicts: Context change in src/mnl.c due to missing commit
|
|
|
f1d1c0 |
6e48df5329eab ("src: add "typeof" build/parse/print support")
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
commit 6156ba34018dddd59cb6737cfd5a69a0cbc5eaa4
|
|
|
f1d1c0 |
Author: Stefano Brivio <sbrivio@redhat.com>
|
|
|
f1d1c0 |
Date: Thu Jan 30 01:16:56 2020 +0100
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
src: Add support for NFTNL_SET_DESC_CONCAT
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
To support arbitrary range concatenations, the kernel needs to know
|
|
|
f1d1c0 |
how long each field in the concatenation is. The new libnftnl
|
|
|
f1d1c0 |
NFTNL_SET_DESC_CONCAT set attribute describes this as an array of
|
|
|
f1d1c0 |
lengths, in bytes, of concatenated fields.
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
While evaluating concatenated expressions, export the datatype size
|
|
|
f1d1c0 |
into the new field_len array, and hand the data over via libnftnl.
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
Similarly, when data is passed back from libnftnl, parse it into
|
|
|
f1d1c0 |
the set description.
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
When set data is cloned, we now need to copy the additional fields
|
|
|
f1d1c0 |
in set_clone(), too.
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
This change depends on the libnftnl patch with title:
|
|
|
f1d1c0 |
set: Add support for NFTA_SET_DESC_CONCAT attributes
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
v4: No changes
|
|
|
f1d1c0 |
v3: Rework to use set description data instead of a stand-alone
|
|
|
f1d1c0 |
attribute
|
|
|
f1d1c0 |
v2: No changes
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
|
|
|
f1d1c0 |
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
f1d1c0 |
---
|
|
|
f1d1c0 |
include/expression.h | 2 ++
|
|
|
f1d1c0 |
include/rule.h | 6 +++++-
|
|
|
f1d1c0 |
src/evaluate.c | 14 +++++++++++---
|
|
|
f1d1c0 |
src/mnl.c | 7 +++++++
|
|
|
f1d1c0 |
src/netlink.c | 11 +++++++++++
|
|
|
f1d1c0 |
src/rule.c | 2 +-
|
|
|
f1d1c0 |
6 files changed, 37 insertions(+), 5 deletions(-)
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
diff --git a/include/expression.h b/include/expression.h
|
|
|
f1d1c0 |
index 717b675..ee726aa 100644
|
|
|
f1d1c0 |
--- a/include/expression.h
|
|
|
f1d1c0 |
+++ b/include/expression.h
|
|
|
f1d1c0 |
@@ -256,6 +256,8 @@ struct expr {
|
|
|
f1d1c0 |
struct list_head expressions;
|
|
|
f1d1c0 |
unsigned int size;
|
|
|
f1d1c0 |
uint32_t set_flags;
|
|
|
f1d1c0 |
+ uint8_t field_len[NFT_REG32_COUNT];
|
|
|
f1d1c0 |
+ uint8_t field_count;
|
|
|
f1d1c0 |
};
|
|
|
f1d1c0 |
struct {
|
|
|
f1d1c0 |
/* EXPR_SET_REF */
|
|
|
f1d1c0 |
diff --git a/include/rule.h b/include/rule.h
|
|
|
f1d1c0 |
index 47eb29f..c03b0b8 100644
|
|
|
f1d1c0 |
--- a/include/rule.h
|
|
|
f1d1c0 |
+++ b/include/rule.h
|
|
|
f1d1c0 |
@@ -290,7 +290,9 @@ extern struct rule *rule_lookup_by_index(const struct chain *chain,
|
|
|
f1d1c0 |
* @rg_cache: cached range element (left)
|
|
|
f1d1c0 |
* @policy: set mechanism policy
|
|
|
f1d1c0 |
* @automerge: merge adjacents and overlapping elements, if possible
|
|
|
f1d1c0 |
- * @desc: set mechanism desc
|
|
|
f1d1c0 |
+ * @desc.size: count of set elements
|
|
|
f1d1c0 |
+ * @desc.field_len: length of single concatenated fields, bytes
|
|
|
f1d1c0 |
+ * @desc.field_count: count of concatenated fields
|
|
|
f1d1c0 |
*/
|
|
|
f1d1c0 |
struct set {
|
|
|
f1d1c0 |
struct list_head list;
|
|
|
f1d1c0 |
@@ -310,6 +312,8 @@ struct set {
|
|
|
f1d1c0 |
bool automerge;
|
|
|
f1d1c0 |
struct {
|
|
|
f1d1c0 |
uint32_t size;
|
|
|
f1d1c0 |
+ uint8_t field_len[NFT_REG32_COUNT];
|
|
|
f1d1c0 |
+ uint8_t field_count;
|
|
|
f1d1c0 |
} desc;
|
|
|
f1d1c0 |
};
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
diff --git a/src/evaluate.c b/src/evaluate.c
|
|
|
f1d1c0 |
index a865902..58f458d 100644
|
|
|
f1d1c0 |
--- a/src/evaluate.c
|
|
|
f1d1c0 |
+++ b/src/evaluate.c
|
|
|
f1d1c0 |
@@ -1216,6 +1216,8 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr,
|
|
|
f1d1c0 |
struct expr *i, *next;
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
list_for_each_entry_safe(i, next, &(*expr)->expressions, list) {
|
|
|
f1d1c0 |
+ unsigned dsize_bytes;
|
|
|
f1d1c0 |
+
|
|
|
f1d1c0 |
if (expr_is_constant(*expr) && dtype && off == 0)
|
|
|
f1d1c0 |
return expr_binary_error(ctx->msgs, i, *expr,
|
|
|
f1d1c0 |
"unexpected concat component, "
|
|
|
f1d1c0 |
@@ -1240,6 +1242,9 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr,
|
|
|
f1d1c0 |
i->dtype->name);
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
ntype = concat_subtype_add(ntype, i->dtype->type);
|
|
|
f1d1c0 |
+
|
|
|
f1d1c0 |
+ dsize_bytes = div_round_up(i->dtype->size, BITS_PER_BYTE);
|
|
|
f1d1c0 |
+ (*expr)->field_len[(*expr)->field_count++] = dsize_bytes;
|
|
|
f1d1c0 |
}
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
(*expr)->flags |= flags;
|
|
|
f1d1c0 |
@@ -3321,9 +3326,12 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
|
|
|
f1d1c0 |
"specified in %s definition",
|
|
|
f1d1c0 |
set->key->dtype->name, type);
|
|
|
f1d1c0 |
}
|
|
|
f1d1c0 |
- if (set->flags & NFT_SET_INTERVAL &&
|
|
|
f1d1c0 |
- set->key->etype == EXPR_CONCAT)
|
|
|
f1d1c0 |
- return set_error(ctx, set, "concatenated types not supported in interval sets");
|
|
|
f1d1c0 |
+
|
|
|
f1d1c0 |
+ if (set->flags & NFT_SET_INTERVAL && set->key->etype == EXPR_CONCAT) {
|
|
|
f1d1c0 |
+ memcpy(&set->desc.field_len, &set->key->field_len,
|
|
|
f1d1c0 |
+ sizeof(set->desc.field_len));
|
|
|
f1d1c0 |
+ set->desc.field_count = set->key->field_count;
|
|
|
f1d1c0 |
+ }
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
if (set_is_datamap(set->flags)) {
|
|
|
f1d1c0 |
if (set->datatype == NULL)
|
|
|
f1d1c0 |
diff --git a/src/mnl.c b/src/mnl.c
|
|
|
f1d1c0 |
index aa5b0b4..221ee05 100644
|
|
|
f1d1c0 |
--- a/src/mnl.c
|
|
|
f1d1c0 |
+++ b/src/mnl.c
|
|
|
f1d1c0 |
@@ -881,6 +881,13 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd,
|
|
|
f1d1c0 |
set->automerge))
|
|
|
f1d1c0 |
memory_allocation_error();
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
+ if (set->desc.field_len[0]) {
|
|
|
f1d1c0 |
+ nftnl_set_set_data(nls, NFTNL_SET_DESC_CONCAT,
|
|
|
f1d1c0 |
+ set->desc.field_len,
|
|
|
f1d1c0 |
+ set->desc.field_count *
|
|
|
f1d1c0 |
+ sizeof(set->desc.field_len[0]));
|
|
|
f1d1c0 |
+ }
|
|
|
f1d1c0 |
+
|
|
|
f1d1c0 |
nftnl_set_set_data(nls, NFTNL_SET_USERDATA, nftnl_udata_buf_data(udbuf),
|
|
|
f1d1c0 |
nftnl_udata_buf_len(udbuf));
|
|
|
f1d1c0 |
nftnl_udata_buf_free(udbuf);
|
|
|
f1d1c0 |
diff --git a/src/netlink.c b/src/netlink.c
|
|
|
f1d1c0 |
index 486e124..83d863c 100644
|
|
|
f1d1c0 |
--- a/src/netlink.c
|
|
|
f1d1c0 |
+++ b/src/netlink.c
|
|
|
f1d1c0 |
@@ -672,6 +672,17 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
|
|
|
f1d1c0 |
if (nftnl_set_is_set(nls, NFTNL_SET_DESC_SIZE))
|
|
|
f1d1c0 |
set->desc.size = nftnl_set_get_u32(nls, NFTNL_SET_DESC_SIZE);
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
+ if (nftnl_set_is_set(nls, NFTNL_SET_DESC_CONCAT)) {
|
|
|
f1d1c0 |
+ uint32_t len = NFT_REG32_COUNT;
|
|
|
f1d1c0 |
+ const uint8_t *data;
|
|
|
f1d1c0 |
+
|
|
|
f1d1c0 |
+ data = nftnl_set_get_data(nls, NFTNL_SET_DESC_CONCAT, &len;;
|
|
|
f1d1c0 |
+ if (data) {
|
|
|
f1d1c0 |
+ memcpy(set->desc.field_len, data, len);
|
|
|
f1d1c0 |
+ set->desc.field_count = len;
|
|
|
f1d1c0 |
+ }
|
|
|
f1d1c0 |
+ }
|
|
|
f1d1c0 |
+
|
|
|
f1d1c0 |
return set;
|
|
|
f1d1c0 |
}
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
diff --git a/src/rule.c b/src/rule.c
|
|
|
f1d1c0 |
index 3ca1805..4669577 100644
|
|
|
f1d1c0 |
--- a/src/rule.c
|
|
|
f1d1c0 |
+++ b/src/rule.c
|
|
|
f1d1c0 |
@@ -337,7 +337,7 @@ struct set *set_clone(const struct set *set)
|
|
|
f1d1c0 |
new_set->objtype = set->objtype;
|
|
|
f1d1c0 |
new_set->policy = set->policy;
|
|
|
f1d1c0 |
new_set->automerge = set->automerge;
|
|
|
f1d1c0 |
- new_set->desc.size = set->desc.size;
|
|
|
f1d1c0 |
+ new_set->desc = set->desc;
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
return new_set;
|
|
|
f1d1c0 |
}
|
|
|
f1d1c0 |
--
|
|
|
f1d1c0 |
1.8.3.1
|
|
|
f1d1c0 |
|