nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto);
 extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p);
 
-/* Protocol registration. */
-extern int nf_conntrack_l4proto_register(struct net *net,
+/* Protocol pernet registration. */
+extern int nf_ct_l4proto_pernet_register(struct net *net,
                                         struct nf_conntrack_l4proto *proto);
-extern void nf_conntrack_l4proto_unregister(struct net *net,
+extern void nf_ct_l4proto_pernet_unregister(struct net *net,
                                            struct nf_conntrack_l4proto *proto);
 
+/* Protocol global registration. */
+extern int nf_ct_l4proto_register(struct nf_conntrack_l4proto *proto);
+extern void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *proto);
+
 static inline void nf_ct_kfree_compat_sysctl_table(struct nf_proto_net *pn)
 {
 #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
 
 {
        int ret = 0;
 
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_tcp4);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_tcp4);
        if (ret < 0) {
-               pr_err("nf_conntrack_l4proto_tcp4 :protocol register failed\n");
+               pr_err("nf_conntrack_tcp4: pernet registration failed\n");
                goto out_tcp;
        }
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_udp4);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udp4);
        if (ret < 0) {
-               pr_err("nf_conntrack_l4proto_udp4 :protocol register failed\n");
+               pr_err("nf_conntrack_udp4: pernet registration failed\n");
                goto out_udp;
        }
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_icmp);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_icmp);
        if (ret < 0) {
-               pr_err("nf_conntrack_l4proto_icmp4 :protocol register failed\n");
+               pr_err("nf_conntrack_icmp4: pernet registration failed\n");
                goto out_icmp;
        }
        ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv4);
        }
        return 0;
 out_ipv4:
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_icmp);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmp);
 out_icmp:
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_udp4);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp4);
 out_udp:
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_tcp4);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp4);
 out_tcp:
        return ret;
 }
 static void ipv4_net_exit(struct net *net)
 {
        nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv4);
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_icmp);
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_udp4);
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_tcp4);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmp);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp4);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp4);
 }
 
 static struct pernet_operations ipv4_net_ops = {
                goto cleanup_pernet;
        }
 
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_tcp4);
+       if (ret < 0) {
+               pr_err("nf_conntrack_ipv4: can't register tcp4 proto.\n");
+               goto cleanup_hooks;
+       }
+
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udp4);
+       if (ret < 0) {
+               pr_err("nf_conntrack_ipv4: can't register udp4 proto.\n");
+               goto cleanup_tcp4;
+       }
+
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_icmp);
+       if (ret < 0) {
+               pr_err("nf_conntrack_ipv4: can't register icmpv4 proto.\n");
+               goto cleanup_udp4;
+       }
+
        ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv4);
        if (ret < 0) {
                pr_err("nf_conntrack_ipv4: can't register ipv4 proto.\n");
-               goto cleanup_hooks;
+               goto cleanup_icmpv4;
        }
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
  cleanup_proto:
        nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
 #endif
+ cleanup_icmpv4:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmp);
+ cleanup_udp4:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp4);
+ cleanup_tcp4:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
  cleanup_hooks:
        nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
  cleanup_pernet:
        nf_conntrack_ipv4_compat_fini();
 #endif
        nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmp);
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp4);
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
        nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
        unregister_pernet_subsys(&ipv4_net_ops);
        nf_unregister_sockopt(&so_getorigdst);
 
 {
        int ret = 0;
 
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_tcp6);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_tcp6);
        if (ret < 0) {
-               printk(KERN_ERR "nf_conntrack_l4proto_tcp6: protocol register failed\n");
+               pr_err("nf_conntrack_tcp6: pernet registration failed\n");
                goto out;
        }
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_udp6);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udp6);
        if (ret < 0) {
-               printk(KERN_ERR "nf_conntrack_l4proto_udp6: protocol register failed\n");
+               pr_err("nf_conntrack_udp6: pernet registration failed\n");
                goto cleanup_tcp6;
        }
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_icmpv6);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_icmpv6);
        if (ret < 0) {
-               printk(KERN_ERR "nf_conntrack_l4proto_icmp6: protocol register failed\n");
+               pr_err("nf_conntrack_icmp6: pernet registration failed\n");
                goto cleanup_udp6;
        }
        ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv6);
        }
        return 0;
  cleanup_icmpv6:
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_icmpv6);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmpv6);
  cleanup_udp6:
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_udp6);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp6);
  cleanup_tcp6:
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_tcp6);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp6);
  out:
        return ret;
 }
 static void ipv6_net_exit(struct net *net)
 {
        nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv6);
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_icmpv6);
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_udp6);
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_tcp6);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmpv6);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp6);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp6);
 }
 
 static struct pernet_operations ipv6_net_ops = {
                goto cleanup_pernet;
        }
 
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_tcp6);
+       if (ret < 0) {
+               pr_err("nf_conntrack_ipv6: can't register tcp6 proto.\n");
+               goto cleanup_hooks;
+       }
+
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udp6);
+       if (ret < 0) {
+               pr_err("nf_conntrack_ipv6: can't register udp6 proto.\n");
+               goto cleanup_tcp6;
+       }
+
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_icmpv6);
+       if (ret < 0) {
+               pr_err("nf_conntrack_ipv6: can't register icmpv6 proto.\n");
+               goto cleanup_udp6;
+       }
+
        ret = nf_ct_l3proto_register(&nf_conntrack_l3proto_ipv6);
        if (ret < 0) {
                pr_err("nf_conntrack_ipv6: can't register ipv6 proto.\n");
-               goto cleanup_hooks;
+               goto cleanup_icmpv6;
        }
        return ret;
 
+ cleanup_icmpv6:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
+ cleanup_udp6:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp6);
+ cleanup_tcp6:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
  cleanup_hooks:
        nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
  cleanup_pernet:
 {
        synchronize_net();
        nf_ct_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udp6);
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
        nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
        unregister_pernet_subsys(&ipv6_net_ops);
        nf_unregister_sockopt(&so_getorigdst6);
 
 
 /* FIXME: Allow NULL functions and sub in pointers to generic for
    them. --RR */
-static int
-nf_conntrack_l4proto_register_net(struct nf_conntrack_l4proto *l4proto)
+int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto)
 {
        int ret = 0;
 
        mutex_unlock(&nf_ct_proto_mutex);
        return ret;
 }
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_register);
 
-int nf_conntrack_l4proto_register(struct net *net,
+int nf_ct_l4proto_pernet_register(struct net *net,
                                  struct nf_conntrack_l4proto *l4proto)
 {
        int ret = 0;
        if (ret < 0)
                goto out;
 
-       if (net == &init_net) {
-               ret = nf_conntrack_l4proto_register_net(l4proto);
-               if (ret < 0) {
-                       nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
-                       goto out;
-               }
-       }
-
        pn->users++;
 out:
        return ret;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_register);
 
-static void
-nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
+void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
 {
        BUG_ON(l4proto->l3proto >= PF_MAX);
 
 
        synchronize_rcu();
 }
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister);
 
-void nf_conntrack_l4proto_unregister(struct net *net,
+void nf_ct_l4proto_pernet_unregister(struct net *net,
                                     struct nf_conntrack_l4proto *l4proto)
 {
        struct nf_proto_net *pn = NULL;
 
-       if (net == &init_net)
-               nf_conntrack_l4proto_unregister_net(l4proto);
-
        pn = nf_ct_l4proto_net(net, l4proto);
        if (pn == NULL)
                return;
        /* Remove all contrack entries for this protocol */
        nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister);
 
 int nf_conntrack_proto_pernet_init(struct net *net)
 {
 
 static __net_init int dccp_net_init(struct net *net)
 {
        int ret = 0;
-       ret = nf_conntrack_l4proto_register(net,
-                                           &dccp_proto4);
+       ret = nf_ct_l4proto_pernet_register(net, &dccp_proto4);
        if (ret < 0) {
-               pr_err("nf_conntrack_l4proto_dccp4 :protocol register failed.\n");
+               pr_err("nf_conntrack_dccp4: pernet registration failed.\n");
                goto out;
        }
-       ret = nf_conntrack_l4proto_register(net,
-                                           &dccp_proto6);
+       ret = nf_ct_l4proto_pernet_register(net, &dccp_proto6);
        if (ret < 0) {
-               pr_err("nf_conntrack_l4proto_dccp6 :protocol register failed.\n");
+               pr_err("nf_conntrack_dccp6: pernet registration failed.\n");
                goto cleanup_dccp4;
        }
        return 0;
 cleanup_dccp4:
-       nf_conntrack_l4proto_unregister(net,
-                                       &dccp_proto4);
+       nf_ct_l4proto_pernet_unregister(net, &dccp_proto4);
 out:
        return ret;
 }
 
 static __net_exit void dccp_net_exit(struct net *net)
 {
-       nf_conntrack_l4proto_unregister(net,
-                                       &dccp_proto6);
-       nf_conntrack_l4proto_unregister(net,
-                                       &dccp_proto4);
+       nf_ct_l4proto_pernet_unregister(net, &dccp_proto6);
+       nf_ct_l4proto_pernet_unregister(net, &dccp_proto4);
 }
 
 static struct pernet_operations dccp_net_ops = {
 
 static int __init nf_conntrack_proto_dccp_init(void)
 {
-       return register_pernet_subsys(&dccp_net_ops);
+       int ret;
+
+       ret = nf_ct_l4proto_register(&dccp_proto4);
+       if (ret < 0)
+               goto out_dccp4;
+
+       ret = nf_ct_l4proto_register(&dccp_proto6);
+       if (ret < 0)
+               goto out_dccp6;
+
+       ret = register_pernet_subsys(&dccp_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
+       return 0;
+out_pernet:
+       nf_ct_l4proto_unregister(&dccp_proto6);
+out_dccp6:
+       nf_ct_l4proto_unregister(&dccp_proto4);
+out_dccp4:
+       return ret;
 }
 
 static void __exit nf_conntrack_proto_dccp_fini(void)
 {
+       nf_ct_l4proto_unregister(&dccp_proto6);
+       nf_ct_l4proto_unregister(&dccp_proto4);
        unregister_pernet_subsys(&dccp_net_ops);
 }
 
 
 static int proto_gre_net_init(struct net *net)
 {
        int ret = 0;
-       ret = nf_conntrack_l4proto_register(net, &nf_conntrack_l4proto_gre4);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_gre4);
        if (ret < 0)
-               pr_err("nf_conntrack_l4proto_gre4 :protocol register failed.\n");
+               pr_err("nf_conntrack_gre4: pernet registration failed.\n");
        return ret;
 }
 
 static void proto_gre_net_exit(struct net *net)
 {
-       nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_gre4);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_gre4);
        nf_ct_gre_keymap_flush(net);
 }
 
 
 static int __init nf_ct_proto_gre_init(void)
 {
-       return register_pernet_subsys(&proto_gre_net_ops);
+       int ret;
+
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_gre4);
+       if (ret < 0)
+               goto out_gre4;
+
+       ret = register_pernet_subsys(&proto_gre_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
+       return 0;
+out_pernet:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_gre4);
+out_gre4:
+       return ret;
 }
 
 static void __exit nf_ct_proto_gre_fini(void)
 {
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_gre4);
        unregister_pernet_subsys(&proto_gre_net_ops);
 }
 
 
 {
        int ret = 0;
 
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_sctp4);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_sctp4);
        if (ret < 0) {
-               pr_err("nf_conntrack_l4proto_sctp4 :protocol register failed.\n");
+               pr_err("nf_conntrack_sctp4: pernet registration failed.\n");
                goto out;
        }
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_sctp6);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_sctp6);
        if (ret < 0) {
-               pr_err("nf_conntrack_l4proto_sctp6 :protocol register failed.\n");
+               pr_err("nf_conntrack_sctp6: pernet registration failed.\n");
                goto cleanup_sctp4;
        }
        return 0;
 
 cleanup_sctp4:
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_sctp4);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_sctp4);
 out:
        return ret;
 }
 
 static void sctp_net_exit(struct net *net)
 {
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_sctp6);
-       nf_conntrack_l4proto_unregister(net,
-                                       &nf_conntrack_l4proto_sctp4);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_sctp6);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_sctp4);
 }
 
 static struct pernet_operations sctp_net_ops = {
 
 static int __init nf_conntrack_proto_sctp_init(void)
 {
-       return register_pernet_subsys(&sctp_net_ops);
+       int ret;
+
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp4);
+       if (ret < 0)
+               goto out_sctp4;
+
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp6);
+       if (ret < 0)
+               goto out_sctp6;
+
+       ret = register_pernet_subsys(&sctp_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
+       return 0;
+out_pernet:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
+out_sctp6:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
+out_sctp4:
+       return ret;
 }
 
 static void __exit nf_conntrack_proto_sctp_fini(void)
 {
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
        unregister_pernet_subsys(&sctp_net_ops);
 }
 
 
 {
        int ret = 0;
 
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_udplite4);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udplite4);
        if (ret < 0) {
-               pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
+               pr_err("nf_conntrack_udplite4: pernet registration failed.\n");
                goto out;
        }
-       ret = nf_conntrack_l4proto_register(net,
-                                           &nf_conntrack_l4proto_udplite6);
+       ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udplite6);
        if (ret < 0) {
-               pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
+               pr_err("nf_conntrack_udplite6: pernet registration failed.\n");
                goto cleanup_udplite4;
        }
        return 0;
 
 cleanup_udplite4:
-       nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udplite4);
 out:
        return ret;
 }
 
 static void udplite_net_exit(struct net *net)
 {
-       nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite6);
-       nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udplite4);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udplite6);
+       nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udplite4);
 }
 
 static struct pernet_operations udplite_net_ops = {
 
 static int __init nf_conntrack_proto_udplite_init(void)
 {
-       return register_pernet_subsys(&udplite_net_ops);
+       int ret;
+
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udplite4);
+       if (ret < 0)
+               goto out_udplite4;
+
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udplite6);
+       if (ret < 0)
+               goto out_udplite6;
+
+       ret = register_pernet_subsys(&udplite_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
+       return 0;
+out_pernet:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
+out_udplite6:
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
+out_udplite4:
+       return ret;
 }
 
 static void __exit nf_conntrack_proto_udplite_exit(void)
 {
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
+       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
        unregister_pernet_subsys(&udplite_net_ops);
 }