summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2019-10-24 10:30:19 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2019-10-26 12:36:44 +0200
commit671312e1a05c579714bc08eb2ac3ad5a2c86a10e (patch)
treee91dd259fd6cd6ce3c714b996f84f38a28eacec7
parent75ceaf862d2c7eb38ba41ddc857618aa4b28b0a2 (diff)
downloadlinux-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.c19
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,