[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250522165238.378456-25-pablo@netfilter.org>
Date: Thu, 22 May 2025 18:52:36 +0200
From: Pablo Neira Ayuso <pablo@...filter.org>
To: netfilter-devel@...r.kernel.org
Cc: davem@...emloft.net,
netdev@...r.kernel.org,
kuba@...nel.org,
pabeni@...hat.com,
edumazet@...gle.com,
fw@...len.de,
horms@...nel.org
Subject: [PATCH net-next 24/26] netfilter: nf_tables: Support wildcard netdev hook specs
From: Phil Sutter <phil@....cc>
User space may pass non-nul-terminated NFTA_DEVICE_NAME attribute values
to indicate a suffix wildcard.
Expect for multiple devices to match the given prefix in
nft_netdev_hook_alloc() and populate 'ops_list' with them all.
When checking for duplicate hooks, compare the shortest prefix so a
device may never match more than a single hook spec.
Finally respect the stored prefix length when hooking into new devices
from event handlers.
Signed-off-by: Phil Sutter <phil@....cc>
Signed-off-by: Pablo Neira Ayuso <pablo@...filter.org>
---
net/netfilter/nf_tables_api.c | 29 ++++++++++++++---------------
net/netfilter/nft_chain_filter.c | 2 +-
2 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index fabc82c98871..a7240736f98e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2330,24 +2330,22 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net,
* indirectly serializing all the other holders of the commit_mutex with
* the rtnl_mutex.
*/
- dev = __dev_get_by_name(net, hook->ifname);
- if (!dev) {
- err = -ENOENT;
- goto err_hook_free;
- }
+ for_each_netdev(net, dev) {
+ if (strncmp(dev->name, hook->ifname, hook->ifnamelen))
+ continue;
- ops = kzalloc(sizeof(struct nf_hook_ops), GFP_KERNEL_ACCOUNT);
- if (!ops) {
- err = -ENOMEM;
- goto err_hook_free;
+ ops = kzalloc(sizeof(struct nf_hook_ops), GFP_KERNEL_ACCOUNT);
+ if (!ops) {
+ err = -ENOMEM;
+ goto err_hook_free;
+ }
+ ops->dev = dev;
+ list_add_tail(&ops->list, &hook->ops_list);
}
- ops->dev = dev;
- list_add_tail(&ops->list, &hook->ops_list);
-
return hook;
err_hook_free:
- kfree(hook);
+ nft_netdev_hook_free(hook);
return ERR_PTR(err);
}
@@ -2357,7 +2355,8 @@ static struct nft_hook *nft_hook_list_find(struct list_head *hook_list,
struct nft_hook *hook;
list_for_each_entry(hook, hook_list, list) {
- if (!strcmp(hook->ifname, this->ifname))
+ if (!strncmp(hook->ifname, this->ifname,
+ min(hook->ifnamelen, this->ifnamelen)))
return hook;
}
@@ -9696,7 +9695,7 @@ static int nft_flowtable_event(unsigned long event, struct net_device *dev,
list_for_each_entry(hook, &flowtable->hook_list, list) {
ops = nft_hook_find_ops(hook, dev);
- match = !strcmp(hook->ifname, dev->name);
+ match = !strncmp(hook->ifname, dev->name, hook->ifnamelen);
switch (event) {
case NETDEV_UNREGISTER:
diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c
index b59f8be6370e..b16185e9a6dd 100644
--- a/net/netfilter/nft_chain_filter.c
+++ b/net/netfilter/nft_chain_filter.c
@@ -328,7 +328,7 @@ static int nft_netdev_event(unsigned long event, struct net_device *dev,
list_for_each_entry(hook, &basechain->hook_list, list) {
ops = nft_hook_find_ops(hook, dev);
- match = !strcmp(hook->ifname, dev->name);
+ match = !strncmp(hook->ifname, dev->name, hook->ifnamelen);
switch (event) {
case NETDEV_UNREGISTER:
--
2.30.2
Powered by blists - more mailing lists