aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-02-24 17:41:57 -0500
committerDavid S. Miller <davem@davemloft.net>2012-02-24 17:41:57 -0500
commite807e566e99b644d8d248ba9393a0ba3f1012fdc (patch)
treeea705f137653dc55dc9804d76f59536790aa35dd /net
parentbff528578fc3c4a14227b052a313109b5ffb73da (diff)
parent7d367e06688dc7a2cc98c2ace04e1296e1d987e2 (diff)
Merge branch 'master' of git://1984.lsi.us.es/net
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_conntrack_core.c38
-rw-r--r--net/netfilter/nf_conntrack_netlink.c11
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
407void nf_conntrack_hash_insert(struct nf_conn *ct) 407int
408nf_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
444out:
445 NF_CT_STAT_INC(net, insert_failed);
446 spin_unlock_bh(&nf_conntrack_lock);
447 return -EEXIST;
418} 448}
419EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert); 449EXPORT_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 */
422int 452int
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;