]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/netfilter/nf_conntrack_proto_generic.c
Merge branch 'v3.6-samsung-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / net / netfilter / nf_conntrack_proto_generic.c
index d8923d54b3585bf579c66eaba82dc4ec7d464236..d25f293776482f5e88c831c290058f2ca2e6af2b 100644 (file)
 
 static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
 
+static inline struct nf_generic_net *generic_pernet(struct net *net)
+{
+       return &net->ct.nf_ct_proto.generic;
+}
+
 static bool generic_pkt_to_tuple(const struct sk_buff *skb,
                                 unsigned int dataoff,
                                 struct nf_conntrack_tuple *tuple)
@@ -42,7 +47,7 @@ static int generic_print_tuple(struct seq_file *s,
 
 static unsigned int *generic_get_timeouts(struct net *net)
 {
-       return &nf_ct_generic_timeout;
+       return &(generic_pernet(net)->timeout);
 }
 
 /* Returns verdict for packet, or -1 for invalid. */
@@ -70,16 +75,18 @@ static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_cttimeout.h>
 
-static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
+                                        struct net *net, void *data)
 {
        unsigned int *timeout = data;
+       struct nf_generic_net *gn = generic_pernet(net);
 
        if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT])
                *timeout =
                    ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
        else {
                /* Set default generic timeout. */
-               *timeout = nf_ct_generic_timeout;
+               *timeout = gn->timeout;
        }
 
        return 0;
@@ -106,11 +113,9 @@ generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = {
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 
 #ifdef CONFIG_SYSCTL
-static struct ctl_table_header *generic_sysctl_header;
 static struct ctl_table generic_sysctl_table[] = {
        {
                .procname       = "nf_conntrack_generic_timeout",
-               .data           = &nf_ct_generic_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec_jiffies,
@@ -121,7 +126,6 @@ static struct ctl_table generic_sysctl_table[] = {
 static struct ctl_table generic_compat_sysctl_table[] = {
        {
                .procname       = "ip_conntrack_generic_timeout",
-               .data           = &nf_ct_generic_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec_jiffies,
@@ -131,6 +135,62 @@ static struct ctl_table generic_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
+static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn,
+                                       struct nf_generic_net *gn)
+{
+#ifdef CONFIG_SYSCTL
+       pn->ctl_table = kmemdup(generic_sysctl_table,
+                               sizeof(generic_sysctl_table),
+                               GFP_KERNEL);
+       if (!pn->ctl_table)
+               return -ENOMEM;
+
+       pn->ctl_table[0].data = &gn->timeout;
+#endif
+       return 0;
+}
+
+static int generic_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
+                                              struct nf_generic_net *gn)
+{
+#ifdef CONFIG_SYSCTL
+#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
+       pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table,
+                                      sizeof(generic_compat_sysctl_table),
+                                      GFP_KERNEL);
+       if (!pn->ctl_compat_table)
+               return -ENOMEM;
+
+       pn->ctl_compat_table[0].data = &gn->timeout;
+#endif
+#endif
+       return 0;
+}
+
+static int generic_init_net(struct net *net, u_int16_t proto)
+{
+       int ret;
+       struct nf_generic_net *gn = generic_pernet(net);
+       struct nf_proto_net *pn = &gn->pn;
+
+       gn->timeout = nf_ct_generic_timeout;
+
+       ret = generic_kmemdup_compat_sysctl_table(pn, gn);
+       if (ret < 0)
+               return ret;
+
+       ret = generic_kmemdup_sysctl_table(pn, gn);
+       if (ret < 0)
+               nf_ct_kfree_compat_sysctl_table(pn);
+
+       return ret;
+}
+
+static struct nf_proto_net *generic_get_net_proto(struct net *net)
+{
+       return &net->ct.nf_ct_proto.generic.pn;
+}
+
 struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
 {
        .l3proto                = PF_UNSPEC,
@@ -151,11 +211,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
                .nla_policy     = generic_timeout_nla_policy,
        },
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
-       .ctl_table_header       = &generic_sysctl_header,
-       .ctl_table              = generic_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
-       .ctl_compat_table       = generic_compat_sysctl_table,
-#endif
-#endif
+       .init_net               = generic_init_net,
+       .get_net_proto          = generic_get_net_proto,
 };