netfilter: nf_tables: Eliminate duplicated code in nf_tables_table_enable()

If something fails in nf_tables_table_enable(), it unregisters the
chains. But the rollback code is the same as nf_tables_table_disable()
almostly, except there is one counter check.  Now create one wrapper
function to eliminate the duplicated codes.

Signed-off-by: Feng <fgao@ikuai8.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Feng 2017-01-20 21:40:43 +08:00 committed by Pablo Neira Ayuso
parent 1a28ad74eb
commit 10435c1192

View File

@ -576,6 +576,28 @@ static int nf_tables_gettable(struct net *net, struct sock *nlsk,
return err;
}
static void _nf_tables_table_disable(struct net *net,
const struct nft_af_info *afi,
struct nft_table *table,
u32 cnt)
{
struct nft_chain *chain;
u32 i = 0;
list_for_each_entry(chain, &table->chains, list) {
if (!nft_is_active_next(net, chain))
continue;
if (!(chain->flags & NFT_BASE_CHAIN))
continue;
if (cnt && i++ == cnt)
break;
nf_unregister_net_hooks(net, nft_base_chain(chain)->ops,
afi->nops);
}
}
static int nf_tables_table_enable(struct net *net,
const struct nft_af_info *afi,
struct nft_table *table)
@ -598,18 +620,8 @@ static int nf_tables_table_enable(struct net *net,
}
return 0;
err:
list_for_each_entry(chain, &table->chains, list) {
if (!nft_is_active_next(net, chain))
continue;
if (!(chain->flags & NFT_BASE_CHAIN))
continue;
if (i-- <= 0)
break;
nf_unregister_net_hooks(net, nft_base_chain(chain)->ops,
afi->nops);
}
if (i)
_nf_tables_table_disable(net, afi, table, i);
return err;
}
@ -617,17 +629,7 @@ static void nf_tables_table_disable(struct net *net,
const struct nft_af_info *afi,
struct nft_table *table)
{
struct nft_chain *chain;
list_for_each_entry(chain, &table->chains, list) {
if (!nft_is_active_next(net, chain))
continue;
if (!(chain->flags & NFT_BASE_CHAIN))
continue;
nf_unregister_net_hooks(net, nft_base_chain(chain)->ops,
afi->nops);
}
_nf_tables_table_disable(net, afi, table, 0);
}
static int nf_tables_updtable(struct nft_ctx *ctx)