diff options
author | David S. Miller <davem@davemloft.net> | 2012-02-24 17:41:57 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-02-24 17:41:57 -0500 |
commit | e807e566e99b644d8d248ba9393a0ba3f1012fdc (patch) | |
tree | ea705f137653dc55dc9804d76f59536790aa35dd /net | |
parent | bff528578fc3c4a14227b052a313109b5ffb73da (diff) | |
parent | 7d367e06688dc7a2cc98c2ace04e1296e1d987e2 (diff) |
Merge branch 'master' of git://1984.lsi.us.es/net
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 38 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 11 |
2 files changed, 38 insertions, 11 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 76613f5a55c0..ed86a3be678e 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -404,19 +404,49 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct, | |||
404 | &net->ct.hash[repl_hash]); | 404 | &net->ct.hash[repl_hash]); |
405 | } | 405 | } |
406 | 406 | ||
407 | void nf_conntrack_hash_insert(struct nf_conn *ct) | 407 | int |
408 | nf_conntrack_hash_check_insert(struct nf_conn *ct) | ||
408 | { | 409 | { |
409 | struct net *net = nf_ct_net(ct); | 410 | struct net *net = nf_ct_net(ct); |
410 | unsigned int hash, repl_hash; | 411 | unsigned int hash, repl_hash; |
412 | struct nf_conntrack_tuple_hash *h; | ||
413 | struct hlist_nulls_node *n; | ||
411 | u16 zone; | 414 | u16 zone; |
412 | 415 | ||
413 | zone = nf_ct_zone(ct); | 416 | zone = nf_ct_zone(ct); |
414 | hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); | 417 | hash = hash_conntrack(net, zone, |
415 | repl_hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_REPLY].tuple); | 418 | &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); |
419 | repl_hash = hash_conntrack(net, zone, | ||
420 | &ct->tuplehash[IP_CT_DIR_REPLY].tuple); | ||
421 | |||
422 | spin_lock_bh(&nf_conntrack_lock); | ||
416 | 423 | ||
424 | /* See if there's one in the list already, including reverse */ | ||
425 | hlist_nulls_for_each_entry(h, n, &net->ct.hash[hash], hnnode) | ||
426 | if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, | ||
427 | &h->tuple) && | ||
428 | zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h))) | ||
429 | goto out; | ||
430 | hlist_nulls_for_each_entry(h, n, &net->ct.hash[repl_hash], hnnode) | ||
431 | if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, | ||
432 | &h->tuple) && | ||
433 | zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h))) | ||
434 | goto out; | ||
435 | |||
436 | add_timer(&ct->timeout); | ||
437 | nf_conntrack_get(&ct->ct_general); | ||
417 | __nf_conntrack_hash_insert(ct, hash, repl_hash); | 438 | __nf_conntrack_hash_insert(ct, hash, repl_hash); |
439 | NF_CT_STAT_INC(net, insert); | ||
440 | spin_unlock_bh(&nf_conntrack_lock); | ||
441 | |||
442 | return 0; | ||
443 | |||
444 | out: | ||
445 | NF_CT_STAT_INC(net, insert_failed); | ||
446 | spin_unlock_bh(&nf_conntrack_lock); | ||
447 | return -EEXIST; | ||
418 | } | 448 | } |
419 | EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert); | 449 | EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert); |
420 | 450 | ||
421 | /* Confirm a connection given skb; places it in hash table */ | 451 | /* Confirm a connection given skb; places it in hash table */ |
422 | int | 452 | int |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index cc705175765c..30c9d4ca0218 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -1465,11 +1465,10 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, | |||
1465 | if (tstamp) | 1465 | if (tstamp) |
1466 | tstamp->start = ktime_to_ns(ktime_get_real()); | 1466 | tstamp->start = ktime_to_ns(ktime_get_real()); |
1467 | 1467 | ||
1468 | add_timer(&ct->timeout); | 1468 | err = nf_conntrack_hash_check_insert(ct); |
1469 | spin_lock_bh(&nf_conntrack_lock); | 1469 | if (err < 0) |
1470 | nf_conntrack_hash_insert(ct); | 1470 | goto err2; |
1471 | nf_conntrack_get(&ct->ct_general); | 1471 | |
1472 | spin_unlock_bh(&nf_conntrack_lock); | ||
1473 | rcu_read_unlock(); | 1472 | rcu_read_unlock(); |
1474 | 1473 | ||
1475 | return ct; | 1474 | return ct; |
@@ -1511,12 +1510,10 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1511 | return err; | 1510 | return err; |
1512 | } | 1511 | } |
1513 | 1512 | ||
1514 | spin_lock_bh(&nf_conntrack_lock); | ||
1515 | if (cda[CTA_TUPLE_ORIG]) | 1513 | if (cda[CTA_TUPLE_ORIG]) |
1516 | h = nf_conntrack_find_get(net, zone, &otuple); | 1514 | h = nf_conntrack_find_get(net, zone, &otuple); |
1517 | else if (cda[CTA_TUPLE_REPLY]) | 1515 | else if (cda[CTA_TUPLE_REPLY]) |
1518 | h = nf_conntrack_find_get(net, zone, &rtuple); | 1516 | h = nf_conntrack_find_get(net, zone, &rtuple); |
1519 | spin_unlock_bh(&nf_conntrack_lock); | ||
1520 | 1517 | ||
1521 | if (h == NULL) { | 1518 | if (h == NULL) { |
1522 | err = -ENOENT; | 1519 | err = -ENOENT; |