Subject: Re: net/netfilter/nf_conntrack_proto_tcp.c:1606:9: error: ‘struct nf_proto_net’ has no member named ‘user’

From: Gao feng <[email-masked]>
Date: Tue, 12 Jun 2012 19:03:31 +0800

于 2012年06月12日 17:29, Pablo Neira Ayuso 写道:

>> nf_proto_net.users has different meaning when SYSCTL enabled or disabled.
>>
>> when SYSCTL enabled,it means if both tcpv4 and tcpv6 register the sysctl,
>> it is increased when register sysctl success and decreased when unregister sysctl.
>> we can regard it as the refcnt of ctl_table.
>>
>> when SYSCTL disabled,it just used to identify if the proto's pernet data
>> has been initialized.
> 
> We have to use two different counters for this. The conditional
> meaning of that variable is really confusing.
> 
Hi David & Pablo

Please have a look at this patch and tell me if it's OK.
it base on Pable's patch.

diff --git a/include/net/netfilter/nf_conntrack_tcp.h b/include/net/netfilter/nf_conntrack_tcp.h
index 8d16ebe..0945446 100644
--- a/include/net/netfilter/nf_conntrack_tcp.h
+++ b/include/net/netfilter/nf_conntrack_tcp.h
@@ -1,8 +1,16 @@
 #ifndef _NF_CONNTRACK_TCP_H_
 #define _NF_CONNTRACK_TCP_H_

-int nf_ct_tcp_kmemdup_sysctl_table(struct nf_proto_net *pn);
-int nf_ct_tcp_compat_kmemdup_sysctl_table(struct nf_proto_net *pn);
-void nf_ct_tcp_compat_kfree_sysctl_table(struct nf_proto_net *pn);
+#ifdef CONFIG_SYSCTL
+int nf_ct_tcpv4_init_sysctl(struct nf_proto_net *pn);
+int nf_ct_tcpv6_init_sysctl(struct nf_proto_net *pn);
+#else
+int nf_ct_tcpv4_init_sysctl(struct nf_proto_net *pn)
+{
+       pn->users++;
+       return 0;
+}

+#define nf_ct_tcpv6_init_sysctl nf_ct_tcpv4_init_sysctl
+#endif
 #endif
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index cdf8b93..367153a 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1368,12 +1368,11 @@ static const struct nla_policy tcp_timeout_nla_policy[CTA_TIMEOUT_TCP_MAX+1] = {

 static int tcpv4_init_net(struct net *net)
 {
-       int i;
-       int ret = 0;
        struct nf_tcp_net *tn = tcp_pernet(net);
        struct nf_proto_net *pn = (struct nf_proto_net *)tn;

-       if (!pn->users++) {
+       if (!pn->users) {
+               int i;
                for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
                        tn->timeouts[i] = tcp_timeouts[i];

@@ -1382,25 +1381,16 @@ static int tcpv4_init_net(struct net *net)
                tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
        }

-       ret = nf_ct_tcp_compat_kmemdup_sysctl_table(pn);
-       if (ret < 0)
-               return ret;
-
-       ret = nf_ct_tcp_kmemdup_sysctl_table(pn);
-       if (ret < 0) {
-               kfree(pn->ctl_compat_table);
-               pn->ctl_compat_table = NULL;
-       }
-       return ret;
+       return nf_ct_tcpv4_init_sysctl(pn);
 }

 static int tcpv6_init_net(struct net *net)
 {
-       int i;
        struct nf_tcp_net *tn = tcp_pernet(net);
        struct nf_proto_net *pn = (struct nf_proto_net *)tn;

-       if (!pn->users++) {
+       if (!pn->users) {
+               int i;
                for (i = 0; i < TCP_CONNTRACK_TIMEOUT_MAX; i++)
                        tn->timeouts[i] = tcp_timeouts[i];
                tn->tcp_loose = nf_ct_tcp_loose;
@@ -1408,7 +1398,7 @@ static int tcpv6_init_net(struct net *net)
                tn->tcp_max_retrans = nf_ct_tcp_max_retrans;
        }

-       return nf_ct_tcp_kmemdup_sysctl_table(pn);
+       return nf_ct_tcpv6_init_sysctl(pn);
 }

 struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
diff --git a/net/netfilter/nf_conntrack_proto_tcp_sysctl.c b/net/netfilter/nf_conntrack_proto_tcp_sysctl.c
index b9e027f..f038de4 100644
--- a/net/netfilter/nf_conntrack_proto_tcp_sysctl.c
+++ b/net/netfilter/nf_conntrack_proto_tcp_sysctl.c
@@ -182,7 +182,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
 };
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */

-int nf_ct_tcp_kmemdup_sysctl_table(struct nf_proto_net *pn)
+static int nf_ct_tcp_kmemdup_sysctl_table(struct nf_proto_net *pn)
 {
        struct nf_tcp_net *tn = (struct nf_tcp_net *)pn;

@@ -211,7 +211,7 @@ int nf_ct_tcp_kmemdup_sysctl_table(struct nf_proto_net *pn)
        return 0;
 }

-int nf_ct_tcp_compat_kmemdup_sysctl_table(struct nf_proto_net *pn)
+static int nf_ct_tcp_compat_kmemdup_sysctl_table(struct nf_proto_net *pn)
 {
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
        struct nf_tcp_net *tn = (struct nf_tcp_net *)pn;
@@ -245,3 +245,23 @@ void nf_ct_tcp_compat_kfree_sysctl_table(struct nf_proto_net *pn)
        pn->ctl_compat_table = NULL;
 #endif
 }
+
+int nf_ct_tcpv4_init_sysctl(struct nf_proto_net *pn)
+{
+       int ret;
+
+       ret = nf_ct_tcp_compat_kmemdup_sysctl_table(pn);
+       if (ret < 0)
+               return ret;
+
+       ret = nf_ct_tcp_kmemdup_sysctl_table(pn);
+       if (ret < 0)
+               nf_ct_tcp_compat_kfree_sysctl_table(pn);
+
+       return ret;
+}
+
+int nf_ct_tcpv6_init_sysctl(struct nf_proto_net *pn)
+{
+       return nf_ct_tcp_compat_kmemdup_sysctl_table(pn);
+}