diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-10-24 10:30:19 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-10-26 12:36:44 +0200 |
commit | 671312e1a05c579714bc08eb2ac3ad5a2c86a10e (patch) | |
tree | e91dd259fd6cd6ce3c714b996f84f38a28eacec7 | |
parent | 75ceaf862d2c7eb38ba41ddc857618aa4b28b0a2 (diff) | |
download | linux-671312e1a05c579714bc08eb2ac3ad5a2c86a10e.tar.bz2 |
netfilter: nf_tables_offload: unbind if multi-device binding fails
nft_flow_block_chain() needs to unbind in case of error when performing
the multi-device binding.
Fixes: d54725cd11a5 ("netfilter: nf_tables: support for multiple devices per netdev hook")
Reported-by: wenxu <wenxu@ucloud.cn>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | net/netfilter/nf_tables_offload.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c index d51728affa1c..4e0625cce647 100644 --- a/net/netfilter/nf_tables_offload.c +++ b/net/netfilter/nf_tables_offload.c @@ -336,7 +336,7 @@ static int nft_flow_block_chain(struct nft_base_chain *basechain, { struct net_device *dev; struct nft_hook *hook; - int err; + int err, i = 0; list_for_each_entry(hook, &basechain->hook_list, list) { dev = hook->ops.dev; @@ -344,11 +344,26 @@ static int nft_flow_block_chain(struct nft_base_chain *basechain, continue; err = nft_chain_offload_cmd(basechain, dev, cmd); - if (err < 0) + if (err < 0 && cmd == FLOW_BLOCK_BIND) { + if (!this_dev) + goto err_flow_block; + return err; + } + i++; } return 0; + +err_flow_block: + list_for_each_entry(hook, &basechain->hook_list, list) { + if (i-- <= 0) + break; + + dev = hook->ops.dev; + nft_chain_offload_cmd(basechain, dev, FLOW_BLOCK_UNBIND); + } + return err; } static int nft_flow_offload_chain(struct nft_chain *chain, u8 *ppolicy, |