Commit c6a1e615 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NETFILTER]: nf_conntrack: simplify l4 protocol array allocation



The retrying after an allocation failure is not necessary anymore
since we're holding the mutex the entire time, for the same
reason the double allocation race can't happen anymore.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0661cca9
Loading
Loading
Loading
Loading
+12 −25
Original line number Diff line number Diff line
@@ -281,47 +281,34 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
		return -EBUSY;

	mutex_lock(&nf_ct_proto_mutex);
retry:
	if (nf_ct_protos[l4proto->l3proto]) {
		if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto]
				!= &nf_conntrack_l4proto_generic) {
			ret = -EBUSY;
			goto out_unlock;
		}
	} else {
	if (!nf_ct_protos[l4proto->l3proto]) {
		/* l3proto may be loaded latter. */
		struct nf_conntrack_l4proto **proto_array;
		int i;

		proto_array = (struct nf_conntrack_l4proto **)
				kmalloc(MAX_NF_CT_PROTO *
		proto_array = kmalloc(MAX_NF_CT_PROTO *
				      sizeof(struct nf_conntrack_l4proto *),
				      GFP_KERNEL);
		if (proto_array == NULL) {
			ret = -ENOMEM;
			goto out_unlock;
		}

		for (i = 0; i < MAX_NF_CT_PROTO; i++)
			proto_array[i] = &nf_conntrack_l4proto_generic;

		if (nf_ct_protos[l4proto->l3proto])
			/* bad timing, but no problem */
			kfree(proto_array);
		else
		nf_ct_protos[l4proto->l3proto] = proto_array;

		/*
		 * Just once because array is never freed until unloading
		 * nf_conntrack.ko
		 */
		goto retry;
	} else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] !=
					&nf_conntrack_l4proto_generic) {
		ret = -EBUSY;
		goto out_unlock;
	}

	ret = nf_ct_l4proto_register_sysctl(l4proto);
	if (ret < 0)
		goto out_unlock;

	rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], l4proto);
	rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
			   l4proto);

out_unlock:
	mutex_unlock(&nf_ct_proto_mutex);