netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Thomas Haller <thaller@redhat.com>
Cc: NetFilter <netfilter-devel@vger.kernel.org>
Subject: Re: [PATCH nft 8/9] datatype: use __attribute__((packed)) instead of enum bitfields
Date: Wed, 20 Sep 2023 18:02:40 +0200	[thread overview]
Message-ID: <ZQsXoASbR1+aimMt@calendula> (raw)
In-Reply-To: <20230920142958.566615-9-thaller@redhat.com>

On Wed, Sep 20, 2023 at 04:26:09PM +0200, Thomas Haller wrote:
> At some places we use bitfields of those enums, to save space inside the
> structure. We can achieve that in a better way, by using GCC's
> __attribute__((packed)) on the enum type.
> 
> It's better because a :8 bitfield makes the assumption that all enum
> values (valid or invalid) fit into that field. With packed enums, we
> don't need that assumption as the field can hold all possible numbers
> that the enum type can hold. This reduces the places we need to worry
> about truncating a value to casts between other types and the enum.
> Those places already require us to be careful.
> 
> On the other hand, previously casting an int (or uint32_t) likely didn't
> cause a truncation as the underlying type was large enough. So we could
> check for invalid enum values after the cast. We might do that at
> places. For example, we do
> 
> 	key  = nftnl_expr_get_u32(nle, NFTNL_EXPR_META_KEY);
> 	expr = meta_expr_alloc(loc, key);
> 
> where we cast from an uint32_t to an enum without checking. Note that
> `enum nft_meta_keys` is not packed by this patch. But this is an example
> how things could be wrong. But the bug already exits before: don't make
> assumption about the underlying enum type and take care of truncation
> during casts.
> 
> This makes the change potentially dangerous, and it's hard to be sure
> that it doesn't uncover bugs (due tow rong assumptions about enum types).
> 
> Note that we were already using the GCC-ism __attribute__((packed))
> previously, however on a struct and not on an enum. Anyway. It seems
> unlikely that we support any other compilers than GCC/Clang. Those both
> support this attribute.  We should not worry about portability towards
> hypothetical compilers (the C standard), unless there is a real compiler
> that we can use and test and shows a problem with this. Especially when
> we support both GCC and Clang, which themselves are ubiquitous and
> accessible to all users (as they also need to build the kernel in the
> first place).
> 
> Signed-off-by: Thomas Haller <thaller@redhat.com>
> ---
>  include/datatype.h   |  1 +
>  include/expression.h |  8 +++++---
>  include/proto.h      | 11 +++++++----
>  3 files changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/include/datatype.h b/include/datatype.h
> index 202935bd322f..c8b3b77ad0c0 100644
> --- a/include/datatype.h
> +++ b/include/datatype.h
> @@ -112,6 +112,7 @@ enum datatypes {
>   * @BYTEORDER_HOST_ENDIAN:	host endian
>   * @BYTEORDER_BIG_ENDIAN:	big endian
>   */
> +__attribute__((packed))
>  enum byteorder {
>  	BYTEORDER_INVALID,
>  	BYTEORDER_HOST_ENDIAN,
> diff --git a/include/expression.h b/include/expression.h
> index aede223db741..11a1dbf00b8c 100644
> --- a/include/expression.h
> +++ b/include/expression.h
> @@ -45,6 +45,7 @@
>   * @EXPR_SET_ELEM_CATCHALL catchall element expression
>   * @EXPR_FLAGCMP	flagcmp expression
>   */
> +__attribute__((packed))

No need for ((packed)) here, we never send this over the wire.

>  enum expr_types {
>  	EXPR_INVALID,
>  	EXPR_VERDICT,
> @@ -80,6 +81,7 @@ enum expr_types {
>  	EXPR_MAX = EXPR_FLAGCMP
>  };
>  
> +__attribute__((packed))
>  enum ops {
>  	OP_INVALID,
>  	OP_IMPLICIT,
> @@ -247,9 +249,9 @@ struct expr {
>  	unsigned int		flags;
>  
>  	const struct datatype	*dtype;
> -	enum byteorder		byteorder:8;
> -	enum expr_types		etype:8;
> -	enum ops		op:8;
> +	enum byteorder		byteorder;
> +	enum expr_types		etype;
> +	enum ops		op;

This is saving _a lot of space_ for us, we currently have a problem
with memory consumption, this is going in the opposite direction.

I prefer to ditch this patch.

  reply	other threads:[~2023-09-20 16:02 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-20 14:26 [PATCH nft 0/9] various cleanups related to enums and struct datatype Thomas Haller
2023-09-20 14:26 ` [PATCH nft 1/9] src: fix indentation/whitespace Thomas Haller
2023-09-20 16:03   ` Pablo Neira Ayuso
2023-09-20 14:26 ` [PATCH nft 2/9] include: fix missing definitions in <cache.h>/<headers.h> Thomas Haller
2023-09-20 14:26 ` [PATCH nft 3/9] datatype: drop flags field from datatype Thomas Haller
2023-09-20 18:10   ` Pablo Neira Ayuso
2023-09-20 19:23     ` Thomas Haller
2023-09-21 14:23       ` Pablo Neira Ayuso
2023-09-22  8:51         ` Thomas Haller
2023-09-22 11:18           ` Pablo Neira Ayuso
2023-09-20 14:26 ` [PATCH nft 4/9] datatype: use "enum byteorder" instead of int in set_datatype_alloc() Thomas Haller
2023-09-20 16:27   ` Pablo Neira Ayuso
2023-09-20 14:26 ` [PATCH nft 5/9] payload: use enum icmp_hdr_field_type in payload_may_dependency_kill_icmp() Thomas Haller
2023-09-20 16:32   ` Pablo Neira Ayuso
2023-09-20 14:26 ` [PATCH nft 6/9] netlink: handle invalid etype in set_make_key() Thomas Haller
2023-09-20 16:22   ` Pablo Neira Ayuso
2023-09-20 16:24   ` Pablo Neira Ayuso
2023-09-20 14:26 ` [PATCH nft 7/9] expression: cleanup expr_ops_by_type() and handle u32 input Thomas Haller
2023-09-20 18:13   ` Pablo Neira Ayuso
2023-09-20 19:28     ` Thomas Haller
2023-09-21 14:19       ` Pablo Neira Ayuso
2023-09-22  8:54         ` Thomas Haller
2023-09-22  9:56           ` Pablo Neira Ayuso
2023-09-25  8:44           ` Pablo Neira Ayuso
2023-09-20 14:26 ` [PATCH nft 8/9] datatype: use __attribute__((packed)) instead of enum bitfields Thomas Haller
2023-09-20 16:02   ` Pablo Neira Ayuso [this message]
2023-09-20 17:48     ` Thomas Haller
2023-09-20 18:07       ` Pablo Neira Ayuso
2023-09-20 16:46   ` Pablo Neira Ayuso
2023-09-20 14:26 ` [PATCH nft 9/9] proto: add missing proto_definitions for PROTO_DESC_GENEVE Thomas Haller
2023-09-20 16:14   ` Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZQsXoASbR1+aimMt@calendula \
    --to=pablo@netfilter.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=thaller@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).