[Debian] Re: lenny updates (networking)

Kir Kolyshkin kir at openvz.org
Mon Mar 16 14:22:16 EDT 2009


Attached four patches fixes conntracks for IPv6.

Ola Lundqvist wrote:
> Thanks for this clarification.
>
> Kir, please list the corrections that you can find. If they are more 
> on improvement please mark that and we can discuss it further.
>
> Best regards,
>
> // Ola
>
> Quoting maximilian attems <max at stro.at>:
>
>> On Mon, Mar 16, 2009 at 02:19:39PM +0300, Kir Kolyshkin wrote:
>>>
>>> So we can either disable IPv6 in config or fix it. It's up to you/Dann
>>> to decide. I'd go with fixing.
>>>
>>> Speaking of IPv6, we also have a bunch of patches for ipv6 
>>> conntracks in
>>> containers which I haven't sent since it looks more like a new
>>> functionality rather than a bugfix.
>>
>> yes please fix it, we have explicit demand for ipv6
>> also ipv6 support is a release goal of lenny,
>> so such updates should just go in.
>>
>>
>
>
>

-------------- next part --------------
>From 2c1b2f728e1ae136ec1713bfec9892cf7cd656b6 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Wed, 24 Sep 2008 14:51:32 +0400
Subject: [PATCH] conntrack: Allocate/free ve_nf_conntrack_l3proto_ipv6

Virtualize nf_ct_ipv6_sysctl_table and allocate/free ve_nf_conntrack_l3proto_ipv6.

Per VE nf_ct_ipv6_sysctl_table sysctl registration looks like:

	nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
		nf_ct_l3proto_register_sysctl(proto);
			nf_ct_register_sysctl(&l3proto->ctl_table_header,
						l3proto->ctl_table_path,
						l3proto->ctl_table, NULL);

So ve_nf_conntrack_l3proto_ipv6 is allocated per VE as l3proto sysctl
registration changes l3proto->ctl_table_header.

Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   34 +++++++++++++++++++++++-
 net/ipv6/netfilter/nf_conntrack_reasm.c        |   25 +++++++++++++++++-
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 71b15ab..8623b7c 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -360,6 +360,33 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai at toshiba.co.jp>");
 
+static int nf_ct_proto_ipv6_init_net(struct net *net)
+{
+	struct nf_conntrack_l3proto *ipv6;
+
+	ipv6 = &nf_conntrack_l3proto_ipv6;
+	if (net != &init_net) {
+		ipv6 = kmemdup(ipv6,
+			       sizeof(struct nf_conntrack_l3proto), GFP_KERNEL);
+		if (!ipv6)
+			return -ENOMEM;
+	}
+
+	ve_nf_conntrack_l3proto_ipv6 = ipv6;
+	return 0;
+}
+
+static void nf_ct_proto_ipv6_exit_net(struct net *net)
+{
+	if (net != &init_net)
+		kfree(ve_nf_conntrack_l3proto_ipv6);
+}
+
+static struct pernet_operations nf_ct_ipv6_ops = {
+	.init = nf_ct_proto_ipv6_init_net,
+	.exit = nf_ct_proto_ipv6_exit_net,
+};
+
 int init_nf_ct_l3proto_ipv6(void)
 {
 	int ret = -ENOMEM;
@@ -435,10 +462,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 
 	need_conntrack();
 
+	register_pernet_subsys(&nf_ct_ipv6_ops);
+
 	ret = nf_ct_frag6_init();
 	if (ret < 0) {
 		printk("nf_conntrack_ipv6: can't initialize frag6.\n");
-		return ret;
+		goto unreg_subsys;
 	}
 
 	ret = init_nf_ct_l3proto_ipv6();
@@ -461,6 +490,8 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 
 cleanup_frag6:
 	nf_ct_frag6_cleanup();
+unreg_subsys:
+	unregister_pernet_subsys(&nf_ct_ipv6_ops);
 	return ret;
 }
 
@@ -473,6 +504,7 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
 	nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
 	fini_nf_ct_l3proto_ipv6();
 	nf_ct_frag6_cleanup();
+	unregister_pernet_subsys(&nf_ct_ipv6_ops);
 }
 
 module_init(nf_conntrack_l3proto_ipv6_init);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 9faaa59..e8e4112 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -40,6 +40,7 @@
 #include <net/ndisc.h>
 #include <net/addrconf.h>
 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
 #include <linux/sysctl.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
@@ -696,17 +697,39 @@ static int nf_ct_frag6_init_net(struct net *net)
 {
 	struct netns_frags *frags = &net->ipv6.ct_frags;
 
+#ifdef CONFIG_SYSCTL
+	if (net != &init_net) {
+		struct nf_conntrack_l3proto *ipv6 =
+			ve_nf_conntrack_l3proto_ipv6;
+
+		ipv6->ctl_table = kmemdup(nf_ct_ipv6_sysctl_table,
+					  sizeof(nf_ct_ipv6_sysctl_table),
+					  GFP_KERNEL);
+		if (!ipv6->ctl_table)
+			return -ENOMEM;
+
+		ipv6->ctl_table_header = NULL;
+		ipv6->ctl_table_path = nf_net_netfilter_sysctl_path;
+
+		ipv6->ctl_table[0].data = &frags->timeout;
+		ipv6->ctl_table[1].data = &frags->low_thresh;
+		ipv6->ctl_table[2].data = &frags->high_thresh;
+	}
+#endif
 	frags->timeout = IPV6_FRAG_TIMEOUT;
 	frags->high_thresh = 256 * 1024;
 	frags->low_thresh = 192 * 1024;
 	inet_frags_init_net(frags);
 
-	return 0; /* FIXME : sysctls */
+	return 0;
 }
 
 static void nf_ct_frag6_exit_net(struct net *net)
 {
 	inet_frags_exit_net(&net->ipv6.ct_frags, &nf_frags);
+	if (net != &init_net)
+		kfree(ve_nf_conntrack_l3proto_ipv6->ctl_table);
+
 }
 
 static struct pernet_operations nf_ct_frag6_ops = {
-- 
1.6.0.6

-------------- next part --------------
>From e29a555d7d8f88dbfcaed541e340a4e3977c76aa Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Wed, 24 Sep 2008 14:52:08 +0400
Subject: [PATCH] ct: Move _nf_conntrack_l3proto_ipv6 to net namespace

Move _nf_conntrack_l3proto_ipv6 from ve_nf_conntrack to net namespace.

The patch [4/5] "conntrack: Allocate/free ve_nf_conntrack_l3proto_ipv6"
has lines:

+static int nf_ct_proto_ipv6_init_net(struct net *net)
...
+	ve_nf_conntrack_l3proto_ipv6 = ipv6;
+	return 0;

ve_nf_conntrack_l3proto_ipv6 points to not allocated memory, as this function
is called during net initialization (conntrack isn't initialized yet).

So move ve_nf_conntrack_l3proto_ipv6 to net namespace

Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
 include/linux/ve.h                             |    1 -
 include/net/netfilter/nf_conntrack_l3proto.h   |    2 --
 include/net/netns/ipv6.h                       |    4 ++++
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   12 ++++++++----
 net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c |    3 ++-
 net/ipv6/netfilter/nf_conntrack_reasm.c        |    4 ++--
 6 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/include/linux/ve.h b/include/linux/ve.h
index 970aadc..2180c1f 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -107,7 +107,6 @@ struct ve_nf_conntrack {
 	struct nf_conntrack_l4proto	**_nf_ct_protos[PF_MAX];
 	/* l3 protocols sysctl tables: */
 	struct nf_conntrack_l3proto	*_nf_conntrack_l3proto_ipv4;
-	struct nf_conntrack_l3proto	*_nf_conntrack_l3proto_ipv6;
 	struct nf_conntrack_l3proto	*_nf_ct_l3protos[AF_MAX];
 	/* sysctl standalone stuff: */
 	struct ctl_table_header		*_nf_ct_sysctl_header;
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 6b1f720..ac81973 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -79,14 +79,12 @@ struct nf_conntrack_l3proto
 #if defined(CONFIG_VE_IPTABLES) && defined(CONFIG_SYSCTL)
 #define ve_nf_ct_l3protos		ve_nf_ct3->_nf_ct_l3protos
 #define ve_nf_conntrack_l3proto_ipv4	(ve_nf_ct3->_nf_conntrack_l3proto_ipv4)
-#define	ve_nf_conntrack_l3proto_ipv6	(ve_nf_ct3->_nf_conntrack_l3proto_ipv6)
 #define ve_nf_conntrack_max		(ve_nf_ct3->_nf_conntrack_max)
 #define ve_nf_conntrack_count		(ve_nf_ct3->_nf_conntrack_count)
 #define ve_nf_conntrack_checksum	(ve_nf_ct3->_nf_conntrack_checksum)
 #else /* !CONFIG_VE_IPTABLES || !CONFIG_SYSCTL: */
 #define ve_nf_ct_l3protos		nf_ct_l3protos
 #define ve_nf_conntrack_l3proto_ipv4	&nf_conntrack_l3proto_ipv4
-#define ve_nf_conntrack_l3proto_ipv6	&nf_conntrack_l3proto_ipv6
 #define ve_nf_conntrack_max		nf_conntrack_max
 #define ve_nf_conntrack_count		nf_conntrack_count
 #define ve_nf_conntrack_checksum	nf_conntrack_checksum
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index c368713..11c8cc8 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -33,6 +33,10 @@ struct netns_ipv6 {
 	struct ipv6_devconf	*devconf_dflt;
 	struct netns_frags	frags;
 	struct netns_frags	ct_frags;
+
+#ifdef CONFIG_SYSCTL
+	struct nf_conntrack_l3proto *nf_conntrack_l3proto_ipv6;
+#endif
 #ifdef CONFIG_NETFILTER
 	struct xt_table		*ip6table_filter;
 	struct xt_table		*ip6table_mangle;
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 8623b7c..8288efc 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -372,14 +372,14 @@ static int nf_ct_proto_ipv6_init_net(struct net *net)
 			return -ENOMEM;
 	}
 
-	ve_nf_conntrack_l3proto_ipv6 = ipv6;
+	net->ipv6.nf_conntrack_l3proto_ipv6 = ipv6;
 	return 0;
 }
 
 static void nf_ct_proto_ipv6_exit_net(struct net *net)
 {
 	if (net != &init_net)
-		kfree(ve_nf_conntrack_l3proto_ipv6);
+		kfree(net->ipv6.nf_conntrack_l3proto_ipv6);
 }
 
 static struct pernet_operations nf_ct_ipv6_ops = {
@@ -389,6 +389,8 @@ static struct pernet_operations nf_ct_ipv6_ops = {
 
 int init_nf_ct_l3proto_ipv6(void)
 {
+	struct net *net = get_exec_env()->ve_netns;
+
 	int ret = -ENOMEM;
 
 #ifdef CONFIG_VE_IPTABLES
@@ -417,7 +419,7 @@ int init_nf_ct_l3proto_ipv6(void)
 		goto unreg_udp;
 	}
 
-	ret = nf_conntrack_l3proto_register(ve_nf_conntrack_l3proto_ipv6);
+	ret = nf_conntrack_l3proto_register(net->ipv6.nf_conntrack_l3proto_ipv6);
 	if (ret < 0) {
 		printk("nf_conntrack_ipv6: can't register ipv6\n");
 		goto unreg_icmpv6;
@@ -443,7 +445,9 @@ EXPORT_SYMBOL(init_nf_ct_l3proto_ipv6);
 
 void fini_nf_ct_l3proto_ipv6(void)
 {
-	nf_conntrack_l3proto_unregister(ve_nf_conntrack_l3proto_ipv6);
+	struct net *net = get_exec_env()->ve_netns;
+
+	nf_conntrack_l3proto_unregister(net->ipv6.nf_conntrack_l3proto_ipv6);
 	nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_icmpv6);
 	nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_udp6);
 	nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_tcp6);
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index cae064f..20e8750 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -132,6 +132,7 @@ icmpv6_error_message(struct sk_buff *skb,
 	struct nf_conntrack_tuple intuple, origtuple;
 	const struct nf_conntrack_tuple_hash *h;
 	const struct nf_conntrack_l4proto *inproto;
+	struct net *net = get_exec_env()->ve_netns;
 
 	NF_CT_ASSERT(skb->nfct == NULL);
 
@@ -151,7 +152,7 @@ icmpv6_error_message(struct sk_buff *skb,
 	/* Ordinarily, we'd expect the inverted tupleproto, but it's
 	   been preserved inside the ICMP. */
 	if (!nf_ct_invert_tuple(&intuple, &origtuple,
-				ve_nf_conntrack_l3proto_ipv6, inproto)) {
+				net->ipv6.nf_conntrack_l3proto_ipv6, inproto)) {
 		pr_debug("icmpv6_error: Can't invert tuple\n");
 		return -NF_ACCEPT;
 	}
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index e8e4112..c2236df 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -700,7 +700,7 @@ static int nf_ct_frag6_init_net(struct net *net)
 #ifdef CONFIG_SYSCTL
 	if (net != &init_net) {
 		struct nf_conntrack_l3proto *ipv6 =
-			ve_nf_conntrack_l3proto_ipv6;
+			net->ipv6.nf_conntrack_l3proto_ipv6;
 
 		ipv6->ctl_table = kmemdup(nf_ct_ipv6_sysctl_table,
 					  sizeof(nf_ct_ipv6_sysctl_table),
@@ -728,7 +728,7 @@ static void nf_ct_frag6_exit_net(struct net *net)
 {
 	inet_frags_exit_net(&net->ipv6.ct_frags, &nf_frags);
 	if (net != &init_net)
-		kfree(ve_nf_conntrack_l3proto_ipv6->ctl_table);
+		kfree(net->ipv6.nf_conntrack_l3proto_ipv6->ctl_table);
 
 }
 
-- 
1.6.0.6

-------------- next part --------------
>From 43553442d9467e2cdca7be044ff0cd497abe987f Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Thu, 25 Sep 2008 13:06:13 +0400
Subject: [PATCH] conntrack: fix oops in nf_ct_frag6_gather

skb->dev == NULL in NF_LOCAL_OUT hook level. So dev_inet(skb->dev)
in nf_ct_frag6_gather() function causes OOPS.
Pass directly net namespace to nf_ct_frag6_gather() as parameter
to avoid this issue.

(#122210)

Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
 include/net/netfilter/ipv6/nf_conntrack_ipv6.h |    3 ++-
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    3 ++-
 net/ipv6/netfilter/nf_conntrack_reasm.c        |    4 ++--
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
index abc55ad..9cc2036 100644
--- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
@@ -9,7 +9,8 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
 
 extern int nf_ct_frag6_init(void);
 extern void nf_ct_frag6_cleanup(void);
-extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb);
+extern struct sk_buff *nf_ct_frag6_gather(struct net *net,
+					  struct sk_buff *skb);
 extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
 			       struct net_device *in,
 			       struct net_device *out,
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 8288efc..5ff46a2 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -191,12 +191,13 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
 				int (*okfn)(struct sk_buff *))
 {
 	struct sk_buff *reasm;
+	struct net *net = out ? dev_net(out) : dev_net(in);
 
 	/* Previously seen (loopback)?  */
 	if (skb->nfct)
 		return NF_ACCEPT;
 
-	reasm = nf_ct_frag6_gather(skb);
+	reasm = nf_ct_frag6_gather(net, skb);
 
 	/* queued */
 	if (reasm == NULL)
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index c2236df..7036eba 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -593,7 +593,8 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
 	return 0;
 }
 
-struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
+struct sk_buff *nf_ct_frag6_gather(struct net *net,
+				   struct sk_buff *skb)
 {
 	struct sk_buff *clone;
 	struct net_device *dev = skb->dev;
@@ -603,7 +604,6 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
 	int fhoff, nhoff;
 	u8 prevhdr;
 	struct sk_buff *ret_skb = NULL;
-	struct net *net = dev_net(dev);
 
 	/* Jumbo payload inhibits frag. header */
 	if (ipv6_hdr(skb)->payload_len == 0) {
-- 
1.6.0.6

-------------- next part --------------
>From 6e9609de26cc3a730b423624ed442cc26308c873 Mon Sep 17 00:00:00 2001
From: Vitaliy Gusev <vgusev at openvz.org>
Date: Tue, 14 Oct 2008 19:14:31 +0400
Subject: [PATCH] conntrack ipv6: Fix error path if nf_register_hooks fails.

commit 482dd20b (conntrack: prevent call nf_register_hooks()) has a error:
immediate return without any cleanup.

Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
---
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 5ff46a2..c047804 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -486,13 +486,15 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 	if (ret < 0) {
 		printk(KERN_ERR "nf_conntrack_ipv6: can't register pre-routing "
 		       "defrag hook.\n");
-		return ret;
+		goto cleanup_l3proto;
 	}
 	KSYMRESOLVE(init_nf_ct_l3proto_ipv6);
 	KSYMRESOLVE(fini_nf_ct_l3proto_ipv6);
 	KSYMMODRESOLVE(nf_conntrack_ipv6);
 	return 0;
 
+cleanup_l3proto:
+	fini_nf_ct_l3proto_ipv6();
 cleanup_frag6:
 	nf_ct_frag6_cleanup();
 unreg_subsys:
-- 
1.6.0.6



More information about the Debian mailing list