[PATCH nft 1/3] src: Add support for and export NFT_SET_SUBKEY attributes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



To support arbitrary range concatenations, the kernel needs to know
how long each field in the concatenation is.

While evaluating concatenated expressions, export the datatype size,
in bits, into the new subkey_len array, and hand the data over via
libnftnl.

Note that, while the subkey length is expressed in bits, and the
kernel attribute is 32-bit long to make UAPI more future-proof, we
just reserve 8 bits for it, at the moment, and still store this data
in bits.

As we don't have subkeys exceeding 128 bits in length, this should be
fine, at least for a while, but it can be easily changed later on to
use the full 32 bits allowed by the netlink attribute.

This change depends on the UAPI kernel patch with title:
  netfilter: nf_tables: Support for subkeys, set with multiple ranged fields

Signed-off-by: Stefano Brivio <sbrivio@xxxxxxxxxx>
---
 include/expression.h |  1 +
 include/rule.h       |  1 +
 src/evaluate.c       | 12 ++++++++----
 src/mnl.c            |  4 ++++
 4 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index 717b6755..b6d5adb2 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -256,6 +256,7 @@ struct expr {
 			struct list_head	expressions;
 			unsigned int		size;
 			uint32_t		set_flags;
+			uint8_t			subkey_len[NFT_REG32_COUNT];
 		};
 		struct {
 			/* EXPR_SET_REF */
diff --git a/include/rule.h b/include/rule.h
index 0b2eba37..a263947d 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -308,6 +308,7 @@ struct set {
 	struct expr		*rg_cache;
 	uint32_t		policy;
 	bool			automerge;
+	uint8_t			subkey_len[NFT_REG32_COUNT];
 	struct {
 		uint32_t	size;
 	} desc;
diff --git a/src/evaluate.c b/src/evaluate.c
index e54eaf1a..e1ecf4de 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1211,7 +1211,7 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr,
 {
 	const struct datatype *dtype = ctx->ectx.dtype, *tmp;
 	uint32_t type = dtype ? dtype->type : 0, ntype = 0;
-	int off = dtype ? dtype->subtypes : 0;
+	int off = dtype ? dtype->subtypes : 0, subkey_idx = 0;
 	unsigned int flags = EXPR_F_CONSTANT | EXPR_F_SINGLETON;
 	struct expr *i, *next;
 
@@ -1240,6 +1240,8 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr,
 						 i->dtype->name);
 
 		ntype = concat_subtype_add(ntype, i->dtype->type);
+
+		(*expr)->subkey_len[subkey_idx++] = i->dtype->size;
 	}
 
 	(*expr)->flags |= flags;
@@ -3301,9 +3303,11 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
 					 "specified in %s definition",
 					 set->key->dtype->name, 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->subkey_len, &set->key->subkey_len,
+		       sizeof(set->subkey_len));
+		set->flags |= NFT_SET_SUBKEY;
+	}
 
 	if (set_is_datamap(set->flags)) {
 		if (set->datatype == NULL)
diff --git a/src/mnl.c b/src/mnl.c
index fdba0af8..292a26fd 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -880,6 +880,10 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd,
 				 set->automerge))
 		memory_allocation_error();
 
+	if (set->flags & NFT_SET_SUBKEY)
+		nftnl_set_set_data(nls, NFTNL_SET_SUBKEY, &set->subkey_len,
+				   sizeof(set->subkey_len));
+
 	nftnl_set_set_data(nls, NFTNL_SET_USERDATA, nftnl_udata_buf_data(udbuf),
 			   nftnl_udata_buf_len(udbuf));
 	nftnl_udata_buf_free(udbuf);
-- 
2.23.0





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux