aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-03-14 19:39:07 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:25:43 -0400
commitc6a1e615d1ba942b9e783079d53f741e4a8e1c89 (patch)
tree230f3c78633b4066cc49af8b45c614d32d760e34 /net
parent0661cca9c216322e77dca7f47df107c02ce4e70c (diff)
[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: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_conntrack_proto.c37
1 files changed, 12 insertions, 25 deletions
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 509725412d3b..e4aad2087f4d 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -281,47 +281,34 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
281 return -EBUSY; 281 return -EBUSY;
282 282
283 mutex_lock(&nf_ct_proto_mutex); 283 mutex_lock(&nf_ct_proto_mutex);
284retry: 284 if (!nf_ct_protos[l4proto->l3proto]) {
285 if (nf_ct_protos[l4proto->l3proto]) {
286 if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto]
287 != &nf_conntrack_l4proto_generic) {
288 ret = -EBUSY;
289 goto out_unlock;
290 }
291 } else {
292 /* l3proto may be loaded latter. */ 285 /* l3proto may be loaded latter. */
293 struct nf_conntrack_l4proto **proto_array; 286 struct nf_conntrack_l4proto **proto_array;
294 int i; 287 int i;
295 288
296 proto_array = (struct nf_conntrack_l4proto **) 289 proto_array = kmalloc(MAX_NF_CT_PROTO *
297 kmalloc(MAX_NF_CT_PROTO * 290 sizeof(struct nf_conntrack_l4proto *),
298 sizeof(struct nf_conntrack_l4proto *), 291 GFP_KERNEL);
299 GFP_KERNEL);
300 if (proto_array == NULL) { 292 if (proto_array == NULL) {
301 ret = -ENOMEM; 293 ret = -ENOMEM;
302 goto out_unlock; 294 goto out_unlock;
303 } 295 }
296
304 for (i = 0; i < MAX_NF_CT_PROTO; i++) 297 for (i = 0; i < MAX_NF_CT_PROTO; i++)
305 proto_array[i] = &nf_conntrack_l4proto_generic; 298 proto_array[i] = &nf_conntrack_l4proto_generic;
306 299 nf_ct_protos[l4proto->l3proto] = proto_array;
307 if (nf_ct_protos[l4proto->l3proto]) 300 } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] !=
308 /* bad timing, but no problem */ 301 &nf_conntrack_l4proto_generic) {
309 kfree(proto_array); 302 ret = -EBUSY;
310 else 303 goto out_unlock;
311 nf_ct_protos[l4proto->l3proto] = proto_array;
312
313 /*
314 * Just once because array is never freed until unloading
315 * nf_conntrack.ko
316 */
317 goto retry;
318 } 304 }
319 305
320 ret = nf_ct_l4proto_register_sysctl(l4proto); 306 ret = nf_ct_l4proto_register_sysctl(l4proto);
321 if (ret < 0) 307 if (ret < 0)
322 goto out_unlock; 308 goto out_unlock;
323 309
324 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], l4proto); 310 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
311 l4proto);
325 312
326out_unlock: 313out_unlock:
327 mutex_unlock(&nf_ct_proto_mutex); 314 mutex_unlock(&nf_ct_proto_mutex);