Commit 671312e1 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

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: d54725cd ("netfilter: nf_tables: support for multiple devices per netdev hook")
Reported-by: default avatarwenxu <wenxu@ucloud.cn>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 75ceaf86
...@@ -336,7 +336,7 @@ static int nft_flow_block_chain(struct nft_base_chain *basechain, ...@@ -336,7 +336,7 @@ static int nft_flow_block_chain(struct nft_base_chain *basechain,
{ {
struct net_device *dev; struct net_device *dev;
struct nft_hook *hook; struct nft_hook *hook;
int err; int err, i = 0;
list_for_each_entry(hook, &basechain->hook_list, list) { list_for_each_entry(hook, &basechain->hook_list, list) {
dev = hook->ops.dev; dev = hook->ops.dev;
...@@ -344,11 +344,26 @@ static int nft_flow_block_chain(struct nft_base_chain *basechain, ...@@ -344,11 +344,26 @@ static int nft_flow_block_chain(struct nft_base_chain *basechain,
continue; continue;
err = nft_chain_offload_cmd(basechain, dev, cmd); 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; return err;
}
i++;
} }
return 0; 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, static int nft_flow_offload_chain(struct nft_chain *chain, u8 *ppolicy,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment