[PATCH nf-next] netfilter: conntrack: simplify init/uninit of L4 protocol trackers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



modify registration and deregistration of layer-4 protocol trackers to
facilitate inclusion of new elements into the current list of built-in
protocols.

Signed-off-by: Davide Caratti <dcaratti@xxxxxxxxxx>
---
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 93 +++++++++++---------------
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 93 +++++++++++---------------
 2 files changed, 78 insertions(+), 108 deletions(-)

diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 713c09a..6ffe3dc 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -336,47 +336,44 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
 MODULE_ALIAS("ip_conntrack");
 MODULE_LICENSE("GPL");
 
+static struct nf_conntrack_l4proto *nf_conntrack_l4proto4[] = {
+	&nf_conntrack_l4proto_tcp4,
+	&nf_conntrack_l4proto_udp4,
+	&nf_conntrack_l4proto_icmp,
+};
+
 static int ipv4_net_init(struct net *net)
 {
-	int ret = 0;
+	int i, ret = 0;
 
-	ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_tcp4);
-	if (ret < 0) {
-		pr_err("nf_conntrack_tcp4: pernet registration failed\n");
-		goto out_tcp;
-	}
-	ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udp4);
-	if (ret < 0) {
-		pr_err("nf_conntrack_udp4: pernet registration failed\n");
-		goto out_udp;
-	}
-	ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_icmp);
-	if (ret < 0) {
-		pr_err("nf_conntrack_icmp4: pernet registration failed\n");
-		goto out_icmp;
+	for (i = 0; i < ARRAY_SIZE(nf_conntrack_l4proto4); i++) {
+		ret = nf_ct_l4proto_pernet_register(net,
+						    nf_conntrack_l4proto4[i]);
+		if (ret < 0)
+			goto cleanup_l4proto;
 	}
 	ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv4);
 	if (ret < 0) {
 		pr_err("nf_conntrack_ipv4: pernet registration failed\n");
-		goto out_ipv4;
+		goto cleanup_l4proto;
 	}
 	return 0;
-out_ipv4:
-	nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmp);
-out_icmp:
-	nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp4);
-out_udp:
-	nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp4);
-out_tcp:
+cleanup_l4proto:
+	if (i < ARRAY_SIZE(nf_conntrack_l4proto4))
+		pr_err("nf_conntrack_%s4: pernet registration failed\n",
+		       nf_conntrack_l4proto4[i]->name);
+	while (--i >= 0)
+		nf_ct_l4proto_pernet_unregister(net, nf_conntrack_l4proto4[i]);
 	return ret;
 }
 
 static void ipv4_net_exit(struct net *net)
 {
+	int i;
+
 	nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv4);
-	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);
+	for (i = ARRAY_SIZE(nf_conntrack_l4proto4) - 1; i >= 0 ; i--)
+		nf_ct_l4proto_pernet_unregister(net, nf_conntrack_l4proto4[i]);
 }
 
 static struct pernet_operations ipv4_net_ops = {
@@ -386,7 +383,7 @@ static struct pernet_operations ipv4_net_ops = {
 
 static int __init nf_conntrack_l3proto_ipv4_init(void)
 {
-	int ret = 0;
+	int ret = 0, i;
 
 	need_conntrack();
 	nf_defrag_ipv4_enable();
@@ -410,38 +407,25 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 		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;
+	for (i = 0; i < ARRAY_SIZE(nf_conntrack_l4proto4); i++) {
+		ret = nf_ct_l4proto_register(nf_conntrack_l4proto4[i]);
+		if (ret < 0)
+			goto cleanup_l4proto;
 	}
 
 	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_icmpv4;
+		goto cleanup_l4proto;
 	}
 
 	return ret;
- 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:
+cleanup_l4proto:
+	if (i < ARRAY_SIZE(nf_conntrack_l4proto4))
+		pr_err("nf_conntrack_ipv4: can't register %s4 proto.\n",
+		       nf_conntrack_l4proto4[i]->name);
+	while (--i >= 0)
+		nf_ct_l4proto_unregister(nf_conntrack_l4proto4[i]);
 	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
  cleanup_pernet:
 	unregister_pernet_subsys(&ipv4_net_ops);
@@ -452,11 +436,12 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 
 static void __exit nf_conntrack_l3proto_ipv4_fini(void)
 {
+	int i;
+
 	synchronize_net();
 	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);
+	for (i = ARRAY_SIZE(nf_conntrack_l4proto4) - 1; i >= 0; i--)
+		nf_ct_l4proto_unregister(nf_conntrack_l4proto4[i]);
 	nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
 	unregister_pernet_subsys(&ipv4_net_ops);
 	nf_unregister_sockopt(&so_getorigdst);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 963ee38..4e219a1 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -336,47 +336,44 @@ static struct nf_sockopt_ops so_getorigdst6 = {
 	.owner		= THIS_MODULE,
 };
 
+static struct nf_conntrack_l4proto *nf_conntrack_l4proto6[] = {
+	&nf_conntrack_l4proto_tcp6,
+	&nf_conntrack_l4proto_udp6,
+	&nf_conntrack_l4proto_icmpv6,
+};
+
 static int ipv6_net_init(struct net *net)
 {
-	int ret = 0;
+	int i, ret = 0;
 
-	ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_tcp6);
-	if (ret < 0) {
-		pr_err("nf_conntrack_tcp6: pernet registration failed\n");
-		goto out;
-	}
-	ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_udp6);
-	if (ret < 0) {
-		pr_err("nf_conntrack_udp6: pernet registration failed\n");
-		goto cleanup_tcp6;
-	}
-	ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_icmpv6);
-	if (ret < 0) {
-		pr_err("nf_conntrack_icmp6: pernet registration failed\n");
-		goto cleanup_udp6;
+	for (i = 0; i < ARRAY_SIZE(nf_conntrack_l4proto6); i++) {
+		ret = nf_ct_l4proto_pernet_register(net,
+						    nf_conntrack_l4proto6[i]);
+		if (ret < 0)
+			goto cleanup_l4proto;
 	}
 	ret = nf_ct_l3proto_pernet_register(net, &nf_conntrack_l3proto_ipv6);
 	if (ret < 0) {
 		pr_err("nf_conntrack_ipv6: pernet registration failed.\n");
-		goto cleanup_icmpv6;
+		goto cleanup_l4proto;
 	}
 	return 0;
- cleanup_icmpv6:
-	nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_icmpv6);
- cleanup_udp6:
-	nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_udp6);
- cleanup_tcp6:
-	nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_tcp6);
- out:
+cleanup_l4proto:
+	if (i < ARRAY_SIZE(nf_conntrack_l4proto6))
+		pr_err("nf_conntrack_%s6: pernet registration failed.\n",
+		       nf_conntrack_l4proto6[i]->name);
+	while (--i >= 0)
+		nf_ct_l4proto_pernet_unregister(net, nf_conntrack_l4proto6[i]);
 	return ret;
 }
 
 static void ipv6_net_exit(struct net *net)
 {
+	int i;
+
 	nf_ct_l3proto_pernet_unregister(net, &nf_conntrack_l3proto_ipv6);
-	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);
+	for (i = ARRAY_SIZE(nf_conntrack_l4proto6) - 1; i >= 0; i--)
+		nf_ct_l4proto_pernet_unregister(net, nf_conntrack_l4proto6[i]);
 }
 
 static struct pernet_operations ipv6_net_ops = {
@@ -386,7 +383,7 @@ static struct pernet_operations ipv6_net_ops = {
 
 static int __init nf_conntrack_l3proto_ipv6_init(void)
 {
-	int ret = 0;
+	int ret = 0, i;
 
 	need_conntrack();
 	nf_defrag_ipv6_enable();
@@ -409,38 +406,25 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 		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;
+	for (i = 0; i < ARRAY_SIZE(nf_conntrack_l4proto6); i++) {
+		ret = nf_ct_l4proto_register(nf_conntrack_l4proto6[i]);
+		if (ret < 0)
+			goto cleanup_l4proto;
 	}
 
 	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_icmpv6;
+		goto cleanup_l4proto;
 	}
 	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:
+cleanup_l4proto:
+	if (i < ARRAY_SIZE(nf_conntrack_l4proto6))
+		pr_err("nf_conntrack_ipv6: can't register %s6 proto.\n",
+		       nf_conntrack_l4proto6[i]->name);
+	while (--i >= 0)
+		nf_ct_l4proto_unregister(nf_conntrack_l4proto6[i]);
 	nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
  cleanup_pernet:
 	unregister_pernet_subsys(&ipv6_net_ops);
@@ -451,11 +435,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 
 static void __exit nf_conntrack_l3proto_ipv6_fini(void)
 {
+	int i;
+
 	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);
+	for (i = 0; i < ARRAY_SIZE(nf_conntrack_l4proto6); i++)
+		nf_ct_l4proto_unregister(nf_conntrack_l4proto6[i]);
 	nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
 	unregister_pernet_subsys(&ipv6_net_ops);
 	nf_unregister_sockopt(&so_getorigdst6);
-- 
2.5.5

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux