Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2225809/?format=api
{ "id": 2225809, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2225809/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260421155859.7049-2-fmancera@suse.de/", "project": { "id": 26, "url": "http://patchwork.ozlabs.org/api/1.1/projects/26/?format=api", "name": "Netfilter Development", "link_name": "netfilter-devel", "list_id": "netfilter-devel.vger.kernel.org", "list_email": "netfilter-devel@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null }, "msgid": "<20260421155859.7049-2-fmancera@suse.de>", "date": "2026-04-21T15:59:00", "name": "[nf-next,v5] netfilter: nf_tables: add math expression support", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "8d66a5c9748af331a035ffbfc8ea042099a5e76a", "submitter": { "id": 90904, "url": "http://patchwork.ozlabs.org/api/1.1/people/90904/?format=api", "name": "Fernando Fernandez Mancera", "email": "fmancera@suse.de" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260421155859.7049-2-fmancera@suse.de/mbox/", "series": [ { "id": 500846, "url": "http://patchwork.ozlabs.org/api/1.1/series/500846/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/list/?series=500846", "date": "2026-04-21T15:59:00", "name": "[nf-next,v5] netfilter: nf_tables: add math expression support", "version": 5, "mbox": "http://patchwork.ozlabs.org/series/500846/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2225809/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2225809/checks/", "tags": {}, "headers": { "Return-Path": "\n <netfilter-devel+bounces-12112-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "netfilter-devel@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256\n header.s=susede2_rsa header.b=Y8EHpmLx;\n\tdkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=u5nE6djo;\n\tdkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de\n header.a=rsa-sha256 header.s=susede2_rsa header.b=Y8EHpmLx;\n\tdkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256\n header.s=susede2_ed25519 header.b=u5nE6djo;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=netfilter-devel+bounces-12112-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de\n header.b=\"Y8EHpmLx\";\n\tdkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de\n header.b=\"u5nE6djo\";\n\tdkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de\n header.b=\"Y8EHpmLx\";\n\tdkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de\n header.b=\"u5nE6djo\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=195.135.223.130", "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=suse.de", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=suse.de", "smtp-out1.suse.de;\n\tnone" ], "Received": [ "from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0S594Btfz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 02:10:53 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 96654305FC12\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 15:59:55 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 56DC236309E;\n\tTue, 21 Apr 2026 15:59:47 +0000 (UTC)", "from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A2A736308D\n\tfor <netfilter-devel@vger.kernel.org>; Tue, 21 Apr 2026 15:59:44 +0000 (UTC)", "from imap1.dmz-prg2.suse.org (unknown [10.150.64.97])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby smtp-out1.suse.de (Postfix) with ESMTPS id 5D4376A7EC;\n\tTue, 21 Apr 2026 15:59:43 +0000 (UTC)", "from imap1.dmz-prg2.suse.org (localhost [127.0.0.1])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id E870B593AF;\n\tTue, 21 Apr 2026 15:59:42 +0000 (UTC)", "from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167])\n\tby imap1.dmz-prg2.suse.org with ESMTPSA\n\tid LkOuNe6e52mtJAAAD6G6ig\n\t(envelope-from <fmancera@suse.de>); Tue, 21 Apr 2026 15:59:42 +0000" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776787186; cv=none;\n b=urNBHE6a7WC7zGxKX3DVXRLtuigyYFpXSnxsujxHSYEeCvsJv30pzO5dLYSR+KGx7OmW8AookEyllc48hiaoAS8Jgde4n4UJ7FlRAUySPGHqga0X8bnV+LWFkMfoy4ks11nx88rY+vUBLJB/q7dVxVeDBGRsTtQRX8eFOVYmNEQ=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776787186; c=relaxed/simple;\n\tbh=zPE3UKhhk/EVnndzgkhk+hRJsvyTe75LjsDZeWukCrA=;\n\th=From:To:Cc:Subject:Date:Message-ID:MIME-Version;\n b=TlnKRGLblwjrVOUVsTP+w8bGI5KkOxKpxhgsZ2ns3jxS02e3gYuqRbtXBfA7k2WqaYEQEeoMtxBbdH0phoaSnhPBQ/CAFtOWnibpldhVBL7iXN0ZZZkxPPsly65l4b5gyWAPAwaaqcX6wn+QlQm8EAA94TwwPsC0WGP10SgBM+w=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=suse.de;\n spf=pass smtp.mailfrom=suse.de;\n dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de\n header.b=Y8EHpmLx;\n dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de\n header.b=u5nE6djo;\n dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de\n header.b=Y8EHpmLx;\n dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de\n header.b=u5nE6djo; arc=none smtp.client-ip=195.135.223.130", "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_rsa;\n\tt=1776787183;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n\t mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding;\n\tbh=gOYUMpySdcb9AwbtQbqy2D5TlPD3Oke7iB6OguMfQAI=;\n\tb=Y8EHpmLxajrwS7qHcypv7HAGw85trUKVghzJACFJP8TVP8GGTG6NWZKBwflCgPZEK6VmjI\n\tfPOxkQk+7w6kNueqpcZo6bb3Yign6t2fHGIKZpgUtrh01ZK26aB0nX65QqwZbibj6HqyOi\n\tMpwd9dXuETxkkb/KxQkSefw0zGCraok=", "v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de;\n\ts=susede2_ed25519; t=1776787183;\n\th=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n\t mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding;\n\tbh=gOYUMpySdcb9AwbtQbqy2D5TlPD3Oke7iB6OguMfQAI=;\n\tb=u5nE6djodfwv88JyxY+o6oVOXxSfC7K1WnCMmocWtSaz1xyE7C0HMLV8Si2YrXxN8neq+S\n\thqf735jthCWo62DA==", "v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de;\n s=susede2_rsa;\n\tt=1776787183;\n h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n\t mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding;\n\tbh=gOYUMpySdcb9AwbtQbqy2D5TlPD3Oke7iB6OguMfQAI=;\n\tb=Y8EHpmLxajrwS7qHcypv7HAGw85trUKVghzJACFJP8TVP8GGTG6NWZKBwflCgPZEK6VmjI\n\tfPOxkQk+7w6kNueqpcZo6bb3Yign6t2fHGIKZpgUtrh01ZK26aB0nX65QqwZbibj6HqyOi\n\tMpwd9dXuETxkkb/KxQkSefw0zGCraok=", "v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de;\n\ts=susede2_ed25519; t=1776787183;\n\th=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc:\n\t mime-version:mime-version:\n content-transfer-encoding:content-transfer-encoding;\n\tbh=gOYUMpySdcb9AwbtQbqy2D5TlPD3Oke7iB6OguMfQAI=;\n\tb=u5nE6djodfwv88JyxY+o6oVOXxSfC7K1WnCMmocWtSaz1xyE7C0HMLV8Si2YrXxN8neq+S\n\thqf735jthCWo62DA==" ], "From": "Fernando Fernandez Mancera <fmancera@suse.de>", "To": "netfilter-devel@vger.kernel.org", "Cc": "coreteam@netfilter.org,\n\tphil@nwl.cc,\n\tfw@strlen.de,\n\tpablo@netfilter.org,\n\tFernando Fernandez Mancera <fmancera@suse.de>", "Subject": "[PATCH nf-next v5] netfilter: nf_tables: add math expression support", "Date": "Tue, 21 Apr 2026 17:59:00 +0200", "Message-ID": "<20260421155859.7049-2-fmancera@suse.de>", "X-Mailer": "git-send-email 2.51.0", "Precedence": "bulk", "X-Mailing-List": "netfilter-devel@vger.kernel.org", "List-Id": "<netfilter-devel.vger.kernel.org>", "List-Subscribe": "<mailto:netfilter-devel+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:netfilter-devel+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Spamd-Result": "default: False [-2.80 / 50.00];\n\tBAYES_HAM(-3.00)[100.00%];\n\tMID_CONTAINS_FROM(1.00)[];\n\tNEURAL_HAM_LONG(-1.00)[-1.000];\n\tR_MISSING_CHARSET(0.50)[];\n\tNEURAL_HAM_SHORT(-0.20)[-1.000];\n\tMIME_GOOD(-0.10)[text/plain];\n\tRCVD_VIA_SMTP_AUTH(0.00)[];\n\tMIME_TRACE(0.00)[0:+];\n\tTO_DN_SOME(0.00)[];\n\tARC_NA(0.00)[];\n\tFUZZY_RATELIMITED(0.00)[rspamd.com];\n\tDKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519];\n\tTO_MATCH_ENVRCPT_ALL(0.00)[];\n\tFROM_HAS_DN(0.00)[];\n\tRCPT_COUNT_FIVE(0.00)[6];\n\tFROM_EQ_ENVFROM(0.00)[];\n\tRCVD_COUNT_TWO(0.00)[2];\n\tRCVD_TLS_ALL(0.00)[]", "X-Spam-Flag": "NO", "X-Spam-Score": "-2.80", "X-Spam-Level": "" }, "content": "Historically, users have requested support for increasing and decreasing\nTTL value in nftables in order to migrate from iptables.\n\nFollowing the nftables spirit of flexible and multipurpose expressions,\nthis patch introduces \"nft_math\" expression. This expression allows to\nincrease and decrease values stored in the register.\n\nThe math expression intends to be flexible enough in case it needs to be\nextended in the future, e.g implement non-contiguous bitfields\noperations. But for now, non-contiguous payloads are not supported.\n\nWhen loading a u8 or u16 payload into a register we don't know if the\nvalue is stored at least significant byte or most significant byte. In\norder to handle such cases, introduce a bitmask indicating what is the\ntarget bit and also use it to handle limits to prevent overflow or\nunderflow. Keep in mind that math expression expects that the sreg and\ndreg are in host byteorder, so the user must use nft_byteorder\nexpressions as needed.\n\nThis implementation comes with a libnftnl patch that allows the user to\ngenerate the following example bytecodes:\n\n- Bytecode to increase the TTL of a packet\n\ntable filter inet flags 0 use 1 handle 1\ninet filter input use 1 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1\ninet filter input 4\n [ payload load 2b @ network header + 8 => reg 1 ]\n [ math mask 0x000000ff reg 1 + 1 => 1]\n [ payload write reg 1 => 2b @ network header + 8 csum_type 1 csum_off 10 csum_flags 0x0 ]\n\n- Bytecode to decrease the TTL of a packet\n\ntable filter inet flags 0 use 1 handle 1\ninet filter input use 1 type filter hook input prio 0 policy accept packets 0 bytes 0 flags 1\ninet filter input 4\n [ payload load 2b @ network header + 8 => reg 1 ]\n [ math mask 0x000000ff reg 1 - 1 => 1]\n [ payload write reg 1 => 2b @ network header + 8 csum_type 1 csum_off 10 csum_flags 0x0 ]\n\n- Bytecode to increase the meta mark of a packet\n\ntable mangle inet flags 0 use 1 handle 6\ninet mangle output use 1 type filter hook output prio 0 policy accept packets 0 bytes 0 flags 1\ninet mangle output 2\n [ meta load mark => reg 1 ]\n [ math mask 0xffffffff reg 1 + 1 => 1]\n [ meta set mark with reg 1 ]\n\nSigned-off-by: Fernando Fernandez Mancera <fmancera@suse.de>\n---\nv2: dropped the byteorder netlink attribute, added bitmask to handle\nLSB/MSB when dealing with u8 and u16, simplified eval logic. I've kept\nnft_math as module, IMHO it would be too much to make it built-in.\nv3: fixed checkpatch warnings, improved Kconfig description and fixed a\nwrong EINVAL return.\nv4: removed NFTA_MATH_LEN as discussed with Phil, added a non-contiguous\nbitmask check\nv5: fixed check on op max value, fixed byteorder inconsistency now\nNLA_U32 for both BITMASK and OP attributes\n---\n include/uapi/linux/netfilter/nf_tables.h | 25 ++++\n net/netfilter/Kconfig | 9 ++\n net/netfilter/Makefile | 1 +\n net/netfilter/nft_math.c | 157 +++++++++++++++++++++++\n 4 files changed, 192 insertions(+)\n create mode 100644 net/netfilter/nft_math.c", "diff": "diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h\nindex 0b708153469c..36a5b42c3ddf 100644\n--- a/include/uapi/linux/netfilter/nf_tables.h\n+++ b/include/uapi/linux/netfilter/nf_tables.h\n@@ -2019,4 +2019,29 @@ enum nft_tunnel_attributes {\n };\n #define NFTA_TUNNEL_MAX\t(__NFTA_TUNNEL_MAX - 1)\n \n+/**\n+ * enum nft_math_attributes - nftables math expression netlink attributes\n+ *\n+ * @NFTA_MATH_SREG: source register (NLA_U32: nft_registers)\n+ * @NFTA_MATH_DREG: destination register (NLA_U32: nft_registers)\n+ * @NFTA_MATH_OP: operation to be performed (NLA_U32)\n+ * @NFTA_MATH_BITMASK: bitmask to be applied on the operation (NLA_U32)\n+ */\n+enum nft_math_attributes {\n+\tNFTA_MATH_UNSPEC,\n+\tNFTA_MATH_SREG,\n+\tNFTA_MATH_DREG,\n+\tNFTA_MATH_OP,\n+\tNFTA_MATH_BITMASK,\n+\t__NFTA_MATH_MAX,\n+};\n+#define NFTA_MATH_MAX (__NFTA_MATH_MAX - 1)\n+\n+enum nft_math_op {\n+\tNFT_MATH_OP_INC,\n+\tNFT_MATH_OP_DEC,\n+\t__NFT_MATH_OP_MAX,\n+};\n+#define NFT_MATH_OP_MAX (__NFT_MATH_OP_MAX - 1)\n+\n #endif /* _LINUX_NF_TABLES_H */\ndiff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig\nindex f3ea0cb26f36..49e723f0dcc8 100644\n--- a/net/netfilter/Kconfig\n+++ b/net/netfilter/Kconfig\n@@ -667,6 +667,15 @@ config NFT_SYNPROXY\n \t server. This allows to avoid conntrack and server resource usage\n \t during SYN-flood attacks.\n \n+config NFT_MATH\n+\ttristate \"Netfilter nf_tables math expression support\"\n+\tdepends on NETFILTER_ADVANCED\n+\thelp\n+\t This option enables support for the nftables math expression.\n+\t It allows arithmetic operations to be performed on nft registers\n+\t content, such as incrementing or decrementing values. Math\n+\t expressions can be used in nftables rules to modify packet fields.\n+\n if NF_TABLES_NETDEV\n \n config NF_DUP_NETDEV\ndiff --git a/net/netfilter/Makefile b/net/netfilter/Makefile\nindex 6bfc250e474f..fe25b1d1ce0a 100644\n--- a/net/netfilter/Makefile\n+++ b/net/netfilter/Makefile\n@@ -131,6 +131,7 @@ obj-$(CONFIG_NFT_OSF)\t\t+= nft_osf.o\n obj-$(CONFIG_NFT_TPROXY)\t+= nft_tproxy.o\n obj-$(CONFIG_NFT_XFRM)\t\t+= nft_xfrm.o\n obj-$(CONFIG_NFT_SYNPROXY)\t+= nft_synproxy.o\n+obj-$(CONFIG_NFT_MATH)\t\t+= nft_math.o\n \n obj-$(CONFIG_NFT_NAT)\t\t+= nft_chain_nat.o\n \ndiff --git a/net/netfilter/nft_math.c b/net/netfilter/nft_math.c\nnew file mode 100644\nindex 000000000000..87dc4ec801d8\n--- /dev/null\n+++ b/net/netfilter/nft_math.c\n@@ -0,0 +1,157 @@\n+// SPDX-License-Identifier: GPL-2.0\n+\n+#include <net/netlink.h>\n+#include <net/netfilter/nf_tables.h>\n+\n+struct nft_math {\n+\tu8\t\t\tsreg;\n+\tu8\t\t\tdreg;\n+\tu32\t\t\tbitmask;\n+\tenum nft_math_op\top;\n+};\n+\n+static const struct nla_policy nft_math_policy[NFTA_MATH_MAX + 1] = {\n+\t[NFTA_MATH_SREG]\t= { .type = NLA_U32 },\n+\t[NFTA_MATH_DREG]\t= { .type = NLA_U32 },\n+\t[NFTA_MATH_OP]\t\t= { .type = NLA_U32 },\n+\t[NFTA_MATH_BITMASK]\t= { .type = NLA_U32 },\n+};\n+\n+static void nft_math_eval_bitmask(u32 *src, u32 *dst,\n+\t\t\t\t const struct nft_math *priv)\n+{\n+\tu32 target, keep, bit_unit;\n+\n+\ttarget = *src & priv->bitmask;\n+\tkeep = *src & ~priv->bitmask;\n+\tbit_unit = priv->bitmask & -priv->bitmask;\n+\n+\tswitch (priv->op) {\n+\tcase NFT_MATH_OP_INC:\n+\t\tif (target == priv->bitmask) {\n+\t\t\t*dst = *src;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\ttarget = target + bit_unit;\n+\t\t*dst = target | keep;\n+\t\tbreak;\n+\tcase NFT_MATH_OP_DEC:\n+\t\tif (!target) {\n+\t\t\t*dst = *src;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\ttarget = target - bit_unit;\n+\t\t*dst = target | keep;\n+\t\tbreak;\n+\tdefault:\n+\t\tDEBUG_NET_WARN_ONCE(true, \"unknown operation path in nft_math\");\n+\t\t*dst = *src;\n+\t\tbreak;\n+\t}\n+}\n+\n+static void nft_math_eval(const struct nft_expr *expr,\n+\t\t\t struct nft_regs *regs,\n+\t\t\t const struct nft_pktinfo *pkt)\n+{\n+\tconst struct nft_math *priv = nft_expr_priv(expr);\n+\tu32 *src = ®s->data[priv->sreg];\n+\tu32 *dst = ®s->data[priv->dreg];\n+\n+\tnft_math_eval_bitmask(src, dst, priv);\n+}\n+\n+static int nft_math_init(const struct nft_ctx *ctx,\n+\t\t\t const struct nft_expr *expr,\n+\t\t\t const struct nlattr * const tb[])\n+{\n+\tstruct nft_math *priv = nft_expr_priv(expr);\n+\tu32 bitmask_check;\n+\tint err;\n+\tu32 op;\n+\n+\tif (!tb[NFTA_MATH_SREG] ||\n+\t !tb[NFTA_MATH_DREG] ||\n+\t !tb[NFTA_MATH_BITMASK] ||\n+\t !tb[NFTA_MATH_OP])\n+\t\treturn -EINVAL;\n+\n+\top = nla_get_u32(tb[NFTA_MATH_OP]);\n+\tif (op > NFT_MATH_OP_MAX)\n+\t\treturn -EOPNOTSUPP;\n+\tpriv->op = op;\n+\n+\tpriv->bitmask = nla_get_u32(tb[NFTA_MATH_BITMASK]);\n+\tif (!priv->bitmask)\n+\t\treturn -EINVAL;\n+\n+\t/* check if the bitmask is contiguous, otherwise reject it */\n+\tbitmask_check = priv->bitmask + (priv->bitmask & -priv->bitmask);\n+\tif (bitmask_check & (bitmask_check - 1))\n+\t\treturn -EINVAL;\n+\n+\terr = nft_parse_register_load(ctx, tb[NFTA_MATH_SREG], &priv->sreg,\n+\t\t\t\t sizeof(u32));\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\treturn nft_parse_register_store(ctx, tb[NFTA_MATH_DREG],\n+\t\t\t\t\t&priv->dreg, NULL, NFT_DATA_VALUE,\n+\t\t\t\t\tsizeof(u32));\n+}\n+\n+static int nft_math_dump(struct sk_buff *skb,\n+\t\t\t const struct nft_expr *expr, bool reset)\n+{\n+\tconst struct nft_math *priv = nft_expr_priv(expr);\n+\n+\tif (nft_dump_register(skb, NFTA_MATH_SREG, priv->sreg))\n+\t\tgoto nla_put_failure;\n+\tif (nft_dump_register(skb, NFTA_MATH_DREG, priv->dreg))\n+\t\tgoto nla_put_failure;\n+\tif (nla_put_u32(skb, NFTA_MATH_BITMASK, priv->bitmask))\n+\t\tgoto nla_put_failure;\n+\tif (nla_put_u32(skb, NFTA_MATH_OP, priv->op))\n+\t\tgoto nla_put_failure;\n+\treturn 0;\n+\n+nla_put_failure:\n+\treturn -1;\n+}\n+\n+static struct nft_expr_type nft_math_type;\n+static const struct nft_expr_ops nft_math_op = {\n+\t.eval\t\t= nft_math_eval,\n+\t.size\t\t= NFT_EXPR_SIZE(sizeof(struct nft_math)),\n+\t.init\t\t= nft_math_init,\n+\t.dump\t\t= nft_math_dump,\n+\t.type\t\t= &nft_math_type,\n+};\n+\n+static struct nft_expr_type nft_math_type __read_mostly = {\n+\t.ops\t\t= &nft_math_op,\n+\t.name\t\t= \"math\",\n+\t.owner\t\t= THIS_MODULE,\n+\t.policy\t\t= nft_math_policy,\n+\t.maxattr\t= NFTA_MATH_MAX,\n+};\n+\n+static int __init nft_math_module_init(void)\n+{\n+\treturn nft_register_expr(&nft_math_type);\n+}\n+\n+static void __exit nft_math_module_exit(void)\n+{\n+\tnft_unregister_expr(&nft_math_type);\n+}\n+\n+module_init(nft_math_module_init);\n+module_exit(nft_math_module_exit);\n+\n+MODULE_LICENSE(\"GPL\");\n+MODULE_AUTHOR(\"Fernando Fernandez Mancera <fmancera@suse.de>\");\n+MODULE_ALIAS_NFT_EXPR(\"math\");\n+MODULE_DESCRIPTION(\"nftables math support to operate with values\");\n", "prefixes": [ "nf-next", "v5" ] }