summary refs log tree commit diff
path: root/net/ipv6
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-10-10 23:28:33 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-10-14 18:00:59 +0200
commit99633ab29b2131b68089a6c7f60458390860e044 (patch)
treeeb7e2ecd9ed875ed4d3a050b95ed3d77bbde762b /net/ipv6
parenteb31628e37a0a4e01fffd79dcc7f815d2357f53a (diff)
downloadlinux-99633ab29b2131b68089a6c7f60458390860e044.tar.gz
netfilter: nf_tables: complete net namespace support
Register family per netnamespace to ensure that sets are
only visible in its approapriate namespace.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/nf_tables_ipv6.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 42f905a808a3..d77db8a13505 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -45,6 +45,34 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = {
 	},
 };
 
+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->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 unsigned int
 nft_do_chain_ipv6(const struct nf_hook_ops *ops,
 		  struct sk_buff *skb,
@@ -82,11 +110,12 @@ static struct nf_chain_type filter_ipv6 = {
 static int __init nf_tables_ipv6_init(void)
 {
 	nft_register_chain_type(&filter_ipv6);
-	return nft_register_afinfo(&nft_af_ipv6);
+	return register_pernet_subsys(&nf_tables_ipv6_net_ops);
 }
+
 static void __exit nf_tables_ipv6_exit(void)
 {
-	nft_unregister_afinfo(&nft_af_ipv6);
+	unregister_pernet_subsys(&nf_tables_ipv6_net_ops);
 	nft_unregister_chain_type(&filter_ipv6);
 }