netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nft 0/5] more various cleanups related to struct datatype
@ 2023-09-27 19:57 Thomas Haller
  2023-09-27 19:57 ` [PATCH nft 1/5] datatype: make "flags" field of datatype struct simple booleans Thomas Haller
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Thomas Haller @ 2023-09-27 19:57 UTC (permalink / raw)
  To: NetFilter; +Cc: Thomas Haller

This is a followup to

  Subject:    [PATCH nft 0/9] various cleanups related to enums and struct datatype
  Date:       Wed, 20 Sep 2023 16:26:01 +0200

From that patchset, several patches were merged. Except:

1) [PATCH nft 8/9] datatype: use __attribute__((packed)) instead of enum bitfields
   This patch was rejected. It's gone and no longer present.

2) [PATCH nft 3/9] datatype: drop flags field from datatype
   This patch become the new "datatype: make "flags" field of datatype struct simple booleans"
   in this series. The flag DTYPE_F_ALLOC flag is preserved (as new "f_alloc" field).

Thomas Haller (5):
  datatype: make "flags" field of datatype struct simple booleans
  datatype: don't clone static name/desc strings for datatype
  datatype: don't clone datatype in set_datatype_alloc() if byteorder
    already matches
  datatype: extend set_datatype_alloc() to change size
  datatype: use xmalloc() for allocating datatype in datatype_clone()

 include/datatype.h        | 39 +++++++++++++------------
 src/datatype.c            | 61 +++++++++++++++++++++++++--------------
 src/evaluate.c            | 43 ++++++++++++---------------
 src/meta.c                |  2 +-
 src/netlink.c             |  4 +--
 src/netlink_delinearize.c |  2 +-
 src/payload.c             |  7 ++---
 src/rt.c                  |  2 +-
 src/segtree.c             |  5 ++--
 9 files changed, 89 insertions(+), 76 deletions(-)

-- 
2.41.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH nft 1/5] datatype: make "flags" field of datatype struct simple booleans
  2023-09-27 19:57 [PATCH nft 0/5] more various cleanups related to struct datatype Thomas Haller
@ 2023-09-27 19:57 ` Thomas Haller
  2024-08-19 22:41   ` Pablo Neira Ayuso
  2023-09-27 19:57 ` [PATCH nft 2/5] datatype: don't clone static name/desc strings for datatype Thomas Haller
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Thomas Haller @ 2023-09-27 19:57 UTC (permalink / raw)
  To: NetFilter; +Cc: Thomas Haller

Flags are not always bad. For example, as a function argument they allow
easier extension in the future. But with datatype's "flags" argument and
enum datatype_flags there are no advantages of this approach.

- replace DTYPE_F_PREFIX with a "bool f_prefix:1" field.

- replace DTYPE_F_ALLOC with a "bool f_alloc:1" field.

- the new boolean fields are made bitfields, although for the moment
  that does not reduce the size of the struct. If we add more flags,
  that will be different.

- also reorder fields in "struct datatype" so that fields of similar
  alignment (and type) are beside each other. Specifically moving
  "refcnt" field beside other integer fields saves one pointer size on
  x86-64.

Signed-off-by: Thomas Haller <thaller@redhat.com>
---
 include/datatype.h        | 32 +++++++++++++++-----------------
 src/datatype.c            | 21 ++++++++++-----------
 src/meta.c                |  2 +-
 src/netlink_delinearize.c |  2 +-
 src/rt.c                  |  2 +-
 src/segtree.c             |  5 ++---
 6 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/include/datatype.h b/include/datatype.h
index 09a7894567e4..b53a739e1e6c 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -120,26 +120,18 @@ enum byteorder {
 
 struct expr;
 
-/**
- * enum datatype_flags
- *
- * @DTYPE_F_ALLOC:		datatype is dynamically allocated
- * @DTYPE_F_PREFIX:		preferred representation for ranges is a prefix
- */
-enum datatype_flags {
-	DTYPE_F_ALLOC		= (1 << 0),
-	DTYPE_F_PREFIX		= (1 << 1),
-};
-
 struct parse_ctx;
 /**
  * struct datatype
  *
  * @type:	numeric identifier
- * @byteorder:	byteorder of type (non-basetypes only)
- * @flags:	flags
  * @size:	type size (fixed sized non-basetypes only)
  * @subtypes:	number of subtypes (concat type)
+ * @refcnt:	reference counter for dynamically allocated instances.
+ * @byteorder:	byteorder of type (non-basetypes only)
+ * @f_prefix:	preferred representation for ranges is a prefix
+ * @f_alloc:	whether the instance is dynamically allocated. If not, datatype_get() and
+ *		datatype_free() are NOPs.
  * @name:	type name
  * @desc:	type description
  * @basetype:	basetype for subtypes, determines type compatibility
@@ -147,14 +139,21 @@ struct parse_ctx;
  * @print:	function to print a constant of this type
  * @parse:	function to parse a symbol and return an expression
  * @sym_tbl:	symbol table for this type
- * @refcnt:	reference counter (only for DTYPE_F_ALLOC)
  */
 struct datatype {
 	uint32_t			type;
-	enum byteorder			byteorder;
-	unsigned int			flags;
 	unsigned int			size;
 	unsigned int			subtypes;
+
+	/* Refcount for dynamically allocated instances. For static instances
+	 * this is zero (get() and free() are NOPs).
+	 */
+	unsigned int			refcnt;
+
+	enum byteorder			byteorder;
+	bool				f_prefix:1;
+	bool				f_alloc:1;
+
 	const char			*name;
 	const char			*desc;
 	const struct datatype		*basetype;
@@ -169,7 +168,6 @@ struct datatype {
 	struct error_record		*(*err)(const struct expr *sym);
 	void				(*describe)(struct output_ctx *octx);
 	const struct symbol_table	*sym_tbl;
-	unsigned int			refcnt;
 };
 
 extern const struct datatype *datatype_lookup(enum datatypes type);
diff --git a/src/datatype.c b/src/datatype.c
index 6fe46e899c4b..464eb49171c6 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -642,7 +642,7 @@ const struct datatype ipaddr_type = {
 	.basetype	= &integer_type,
 	.print		= ipaddr_type_print,
 	.parse		= ipaddr_type_parse,
-	.flags		= DTYPE_F_PREFIX,
+	.f_prefix	= true,
 };
 
 static void ip6addr_type_print(const struct expr *expr, struct output_ctx *octx)
@@ -709,7 +709,7 @@ const struct datatype ip6addr_type = {
 	.basetype	= &integer_type,
 	.print		= ip6addr_type_print,
 	.parse		= ip6addr_type_parse,
-	.flags		= DTYPE_F_PREFIX,
+	.f_prefix	= true,
 };
 
 static void inet_protocol_type_print(const struct expr *expr,
@@ -945,7 +945,7 @@ const struct datatype mark_type = {
 	.print		= mark_type_print,
 	.json		= mark_type_json,
 	.parse		= mark_type_parse,
-	.flags		= DTYPE_F_PREFIX,
+	.f_prefix	= true,
 };
 
 static const struct symbol_table icmp_code_tbl = {
@@ -1204,7 +1204,7 @@ static struct datatype *datatype_alloc(void)
 	struct datatype *dtype;
 
 	dtype = xzalloc(sizeof(*dtype));
-	dtype->flags = DTYPE_F_ALLOC;
+	dtype->f_alloc = true;
 	dtype->refcnt = 1;
 
 	return dtype;
@@ -1216,10 +1216,10 @@ const struct datatype *datatype_get(const struct datatype *ptr)
 
 	if (!dtype)
 		return NULL;
-	if (!(dtype->flags & DTYPE_F_ALLOC))
-		return dtype;
 
-	dtype->refcnt++;
+	if (dtype->f_alloc)
+		dtype->refcnt++;
+
 	return dtype;
 }
 
@@ -1246,7 +1246,7 @@ struct datatype *datatype_clone(const struct datatype *orig_dtype)
 	*dtype = *orig_dtype;
 	dtype->name = xstrdup(orig_dtype->name);
 	dtype->desc = xstrdup(orig_dtype->desc);
-	dtype->flags = DTYPE_F_ALLOC | orig_dtype->flags;
+	dtype->f_alloc = true;
 	dtype->refcnt = 1;
 
 	return dtype;
@@ -1258,10 +1258,9 @@ void datatype_free(const struct datatype *ptr)
 
 	if (!dtype)
 		return;
-	if (!(dtype->flags & DTYPE_F_ALLOC))
-		return;
 
-	assert(dtype->refcnt != 0);
+	if (!dtype->f_alloc)
+		return;
 
 	if (--dtype->refcnt > 0)
 		return;
diff --git a/src/meta.c b/src/meta.c
index b578d5e24c06..536954a7f9eb 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -367,7 +367,7 @@ const struct datatype devgroup_type = {
 	.print		= devgroup_type_print,
 	.json		= devgroup_type_json,
 	.parse		= devgroup_type_parse,
-	.flags		= DTYPE_F_PREFIX,
+	.f_prefix	= true,
 };
 
 const struct datatype ifname_type = {
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index e21451044451..9dc1ffa533d4 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -2567,7 +2567,7 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx,
 		default:
 			break;
 		}
-	} else if (binop->left->dtype->flags & DTYPE_F_PREFIX &&
+	} else if (binop->left->dtype->f_prefix &&
 		   binop->op == OP_AND && expr->right->etype == EXPR_VALUE &&
 		   expr_mask_is_prefix(binop->right)) {
 		expr->left = expr_get(binop->left);
diff --git a/src/rt.c b/src/rt.c
index f5c80559ffee..63939c23604c 100644
--- a/src/rt.c
+++ b/src/rt.c
@@ -54,7 +54,7 @@ const struct datatype realm_type = {
 	.basetype	= &integer_type,
 	.print		= realm_type_print,
 	.parse		= realm_type_parse,
-	.flags		= DTYPE_F_PREFIX,
+	.f_prefix	= true,
 };
 
 const struct rt_template rt_templates[] = {
diff --git a/src/segtree.c b/src/segtree.c
index 28172b30c5b3..768d27b8188c 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -401,8 +401,7 @@ void concat_range_aggregate(struct expr *set)
 				goto next;
 			}
 
-			if (prefix_len < 0 ||
-			    !(r1->dtype->flags & DTYPE_F_PREFIX)) {
+			if (prefix_len < 0 || !r1->dtype->f_prefix) {
 				tmp = range_expr_alloc(&r1->location, r1,
 						       r2);
 
@@ -517,7 +516,7 @@ add_interval(struct expr *set, struct expr *low, struct expr *i)
 		expr = expr_get(low);
 	} else if (range_is_prefix(range) && !mpz_cmp_ui(p, 0)) {
 
-		if (i->dtype->flags & DTYPE_F_PREFIX)
+		if (i->dtype->f_prefix)
 			expr = interval_to_prefix(low, i, range);
 		else if (expr_basetype(i)->type == TYPE_STRING)
 			expr = interval_to_string(low, i, range);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH nft 2/5] datatype: don't clone static name/desc strings for datatype
  2023-09-27 19:57 [PATCH nft 0/5] more various cleanups related to struct datatype Thomas Haller
  2023-09-27 19:57 ` [PATCH nft 1/5] datatype: make "flags" field of datatype struct simple booleans Thomas Haller
@ 2023-09-27 19:57 ` Thomas Haller
  2023-09-27 19:57 ` [PATCH nft 3/5] datatype: don't clone datatype in set_datatype_alloc() if byteorder already matches Thomas Haller
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Thomas Haller @ 2023-09-27 19:57 UTC (permalink / raw)
  To: NetFilter; +Cc: Thomas Haller

Avoid cloning static strings for "struct datatype". With
concat_type_alloc(), the name/desc are generated dynamically and need to
be allocated. However, datatype_clone() only reuses the original
name/desc strings. If those strings are static already, we don't need to
clone them.

Note that there are no other places that also want to change or set the
name/desc. If there were, they would need to handle the new fact that
the strings may or may not be dynamically allocated.

Signed-off-by: Thomas Haller <thaller@redhat.com>
---
 include/datatype.h |  2 ++
 src/datatype.c     | 15 ++++++++++-----
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/include/datatype.h b/include/datatype.h
index b53a739e1e6c..465ade290652 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -132,6 +132,7 @@ struct parse_ctx;
  * @f_prefix:	preferred representation for ranges is a prefix
  * @f_alloc:	whether the instance is dynamically allocated. If not, datatype_get() and
  *		datatype_free() are NOPs.
+ * @f_allocated_strings: whether @name and @desc are heap allocated or static.
  * @name:	type name
  * @desc:	type description
  * @basetype:	basetype for subtypes, determines type compatibility
@@ -153,6 +154,7 @@ struct datatype {
 	enum byteorder			byteorder;
 	bool				f_prefix:1;
 	bool				f_alloc:1;
+	bool				f_allocated_strings:1;
 
 	const char			*name;
 	const char			*desc;
diff --git a/src/datatype.c b/src/datatype.c
index 464eb49171c6..1c557a06c751 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -1244,8 +1244,10 @@ struct datatype *datatype_clone(const struct datatype *orig_dtype)
 
 	dtype = xzalloc(sizeof(*dtype));
 	*dtype = *orig_dtype;
-	dtype->name = xstrdup(orig_dtype->name);
-	dtype->desc = xstrdup(orig_dtype->desc);
+	if (orig_dtype->f_allocated_strings) {
+		dtype->name = xstrdup(orig_dtype->name);
+		dtype->desc = xstrdup(orig_dtype->desc);
+	}
 	dtype->f_alloc = true;
 	dtype->refcnt = 1;
 
@@ -1265,8 +1267,10 @@ void datatype_free(const struct datatype *ptr)
 	if (--dtype->refcnt > 0)
 		return;
 
-	xfree(dtype->name);
-	xfree(dtype->desc);
+	if (dtype->f_allocated_strings) {
+		xfree(dtype->name);
+		xfree(dtype->desc);
+	}
 	xfree(dtype);
 }
 
@@ -1299,7 +1303,8 @@ const struct datatype *concat_type_alloc(uint32_t type)
 	dtype		= datatype_alloc();
 	dtype->type	= type;
 	dtype->size	= size;
-	dtype->subtypes = subtypes;
+	dtype->subtypes	= subtypes;
+	dtype->f_allocated_strings = true;
 	dtype->name	= xstrdup(name);
 	dtype->desc	= xstrdup(desc);
 	dtype->parse	= concat_type_parse;
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH nft 3/5] datatype: don't clone datatype in set_datatype_alloc() if byteorder already matches
  2023-09-27 19:57 [PATCH nft 0/5] more various cleanups related to struct datatype Thomas Haller
  2023-09-27 19:57 ` [PATCH nft 1/5] datatype: make "flags" field of datatype struct simple booleans Thomas Haller
  2023-09-27 19:57 ` [PATCH nft 2/5] datatype: don't clone static name/desc strings for datatype Thomas Haller
@ 2023-09-27 19:57 ` Thomas Haller
  2023-09-27 19:57 ` [PATCH nft 4/5] datatype: extend set_datatype_alloc() to change size Thomas Haller
  2023-09-27 19:57 ` [PATCH nft 5/5] datatype: use xmalloc() for allocating datatype in datatype_clone() Thomas Haller
  4 siblings, 0 replies; 8+ messages in thread
From: Thomas Haller @ 2023-09-27 19:57 UTC (permalink / raw)
  To: NetFilter; +Cc: Thomas Haller

"struct datatype" instances are treated immutable and not changed after
creation.  set_datatype_alloc() returns a const pointer, indicating that
the caller must not modify the instance anymore. In particular it must
not, because for non-integer types we just return a reference to the
(already immutable) orig_dtype.

If the byteorder that we are about to set is already as-requested, there
is no need to clone the instance either. Just return a reference to
orig_dtype() too.

Also drop the same optimization from key_fix_dtype_byteorder().

Signed-off-by: Thomas Haller <thaller@redhat.com>
---
 src/datatype.c |  6 +++++-
 src/evaluate.c | 19 +++++++------------
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/src/datatype.c b/src/datatype.c
index 1c557a06c751..6a35c6a76028 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -1321,9 +1321,13 @@ const struct datatype *set_datatype_alloc(const struct datatype *orig_dtype,
 	if (orig_dtype != &integer_type)
 		return datatype_get(orig_dtype);
 
+	if (orig_dtype->byteorder == byteorder) {
+		/* The (immutable) type instance is already as requested. */
+		return datatype_get(orig_dtype);
+	}
+
 	dtype = datatype_clone(orig_dtype);
 	dtype->byteorder = byteorder;
-
 	return dtype;
 }
 
diff --git a/src/evaluate.c b/src/evaluate.c
index c699a9bc7b86..e84895bf1610 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -74,17 +74,8 @@ static int __fmtstring(3, 4) set_error(struct eval_ctx *ctx,
 	return -1;
 }
 
-static void key_fix_dtype_byteorder(struct expr *key)
-{
-	const struct datatype *dtype = key->dtype;
-
-	if (dtype->byteorder == key->byteorder)
-		return;
-
-	__datatype_set(key, set_datatype_alloc(dtype, key->byteorder));
-}
-
 static int set_evaluate(struct eval_ctx *ctx, struct set *set);
+
 static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
 					     const char *name,
 					     struct expr *key,
@@ -95,8 +86,12 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
 	struct set *set;
 	struct handle h;
 
-	if (set_is_datamap(expr->set_flags))
-		key_fix_dtype_byteorder(key);
+	if (set_is_datamap(expr->set_flags)) {
+		const struct datatype *dtype;
+
+		dtype = set_datatype_alloc(key->dtype, key->byteorder);
+		__datatype_set(key, dtype);
+	}
 
 	set = set_alloc(&expr->location);
 	set->flags	= NFT_SET_ANONYMOUS | expr->set_flags;
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH nft 4/5] datatype: extend set_datatype_alloc() to change size
  2023-09-27 19:57 [PATCH nft 0/5] more various cleanups related to struct datatype Thomas Haller
                   ` (2 preceding siblings ...)
  2023-09-27 19:57 ` [PATCH nft 3/5] datatype: don't clone datatype in set_datatype_alloc() if byteorder already matches Thomas Haller
@ 2023-09-27 19:57 ` Thomas Haller
  2023-09-27 19:57 ` [PATCH nft 5/5] datatype: use xmalloc() for allocating datatype in datatype_clone() Thomas Haller
  4 siblings, 0 replies; 8+ messages in thread
From: Thomas Haller @ 2023-09-27 19:57 UTC (permalink / raw)
  To: NetFilter; +Cc: Thomas Haller

All remaining users of datatype_clone() only use this function to set
the byteorder and the size. Extend set_datatype_alloc() to not only
change the byteorder but also the size. With that, it can be used
instead of clone.

The benefit is that set_datatype_alloc() takes care to re-use the same
instance, if the values end up being the same.

Another benefit is to expose and make clear the oddity related to the
"for_any_integer" argument. The argument exists to preserve the previous
behavior.  However, it's not clear why some places would only want to
change the values for &integer_type and some check for orig_dtype->type
== TYPE_INTEGER. This is possibly a bug, especially because it means
once you clone an &integer_type, you cannot change it's byteorder/size
again.  So &integer_type is very special here, not only based on the
TYPE_INTEGER.

Signed-off-by: Thomas Haller <thaller@redhat.com>
---
 include/datatype.h |  5 ++++-
 src/datatype.c     | 21 ++++++++++++++++-----
 src/evaluate.c     | 26 ++++++++++++--------------
 src/netlink.c      |  4 ++--
 src/payload.c      |  7 +++----
 5 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/include/datatype.h b/include/datatype.h
index 465ade290652..f01e15b6ff3e 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -301,7 +301,10 @@ concat_subtype_lookup(uint32_t type, unsigned int n)
 }
 
 extern const struct datatype *
-set_datatype_alloc(const struct datatype *orig_dtype, enum byteorder byteorder);
+set_datatype_alloc(const struct datatype *orig_dtype,
+		   bool for_any_integer,
+		   enum byteorder byteorder,
+		   unsigned int size);
 
 extern void time_print(uint64_t msec, struct output_ctx *octx);
 extern struct error_record *time_parse(const struct location *loc,
diff --git a/src/datatype.c b/src/datatype.c
index 6a35c6a76028..f9570603467a 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -1313,21 +1313,32 @@ const struct datatype *concat_type_alloc(uint32_t type)
 }
 
 const struct datatype *set_datatype_alloc(const struct datatype *orig_dtype,
-					  enum byteorder byteorder)
+					  bool for_any_integer,
+					  enum byteorder byteorder,
+					  unsigned int size)
 {
 	struct datatype *dtype;
 
-	/* Restrict dynamic datatype allocation to generic integer datatype. */
-	if (orig_dtype != &integer_type)
-		return datatype_get(orig_dtype);
+	if (for_any_integer) {
+		if (orig_dtype->type != TYPE_INTEGER) {
+			/* Restrict changing byteorder/size to any integer datatype. */
+			return datatype_get(orig_dtype);
+		}
+	} else {
+		if (orig_dtype != &integer_type) {
+			/* Restrict changing byteorder/size to the generic integer datatype. */
+			return datatype_get(orig_dtype);
+		}
+	}
 
-	if (orig_dtype->byteorder == byteorder) {
+	if (orig_dtype->byteorder == byteorder && orig_dtype->size == size) {
 		/* The (immutable) type instance is already as requested. */
 		return datatype_get(orig_dtype);
 	}
 
 	dtype = datatype_clone(orig_dtype);
 	dtype->byteorder = byteorder;
+	dtype->size = size;
 	return dtype;
 }
 
diff --git a/src/evaluate.c b/src/evaluate.c
index e84895bf1610..a118aa6a7209 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -89,7 +89,8 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
 	if (set_is_datamap(expr->set_flags)) {
 		const struct datatype *dtype;
 
-		dtype = set_datatype_alloc(key->dtype, key->byteorder);
+		dtype = set_datatype_alloc(key->dtype, false, key->byteorder,
+					   key->dtype->size);
 		__datatype_set(key, dtype);
 	}
 
@@ -1508,13 +1509,12 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
 			return -1;
 		flags &= i->flags;
 
-		if (!key && i->dtype->type == TYPE_INTEGER) {
-			struct datatype *clone;
+		if (!key) {
+			const struct datatype *dtype;
 
-			clone = datatype_clone(i->dtype);
-			clone->size = i->len;
-			clone->byteorder = i->byteorder;
-			__datatype_set(i, clone);
+			dtype = set_datatype_alloc(i->dtype, true,
+						   i->byteorder, i->len);
+			__datatype_set(i, dtype);
 		}
 
 		if (dtype == NULL && i->dtype->size == 0)
@@ -1933,7 +1933,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
 		} else {
 			const struct datatype *dtype;
 
-			dtype = set_datatype_alloc(ectx.dtype, ectx.byteorder);
+			dtype = set_datatype_alloc(ectx.dtype, false, ectx.byteorder, ectx.dtype->size);
 			data = constant_expr_alloc(&netlink_location, dtype,
 						   dtype->byteorder, ectx.len, NULL);
 			datatype_free(dtype);
@@ -4553,13 +4553,11 @@ static int set_expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
 			return expr_error(ctx->msgs, i,
 					  "specify either ip or ip6 for address matching");
 
-		if (i->etype == EXPR_PAYLOAD &&
-		    i->dtype->type == TYPE_INTEGER) {
-			struct datatype *dtype;
+		if (i->etype == EXPR_PAYLOAD) {
+			const struct datatype *dtype;
 
-			dtype = datatype_clone(i->dtype);
-			dtype->size = i->len;
-			dtype->byteorder = i->byteorder;
+			dtype = set_datatype_alloc(i->dtype, true,
+						   i->byteorder, i->len);
 			__datatype_set(i, dtype);
 		}
 
diff --git a/src/netlink.c b/src/netlink.c
index 120a8ba9ceb1..9fe870885e2e 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -1034,7 +1034,7 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 	if (datatype) {
 		uint32_t dlen;
 
-		dtype2 = set_datatype_alloc(datatype, databyteorder);
+		dtype2 = set_datatype_alloc(datatype, false, databyteorder, datatype->size);
 		klen = nftnl_set_get_u32(nls, NFTNL_SET_DATA_LEN) * BITS_PER_BYTE;
 
 		dlen = data_interval ?  klen / 2 : klen;
@@ -1058,7 +1058,7 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 			set->data->flags |= EXPR_F_INTERVAL;
 	}
 
-	dtype = set_datatype_alloc(keytype, keybyteorder);
+	dtype = set_datatype_alloc(keytype, false, keybyteorder, keytype->size);
 	klen = nftnl_set_get_u32(nls, NFTNL_SET_KEY_LEN) * BITS_PER_BYTE;
 
 	if (set_udata_key_valid(typeof_expr_key, klen)) {
diff --git a/src/payload.c b/src/payload.c
index 89bb38eb0099..55e075dab033 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -243,15 +243,14 @@ static struct expr *payload_expr_parse_udata(const struct nftnl_udata *attr)
 		expr->len = len;
 
 	if (is_raw) {
-		struct datatype *dtype;
+		const struct datatype *dtype;
 
 		expr->payload.base = base;
 		expr->payload.offset = offset;
 		expr->payload.is_raw = true;
 		expr->len = len;
-		dtype = datatype_clone(&xinteger_type);
-		dtype->size = len;
-		dtype->byteorder = BYTEORDER_BIG_ENDIAN;
+		dtype = set_datatype_alloc(&xinteger_type, true,
+					   BYTEORDER_BIG_ENDIAN, len);
 		__datatype_set(expr, dtype);
 	}
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH nft 5/5] datatype: use xmalloc() for allocating datatype in datatype_clone()
  2023-09-27 19:57 [PATCH nft 0/5] more various cleanups related to struct datatype Thomas Haller
                   ` (3 preceding siblings ...)
  2023-09-27 19:57 ` [PATCH nft 4/5] datatype: extend set_datatype_alloc() to change size Thomas Haller
@ 2023-09-27 19:57 ` Thomas Haller
  2023-09-28 19:11   ` Pablo Neira Ayuso
  4 siblings, 1 reply; 8+ messages in thread
From: Thomas Haller @ 2023-09-27 19:57 UTC (permalink / raw)
  To: NetFilter; +Cc: Thomas Haller

The returned memory will be initialized. No need to zero it first. Use
xmalloc() instead of xzalloc().

Signed-off-by: Thomas Haller <thaller@redhat.com>
---
 src/datatype.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/datatype.c b/src/datatype.c
index f9570603467a..eae7f4c71fbe 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -1242,7 +1242,7 @@ struct datatype *datatype_clone(const struct datatype *orig_dtype)
 {
 	struct datatype *dtype;
 
-	dtype = xzalloc(sizeof(*dtype));
+	dtype = xmalloc(sizeof(*dtype));
 	*dtype = *orig_dtype;
 	if (orig_dtype->f_allocated_strings) {
 		dtype->name = xstrdup(orig_dtype->name);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH nft 5/5] datatype: use xmalloc() for allocating datatype in datatype_clone()
  2023-09-27 19:57 ` [PATCH nft 5/5] datatype: use xmalloc() for allocating datatype in datatype_clone() Thomas Haller
@ 2023-09-28 19:11   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2023-09-28 19:11 UTC (permalink / raw)
  To: Thomas Haller; +Cc: NetFilter

On Wed, Sep 27, 2023 at 09:57:28PM +0200, Thomas Haller wrote:
> The returned memory will be initialized. No need to zero it first. Use
> xmalloc() instead of xzalloc().

Applied this little patch, thanks

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH nft 1/5] datatype: make "flags" field of datatype struct simple booleans
  2023-09-27 19:57 ` [PATCH nft 1/5] datatype: make "flags" field of datatype struct simple booleans Thomas Haller
@ 2024-08-19 22:41   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2024-08-19 22:41 UTC (permalink / raw)
  To: Thomas Haller; +Cc: NetFilter

On Wed, Sep 27, 2023 at 09:57:24PM +0200, Thomas Haller wrote:
> Flags are not always bad. For example, as a function argument they allow
> easier extension in the future. But with datatype's "flags" argument and
> enum datatype_flags there are no advantages of this approach.
> 
> - replace DTYPE_F_PREFIX with a "bool f_prefix:1" field.
> 
> - replace DTYPE_F_ALLOC with a "bool f_alloc:1" field.
> 
> - the new boolean fields are made bitfields, although for the moment
>   that does not reduce the size of the struct. If we add more flags,
>   that will be different.

For the record, I followed a different approach to replace these:

https://patchwork.ozlabs.org/project/netfilter-devel/patch/20240819221834.972153-1-pablo@netfilter.org/
https://patchwork.ozlabs.org/project/netfilter-devel/patch/20240819221834.972153-2-pablo@netfilter.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-08-19 22:41 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-27 19:57 [PATCH nft 0/5] more various cleanups related to struct datatype Thomas Haller
2023-09-27 19:57 ` [PATCH nft 1/5] datatype: make "flags" field of datatype struct simple booleans Thomas Haller
2024-08-19 22:41   ` Pablo Neira Ayuso
2023-09-27 19:57 ` [PATCH nft 2/5] datatype: don't clone static name/desc strings for datatype Thomas Haller
2023-09-27 19:57 ` [PATCH nft 3/5] datatype: don't clone datatype in set_datatype_alloc() if byteorder already matches Thomas Haller
2023-09-27 19:57 ` [PATCH nft 4/5] datatype: extend set_datatype_alloc() to change size Thomas Haller
2023-09-27 19:57 ` [PATCH nft 5/5] datatype: use xmalloc() for allocating datatype in datatype_clone() Thomas Haller
2023-09-28 19:11   ` Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).