|
@@ -611,16 +611,15 @@ __nf_conntrack_confirm(struct sk_buff *skb)
|
|
|
*/
|
|
|
NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
|
|
|
pr_debug("Confirming conntrack %p\n", ct);
|
|
|
- /* We have to check the DYING flag inside the lock to prevent
|
|
|
- a race against nf_ct_get_next_corpse() possibly called from
|
|
|
- user context, else we insert an already 'dead' hash, blocking
|
|
|
- further use of that particular connection -JM */
|
|
|
+ /* We have to check the DYING flag after unlink to prevent
|
|
|
+ * a race against nf_ct_get_next_corpse() possibly called from
|
|
|
+ * user context, else we insert an already 'dead' hash, blocking
|
|
|
+ * further use of that particular connection -JM.
|
|
|
+ */
|
|
|
+ nf_ct_del_from_dying_or_unconfirmed_list(ct);
|
|
|
|
|
|
- if (unlikely(nf_ct_is_dying(ct))) {
|
|
|
- nf_conntrack_double_unlock(hash, reply_hash);
|
|
|
- local_bh_enable();
|
|
|
- return NF_ACCEPT;
|
|
|
- }
|
|
|
+ if (unlikely(nf_ct_is_dying(ct)))
|
|
|
+ goto out;
|
|
|
|
|
|
/* See if there's one in the list already, including reverse:
|
|
|
NAT could have grabbed it without realizing, since we're
|
|
@@ -636,8 +635,6 @@ __nf_conntrack_confirm(struct sk_buff *skb)
|
|
|
zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
|
|
|
goto out;
|
|
|
|
|
|
- nf_ct_del_from_dying_or_unconfirmed_list(ct);
|
|
|
-
|
|
|
/* Timer relative to confirmation time, not original
|
|
|
setting time, otherwise we'd get timer wrap in
|
|
|
weird delay cases. */
|
|
@@ -673,6 +670,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
|
|
|
return NF_ACCEPT;
|
|
|
|
|
|
out:
|
|
|
+ nf_ct_add_to_dying_list(ct);
|
|
|
nf_conntrack_double_unlock(hash, reply_hash);
|
|
|
NF_CT_STAT_INC(net, insert_failed);
|
|
|
local_bh_enable();
|