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 *
- sizeof(struct nf_conntrack_l4proto *),
- GFP_KERNEL);
+ 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;
+ nf_ct_protos[l4proto->l3proto] = proto_array;
+ } 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);