netfilter: flowtable: check namespace before iterating flows

nf_flow_table_cleanup() walks every registered flow table, checking the
network namespace for each flow in nf_flow_table_do_cleanup(). As a
result, tables in other namespaces are still iterated and their cleanup
work is flushed.

Compare the flow table's namespace with the device's namespace in
nf_flow_table_cleanup() and skip nonmatching tables. This avoids
unnecessary iteration and work flushing, and leaves the per-flow cleanup
callback to check only the interface index.

Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Qingfang Deng 2026-09-09 16:17:04 +08:00 committed by Pablo Neira Ayuso
parent d4548625f3
commit c48fdf027a

View File

@ -737,14 +737,9 @@ static void nf_flow_table_do_cleanup(struct nf_flowtable *flow_table,
{
struct net_device *dev = data;
if (!dev) {
flow_offload_teardown(flow);
return;
}
if (net_eq(nf_ct_net(flow->ct), dev_net(dev)) &&
(flow->tuplehash[0].tuple.iifidx == dev->ifindex ||
flow->tuplehash[1].tuple.iifidx == dev->ifindex))
if (!dev ||
flow->tuplehash[0].tuple.iifidx == dev->ifindex ||
flow->tuplehash[1].tuple.iifidx == dev->ifindex)
flow_offload_teardown(flow);
}
@ -761,8 +756,10 @@ void nf_flow_table_cleanup(struct net_device *dev)
struct nf_flowtable *flowtable;
mutex_lock(&flowtable_lock);
list_for_each_entry(flowtable, &flowtables, list)
nf_flow_table_gc_cleanup(flowtable, dev);
list_for_each_entry(flowtable, &flowtables, list) {
if (net_eq(read_pnet(&flowtable->net), dev_net(dev)))
nf_flow_table_gc_cleanup(flowtable, dev);
}
mutex_unlock(&flowtable_lock);
}
EXPORT_SYMBOL_GPL(nf_flow_table_cleanup);