Patchwork [07/15] netfilter: add namespace support for l4proto_icmpv6

login
register
mail settings
Submitter Gao feng
Date May 29, 2012, 7:04 a.m.
Message ID <1338275063-11711-8-git-send-email-gaofeng@cn.fujitsu.com>
Download mbox | patch
Permalink /patch/161690/
State Accepted
Headers show

Comments

Gao feng - May 29, 2012, 7:04 a.m.
implement icmpv6_init_net is to initial the pernet data for
icmpv6 proto.

because nf_icmp_net is a field of netns_ct,so when proto is icmpv6,
return net->ct.proto.icmpv6 in function nf_ct_l4proto_net.

Acked-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
 include/net/netns/conntrack.h                  |    1 +
 net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c |   25 ++++++++++++++++++++++-
 net/netfilter/nf_conntrack_proto.c             |    2 +
 3 files changed, 26 insertions(+), 2 deletions(-)

Patch

diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index 3d8e9e3..3aecdc7 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -55,6 +55,7 @@  struct nf_ip_net {
 	struct nf_tcp_net	tcp;
 	struct nf_udp_net	udp;
 	struct nf_icmp_net	icmp;
+	struct nf_icmp_net	icmpv6;
 #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
 	struct ctl_table_header *ctl_table_header;
 	struct ctl_table	*ctl_table;
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 3e81904..f606355 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -29,6 +29,11 @@ 
 
 static unsigned int nf_ct_icmpv6_timeout __read_mostly = 30*HZ;
 
+static inline struct nf_icmp_net *icmpv6_pernet(struct net *net)
+{
+	return &net->ct.nf_ct_proto.icmpv6;
+}
+
 static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb,
 				unsigned int dataoff,
 				struct nf_conntrack_tuple *tuple)
@@ -90,7 +95,7 @@  static int icmpv6_print_tuple(struct seq_file *s,
 
 static unsigned int *icmpv6_get_timeouts(struct net *net)
 {
-	return &nf_ct_icmpv6_timeout;
+	return &icmpv6_pernet(net)->timeout;
 }
 
 /* Returns verdict for packet, or -1 for invalid. */
@@ -319,7 +324,6 @@  static struct ctl_table_header *icmpv6_sysctl_header;
 static struct ctl_table icmpv6_sysctl_table[] = {
 	{
 		.procname	= "nf_conntrack_icmpv6_timeout",
-		.data		= &nf_ct_icmpv6_timeout,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
@@ -328,6 +332,22 @@  static struct ctl_table icmpv6_sysctl_table[] = {
 };
 #endif /* CONFIG_SYSCTL */
 
+static int icmpv6_init_net(struct net *net)
+{
+	struct nf_icmp_net *in = icmpv6_pernet(net);
+	struct nf_proto_net *pn = (struct nf_proto_net *)in;
+	in->timeout = nf_ct_icmpv6_timeout;
+#ifdef CONFIG_SYSCTL
+	pn->ctl_table = kmemdup(icmpv6_sysctl_table,
+				sizeof(icmpv6_sysctl_table),
+				GFP_KERNEL);
+	if (!pn->ctl_table)
+		return -ENOMEM;
+	pn->ctl_table[0].data = &in->timeout;
+#endif
+	return 0;
+}
+
 struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
 {
 	.l3proto		= PF_INET6,
@@ -359,4 +379,5 @@  struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
 	.ctl_table_header	= &icmpv6_sysctl_header,
 	.ctl_table		= icmpv6_sysctl_table,
 #endif
+	.init_net		= icmpv6_init_net,
 };
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 1bea0ed..8a18e2e 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -308,6 +308,8 @@  static struct nf_proto_net *nf_ct_l4proto_net(struct net *net,
 		return (struct nf_proto_net *)&net->ct.nf_ct_proto.udp;
 	case IPPROTO_ICMP:
 		return (struct nf_proto_net *)&net->ct.nf_ct_proto.icmp;
+	case IPPROTO_ICMPV6:
+		return (struct nf_proto_net *)&net->ct.nf_ct_proto.icmpv6;
 	case 255: /* l4proto_generic */
 		return (struct nf_proto_net *)&net->ct.nf_ct_proto.generic;
 	default: