forked from Minki/linux
[NETFILTER]: nf_conntrack: Don't try to find clashed expectation
The original code continues loop to find expectation in list if the master conntrack of the found expectation is unconfirmed. But it never success in that case, because nf_conntrack_expect_related() never insert clashed expectation to the list. This stops loop in that case. Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9ee0779e99
commit
ece006416d
@ -91,25 +91,28 @@ EXPORT_SYMBOL_GPL(nf_conntrack_expect_find_get);
|
||||
struct nf_conntrack_expect *
|
||||
find_expectation(const struct nf_conntrack_tuple *tuple)
|
||||
{
|
||||
struct nf_conntrack_expect *i;
|
||||
struct nf_conntrack_expect *exp;
|
||||
|
||||
exp = __nf_conntrack_expect_find(tuple);
|
||||
if (!exp)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(i, &nf_conntrack_expect_list, list) {
|
||||
/* If master is not in hash table yet (ie. packet hasn't left
|
||||
this machine yet), how can other end know about expected?
|
||||
Hence these are not the droids you are looking for (if
|
||||
master ct never got confirmed, we'd hold a reference to it
|
||||
and weird things would happen to future packets). */
|
||||
if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
|
||||
&& nf_ct_is_confirmed(i->master)) {
|
||||
if (i->flags & NF_CT_EXPECT_PERMANENT) {
|
||||
atomic_inc(&i->use);
|
||||
return i;
|
||||
} else if (del_timer(&i->timeout)) {
|
||||
nf_ct_unlink_expect(i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (!nf_ct_is_confirmed(exp->master))
|
||||
return NULL;
|
||||
|
||||
if (exp->flags & NF_CT_EXPECT_PERMANENT) {
|
||||
atomic_inc(&exp->use);
|
||||
return exp;
|
||||
} else if (del_timer(&exp->timeout)) {
|
||||
nf_ct_unlink_expect(exp);
|
||||
return exp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user