aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-02-01 12:49:00 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2018-02-02 12:26:42 -0500
commitc7f0030b5b67866c588845abde7bf011de25b98a (patch)
tree88aa5bcfc07581b764d8db201d356a541c92ead3
parentba7cd5d95f25cc6005f687dabdb4e7a6063adda9 (diff)
netfilter: nft_flow_offload: wait for garbage collector to run after cleanup
If netdevice goes down, then flowtable entries are scheduled to be removed. Wait for garbage collector to have a chance to run so it can delete them from the hashtable. The flush call might sleep, so hold the nfnl mutex from nft_flow_table_iterate() instead of rcu read side lock. The use of the nfnl mutex is also implicitly fixing races between updates via nfnetlink and netdevice event. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/nf_tables_api.c8
-rw-r--r--net/netfilter/nft_flow_offload.c1
2 files changed, 5 insertions, 4 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 0791813a1e7d..07dd1fac78a8 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5006,13 +5006,13 @@ void nft_flow_table_iterate(struct net *net,
5006 struct nft_flowtable *flowtable; 5006 struct nft_flowtable *flowtable;
5007 const struct nft_table *table; 5007 const struct nft_table *table;
5008 5008
5009 rcu_read_lock(); 5009 nfnl_lock(NFNL_SUBSYS_NFTABLES);
5010 list_for_each_entry_rcu(table, &net->nft.tables, list) { 5010 list_for_each_entry(table, &net->nft.tables, list) {
5011 list_for_each_entry_rcu(flowtable, &table->flowtables, list) { 5011 list_for_each_entry(flowtable, &table->flowtables, list) {
5012 iter(&flowtable->data, data); 5012 iter(&flowtable->data, data);
5013 } 5013 }
5014 } 5014 }
5015 rcu_read_unlock(); 5015 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
5016} 5016}
5017EXPORT_SYMBOL_GPL(nft_flow_table_iterate); 5017EXPORT_SYMBOL_GPL(nft_flow_table_iterate);
5018 5018
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index 4503b8dcf9c0..1739ff8ca21f 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -208,6 +208,7 @@ static void nft_flow_offload_iterate_cleanup(struct nf_flowtable *flowtable,
208 void *data) 208 void *data)
209{ 209{
210 nf_flow_table_iterate(flowtable, flow_offload_iterate_cleanup, data); 210 nf_flow_table_iterate(flowtable, flow_offload_iterate_cleanup, data);
211 flush_delayed_work(&flowtable->gc_work);
211} 212}
212 213
213static int flow_offload_netdev_event(struct notifier_block *this, 214static int flow_offload_netdev_event(struct notifier_block *this,