[iptables] nft: Use ARRAY_SIZE() macro in nft_strerror()
diff mbox series

Message ID 20191018155114.7423-1-phil@nwl.cc
State Accepted
Delegated to: Pablo Neira
Headers show
Series
  • [iptables] nft: Use ARRAY_SIZE() macro in nft_strerror()
Related show

Commit Message

Phil Sutter Oct. 18, 2019, 3:51 p.m. UTC
Variable 'table' is an array of type struct table_struct, so this is a
classical use-case for ARRAY_SIZE() macro.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/nft.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Pablo Neira Ayuso Oct. 23, 2019, 11:20 a.m. UTC | #1
On Fri, Oct 18, 2019 at 05:51:14PM +0200, Phil Sutter wrote:
> Variable 'table' is an array of type struct table_struct, so this is a
> classical use-case for ARRAY_SIZE() macro.
> 
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Pablo Neira Ayuso Oct. 23, 2019, 11:23 a.m. UTC | #2
On Wed, Oct 23, 2019 at 01:20:24PM +0200, Pablo Neira Ayuso wrote:
> On Fri, Oct 18, 2019 at 05:51:14PM +0200, Phil Sutter wrote:
> > Variable 'table' is an array of type struct table_struct, so this is a
> > classical use-case for ARRAY_SIZE() macro.
> > 
> > Signed-off-by: Phil Sutter <phil@nwl.cc>
> 
> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>

BTW, probably good to add the array check?

https://sourceforge.net/p/libhx/libhx/ci/master/tree/include/libHX/defs.h#l152
Phil Sutter Oct. 23, 2019, 12:16 p.m. UTC | #3
Hi Pablo,

On Wed, Oct 23, 2019 at 01:23:11PM +0200, Pablo Neira Ayuso wrote:
> On Wed, Oct 23, 2019 at 01:20:24PM +0200, Pablo Neira Ayuso wrote:
> > On Fri, Oct 18, 2019 at 05:51:14PM +0200, Phil Sutter wrote:
> > > Variable 'table' is an array of type struct table_struct, so this is a
> > > classical use-case for ARRAY_SIZE() macro.
> > > 
> > > Signed-off-by: Phil Sutter <phil@nwl.cc>
> > 
> > Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> BTW, probably good to add the array check?
> 
> https://sourceforge.net/p/libhx/libhx/ci/master/tree/include/libHX/defs.h#l152

Copying from kernel sources, do you think that's fine?

|  #      ifndef ARRAY_SIZE
| -#              define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
| +#              define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
| +#              define __same_type(a, b) \
| +                       __builtin_types_compatible_p(typeof(a), typeof(b))
| +/*             &a[0] degrades to a pointer: a different type from an array */
| +#              define __must_be_array(a) \
| +                       BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
| +#              define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + __must_be_array(x)
|  #      endif

Cheers, Phil
Pablo Neira Ayuso Oct. 23, 2019, 8:41 p.m. UTC | #4
On Wed, Oct 23, 2019 at 02:16:27PM +0200, Phil Sutter wrote:
> Hi Pablo,
> 
> On Wed, Oct 23, 2019 at 01:23:11PM +0200, Pablo Neira Ayuso wrote:
> > On Wed, Oct 23, 2019 at 01:20:24PM +0200, Pablo Neira Ayuso wrote:
> > > On Fri, Oct 18, 2019 at 05:51:14PM +0200, Phil Sutter wrote:
> > > > Variable 'table' is an array of type struct table_struct, so this is a
> > > > classical use-case for ARRAY_SIZE() macro.
> > > > 
> > > > Signed-off-by: Phil Sutter <phil@nwl.cc>
> > > 
> > > Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
> > 
> > BTW, probably good to add the array check?
> > 
> > https://sourceforge.net/p/libhx/libhx/ci/master/tree/include/libHX/defs.h#l152
> 
> Copying from kernel sources, do you think that's fine?
> 
> |  #      ifndef ARRAY_SIZE
> | -#              define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
> | +#              define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
> | +#              define __same_type(a, b) \
> | +                       __builtin_types_compatible_p(typeof(a), typeof(b))
> | +/*             &a[0] degrades to a pointer: a different type from an array */
> | +#              define __must_be_array(a) \
> | +                       BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
> | +#              define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + __must_be_array(x)
> |  #      endif

At quick glance I would say that's fine.
Phil Sutter Oct. 24, 2019, 8:45 a.m. UTC | #5
Hi,

On Wed, Oct 23, 2019 at 10:41:49PM +0200, Pablo Neira Ayuso wrote:
> On Wed, Oct 23, 2019 at 02:16:27PM +0200, Phil Sutter wrote:
> > Hi Pablo,
> > 
> > On Wed, Oct 23, 2019 at 01:23:11PM +0200, Pablo Neira Ayuso wrote:
> > > On Wed, Oct 23, 2019 at 01:20:24PM +0200, Pablo Neira Ayuso wrote:
> > > > On Fri, Oct 18, 2019 at 05:51:14PM +0200, Phil Sutter wrote:
> > > > > Variable 'table' is an array of type struct table_struct, so this is a
> > > > > classical use-case for ARRAY_SIZE() macro.
> > > > > 
> > > > > Signed-off-by: Phil Sutter <phil@nwl.cc>
> > > > 
> > > > Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
> > > 
> > > BTW, probably good to add the array check?
> > > 
> > > https://sourceforge.net/p/libhx/libhx/ci/master/tree/include/libHX/defs.h#l152
> > 
> > Copying from kernel sources, do you think that's fine?
> > 
> > |  #      ifndef ARRAY_SIZE
> > | -#              define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
> > | +#              define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
> > | +#              define __same_type(a, b) \
> > | +                       __builtin_types_compatible_p(typeof(a), typeof(b))
> > | +/*             &a[0] degrades to a pointer: a different type from an array */
> > | +#              define __must_be_array(a) \
> > | +                       BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
> > | +#              define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + __must_be_array(x)
> > |  #      endif
> 
> At quick glance I would say that's fine.

While testing it, I noticed that gcc has a builtin check already:

| ../include/xtables.h:640:36: warning: division 'sizeof (const uint32_t * {aka const unsigned int *}) / sizeof (uint32_t {aka const unsigned int})' does not compute the number of array elements [-Wsizeof-pointer-div]
|   640 | #  define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
|       |                                    ^
| nft.c:914:18: note: in expansion of macro 'ARRAY_SIZE'
|   914 |  for (i = 1; i < ARRAY_SIZE(multp); i++) {
|       |                  ^~~~~~~~~~
| nft.c:906:25: note: first 'sizeof' operand was declared here
|   906 |  static const uint32_t *multp = mult;
|       |                         ^~~~~

AFAICT, the only benefit the above brings is that it causes an error
instead of warning. Do you think we still need it? Maybe instead enable
-Werror? ;)

Cheers, Phil
Pablo Neira Ayuso Oct. 24, 2019, 9:29 a.m. UTC | #6
On Thu, Oct 24, 2019 at 10:45:03AM +0200, Phil Sutter wrote:
> Hi,
> 
> On Wed, Oct 23, 2019 at 10:41:49PM +0200, Pablo Neira Ayuso wrote:
> > On Wed, Oct 23, 2019 at 02:16:27PM +0200, Phil Sutter wrote:
> > > Hi Pablo,
> > > 
> > > On Wed, Oct 23, 2019 at 01:23:11PM +0200, Pablo Neira Ayuso wrote:
> > > > On Wed, Oct 23, 2019 at 01:20:24PM +0200, Pablo Neira Ayuso wrote:
> > > > > On Fri, Oct 18, 2019 at 05:51:14PM +0200, Phil Sutter wrote:
> > > > > > Variable 'table' is an array of type struct table_struct, so this is a
> > > > > > classical use-case for ARRAY_SIZE() macro.
> > > > > > 
> > > > > > Signed-off-by: Phil Sutter <phil@nwl.cc>
> > > > > 
> > > > > Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
> > > > 
> > > > BTW, probably good to add the array check?
> > > > 
> > > > https://sourceforge.net/p/libhx/libhx/ci/master/tree/include/libHX/defs.h#l152
> > > 
> > > Copying from kernel sources, do you think that's fine?
> > > 
> > > |  #      ifndef ARRAY_SIZE
> > > | -#              define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
> > > | +#              define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
> > > | +#              define __same_type(a, b) \
> > > | +                       __builtin_types_compatible_p(typeof(a), typeof(b))
> > > | +/*             &a[0] degrades to a pointer: a different type from an array */
> > > | +#              define __must_be_array(a) \
> > > | +                       BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
> > > | +#              define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + __must_be_array(x)
> > > |  #      endif
> > 
> > At quick glance I would say that's fine.
> 
> While testing it, I noticed that gcc has a builtin check already:
> 
> | ../include/xtables.h:640:36: warning: division 'sizeof (const uint32_t * {aka const unsigned int *}) / sizeof (uint32_t {aka const unsigned int})' does not compute the number of array elements [-Wsizeof-pointer-div]
> |   640 | #  define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
> |       |                                    ^
> | nft.c:914:18: note: in expansion of macro 'ARRAY_SIZE'
> |   914 |  for (i = 1; i < ARRAY_SIZE(multp); i++) {
> |       |                  ^~~~~~~~~~
> | nft.c:906:25: note: first 'sizeof' operand was declared here
> |   906 |  static const uint32_t *multp = mult;
> |       |                         ^~~~~
> 
> AFAICT, the only benefit the above brings is that it causes an error
> instead of warning. Do you think we still need it? Maybe instead enable
> -Werror? ;)

If gcc is already checking for this. Warning should be fine.

Regarding -Werror, we would at least need to keep the autogenerated C
code by bison away from it.

IIRC I enabled this in conntrack-tools long time ago, and I started
getting reports on it breaking compilation with new gcc versions that
were actually spewing new warnings. That was stopping users to install
latest, probably -Werror is too agressive?
Phil Sutter Oct. 24, 2019, 9:51 a.m. UTC | #7
Hey,

On Thu, Oct 24, 2019 at 11:29:03AM +0200, Pablo Neira Ayuso wrote:
[...]
> If gcc is already checking for this. Warning should be fine.
> 
> Regarding -Werror, we would at least need to keep the autogenerated C
> code by bison away from it.

In nftables there is libparser_la_CFLAGS which holds quite some
exclusions already and could be used to pass -Wno-error as well. (Maybe
a good idea to add this regardless of whether we set -Werror by default
or not.)

> IIRC I enabled this in conntrack-tools long time ago, and I started
> getting reports on it breaking compilation with new gcc versions that
> were actually spewing new warnings. That was stopping users to install
> latest, probably -Werror is too agressive?

Yes, I wasn't completely serious. Breaking users' builds for things they
may not be in control of is not the best idea. We could instead add a
configure option to enable strict mode, but checking for warnings is
something I usually do so probably not that important after all.

Cheers, Phil
Pablo Neira Ayuso Oct. 24, 2019, 10:01 a.m. UTC | #8
On Thu, Oct 24, 2019 at 11:51:01AM +0200, Phil Sutter wrote:
> Hey,
> 
> On Thu, Oct 24, 2019 at 11:29:03AM +0200, Pablo Neira Ayuso wrote:
> [...]
> > If gcc is already checking for this. Warning should be fine.
> > 
> > Regarding -Werror, we would at least need to keep the autogenerated C
> > code by bison away from it.
> 
> In nftables there is libparser_la_CFLAGS which holds quite some
> exclusions already and could be used to pass -Wno-error as well. (Maybe
> a good idea to add this regardless of whether we set -Werror by default
> or not.)
> 
> > IIRC I enabled this in conntrack-tools long time ago, and I started
> > getting reports on it breaking compilation with new gcc versions that
> > were actually spewing new warnings. That was stopping users to install
> > latest, probably -Werror is too agressive?
> 
> Yes, I wasn't completely serious. Breaking users' builds for things they
> may not be in control of is not the best idea. We could instead add a
> configure option to enable strict mode, but checking for warnings is
> something I usually do so probably not that important after all.

Indeed. So let's leave things as is then.

Patch
diff mbox series

diff --git a/iptables/nft.c b/iptables/nft.c
index 89b1c7a808f57..3c230c121f8b9 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -2888,7 +2888,7 @@  const char *nft_strerror(int err)
 	    { NULL, ENOENT, "No chain/target/match by that name" },
 	  };
 
-	for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) {
+	for (i = 0; i < ARRAY_SIZE(table); i++) {
 		if ((!table[i].fn || table[i].fn == nft_fn)
 		    && table[i].err == err)
 			return table[i].message;