All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vasily Averin <vvs@parallels.com>
To: Bart De Schuymer <bdschuym@pandora.be>,
	Patrick McHardy <kaber@trash.net>
Cc: Florian Westphal <fw@strlen.de>,
	netfilter-devel@vger.kernel.org,
	Pablo Neira Ayuso <pablo@netfilter.org>
Subject: [PATCH RFC v3 2/2] br_netfilter: per-netns copy of structure for sysctl flags
Date: Mon, 12 May 2014 20:32:01 +0400	[thread overview]
Message-ID: <5370F781.7010909@parallels.com> (raw)
In-Reply-To: <cover.1399909529.git.vvs@openvz.org>

pernet_operations creates per-netns copy of common structure for sysctl flags
and initialize it values taken from init_brnf_net.

Signed-off-by: Vasily Averin <vvs@openvz.org>
---
 net/bridge/br_netfilter.c |  104 +++++++++++++++++++++++++++++++++++++-------
 1 files changed, 87 insertions(+), 17 deletions(-)

diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 31bfd90..9886afc 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -40,6 +40,7 @@
 #include "br_private.h"
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
+#include <net/netns/generic.h>
 #endif
 
 #define skb_origaddr(skb)	 (((struct bridge_skb_cb *) \
@@ -47,9 +48,6 @@
 #define store_orig_dstaddr(skb)	 (skb_origaddr(skb) = ip_hdr(skb)->daddr)
 #define dnat_took_place(skb)	 (skb_origaddr(skb) != ip_hdr(skb)->daddr)
 
-#ifdef CONFIG_SYSCTL
-static struct ctl_table_header *brnf_sysctl_header;
-#endif
 #define brnf_call_arptables 1
 #define brnf_call_iptables 1
 #define brnf_call_ip6tables 1
@@ -58,6 +56,7 @@ static struct ctl_table_header *brnf_sysctl_header;
 #define brnf_pass_vlan_indev 0
 
 #ifdef CONFIG_SYSCTL
+static int brnf_net_id __read_mostly;
 static struct brnf_net init_brnf_net = {
 	.hdr			= NULL,
 	.call_arptables		= brnf_call_arptables,
@@ -68,7 +67,13 @@ static struct brnf_net init_brnf_net = {
 	.pass_vlan_indev	= brnf_pass_vlan_indev,
 };
 
-#define brnf_flag(skb, flag)		init_brnf_net.flag
+static inline struct brnf_net *brnf_net(const struct net *net)
+{
+	return net_generic(net, brnf_net_id);
+}
+
+#define skb_netns(skb)			net((skb)->dev)
+#define brnf_flag(skb, flag)		brnf_net(skb_netns(skb))->flag
 #else
 #define brnf_flag(skb, flag)		brnf_##flag
 #endif
@@ -1066,6 +1071,70 @@ static struct ctl_table brnf_table[] = {
 	},
 	{ }
 };
+
+static int brnf_sysctl_net_register(struct brnf_net *bn)
+{
+	struct ctl_table *table;
+	struct ctl_table_header *hdr;
+	int i;
+
+	table = brnf_table;
+	if (!net_eq(bn->net, &init_net)) {
+
+		table = kmemdup(table, sizeof(brnf_table), GFP_KERNEL);
+		if (!table)
+			goto err_alloc;
+	}
+	for (i = 0; table[i].data; i++)
+		table[i].data += (char *)bn - (char *)&init_brnf_net;
+
+	hdr = register_net_sysctl(bn->net, "net/bridge", table);
+	if (!hdr)
+		goto err_reg;
+
+	bn->hdr = hdr;
+	return 0;
+
+err_reg:
+	if (!net_eq(bn->net, &init_net))
+		kfree(table);
+err_alloc:
+	return -ENOMEM;
+}
+
+static void brnf_sysctl_net_unregister(struct brnf_net *bn)
+{
+	struct ctl_table *table;
+
+	if (bn->hdr == NULL)
+		return;
+
+	table = bn->hdr->ctl_table_arg;
+	unregister_net_sysctl_table(bn->hdr);
+	if (!net_eq(bn->net, &init_net))
+		kfree(table);
+}
+
+static int __net_init brnf_net_init(struct net *net)
+{
+	struct brnf_net *bn = brnf_net(net);
+
+	memcpy(bn, &init_brnf_net, sizeof(struct brnf_net));
+	bn->net = net;
+	return brnf_sysctl_net_register(bn);
+}
+
+static void __net_exit brnf_net_exit(struct net *net)
+{
+	brnf_sysctl_net_unregister(brnf_net(net));
+}
+
+static struct pernet_operations __net_initdata brnf_net_ops = {
+	.init	= brnf_net_init,
+	.exit	= brnf_net_exit,
+	.id	= &brnf_net_id,
+	.size	= sizeof(struct brnf_net),
+};
 #endif
 
 int __init br_netfilter_init(void)
@@ -1074,32 +1143,33 @@ int __init br_netfilter_init(void)
 
 	ret = dst_entries_init(&fake_dst_ops);
 	if (ret < 0)
-		return ret;
+		goto err_dst;
 
 	ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
-	if (ret < 0) {
-		dst_entries_destroy(&fake_dst_ops);
-		return ret;
-	}
+	if (ret < 0)
+		goto err_nf;
+
 #ifdef CONFIG_SYSCTL
-	brnf_sysctl_header = register_net_sysctl(&init_net, "net/bridge", brnf_table);
-	if (brnf_sysctl_header == NULL) {
-		printk(KERN_WARNING
-		       "br_netfilter: can't register to sysctl.\n");
+	ret = register_pernet_subsys(&brnf_net_ops);
+	if (ret < 0) {
 		nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
-		dst_entries_destroy(&fake_dst_ops);
-		return -ENOMEM;
+		goto err_nf;
 	}
 #endif
 	printk(KERN_NOTICE "Bridge firewalling registered\n");
 	return 0;
+
+err_nf:
+	dst_entries_destroy(&fake_dst_ops);
+err_dst:
+	return ret;
 }
 
 void br_netfilter_fini(void)
 {
-	nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
 #ifdef CONFIG_SYSCTL
-	unregister_net_sysctl_table(brnf_sysctl_header);
+	unregister_pernet_subsys(&brnf_net_ops);
 #endif
+	nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
 	dst_entries_destroy(&fake_dst_ops);
 }
-- 
1.7.5.4


  parent reply	other threads:[~2014-05-12 16:33 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <536FD0FD.8010204@pandora.de>
2014-05-12 12:56 ` [PATCH RFC v2 00/11] per-netns sysctl for br_netfilter Vasily Averin
     [not found] ` <cover.1399897184.git.vvs@openvz.org>
2014-05-12 12:56   ` [PATCH RFC v2 01/11] br_netfilter: brnf_net structure for sysctl setting Vasily Averin
2014-05-12 12:56   ` [PATCH RFC v2 02/11] br_netfilter: default sysctl settings in init_brnf_net Vasily Averin
2014-05-12 14:07     ` Patrick McHardy
2014-05-12 16:31       ` [PATCH RFC v3 0/2] per-netns sysctl for br_netfilter Vasily Averin
2014-05-29 12:28         ` Pablo Neira Ayuso
2014-05-30 10:04           ` Vasily Averin
     [not found]       ` <cover.1399909529.git.vvs@openvz.org>
2014-05-12 16:31         ` [PATCH RFC v3 1/2] br_netfilter: common structure for sysctl flags Vasily Averin
2014-05-12 16:32         ` Vasily Averin [this message]
2014-05-12 19:04           ` [PATCH RFC v3 2/2] br_netfilter: per-netns copy of " Bart De Schuymer
2014-05-12 20:11             ` Vasily Averin
2014-05-13 19:28               ` Bart De Schuymer
     [not found]                 ` <53727246.4050306-LPO8gxj9N8aZIoH1IeqzKA@public.gmane.org>
2014-05-15  9:01                   ` question about default values for per-namespace settings Vasily Averin
2014-05-15  9:01                     ` Vasily Averin
2014-05-15 17:48                     ` Tejun Heo
     [not found]                       ` <20140515174850.GB20738-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2014-05-16 11:16                         ` Maciej Żenczykowski
     [not found]                     ` <53748280.60906-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2014-05-15 11:02                       ` Serge Hallyn
2014-05-15 17:48                       ` Tejun Heo
2014-05-19 19:30                       ` Bart De Schuymer
2014-05-19 19:30                     ` Bart De Schuymer
     [not found]                       ` <537A5BD1.90906-LPO8gxj9N8aZIoH1IeqzKA@public.gmane.org>
2014-06-24  8:21                         ` Vasily Averin
     [not found]                           ` <53A934F1.7040906-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2014-06-25  7:45                             ` Eric W. Biederman
2014-06-25  7:45                               ` Eric W. Biederman
2014-05-12 12:57   ` [PATCH RFC v2 03/11] br_netfilter: brnf_flag macro Vasily Averin
2014-05-12 12:57   ` [PATCH RFC v2 04/11] br_netfilter: switch sysctl call_arptables to init_brnf_net Vasily Averin
2014-05-12 12:57   ` [PATCH RFC v2 05/11] br_netfilter: switch sysctls call_iptables and call_ip6tables " Vasily Averin
2014-05-12 12:57   ` [PATCH RFC v2 06/11] br_netfilter: switch sysctl filter_vlan_tagged " Vasily Averin
2014-05-12 12:57   ` [PATCH RFC v2 07/11] br_netfilter: switch sysctl filter_pppoe_tagged " Vasily Averin
2014-05-12 12:57   ` [PATCH RFC v2 08/11] br_netfilter: switch sysctl pass_vlan_indev " Vasily Averin
2014-05-12 12:57   ` [PATCH RFC v2 09/11] br_netfilter: added pernet_operations without sysctl registration Vasily Averin
2014-05-12 12:58   ` [PATCH RFC v2 10/11] br_netfilter: per-netns " Vasily Averin
2014-05-12 12:58   ` [PATCH RFC v2 11/11] br_netfilter: switch all sysctls to per-netns processing Vasily Averin

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=5370F781.7010909@parallels.com \
    --to=vvs@parallels.com \
    --cc=bdschuym@pandora.be \
    --cc=fw@strlen.de \
    --cc=kaber@trash.net \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.