All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH nf-next v5] netfilter: nf_tables: add math expression support
@ 2026-04-21 15:59 Fernando Fernandez Mancera
  2026-04-26  3:57 ` kernel test robot
  2026-05-05  1:55 ` kernel test robot
  0 siblings, 2 replies; 6+ messages in thread
From: Fernando Fernandez Mancera @ 2026-04-21 15:59 UTC (permalink / raw)
  To: netfilter-devel; +Cc: coreteam, phil, fw, pablo, Fernando Fernandez Mancera

Historically, users have requested support for increasing and decreasing
TTL value in nftables in order to migrate from iptables.

Following the nftables spirit of flexible and multipurpose expressions,
this patch introduces "nft_math" expression. This expression allows to
increase and decrease values stored in the register.

The math expression intends to be flexible enough in case it needs to be
extended in the future, e.g implement non-contiguous bitfields
operations. But for now, non-contiguous payloads are not supported.

When loading a u8 or u16 payload into a register we don't know if the
value is stored at least significant byte or most significant byte. In
order to handle such cases, introduce a bitmask indicating what is the
target bit and also use it to handle limits to prevent overflow or
underflow. Keep in mind that math expression expects that the sreg and
dreg are in host byteorder, so the user must use nft_byteorder
expressions as needed.

This implementation comes with a libnftnl patch that allows the user to
generate the following example bytecodes:

- Bytecode to increase the TTL of a packet

table filter inet flags 0 use 1 handle 1
inet filter input use 1 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1
inet filter input 4
  [ payload load 2b @ network header + 8 => reg 1 ]
  [ math mask 0x000000ff reg 1 + 1 => 1]
  [ payload write reg 1 => 2b @ network header + 8 csum_type 1 csum_off 10 csum_flags 0x0 ]

- Bytecode to decrease the TTL of a packet

table filter inet flags 0 use 1 handle 1
inet filter input use 1 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1
inet filter input 4
  [ payload load 2b @ network header + 8 => reg 1 ]
  [ math mask 0x000000ff reg 1 - 1 => 1]
  [ payload write reg 1 => 2b @ network header + 8 csum_type 1 csum_off 10 csum_flags 0x0 ]

- Bytecode to increase the meta mark of a packet

table mangle inet flags 0 use 1 handle 6
inet mangle output use 1 type filter hook output prio 0 policy accept packets 0 bytes 0 flags 1
inet mangle output 2
  [ meta load mark => reg 1 ]
  [ math mask 0xffffffff reg 1 + 1 => 1]
  [ meta set mark with reg 1 ]

Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
---
v2: dropped the byteorder netlink attribute, added bitmask to handle
LSB/MSB when dealing with u8 and u16, simplified eval logic. I've kept
nft_math as module, IMHO it would be too much to make it built-in.
v3: fixed checkpatch warnings, improved Kconfig description and fixed a
wrong EINVAL return.
v4: removed NFTA_MATH_LEN as discussed with Phil, added a non-contiguous
bitmask check
v5: fixed check on op max value, fixed byteorder inconsistency now
NLA_U32 for both BITMASK and OP attributes
---
 include/uapi/linux/netfilter/nf_tables.h |  25 ++++
 net/netfilter/Kconfig                    |   9 ++
 net/netfilter/Makefile                   |   1 +
 net/netfilter/nft_math.c                 | 157 +++++++++++++++++++++++
 4 files changed, 192 insertions(+)
 create mode 100644 net/netfilter/nft_math.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 0b708153469c..36a5b42c3ddf 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -2019,4 +2019,29 @@ enum nft_tunnel_attributes {
 };
 #define NFTA_TUNNEL_MAX	(__NFTA_TUNNEL_MAX - 1)
 
+/**
+ * enum nft_math_attributes - nftables math expression netlink attributes
+ *
+ * @NFTA_MATH_SREG: source register (NLA_U32: nft_registers)
+ * @NFTA_MATH_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_MATH_OP: operation to be performed (NLA_U32)
+ * @NFTA_MATH_BITMASK: bitmask to be applied on the operation (NLA_U32)
+ */
+enum nft_math_attributes {
+	NFTA_MATH_UNSPEC,
+	NFTA_MATH_SREG,
+	NFTA_MATH_DREG,
+	NFTA_MATH_OP,
+	NFTA_MATH_BITMASK,
+	__NFTA_MATH_MAX,
+};
+#define NFTA_MATH_MAX (__NFTA_MATH_MAX - 1)
+
+enum nft_math_op {
+	NFT_MATH_OP_INC,
+	NFT_MATH_OP_DEC,
+	__NFT_MATH_OP_MAX,
+};
+#define NFT_MATH_OP_MAX (__NFT_MATH_OP_MAX - 1)
+
 #endif /* _LINUX_NF_TABLES_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index f3ea0cb26f36..49e723f0dcc8 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -667,6 +667,15 @@ config NFT_SYNPROXY
 	  server. This allows to avoid conntrack and server resource usage
 	  during SYN-flood attacks.
 
+config NFT_MATH
+	tristate "Netfilter nf_tables math expression support"
+	depends on NETFILTER_ADVANCED
+	help
+	  This option enables support for the nftables math expression.
+	  It allows arithmetic operations to be performed on nft registers
+	  content, such as incrementing or decrementing values. Math
+	  expressions can be used in nftables rules to modify packet fields.
+
 if NF_TABLES_NETDEV
 
 config NF_DUP_NETDEV
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 6bfc250e474f..fe25b1d1ce0a 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -131,6 +131,7 @@ obj-$(CONFIG_NFT_OSF)		+= nft_osf.o
 obj-$(CONFIG_NFT_TPROXY)	+= nft_tproxy.o
 obj-$(CONFIG_NFT_XFRM)		+= nft_xfrm.o
 obj-$(CONFIG_NFT_SYNPROXY)	+= nft_synproxy.o
+obj-$(CONFIG_NFT_MATH)		+= nft_math.o
 
 obj-$(CONFIG_NFT_NAT)		+= nft_chain_nat.o
 
diff --git a/net/netfilter/nft_math.c b/net/netfilter/nft_math.c
new file mode 100644
index 000000000000..87dc4ec801d8
--- /dev/null
+++ b/net/netfilter/nft_math.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <net/netlink.h>
+#include <net/netfilter/nf_tables.h>
+
+struct nft_math {
+	u8			sreg;
+	u8			dreg;
+	u32			bitmask;
+	enum nft_math_op	op;
+};
+
+static const struct nla_policy nft_math_policy[NFTA_MATH_MAX + 1] = {
+	[NFTA_MATH_SREG]	= { .type = NLA_U32 },
+	[NFTA_MATH_DREG]	= { .type = NLA_U32 },
+	[NFTA_MATH_OP]		= { .type = NLA_U32 },
+	[NFTA_MATH_BITMASK]	= { .type = NLA_U32 },
+};
+
+static void nft_math_eval_bitmask(u32 *src, u32 *dst,
+				  const struct nft_math *priv)
+{
+	u32 target, keep, bit_unit;
+
+	target = *src & priv->bitmask;
+	keep = *src & ~priv->bitmask;
+	bit_unit = priv->bitmask & -priv->bitmask;
+
+	switch (priv->op) {
+	case NFT_MATH_OP_INC:
+		if (target == priv->bitmask) {
+			*dst = *src;
+			break;
+		}
+
+		target = target + bit_unit;
+		*dst = target | keep;
+		break;
+	case NFT_MATH_OP_DEC:
+		if (!target) {
+			*dst = *src;
+			break;
+		}
+
+		target = target - bit_unit;
+		*dst = target | keep;
+		break;
+	default:
+		DEBUG_NET_WARN_ONCE(true, "unknown operation path in nft_math");
+		*dst = *src;
+		break;
+	}
+}
+
+static void nft_math_eval(const struct nft_expr *expr,
+			  struct nft_regs *regs,
+			  const struct nft_pktinfo *pkt)
+{
+	const struct nft_math *priv = nft_expr_priv(expr);
+	u32 *src = &regs->data[priv->sreg];
+	u32 *dst = &regs->data[priv->dreg];
+
+	nft_math_eval_bitmask(src, dst, priv);
+}
+
+static int nft_math_init(const struct nft_ctx *ctx,
+			 const struct nft_expr *expr,
+			 const struct nlattr * const tb[])
+{
+	struct nft_math *priv = nft_expr_priv(expr);
+	u32 bitmask_check;
+	int err;
+	u32 op;
+
+	if (!tb[NFTA_MATH_SREG] ||
+	    !tb[NFTA_MATH_DREG] ||
+	    !tb[NFTA_MATH_BITMASK] ||
+	    !tb[NFTA_MATH_OP])
+		return -EINVAL;
+
+	op = nla_get_u32(tb[NFTA_MATH_OP]);
+	if (op > NFT_MATH_OP_MAX)
+		return -EOPNOTSUPP;
+	priv->op = op;
+
+	priv->bitmask = nla_get_u32(tb[NFTA_MATH_BITMASK]);
+	if (!priv->bitmask)
+		return -EINVAL;
+
+	/* check if the bitmask is contiguous, otherwise reject it */
+	bitmask_check = priv->bitmask + (priv->bitmask & -priv->bitmask);
+	if (bitmask_check & (bitmask_check - 1))
+		return -EINVAL;
+
+	err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
+				      sizeof(u32));
+	if (err < 0)
+		return err;
+
+	return nft_parse_register_store(ctx, tb[NFTA_MATH_DREG],
+					&priv->dreg, NULL, NFT_DATA_VALUE,
+					sizeof(u32));
+}
+
+static int nft_math_dump(struct sk_buff *skb,
+			 const struct nft_expr *expr, bool reset)
+{
+	const struct nft_math *priv = nft_expr_priv(expr);
+
+	if (nft_dump_register(skb, NFTA_MATH_SREG, priv->sreg))
+		goto nla_put_failure;
+	if (nft_dump_register(skb, NFTA_MATH_DREG, priv->dreg))
+		goto nla_put_failure;
+	if (nla_put_u32(skb, NFTA_MATH_BITMASK, priv->bitmask))
+		goto nla_put_failure;
+	if (nla_put_u32(skb, NFTA_MATH_OP, priv->op))
+		goto nla_put_failure;
+	return 0;
+
+nla_put_failure:
+	return -1;
+}
+
+static struct nft_expr_type nft_math_type;
+static const struct nft_expr_ops nft_math_op = {
+	.eval		= nft_math_eval,
+	.size		= NFT_EXPR_SIZE(sizeof(struct nft_math)),
+	.init		= nft_math_init,
+	.dump		= nft_math_dump,
+	.type		= &nft_math_type,
+};
+
+static struct nft_expr_type nft_math_type __read_mostly = {
+	.ops		= &nft_math_op,
+	.name		= "math",
+	.owner		= THIS_MODULE,
+	.policy		= nft_math_policy,
+	.maxattr	= NFTA_MATH_MAX,
+};
+
+static int __init nft_math_module_init(void)
+{
+	return nft_register_expr(&nft_math_type);
+}
+
+static void __exit nft_math_module_exit(void)
+{
+	nft_unregister_expr(&nft_math_type);
+}
+
+module_init(nft_math_module_init);
+module_exit(nft_math_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fernando Fernandez Mancera <fmancera@suse.de>");
+MODULE_ALIAS_NFT_EXPR("math");
+MODULE_DESCRIPTION("nftables math support to operate with values");
-- 
2.53.0


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

* Re: [PATCH nf-next v5] netfilter: nf_tables: add math expression support
  2026-04-21 15:59 [PATCH nf-next v5] netfilter: nf_tables: add math expression support Fernando Fernandez Mancera
@ 2026-04-26  3:57 ` kernel test robot
  2026-04-27  7:26   ` Fernando Fernandez Mancera
  2026-05-05  1:55 ` kernel test robot
  1 sibling, 1 reply; 6+ messages in thread
From: kernel test robot @ 2026-04-26  3:57 UTC (permalink / raw)
  To: Fernando Fernandez Mancera, netfilter-devel
  Cc: oe-kbuild-all, coreteam, phil, fw, pablo,
	Fernando Fernandez Mancera

Hi Fernando,

kernel test robot noticed the following build errors:

[auto build test ERROR on nf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Fernando-Fernandez-Mancera/netfilter-nf_tables-add-math-expression-support/20260424-055358
base:   https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git master
patch link:    https://lore.kernel.org/r/20260421155859.7049-2-fmancera%40suse.de
patch subject: [PATCH nf-next v5] netfilter: nf_tables: add math expression support
config: nios2-allmodconfig (https://download.01.org/0day-ci/archive/20260426/202604261140.gX71SoJp-lkp@intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260426/202604261140.gX71SoJp-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604261140.gX71SoJp-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   net/netfilter/nft_math.c: In function 'nft_math_eval_bitmask':
   net/netfilter/nft_math.c:49:17: error: implicit declaration of function 'DEBUG_NET_WARN_ONCE'; did you mean 'DEBUG_NET_WARN_ON_ONCE'? [-Werror=implicit-function-declaration]
      49 |                 DEBUG_NET_WARN_ONCE(true, "unknown operation path in nft_math");
         |                 ^~~~~~~~~~~~~~~~~~~
         |                 DEBUG_NET_WARN_ON_ONCE
   net/netfilter/nft_math.c: In function 'nft_math_init':
   net/netfilter/nft_math.c:95:39: error: passing argument 1 of 'nft_parse_register_load' from incompatible pointer type [-Werror=incompatible-pointer-types]
      95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
         |                                       ^~~
         |                                       |
         |                                       const struct nft_ctx *
   In file included from net/netfilter/nft_math.c:4:
   include/net/netfilter/nf_tables.h:235:50: note: expected 'const struct nlattr *' but argument is of type 'const struct nft_ctx *'
     235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
         |                             ~~~~~~~~~~~~~~~~~~~~~^~~~
   net/netfilter/nft_math.c:95:46: error: passing argument 2 of 'nft_parse_register_load' from incompatible pointer type [-Werror=incompatible-pointer-types]
      95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
         |                                            ~~^~~~~~~~~~~~~~~~
         |                                              |
         |                                              const struct nlattr *
   In file included from net/netfilter/nft_math.c:4:
   include/net/netfilter/nf_tables.h:235:60: note: expected 'u8 *' {aka 'unsigned char *'} but argument is of type 'const struct nlattr *'
     235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
         |                                                        ~~~~^~~~
>> net/netfilter/nft_math.c:95:64: warning: passing argument 3 of 'nft_parse_register_load' makes integer from pointer without a cast [-Wint-conversion]
      95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
         |                                                                ^~~~~~~~~~~
         |                                                                |
         |                                                                u8 * {aka unsigned char *}
   In file included from net/netfilter/nft_math.c:4:
   include/net/netfilter/nf_tables.h:235:70: note: expected 'u32' {aka 'unsigned int'} but argument is of type 'u8 *' {aka 'unsigned char *'}
     235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
         |                                                                  ~~~~^~~
>> net/netfilter/nft_math.c:95:15: error: too many arguments to function 'nft_parse_register_load'
      95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
         |               ^~~~~~~~~~~~~~~~~~~~~~~
   In file included from net/netfilter/nft_math.c:4:
   include/net/netfilter/nf_tables.h:235:5: note: declared here
     235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
         |     ^~~~~~~~~~~~~~~~~~~~~~~
   net/netfilter/nft_math.c: At top level:
   net/netfilter/nft_math.c:129:27: error: initialization of 'int (*)(struct sk_buff *, const struct nft_expr *)' from incompatible pointer type 'int (*)(struct sk_buff *, const struct nft_expr *, bool)' {aka 'int (*)(struct sk_buff *, const struct nft_expr *, _Bool)'} [-Werror=incompatible-pointer-types]
     129 |         .dump           = nft_math_dump,
         |                           ^~~~~~~~~~~~~
   net/netfilter/nft_math.c:129:27: note: (near initialization for 'nft_math_op.dump')
   cc1: some warnings being treated as errors


vim +/nft_parse_register_load +95 net/netfilter/nft_math.c

    65	
    66	static int nft_math_init(const struct nft_ctx *ctx,
    67				 const struct nft_expr *expr,
    68				 const struct nlattr * const tb[])
    69	{
    70		struct nft_math *priv = nft_expr_priv(expr);
    71		u32 bitmask_check;
    72		int err;
    73		u32 op;
    74	
    75		if (!tb[NFTA_MATH_SREG] ||
    76		    !tb[NFTA_MATH_DREG] ||
    77		    !tb[NFTA_MATH_BITMASK] ||
    78		    !tb[NFTA_MATH_OP])
    79			return -EINVAL;
    80	
    81		op = nla_get_u32(tb[NFTA_MATH_OP]);
    82		if (op > NFT_MATH_OP_MAX)
    83			return -EOPNOTSUPP;
    84		priv->op = op;
    85	
    86		priv->bitmask = nla_get_u32(tb[NFTA_MATH_BITMASK]);
    87		if (!priv->bitmask)
    88			return -EINVAL;
    89	
    90		/* check if the bitmask is contiguous, otherwise reject it */
    91		bitmask_check = priv->bitmask + (priv->bitmask & -priv->bitmask);
    92		if (bitmask_check & (bitmask_check - 1))
    93			return -EINVAL;
    94	
  > 95		err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
    96					      sizeof(u32));
    97		if (err < 0)
    98			return err;
    99	
   100		return nft_parse_register_store(ctx, tb[NFTA_MATH_DREG],
   101						&priv->dreg, NULL, NFT_DATA_VALUE,
   102						sizeof(u32));
   103	}
   104	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH nf-next v5] netfilter: nf_tables: add math expression support
  2026-04-26  3:57 ` kernel test robot
@ 2026-04-27  7:26   ` Fernando Fernandez Mancera
  2026-04-27  8:07     ` Florian Westphal
  0 siblings, 1 reply; 6+ messages in thread
From: Fernando Fernandez Mancera @ 2026-04-27  7:26 UTC (permalink / raw)
  To: kernel test robot, netfilter-devel
  Cc: oe-kbuild-all, coreteam, phil, fw, pablo

On 4/26/26 5:57 AM, kernel test robot wrote:
> Hi Fernando,
> 
> kernel test robot noticed the following build errors:
> 
> [auto build test ERROR on nf-next/master]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Fernando-Fernandez-Mancera/netfilter-nf_tables-add-math-expression-support/20260424-055358
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git master
> patch link:    https://lore.kernel.org/r/20260421155859.7049-2-fmancera%40suse.de
> patch subject: [PATCH nf-next v5] netfilter: nf_tables: add math expression support
> config: nios2-allmodconfig (https://download.01.org/0day-ci/archive/20260426/202604261140.gX71SoJp-lkp@intel.com/config)
> compiler: nios2-linux-gcc (GCC) 11.5.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260426/202604261140.gX71SoJp-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202604261140.gX71SoJp-lkp@intel.com/
> 

I am completely lost here. How is this happening? I do not see any of 
these errors locally with W=1.

> All error/warnings (new ones prefixed by >>):
> 
>     net/netfilter/nft_math.c: In function 'nft_math_eval_bitmask':
>     net/netfilter/nft_math.c:49:17: error: implicit declaration of function 'DEBUG_NET_WARN_ONCE'; did you mean 'DEBUG_NET_WARN_ON_ONCE'? [-Werror=implicit-function-declaration]
>        49 |                 DEBUG_NET_WARN_ONCE(true, "unknown operation path in nft_math");
>           |                 ^~~~~~~~~~~~~~~~~~~
>           |                 DEBUG_NET_WARN_ON_ONCE
>     net/netfilter/nft_math.c: In function 'nft_math_init':
>     net/netfilter/nft_math.c:95:39: error: passing argument 1 of 'nft_parse_register_load' from incompatible pointer type [-Werror=incompatible-pointer-types]
>        95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
>           |                                       ^~~
>           |                                       |
>           |                                       const struct nft_ctx *

What? But I see:

int nft_parse_register_load(const struct nft_ctx *ctx,
                             const struct nlattr *attr, u8 *sreg, u32 len);

Is this a bogus report?

>     In file included from net/netfilter/nft_math.c:4:
>     include/net/netfilter/nf_tables.h:235:50: note: expected 'const struct nlattr *' but argument is of type 'const struct nft_ctx *'
>       235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
>           |                             ~~~~~~~~~~~~~~~~~~~~~^~~~
>     net/netfilter/nft_math.c:95:46: error: passing argument 2 of 'nft_parse_register_load' from incompatible pointer type [-Werror=incompatible-pointer-types]
>        95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
>           |                                            ~~^~~~~~~~~~~~~~~~
>           |                                              |
>           |                                              const struct nlattr *
>     In file included from net/netfilter/nft_math.c:4:
>     include/net/netfilter/nf_tables.h:235:60: note: expected 'u8 *' {aka 'unsigned char *'} but argument is of type 'const struct nlattr *'
>       235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
>           |                                                        ~~~~^~~~
>>> net/netfilter/nft_math.c:95:64: warning: passing argument 3 of 'nft_parse_register_load' makes integer from pointer without a cast [-Wint-conversion]
>        95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
>           |                                                                ^~~~~~~~~~~
>           |                                                                |
>           |                                                                u8 * {aka unsigned char *}
>     In file included from net/netfilter/nft_math.c:4:
>     include/net/netfilter/nf_tables.h:235:70: note: expected 'u32' {aka 'unsigned int'} but argument is of type 'u8 *' {aka 'unsigned char *'}
>       235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
>           |                                                                  ~~~~^~~
>>> net/netfilter/nft_math.c:95:15: error: too many arguments to function 'nft_parse_register_load'
>        95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
>           |               ^~~~~~~~~~~~~~~~~~~~~~~
>     In file included from net/netfilter/nft_math.c:4:
>     include/net/netfilter/nf_tables.h:235:5: note: declared here
>       235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
>           |     ^~~~~~~~~~~~~~~~~~~~~~~
>     net/netfilter/nft_math.c: At top level:
>     net/netfilter/nft_math.c:129:27: error: initialization of 'int (*)(struct sk_buff *, const struct nft_expr *)' from incompatible pointer type 'int (*)(struct sk_buff *, const struct nft_expr *, bool)' {aka 'int (*)(struct sk_buff *, const struct nft_expr *, _Bool)'} [-Werror=incompatible-pointer-types]
>       129 |         .dump           = nft_math_dump,
>           |                           ^~~~~~~~~~~~~
>     net/netfilter/nft_math.c:129:27: note: (near initialization for 'nft_math_op.dump')
>     cc1: some warnings being treated as errors
> 
> 
> vim +/nft_parse_register_load +95 net/netfilter/nft_math.c
> 
>      65	
>      66	static int nft_math_init(const struct nft_ctx *ctx,
>      67				 const struct nft_expr *expr,
>      68				 const struct nlattr * const tb[])
>      69	{
>      70		struct nft_math *priv = nft_expr_priv(expr);
>      71		u32 bitmask_check;
>      72		int err;
>      73		u32 op;
>      74	
>      75		if (!tb[NFTA_MATH_SREG] ||
>      76		    !tb[NFTA_MATH_DREG] ||
>      77		    !tb[NFTA_MATH_BITMASK] ||
>      78		    !tb[NFTA_MATH_OP])
>      79			return -EINVAL;
>      80	
>      81		op = nla_get_u32(tb[NFTA_MATH_OP]);
>      82		if (op > NFT_MATH_OP_MAX)
>      83			return -EOPNOTSUPP;
>      84		priv->op = op;
>      85	
>      86		priv->bitmask = nla_get_u32(tb[NFTA_MATH_BITMASK]);
>      87		if (!priv->bitmask)
>      88			return -EINVAL;
>      89	
>      90		/* check if the bitmask is contiguous, otherwise reject it */
>      91		bitmask_check = priv->bitmask + (priv->bitmask & -priv->bitmask);
>      92		if (bitmask_check & (bitmask_check - 1))
>      93			return -EINVAL;
>      94	
>    > 95		err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
>      96					      sizeof(u32));
>      97		if (err < 0)
>      98			return err;
>      99	
>     100		return nft_parse_register_store(ctx, tb[NFTA_MATH_DREG],
>     101						&priv->dreg, NULL, NFT_DATA_VALUE,
>     102						sizeof(u32));
>     103	}
>     104	
> 


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

* Re: [PATCH nf-next v5] netfilter: nf_tables: add math expression support
  2026-04-27  7:26   ` Fernando Fernandez Mancera
@ 2026-04-27  8:07     ` Florian Westphal
  2026-04-27 14:07       ` Philip Li
  0 siblings, 1 reply; 6+ messages in thread
From: Florian Westphal @ 2026-04-27  8:07 UTC (permalink / raw)
  To: Fernando Fernandez Mancera
  Cc: kernel test robot, netfilter-devel, oe-kbuild-all, coreteam, phil,
	pablo

Fernando Fernandez Mancera <fmancera@suse.de> wrote:
> On 4/26/26 5:57 AM, kernel test robot wrote:
> > Hi Fernando,
> > 
> > kernel test robot noticed the following build errors:
> > 
> > [auto build test ERROR on nf-next/master]
> > 
> > url:    https://github.com/intel-lab-lkp/linux/commits/Fernando-Fernandez-Mancera/netfilter-nf_tables-add-math-expression-support/20260424-055358
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git master
                                                                                  ~~~~~~


> > | Reported-by: kernel test robot <lkp@intel.com>
> > | Closes: https://lore.kernel.org/oe-kbuild-all/202604261140.gX71SoJp-lkp@intel.com/
> > 
> 
> I am completely lost here. How is this happening? I do not see any of 
> these errors locally with W=1.

Sure, you use main, not master. I'll remove master from the repository,
hopefully that will stop future reports like this.

> What? But I see:
> 
> int nft_parse_register_load(const struct nft_ctx *ctx,
>                              const struct nlattr *attr, u8 *sreg, u32 len);
> 
> Is this a bogus report?

Yes, wrong branch.

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

* Re: [PATCH nf-next v5] netfilter: nf_tables: add math expression support
  2026-04-27  8:07     ` Florian Westphal
@ 2026-04-27 14:07       ` Philip Li
  0 siblings, 0 replies; 6+ messages in thread
From: Philip Li @ 2026-04-27 14:07 UTC (permalink / raw)
  To: Florian Westphal
  Cc: Fernando Fernandez Mancera, kernel test robot, netfilter-devel,
	oe-kbuild-all, coreteam, phil, pablo

On Mon, Apr 27, 2026 at 10:07:22AM +0200, Florian Westphal wrote:
> Fernando Fernandez Mancera <fmancera@suse.de> wrote:
> > On 4/26/26 5:57 AM, kernel test robot wrote:
> > > Hi Fernando,
> > > 
> > > kernel test robot noticed the following build errors:
> > > 
> > > [auto build test ERROR on nf-next/master]
> > > 
> > > url:    https://github.com/intel-lab-lkp/linux/commits/Fernando-Fernandez-Mancera/netfilter-nf_tables-add-math-expression-support/20260424-055358
> > > base:   https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git master
>                                                                                   ~~~~~~
> 
> 
> > > | Reported-by: kernel test robot <lkp@intel.com>
> > > | Closes: https://lore.kernel.org/oe-kbuild-all/202604261140.gX71SoJp-lkp@intel.com/
> > > 
> > 
> > I am completely lost here. How is this happening? I do not see any of 
> > these errors locally with W=1.
> 
> Sure, you use main, not master. I'll remove master from the repository,
> hopefully that will stop future reports like this.

Sorry for the wrong report, this is the issue of the bot, the base candidate is configured
as master. Now i have corrected it to be main branch.

> 
> > What? But I see:
> > 
> > int nft_parse_register_load(const struct nft_ctx *ctx,
> >                              const struct nlattr *attr, u8 *sreg, u32 len);
> > 
> > Is this a bogus report?
> 
> Yes, wrong branch.
> 

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

* Re: [PATCH nf-next v5] netfilter: nf_tables: add math expression support
  2026-04-21 15:59 [PATCH nf-next v5] netfilter: nf_tables: add math expression support Fernando Fernandez Mancera
  2026-04-26  3:57 ` kernel test robot
@ 2026-05-05  1:55 ` kernel test robot
  1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2026-05-05  1:55 UTC (permalink / raw)
  To: Fernando Fernandez Mancera, netfilter-devel
  Cc: oe-kbuild-all, coreteam, phil, fw, pablo,
	Fernando Fernandez Mancera

Hi Fernando,

kernel test robot noticed the following build errors:

[auto build test ERROR on nf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Fernando-Fernandez-Mancera/netfilter-nf_tables-add-math-expression-support/20260424-055358
base:   https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git master
patch link:    https://lore.kernel.org/r/20260421155859.7049-2-fmancera%40suse.de
patch subject: [PATCH nf-next v5] netfilter: nf_tables: add math expression support
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20260505/202605050928.BM8aFWgX-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260505/202605050928.BM8aFWgX-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605050928.BM8aFWgX-lkp@intel.com/

All errors (new ones prefixed by >>):

   net/netfilter/nft_math.c: In function 'nft_math_eval_bitmask':
>> net/netfilter/nft_math.c:49:17: error: implicit declaration of function 'DEBUG_NET_WARN_ONCE'; did you mean 'DEBUG_NET_WARN_ON_ONCE'? [-Wimplicit-function-declaration]
      49 |                 DEBUG_NET_WARN_ONCE(true, "unknown operation path in nft_math");
         |                 ^~~~~~~~~~~~~~~~~~~
         |                 DEBUG_NET_WARN_ON_ONCE
   net/netfilter/nft_math.c: In function 'nft_math_init':
>> net/netfilter/nft_math.c:95:39: error: passing argument 1 of 'nft_parse_register_load' from incompatible pointer type [-Wincompatible-pointer-types]
      95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
         |                                       ^~~
         |                                       |
         |                                       const struct nft_ctx *
   In file included from net/netfilter/nft_math.c:4:
   include/net/netfilter/nf_tables.h:235:50: note: expected 'const struct nlattr *' but argument is of type 'const struct nft_ctx *'
     235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
         |                             ~~~~~~~~~~~~~~~~~~~~~^~~~
   net/netfilter/nft_math.c:95:46: error: passing argument 2 of 'nft_parse_register_load' from incompatible pointer type [-Wincompatible-pointer-types]
      95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
         |                                            ~~^~~~~~~~~~~~~~~~
         |                                              |
         |                                              const struct nlattr *
   include/net/netfilter/nf_tables.h:235:60: note: expected 'u8 *' {aka 'unsigned char *'} but argument is of type 'const struct nlattr *'
     235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
         |                                                        ~~~~^~~~
>> net/netfilter/nft_math.c:95:64: error: passing argument 3 of 'nft_parse_register_load' makes integer from pointer without a cast [-Wint-conversion]
      95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
         |                                                                ^~~~~~~~~~~
         |                                                                |
         |                                                                u8 * {aka unsigned char *}
   include/net/netfilter/nf_tables.h:235:70: note: expected 'u32' {aka 'unsigned int'} but argument is of type 'u8 *' {aka 'unsigned char *'}
     235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
         |                                                                  ~~~~^~~
>> net/netfilter/nft_math.c:95:15: error: too many arguments to function 'nft_parse_register_load'; expected 3, have 4
      95 |         err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
         |               ^~~~~~~~~~~~~~~~~~~~~~~
      96 |                                       sizeof(u32));
         |                                       ~~~~~~~~~~~
   include/net/netfilter/nf_tables.h:235:5: note: declared here
     235 | int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
         |     ^~~~~~~~~~~~~~~~~~~~~~~
   net/netfilter/nft_math.c: At top level:
>> net/netfilter/nft_math.c:129:27: error: initialization of 'int (*)(struct sk_buff *, const struct nft_expr *)' from incompatible pointer type 'int (*)(struct sk_buff *, const struct nft_expr *, bool)' {aka 'int (*)(struct sk_buff *, const struct nft_expr *, _Bool)'} [-Wincompatible-pointer-types]
     129 |         .dump           = nft_math_dump,
         |                           ^~~~~~~~~~~~~
   net/netfilter/nft_math.c:129:27: note: (near initialization for 'nft_math_op.dump')
   net/netfilter/nft_math.c:105:12: note: 'nft_math_dump' declared here
     105 | static int nft_math_dump(struct sk_buff *skb,
         |            ^~~~~~~~~~~~~


vim +49 net/netfilter/nft_math.c

    19	
    20	static void nft_math_eval_bitmask(u32 *src, u32 *dst,
    21					  const struct nft_math *priv)
    22	{
    23		u32 target, keep, bit_unit;
    24	
    25		target = *src & priv->bitmask;
    26		keep = *src & ~priv->bitmask;
    27		bit_unit = priv->bitmask & -priv->bitmask;
    28	
    29		switch (priv->op) {
    30		case NFT_MATH_OP_INC:
    31			if (target == priv->bitmask) {
    32				*dst = *src;
    33				break;
    34			}
    35	
    36			target = target + bit_unit;
    37			*dst = target | keep;
    38			break;
    39		case NFT_MATH_OP_DEC:
    40			if (!target) {
    41				*dst = *src;
    42				break;
    43			}
    44	
    45			target = target - bit_unit;
    46			*dst = target | keep;
    47			break;
    48		default:
  > 49			DEBUG_NET_WARN_ONCE(true, "unknown operation path in nft_math");
    50			*dst = *src;
    51			break;
    52		}
    53	}
    54	
    55	static void nft_math_eval(const struct nft_expr *expr,
    56				  struct nft_regs *regs,
    57				  const struct nft_pktinfo *pkt)
    58	{
    59		const struct nft_math *priv = nft_expr_priv(expr);
    60		u32 *src = &regs->data[priv->sreg];
    61		u32 *dst = &regs->data[priv->dreg];
    62	
    63		nft_math_eval_bitmask(src, dst, priv);
    64	}
    65	
    66	static int nft_math_init(const struct nft_ctx *ctx,
    67				 const struct nft_expr *expr,
    68				 const struct nlattr * const tb[])
    69	{
    70		struct nft_math *priv = nft_expr_priv(expr);
    71		u32 bitmask_check;
    72		int err;
    73		u32 op;
    74	
    75		if (!tb[NFTA_MATH_SREG] ||
    76		    !tb[NFTA_MATH_DREG] ||
    77		    !tb[NFTA_MATH_BITMASK] ||
    78		    !tb[NFTA_MATH_OP])
    79			return -EINVAL;
    80	
    81		op = nla_get_u32(tb[NFTA_MATH_OP]);
    82		if (op > NFT_MATH_OP_MAX)
    83			return -EOPNOTSUPP;
    84		priv->op = op;
    85	
    86		priv->bitmask = nla_get_u32(tb[NFTA_MATH_BITMASK]);
    87		if (!priv->bitmask)
    88			return -EINVAL;
    89	
    90		/* check if the bitmask is contiguous, otherwise reject it */
    91		bitmask_check = priv->bitmask + (priv->bitmask & -priv->bitmask);
    92		if (bitmask_check & (bitmask_check - 1))
    93			return -EINVAL;
    94	
  > 95		err = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,
    96					      sizeof(u32));
    97		if (err < 0)
    98			return err;
    99	
   100		return nft_parse_register_store(ctx, tb[NFTA_MATH_DREG],
   101						&priv->dreg, NULL, NFT_DATA_VALUE,
   102						sizeof(u32));
   103	}
   104	
   105	static int nft_math_dump(struct sk_buff *skb,
   106				 const struct nft_expr *expr, bool reset)
   107	{
   108		const struct nft_math *priv = nft_expr_priv(expr);
   109	
   110		if (nft_dump_register(skb, NFTA_MATH_SREG, priv->sreg))
   111			goto nla_put_failure;
   112		if (nft_dump_register(skb, NFTA_MATH_DREG, priv->dreg))
   113			goto nla_put_failure;
   114		if (nla_put_u32(skb, NFTA_MATH_BITMASK, priv->bitmask))
   115			goto nla_put_failure;
   116		if (nla_put_u32(skb, NFTA_MATH_OP, priv->op))
   117			goto nla_put_failure;
   118		return 0;
   119	
   120	nla_put_failure:
   121		return -1;
   122	}
   123	
   124	static struct nft_expr_type nft_math_type;
   125	static const struct nft_expr_ops nft_math_op = {
   126		.eval		= nft_math_eval,
   127		.size		= NFT_EXPR_SIZE(sizeof(struct nft_math)),
   128		.init		= nft_math_init,
 > 129		.dump		= nft_math_dump,
   130		.type		= &nft_math_type,
   131	};
   132	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

end of thread, other threads:[~2026-05-05  1:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-21 15:59 [PATCH nf-next v5] netfilter: nf_tables: add math expression support Fernando Fernandez Mancera
2026-04-26  3:57 ` kernel test robot
2026-04-27  7:26   ` Fernando Fernandez Mancera
2026-04-27  8:07     ` Florian Westphal
2026-04-27 14:07       ` Philip Li
2026-05-05  1:55 ` kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.