Skip to content

Commit e807e56

Browse files
committed
Merge branch 'master' of git://1984.lsi.us.es/net
2 parents bff5285 + 7d367e0 commit e807e56

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

include/net/netfilter/nf_conntrack.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ extern struct nf_conntrack_tuple_hash *
209209
__nf_conntrack_find(struct net *net, u16 zone,
210210
const struct nf_conntrack_tuple *tuple);
211211

212-
extern void nf_conntrack_hash_insert(struct nf_conn *ct);
212+
extern int nf_conntrack_hash_check_insert(struct nf_conn *ct);
213213
extern void nf_ct_delete_from_lists(struct nf_conn *ct);
214214
extern void nf_ct_insert_dying_list(struct nf_conn *ct);
215215

net/netfilter/nf_conntrack_core.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,19 +404,49 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
404404
&net->ct.hash[repl_hash]);
405405
}
406406

407-
void nf_conntrack_hash_insert(struct nf_conn *ct)
407+
int
408+
nf_conntrack_hash_check_insert(struct nf_conn *ct)
408409
{
409410
struct net *net = nf_ct_net(ct);
410411
unsigned int hash, repl_hash;
412+
struct nf_conntrack_tuple_hash *h;
413+
struct hlist_nulls_node *n;
411414
u16 zone;
412415

413416
zone = nf_ct_zone(ct);
414-
hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
415-
repl_hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
417+
hash = hash_conntrack(net, zone,
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);
416423

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);
417438
__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;
418448
}
419-
EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert);
449+
EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert);
420450

421451
/* Confirm a connection given skb; places it in hash table */
422452
int

net/netfilter/nf_conntrack_netlink.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,11 +1465,10 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
14651465
if (tstamp)
14661466
tstamp->start = ktime_to_ns(ktime_get_real());
14671467

1468-
add_timer(&ct->timeout);
1469-
spin_lock_bh(&nf_conntrack_lock);
1470-
nf_conntrack_hash_insert(ct);
1471-
nf_conntrack_get(&ct->ct_general);
1472-
spin_unlock_bh(&nf_conntrack_lock);
1468+
err = nf_conntrack_hash_check_insert(ct);
1469+
if (err < 0)
1470+
goto err2;
1471+
14731472
rcu_read_unlock();
14741473

14751474
return ct;
@@ -1511,12 +1510,10 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
15111510
return err;
15121511
}
15131512

1514-
spin_lock_bh(&nf_conntrack_lock);
15151513
if (cda[CTA_TUPLE_ORIG])
15161514
h = nf_conntrack_find_get(net, zone, &otuple);
15171515
else if (cda[CTA_TUPLE_REPLY])
15181516
h = nf_conntrack_find_get(net, zone, &rtuple);
1519-
spin_unlock_bh(&nf_conntrack_lock);
15201517

15211518
if (h == NULL) {
15221519
err = -ENOENT;

0 commit comments

Comments
 (0)