All of lore.kernel.org
 help / color / mirror / Atom feed
From: Phil Sutter <phil@nwl.cc>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: [nft PATCH v5 1/3] mnl: Support simple wildcards in netdev hooks
Date: Fri,  1 Aug 2025 00:29:43 +0200	[thread overview]
Message-ID: <20250731222945.27611-2-phil@nwl.cc> (raw)
In-Reply-To: <20250731222945.27611-1-phil@nwl.cc>

When building NFTA_{FLOWTABLE_,}HOOK_DEVS attributes, detect trailing
asterisks in interface names and transmit the leading part in a
NFTA_DEVICE_PREFIX attribute.

Deserialization (i.e., appending asterisk to interface prefixes returned
in NFTA_DEVICE_PREFIX atributes happens in libnftnl.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v4:
- Introduce and use NFTA_DEVICE_PREFIX which contains a NUL-terminated
  string as well but signals the kernel to interpret it as a prefix to
  match interfaces on.
- Do not send wildcards in NFTA_HOOK_DEV: On one hand, the kernel can't
  detect them anymore since they are NUL-terminated as well. On the
  other, it would defeat the purpose of having NFTA_DEVICE_PREFIX, which
  is to not crash old user space.

Changes since v3:
- Use uint16_t for 'attr' parameter and size_t for 'len' variable
- Use mnl_nft_ prefix for the helper function

Changes since v2:
- Introduce mnl_attr_put_ifname() to perform the conditional
  mnl_attr_put() parameter adjustment
- Sanity-check array index in above function to avoid out-of-bounds
  access
---
 include/linux/netfilter/nf_tables.h |  2 ++
 src/mnl.c                           | 26 +++++++++++++++++++++++---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index f57963e89fd16..b38d4780ae8c8 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1774,10 +1774,12 @@ enum nft_synproxy_attributes {
  * enum nft_device_attributes - nf_tables device netlink attributes
  *
  * @NFTA_DEVICE_NAME: name of this device (NLA_STRING)
+ * @NFTA_DEVICE_PREFIX: device name prefix, a simple wildcard (NLA_STRING)
  */
 enum nft_devices_attributes {
 	NFTA_DEVICE_UNSPEC,
 	NFTA_DEVICE_NAME,
+	NFTA_DEVICE_PREFIX,
 	__NFTA_DEVICE_MAX
 };
 #define NFTA_DEVICE_MAX		(__NFTA_DEVICE_MAX - 1)
diff --git a/src/mnl.c b/src/mnl.c
index 43229f2498e55..b532b8ff00c1e 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -795,6 +795,26 @@ static void nft_dev_array_free(const struct nft_dev *dev_array)
 	free_const(dev_array);
 }
 
+static bool is_wildcard_str(const char *str)
+{
+	size_t len = strlen(str);
+
+	if (len < 1 || str[len - 1] != '*')
+		return false;
+	if (len < 2 || str[len - 2] != '\\')
+		return true;
+	/* XXX: ignore backslash escaping for now */
+	return false;
+}
+
+static void mnl_nft_attr_put_ifname(struct nlmsghdr *nlh, const char *ifname)
+{
+	uint16_t attr = is_wildcard_str(ifname) ?
+			NFTA_DEVICE_PREFIX : NFTA_DEVICE_NAME;
+
+	mnl_attr_put_strz(nlh, attr, ifname);
+}
+
 static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
 {
 	const struct expr *dev_expr = cmd->chain->dev_expr;
@@ -803,14 +823,14 @@ static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
 	int i, num_devs = 0;
 
 	dev_array = nft_dev_array(dev_expr, &num_devs);
-	if (num_devs == 1) {
+	if (num_devs == 1 && !is_wildcard_str(dev_array[0].ifname)) {
 		cmd_add_loc(cmd, nlh, dev_array[0].location);
 		mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, dev_array[0].ifname);
 	} else {
 		nest_dev = mnl_attr_nest_start(nlh, NFTA_HOOK_DEVS);
 		for (i = 0; i < num_devs; i++) {
 			cmd_add_loc(cmd, nlh, dev_array[i].location);
-			mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+			mnl_nft_attr_put_ifname(nlh, dev_array[i].ifname);
 		}
 		mnl_attr_nest_end(nlh, nest_dev);
 	}
@@ -2091,7 +2111,7 @@ static void mnl_nft_ft_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
 	nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS);
 	for (i = 0; i < num_devs; i++) {
 		cmd_add_loc(cmd, nlh, dev_array[i].location);
-		mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+		mnl_nft_attr_put_ifname(nlh, dev_array[i].ifname);
 	}
 
 	mnl_attr_nest_end(nlh, nest_dev);
-- 
2.49.0


  reply	other threads:[~2025-07-31 22:29 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-31 22:29 [nft PATCH v5 0/3] Support wildcard netdev hooks Phil Sutter
2025-07-31 22:29 ` Phil Sutter [this message]
2025-09-04 15:16   ` [nft PATCH v5 1/3] mnl: Support simple wildcards in " Pablo Neira Ayuso
2025-09-04 22:27     ` Phil Sutter
2025-09-05 11:20       ` Pablo Neira Ayuso
2025-09-30 21:06         ` Phil Sutter
2025-07-31 22:29 ` [nft PATCH v5 2/3] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member Phil Sutter
2025-09-04 15:20   ` Pablo Neira Ayuso
2025-09-04 22:29     ` Phil Sutter
2025-07-31 22:29 ` [nft PATCH v5 3/3] tests: shell: Test ifname-based hooks Phil Sutter

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=20250731222945.27611-2-phil@nwl.cc \
    --to=phil@nwl.cc \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /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 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.