From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Subject: [PATCH nf-next RFC 6/8] netfilter: nf_tables: get rid of pernet families
Date: Sun, 31 Dec 2017 00:13:46 +0100 [thread overview]
Message-ID: <20171230231348.5497-7-pablo@netfilter.org> (raw)
In-Reply-To: <20171230231348.5497-1-pablo@netfilter.org>
Now that we have a single table list for each netns, we can get rid of
one pointer per family, thus, shrinking struct netns for nftables.
Call __nft_release_afinfo() from __net_exit path.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 4 +--
include/net/netns/nftables.h | 6 -----
net/bridge/netfilter/nf_tables_bridge.c | 38 ++++-----------------------
net/ipv4/netfilter/nf_tables_arp.c | 41 +++++++----------------------
net/ipv4/netfilter/nf_tables_ipv4.c | 40 ++++++----------------------
net/ipv6/netfilter/nf_tables_ipv6.c | 40 ++++++----------------------
net/netfilter/nf_tables_api.c | 40 +++++++++++++++-------------
net/netfilter/nf_tables_inet.c | 41 ++++++-----------------------
net/netfilter/nf_tables_netdev.c | 46 +++++++--------------------------
9 files changed, 71 insertions(+), 225 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index fb7b560806f0..928d50bb3302 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -976,8 +976,8 @@ struct nft_af_info {
struct module *owner;
};
-int nft_register_afinfo(struct net *, struct nft_af_info *);
-void nft_unregister_afinfo(struct net *, struct nft_af_info *);
+int nft_register_afinfo(struct nft_af_info *);
+void nft_unregister_afinfo(struct nft_af_info *);
int nft_register_chain_type(const struct nf_chain_type *);
void nft_unregister_chain_type(const struct nf_chain_type *);
diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h
index 7f86a63ac21f..44e4de0bb59b 100644
--- a/include/net/netns/nftables.h
+++ b/include/net/netns/nftables.h
@@ -10,12 +10,6 @@ struct netns_nftables {
struct list_head af_info;
struct list_head tables;
struct list_head commit_list;
- struct nft_af_info *ipv4;
- struct nft_af_info *ipv6;
- struct nft_af_info *inet;
- struct nft_af_info *arp;
- struct nft_af_info *bridge;
- struct nft_af_info *netdev;
unsigned int base_seq;
u8 gencursor;
};
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index 66c97b1e3303..dbf7195f059c 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -47,34 +47,6 @@ static struct nft_af_info nft_af_bridge __read_mostly = {
.owner = THIS_MODULE,
};
-static int nf_tables_bridge_init_net(struct net *net)
-{
- net->nft.bridge = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
- if (net->nft.bridge == NULL)
- return -ENOMEM;
-
- memcpy(net->nft.bridge, &nft_af_bridge, sizeof(nft_af_bridge));
-
- if (nft_register_afinfo(net, net->nft.bridge) < 0)
- goto err;
-
- return 0;
-err:
- kfree(net->nft.bridge);
- return -ENOMEM;
-}
-
-static void nf_tables_bridge_exit_net(struct net *net)
-{
- nft_unregister_afinfo(net, net->nft.bridge);
- kfree(net->nft.bridge);
-}
-
-static struct pernet_operations nf_tables_bridge_net_ops = {
- .init = nf_tables_bridge_init_net,
- .exit = nf_tables_bridge_exit_net,
-};
-
static const struct nf_chain_type filter_bridge = {
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
@@ -98,17 +70,17 @@ static int __init nf_tables_bridge_init(void)
{
int ret;
- ret = nft_register_chain_type(&filter_bridge);
+ ret = nft_register_afinfo(&nft_af_bridge);
if (ret < 0)
return ret;
- ret = register_pernet_subsys(&nf_tables_bridge_net_ops);
+ ret = nft_register_chain_type(&filter_bridge);
if (ret < 0)
- goto err_register_subsys;
+ goto err_register_chain;
return ret;
-err_register_subsys:
+err_register_chain:
nft_unregister_chain_type(&filter_bridge);
return ret;
@@ -116,8 +88,8 @@ static int __init nf_tables_bridge_init(void)
static void __exit nf_tables_bridge_exit(void)
{
- unregister_pernet_subsys(&nf_tables_bridge_net_ops);
nft_unregister_chain_type(&filter_bridge);
+ nft_unregister_afinfo(&nft_af_bridge);
}
module_init(nf_tables_bridge_init);
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index f9089b2ad905..07667388ceb5 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -32,34 +32,6 @@ static struct nft_af_info nft_af_arp __read_mostly = {
.owner = THIS_MODULE,
};
-static int nf_tables_arp_init_net(struct net *net)
-{
- net->nft.arp = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
- if (net->nft.arp== NULL)
- return -ENOMEM;
-
- memcpy(net->nft.arp, &nft_af_arp, sizeof(nft_af_arp));
-
- if (nft_register_afinfo(net, net->nft.arp) < 0)
- goto err;
-
- return 0;
-err:
- kfree(net->nft.arp);
- return -ENOMEM;
-}
-
-static void nf_tables_arp_exit_net(struct net *net)
-{
- nft_unregister_afinfo(net, net->nft.arp);
- kfree(net->nft.arp);
-}
-
-static struct pernet_operations nf_tables_arp_net_ops = {
- .init = nf_tables_arp_init_net,
- .exit = nf_tables_arp_exit_net,
-};
-
static const struct nf_chain_type filter_arp = {
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
@@ -77,21 +49,26 @@ static int __init nf_tables_arp_init(void)
{
int ret;
- ret = nft_register_chain_type(&filter_arp);
+ ret = nft_register_afinfo(&nft_af_arp);
if (ret < 0)
return ret;
- ret = register_pernet_subsys(&nf_tables_arp_net_ops);
+ ret = nft_register_chain_type(&filter_arp);
if (ret < 0)
- nft_unregister_chain_type(&filter_arp);
+ goto err_register_chain;
+
+ return 0;
+
+err_register_chain:
+ nft_unregister_chain_type(&filter_arp);
return ret;
}
static void __exit nf_tables_arp_exit(void)
{
- unregister_pernet_subsys(&nf_tables_arp_net_ops);
nft_unregister_chain_type(&filter_arp);
+ nft_unregister_afinfo(&nft_af_arp);
}
module_init(nf_tables_arp_init);
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index a98f2de63771..e1441738acb4 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -35,34 +35,6 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = {
.owner = THIS_MODULE,
};
-static int nf_tables_ipv4_init_net(struct net *net)
-{
- net->nft.ipv4 = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
- if (net->nft.ipv4 == NULL)
- return -ENOMEM;
-
- memcpy(net->nft.ipv4, &nft_af_ipv4, sizeof(nft_af_ipv4));
-
- if (nft_register_afinfo(net, net->nft.ipv4) < 0)
- goto err;
-
- return 0;
-err:
- kfree(net->nft.ipv4);
- return -ENOMEM;
-}
-
-static void nf_tables_ipv4_exit_net(struct net *net)
-{
- nft_unregister_afinfo(net, net->nft.ipv4);
- kfree(net->nft.ipv4);
-}
-
-static struct pernet_operations nf_tables_ipv4_net_ops = {
- .init = nf_tables_ipv4_init_net,
- .exit = nf_tables_ipv4_exit_net,
-};
-
static const struct nf_chain_type filter_ipv4 = {
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
@@ -86,21 +58,25 @@ static int __init nf_tables_ipv4_init(void)
{
int ret;
- ret = nft_register_chain_type(&filter_ipv4);
+ ret = nft_register_afinfo(&nft_af_ipv4);
if (ret < 0)
return ret;
- ret = register_pernet_subsys(&nf_tables_ipv4_net_ops);
+ ret = nft_register_chain_type(&filter_ipv4);
if (ret < 0)
- nft_unregister_chain_type(&filter_ipv4);
+ goto err_register_chain;
+
+ return 0;
+err_register_chain:
+ nft_unregister_afinfo(&nft_af_ipv4);
return ret;
}
static void __exit nf_tables_ipv4_exit(void)
{
- unregister_pernet_subsys(&nf_tables_ipv4_net_ops);
nft_unregister_chain_type(&filter_ipv4);
+ nft_unregister_afinfo(&nft_af_ipv4);
}
module_init(nf_tables_ipv4_init);
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index bddd39dc1cf3..912d0e5516b0 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -33,34 +33,6 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = {
.owner = THIS_MODULE,
};
-static int nf_tables_ipv6_init_net(struct net *net)
-{
- net->nft.ipv6 = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
- if (net->nft.ipv6 == NULL)
- return -ENOMEM;
-
- memcpy(net->nft.ipv6, &nft_af_ipv6, sizeof(nft_af_ipv6));
-
- if (nft_register_afinfo(net, net->nft.ipv6) < 0)
- goto err;
-
- return 0;
-err:
- kfree(net->nft.ipv6);
- return -ENOMEM;
-}
-
-static void nf_tables_ipv6_exit_net(struct net *net)
-{
- nft_unregister_afinfo(net, net->nft.ipv6);
- kfree(net->nft.ipv6);
-}
-
-static struct pernet_operations nf_tables_ipv6_net_ops = {
- .init = nf_tables_ipv6_init_net,
- .exit = nf_tables_ipv6_exit_net,
-};
-
static const struct nf_chain_type filter_ipv6 = {
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
@@ -84,20 +56,24 @@ static int __init nf_tables_ipv6_init(void)
{
int ret;
- ret = nft_register_chain_type(&filter_ipv6);
+ ret = nft_register_afinfo(&nft_af_ipv6);
if (ret < 0)
return ret;
- ret = register_pernet_subsys(&nf_tables_ipv6_net_ops);
+ ret = nft_register_chain_type(&filter_ipv6);
if (ret < 0)
- nft_unregister_chain_type(&filter_ipv6);
+ goto err_register_chain;
+
+ return 0;
+err_register_chain:
+ nft_unregister_afinfo(&nft_af_ipv6);
return ret;
}
static void __exit nf_tables_ipv6_exit(void)
{
- unregister_pernet_subsys(&nf_tables_ipv6_net_ops);
+ nft_unregister_afinfo(&nft_af_ipv6);
nft_unregister_chain_type(&filter_ipv6);
}
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 3505cca8262f..0e5e0f76a664 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -24,6 +24,7 @@
static LIST_HEAD(nf_tables_expressions);
static LIST_HEAD(nf_tables_objects);
+static LIST_HEAD(nf_tables_af_info);
/**
* nft_register_afinfo - register nf_tables address family info
@@ -33,17 +34,15 @@ static LIST_HEAD(nf_tables_objects);
* 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
*
@@ -51,10 +50,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);
}
@@ -5800,15 +5798,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;
-}
-
int __nft_release_basechain(struct nft_ctx *ctx)
{
struct nft_rule *rule, *nr;
@@ -5829,8 +5818,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_table *table, *nt;
struct nft_chain *chain, *nc;
@@ -5839,10 +5827,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);
/* No packets are walking on these chains anymore. */
@@ -5875,8 +5864,23 @@ 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.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)
+{
+ __nft_release_afinfo(net);
+}
+
static struct pernet_operations nf_tables_net_ops = {
.init = nf_tables_init_net,
+ .exit = nf_tables_exit_net,
};
static int __init nf_tables_module_init(void)
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c
index 5128ffd053df..c77b27b501c7 100644
--- a/net/netfilter/nf_tables_inet.c
+++ b/net/netfilter/nf_tables_inet.c
@@ -64,34 +64,6 @@ static struct nft_af_info nft_af_inet __read_mostly = {
.owner = THIS_MODULE,
};
-static int __net_init nf_tables_inet_init_net(struct net *net)
-{
- net->nft.inet = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
- if (net->nft.inet == NULL)
- return -ENOMEM;
- memcpy(net->nft.inet, &nft_af_inet, sizeof(nft_af_inet));
-
- if (nft_register_afinfo(net, net->nft.inet) < 0)
- goto err;
-
- return 0;
-
-err:
- kfree(net->nft.inet);
- return -ENOMEM;
-}
-
-static void __net_exit nf_tables_inet_exit_net(struct net *net)
-{
- nft_unregister_afinfo(net, net->nft.inet);
- kfree(net->nft.inet);
-}
-
-static struct pernet_operations nf_tables_inet_net_ops = {
- .init = nf_tables_inet_init_net,
- .exit = nf_tables_inet_exit_net,
-};
-
static const struct nf_chain_type filter_inet = {
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
@@ -115,21 +87,24 @@ static int __init nf_tables_inet_init(void)
{
int ret;
- ret = nft_register_chain_type(&filter_inet);
- if (ret < 0)
+ if (nft_register_afinfo(&nft_af_inet) < 0)
return ret;
- ret = register_pernet_subsys(&nf_tables_inet_net_ops);
+ ret = nft_register_chain_type(&filter_inet);
if (ret < 0)
- nft_unregister_chain_type(&filter_inet);
+ goto err_register_chain;
+
+ return ret;
+err_register_chain:
+ nft_unregister_afinfo(&nft_af_inet);
return ret;
}
static void __exit nf_tables_inet_exit(void)
{
- unregister_pernet_subsys(&nf_tables_inet_net_ops);
nft_unregister_chain_type(&filter_inet);
+ nft_unregister_afinfo(&nft_af_inet);
}
module_init(nf_tables_inet_init);
diff --git a/net/netfilter/nf_tables_netdev.c b/net/netfilter/nf_tables_netdev.c
index 01b61a67a2ac..404b49acb125 100644
--- a/net/netfilter/nf_tables_netdev.c
+++ b/net/netfilter/nf_tables_netdev.c
@@ -43,34 +43,6 @@ static struct nft_af_info nft_af_netdev __read_mostly = {
.owner = THIS_MODULE,
};
-static int nf_tables_netdev_init_net(struct net *net)
-{
- net->nft.netdev = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
- if (net->nft.netdev == NULL)
- return -ENOMEM;
-
- memcpy(net->nft.netdev, &nft_af_netdev, sizeof(nft_af_netdev));
-
- if (nft_register_afinfo(net, net->nft.netdev) < 0)
- goto err;
-
- return 0;
-err:
- kfree(net->nft.netdev);
- return -ENOMEM;
-}
-
-static void nf_tables_netdev_exit_net(struct net *net)
-{
- nft_unregister_afinfo(net, net->nft.netdev);
- kfree(net->nft.netdev);
-}
-
-static struct pernet_operations nf_tables_netdev_net_ops = {
- .init = nf_tables_netdev_init_net,
- .exit = nf_tables_netdev_exit_net,
-};
-
static const struct nf_chain_type nft_filter_chain_netdev = {
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
@@ -145,32 +117,32 @@ static int __init nf_tables_netdev_init(void)
{
int ret;
- ret = nft_register_chain_type(&nft_filter_chain_netdev);
- if (ret)
+ if (nft_register_afinfo(&nft_af_netdev) < 0)
return ret;
- ret = register_pernet_subsys(&nf_tables_netdev_net_ops);
+ ret = nft_register_chain_type(&nft_filter_chain_netdev);
if (ret)
- goto err1;
+ goto err_register_chain_type;
ret = register_netdevice_notifier(&nf_tables_netdev_notifier);
if (ret)
- goto err2;
+ goto err_register_netdevice_notifier;
return 0;
-err2:
- unregister_pernet_subsys(&nf_tables_netdev_net_ops);
-err1:
+err_register_netdevice_notifier:
nft_unregister_chain_type(&nft_filter_chain_netdev);
+err_register_chain_type:
+ nft_unregister_afinfo(&nft_af_netdev);
+
return ret;
}
static void __exit nf_tables_netdev_exit(void)
{
unregister_netdevice_notifier(&nf_tables_netdev_notifier);
- unregister_pernet_subsys(&nf_tables_netdev_net_ops);
nft_unregister_chain_type(&nft_filter_chain_netdev);
+ nft_unregister_afinfo(&nft_af_netdev);
}
module_init(nf_tables_netdev_init);
--
2.11.0
next prev parent reply other threads:[~2017-12-30 23:13 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-30 23:13 [PATCH nf-next RFC 0/8] simplify nf_tables family and filter chain infra Pablo Neira Ayuso
2017-12-30 23:13 ` [PATCH nf-next RFC 1/8] netfilter: nf_tables: remove nhooks field from struct nft_af_info Pablo Neira Ayuso
2017-12-30 23:13 ` [PATCH nf-next RFC 2/8] netfilter: nf_tables: remove flag " Pablo Neira Ayuso
2017-12-30 23:13 ` [PATCH nf-next RFC 3/8] netfilter: nf_tables: no need for struct nft_af_info to enable/disable table Pablo Neira Ayuso
2017-12-30 23:13 ` [PATCH nf-next RFC 4/8] netfilter: nf_tables: remove struct nft_af_info parameter in nf_tables_chain_type_lookup() Pablo Neira Ayuso
2017-12-30 23:13 ` [PATCH nf-next RFC 5/8] netfilter: nf_tables: add single table list for all families Pablo Neira Ayuso
2017-12-30 23:13 ` Pablo Neira Ayuso [this message]
2017-12-30 23:13 ` [PATCH nf-next RFC 7/8] netfilter: nf_tables: get rid of struct nft_af_info abstraction Pablo Neira Ayuso
2017-12-30 23:13 ` [PATCH nf-next RFC 8/8] netfilter: nf_tables: consolidate filter chain definitions Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171230231348.5497-7-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).