Blame SOURCES/0020-src-Add-support-for-NFTNL_SET_DESC_CONCAT.patch

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