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
next prev parent 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.