diff options
Diffstat (limited to 'net/netfilter/nf_tables_api.c')
-rw-r--r-- | net/netfilter/nf_tables_api.c | 57 |
1 files changed, 26 insertions, 31 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 084d1f553c46..b0ff26beec80 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -26,6 +26,7 @@ static LIST_HEAD(nf_tables_expressions); static LIST_HEAD(nf_tables_objects); static LIST_HEAD(nf_tables_flowtables); +static LIST_HEAD(nf_tables_af_info); /** * nft_register_afinfo - register nf_tables address family info @@ -35,17 +36,15 @@ static LIST_HEAD(nf_tables_flowtables); * Register the address family for use with nf_tables. Returns zero on * success or a negative errno code otherwise. */ -int nft_register_afinfo(struct net *net, struct nft_af_info *afi) +int nft_register_afinfo(struct nft_af_info *afi) { nfnl_lock(NFNL_SUBSYS_NFTABLES); - list_add_tail_rcu(&afi->list, &net->nft.af_info); + list_add_tail_rcu(&afi->list, &nf_tables_af_info); nfnl_unlock(NFNL_SUBSYS_NFTABLES); return 0; } EXPORT_SYMBOL_GPL(nft_register_afinfo); -static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi); - /** * nft_unregister_afinfo - unregister nf_tables address family info * @@ -53,10 +52,9 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi); * * Unregister the address family for use with nf_tables. */ -void nft_unregister_afinfo(struct net *net, struct nft_af_info *afi) +void nft_unregister_afinfo(struct nft_af_info *afi) { nfnl_lock(NFNL_SUBSYS_NFTABLES); - __nft_release_afinfo(net, afi); list_del_rcu(&afi->list); nfnl_unlock(NFNL_SUBSYS_NFTABLES); } @@ -66,7 +64,7 @@ static struct nft_af_info *nft_afinfo_lookup(struct net *net, int family) { struct nft_af_info *afi; - list_for_each_entry(afi, &net->nft.af_info, list) { + list_for_each_entry(afi, &nf_tables_af_info, list) { if (afi->family == family) return afi; } @@ -5042,15 +5040,12 @@ void nft_flow_table_iterate(struct net *net, void *data) { struct nft_flowtable *flowtable; - const struct nft_af_info *afi; const struct nft_table *table; rcu_read_lock(); - list_for_each_entry_rcu(afi, &net->nft.af_info, list) { - list_for_each_entry_rcu(table, &net->nft.tables, list) { - list_for_each_entry_rcu(flowtable, &table->flowtables, list) { - iter(&flowtable->data, data); - } + list_for_each_entry_rcu(table, &net->nft.tables, list) { + list_for_each_entry_rcu(flowtable, &table->flowtables, list) { + iter(&flowtable->data, data); } } rcu_read_unlock(); @@ -6533,21 +6528,6 @@ int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data, } EXPORT_SYMBOL_GPL(nft_data_dump); -static int __net_init nf_tables_init_net(struct net *net) -{ - INIT_LIST_HEAD(&net->nft.af_info); - INIT_LIST_HEAD(&net->nft.tables); - INIT_LIST_HEAD(&net->nft.commit_list); - net->nft.base_seq = 1; - return 0; -} - -static void __net_exit nf_tables_exit_net(struct net *net) -{ - WARN_ON_ONCE(!list_empty(&net->nft.af_info)); - WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); -} - int __nft_release_basechain(struct nft_ctx *ctx) { struct nft_rule *rule, *nr; @@ -6568,8 +6548,7 @@ int __nft_release_basechain(struct nft_ctx *ctx) } EXPORT_SYMBOL_GPL(__nft_release_basechain); -/* Called by nft_unregister_afinfo() from __net_exit path, nfnl_lock is held. */ -static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) +static void __nft_release_afinfo(struct net *net) { struct nft_flowtable *flowtable, *nf; struct nft_table *table, *nt; @@ -6579,10 +6558,11 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) struct nft_set *set, *ns; struct nft_ctx ctx = { .net = net, - .family = afi->family, }; list_for_each_entry_safe(table, nt, &net->nft.tables, list) { + ctx.family = table->afi->family; + list_for_each_entry(chain, &table->chains, list) nf_tables_unregister_hook(net, table, chain); list_for_each_entry(flowtable, &table->flowtables, list) @@ -6623,6 +6603,21 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) } } +static int __net_init nf_tables_init_net(struct net *net) +{ + INIT_LIST_HEAD(&net->nft.tables); + INIT_LIST_HEAD(&net->nft.commit_list); + net->nft.base_seq = 1; + return 0; +} + +static void __net_exit nf_tables_exit_net(struct net *net) +{ + __nft_release_afinfo(net); + WARN_ON_ONCE(!list_empty(&net->nft.tables)); + WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); +} + static struct pernet_operations nf_tables_net_ops = { .init = nf_tables_init_net, .exit = nf_tables_exit_net, |