diff options
author | Patrick McHardy <kaber@trash.net> | 2007-03-14 19:39:07 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 01:25:43 -0400 |
commit | c6a1e615d1ba942b9e783079d53f741e4a8e1c89 (patch) | |
tree | 230f3c78633b4066cc49af8b45c614d32d760e34 /net | |
parent | 0661cca9c216322e77dca7f47df107c02ce4e70c (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.c | 37 |
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); |
284 | retry: | 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 | ||
326 | out_unlock: | 313 | out_unlock: |
327 | mutex_unlock(&nf_ct_proto_mutex); | 314 | mutex_unlock(&nf_ct_proto_mutex); |