X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=net%2Fnetfilter%2Fnf_conntrack_core.c;h=db4d46332e8681ab7ccbe1e920a14ecd3776f0d1;hb=df3865f8f56879b7e9f0ca47fa7bc5f2252df6d3;hp=741b533148baedd70cd4184ba47bb507b055c142;hpb=115502a6f31d84d8172a71283aaea266302a8ad5;p=uclinux-h8%2Flinux.git diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 741b533148ba..db4d46332e86 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1007,6 +1007,22 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, } if (nf_ct_key_equal(h, tuple, zone, net)) { + /* Tuple is taken already, so caller will need to find + * a new source port to use. + * + * Only exception: + * If the *original tuples* are identical, then both + * conntracks refer to the same flow. + * This is a rare situation, it can occur e.g. when + * more than one UDP packet is sent from same socket + * in different threads. + * + * Let nf_ct_resolve_clash() deal with this later. + */ + if (nf_ct_tuple_equal(&ignored_conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple, + &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)) + continue; + NF_CT_STAT_INC_ATOMIC(net, found); rcu_read_unlock(); return 1;