Skip to content

Commit 6d07a28

Browse files
Phil Sutterummakynes
authored andcommitted
netfilter: nf_tables: Support wildcard netdev hook specs
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 <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 6f67093 commit 6d07a28

File tree

2 files changed

+15
-16
lines changed

2 files changed

+15
-16
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2330,24 +2330,22 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net,
23302330
* indirectly serializing all the other holders of the commit_mutex with
23312331
* the rtnl_mutex.
23322332
*/
2333-
dev = __dev_get_by_name(net, hook->ifname);
2334-
if (!dev) {
2335-
err = -ENOENT;
2336-
goto err_hook_free;
2337-
}
2333+
for_each_netdev(net, dev) {
2334+
if (strncmp(dev->name, hook->ifname, hook->ifnamelen))
2335+
continue;
23382336

2339-
ops = kzalloc(sizeof(struct nf_hook_ops), GFP_KERNEL_ACCOUNT);
2340-
if (!ops) {
2341-
err = -ENOMEM;
2342-
goto err_hook_free;
2337+
ops = kzalloc(sizeof(struct nf_hook_ops), GFP_KERNEL_ACCOUNT);
2338+
if (!ops) {
2339+
err = -ENOMEM;
2340+
goto err_hook_free;
2341+
}
2342+
ops->dev = dev;
2343+
list_add_tail(&ops->list, &hook->ops_list);
23432344
}
2344-
ops->dev = dev;
2345-
list_add_tail(&ops->list, &hook->ops_list);
2346-
23472345
return hook;
23482346

23492347
err_hook_free:
2350-
kfree(hook);
2348+
nft_netdev_hook_free(hook);
23512349
return ERR_PTR(err);
23522350
}
23532351

@@ -2357,7 +2355,8 @@ static struct nft_hook *nft_hook_list_find(struct list_head *hook_list,
23572355
struct nft_hook *hook;
23582356

23592357
list_for_each_entry(hook, hook_list, list) {
2360-
if (!strcmp(hook->ifname, this->ifname))
2358+
if (!strncmp(hook->ifname, this->ifname,
2359+
min(hook->ifnamelen, this->ifnamelen)))
23612360
return hook;
23622361
}
23632362

@@ -9696,7 +9695,7 @@ static int nft_flowtable_event(unsigned long event, struct net_device *dev,
96969695

96979696
list_for_each_entry(hook, &flowtable->hook_list, list) {
96989697
ops = nft_hook_find_ops(hook, dev);
9699-
match = !strcmp(hook->ifname, dev->name);
9698+
match = !strncmp(hook->ifname, dev->name, hook->ifnamelen);
97009699

97019700
switch (event) {
97029701
case NETDEV_UNREGISTER:

net/netfilter/nft_chain_filter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ static int nft_netdev_event(unsigned long event, struct net_device *dev,
328328

329329
list_for_each_entry(hook, &basechain->hook_list, list) {
330330
ops = nft_hook_find_ops(hook, dev);
331-
match = !strcmp(hook->ifname, dev->name);
331+
match = !strncmp(hook->ifname, dev->name, hook->ifnamelen);
332332

333333
switch (event) {
334334
case NETDEV_UNREGISTER:

0 commit comments

Comments
 (0)