OpenWrt – Blame information for rev 3
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From: Pablo Neira Ayuso <pablo@netfilter.org> |
2 | Date: Thu, 1 Feb 2018 18:49:00 +0100 |
||
3 | Subject: [PATCH] netfilter: nft_flow_offload: wait for garbage collector |
||
4 | to run after cleanup |
||
5 | |||
6 | If netdevice goes down, then flowtable entries are scheduled to be |
||
7 | removed. Wait for garbage collector to have a chance to run so it can |
||
8 | delete them from the hashtable. |
||
9 | |||
10 | The flush call might sleep, so hold the nfnl mutex from |
||
11 | nft_flow_table_iterate() instead of rcu read side lock. The use of the |
||
12 | nfnl mutex is also implicitly fixing races between updates via nfnetlink |
||
13 | and netdevice event. |
||
14 | |||
15 | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
||
16 | --- |
||
17 | |||
18 | --- a/net/netfilter/nf_tables_api.c |
||
19 | +++ b/net/netfilter/nf_tables_api.c |
||
3 | office | 20 | @@ -4869,13 +4869,13 @@ void nft_flow_table_iterate(struct net * |
1 | office | 21 | struct nft_flowtable *flowtable; |
22 | const struct nft_table *table; |
||
23 | |||
24 | - rcu_read_lock(); |
||
25 | - list_for_each_entry_rcu(table, &net->nft.tables, list) { |
||
26 | - list_for_each_entry_rcu(flowtable, &table->flowtables, list) { |
||
27 | + nfnl_lock(NFNL_SUBSYS_NFTABLES); |
||
28 | + list_for_each_entry(table, &net->nft.tables, list) { |
||
29 | + list_for_each_entry(flowtable, &table->flowtables, list) { |
||
30 | iter(&flowtable->data, data); |
||
31 | } |
||
32 | } |
||
33 | - rcu_read_unlock(); |
||
34 | + nfnl_unlock(NFNL_SUBSYS_NFTABLES); |
||
35 | } |
||
36 | EXPORT_SYMBOL_GPL(nft_flow_table_iterate); |
||
37 | |||
38 | --- a/net/netfilter/nft_flow_offload.c |
||
39 | +++ b/net/netfilter/nft_flow_offload.c |
||
40 | @@ -208,6 +208,7 @@ static void nft_flow_offload_iterate_cle |
||
41 | void *data) |
||
42 | { |
||
43 | nf_flow_table_iterate(flowtable, flow_offload_iterate_cleanup, data); |
||
44 | + flush_delayed_work(&flowtable->gc_work); |
||
45 | } |
||
46 | |||
47 | static int flow_offload_netdev_event(struct notifier_block *this, |