]> git.baikalelectronics.ru Git - kernel.git/commitdiff
netfilter: nf_conntrack: fix nf_conntrack_l3proto_register
authorGao feng <gaofeng@cn.fujitsu.com>
Thu, 21 Jun 2012 04:36:38 +0000 (04:36 +0000)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 27 Jun 2012 16:11:15 +0000 (18:11 +0200)
Before commit c1dfb81ebe045b5141f6e648766a3c45b47d9b92
(netfilter: nf_conntrack: prepare namespace support for
l4 protocol trackers), we register sysctl before register
protocol tracker. Thus, if sysctl is registration fails,
the protocol tracker will not be registered.

After that commit, if sysctl registration fails, protocol
registration still remains, so we leave things in intermediate
state.

To fix this, this patch registers sysctl before protocols.
And if protocol registration fail, sysctl is unregistered.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_conntrack_proto.c

index 1ea919450fc3b654ab9445cc7d6543adb79bb0fc..9bd88aa3c74f5c850a5e3125258677bad7d96ae5 100644 (file)
@@ -253,18 +253,23 @@ int nf_conntrack_l3proto_register(struct net *net,
 {
        int ret = 0;
 
-       if (net == &init_net)
-               ret = nf_conntrack_l3proto_register_net(proto);
+       if (proto->init_net) {
+               ret = proto->init_net(net);
+               if (ret < 0)
+                       return ret;
+       }
 
+       ret = nf_ct_l3proto_register_sysctl(net, proto);
        if (ret < 0)
                return ret;
 
-       if (proto->init_net) {
-               ret = proto->init_net(net);
+       if (net == &init_net) {
+               ret = nf_conntrack_l3proto_register_net(proto);
                if (ret < 0)
-                       return ret;
+                       nf_ct_l3proto_unregister_sysctl(net, proto);
        }
-       return nf_ct_l3proto_register_sysctl(net, proto);
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
 
@@ -454,19 +459,24 @@ int nf_conntrack_l4proto_register(struct net *net,
                                  struct nf_conntrack_l4proto *l4proto)
 {
        int ret = 0;
-       if (net == &init_net)
-               ret = nf_conntrack_l4proto_register_net(l4proto);
 
-       if (ret < 0)
-               return ret;
-
-       if (l4proto->init_net)
+       if (l4proto->init_net) {
                ret = l4proto->init_net(net);
+               if (ret < 0)
+                       return ret;
+       }
 
+       ret = nf_ct_l4proto_register_sysctl(net, l4proto);
        if (ret < 0)
                return ret;
 
-       return nf_ct_l4proto_register_sysctl(net, l4proto);
+       if (net == &init_net) {
+               ret = nf_conntrack_l4proto_register_net(l4proto);
+               if (ret < 0)
+                       nf_ct_l4proto_unregister_sysctl(net, l4proto);
+       }
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);