--- net/netfilter/nf_conntrack_core.c | 9 ++++++--- net/netfilter/nf_conntrack_proto_udp.c | 6 ++++-- net/netfilter/nf_conntrack_proto_udplite.c | 6 ++++-- 3 files changed, 14 insertions(+), 7 deletions(-) Index: linux-2.6.23-rc6.quilt/net/netfilter/nf_conntrack_core.c =================================================================== --- linux-2.6.23-rc6.quilt.orig/net/netfilter/nf_conntrack_core.c 2007-09-23 01:06:08.000000000 +0200 +++ linux-2.6.23-rc6.quilt/net/netfilter/nf_conntrack_core.c 2007-09-23 01:06:17.000000000 +0200 @@ -511,7 +511,8 @@ struct nf_conn *nf_conntrack_alloc(const return ERR_PTR(-ENOMEM); } - /* FIXME: Absolutely no need to use an atomic set here */ + /* FIXME: Absolutely no need to use an atomic set here + not atomic on x86 but maybe on other archs? */ atomic_set(&conntrack->ct_general.use, 1); conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; @@ -763,9 +764,11 @@ nf_conntrack_in(int pf, unsigned int hoo return -ret; } - /* FIXME: Should test if bit is set or not before atomic operation */ - if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) + /* Test bit before we use an atomic set */ + if (set_reply && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status) && + !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { nf_conntrack_event_cache(IPCT_STATUS, ct); + } return ret; } Index: linux-2.6.23-rc6.quilt/net/netfilter/nf_conntrack_proto_udp.c =================================================================== --- linux-2.6.23-rc6.quilt.orig/net/netfilter/nf_conntrack_proto_udp.c 2007-09-23 00:44:23.000000000 +0200 +++ linux-2.6.23-rc6.quilt/net/netfilter/nf_conntrack_proto_udp.c 2007-09-23 01:06:17.000000000 +0200 @@ -79,8 +79,10 @@ static int udp_packet(struct nf_conn *co if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) { nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_udp_timeout_stream); - /* Also, more likely to be important, and not a probe */ - if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status)) + /* Also, more likely to be important, and not a probe. + Test bit before using an atomic set. */ + if (!test_bit(IPS_ASSURED_BIT, &conntrack->status) && + !test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status)) nf_conntrack_event_cache(IPCT_STATUS, conntrack); } else nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_udp_timeout); Index: linux-2.6.23-rc6.quilt/net/netfilter/nf_conntrack_proto_udplite.c =================================================================== --- linux-2.6.23-rc6.quilt.orig/net/netfilter/nf_conntrack_proto_udplite.c 2007-09-23 00:44:23.000000000 +0200 +++ linux-2.6.23-rc6.quilt/net/netfilter/nf_conntrack_proto_udplite.c 2007-09-23 01:06:17.000000000 +0200 @@ -78,8 +78,10 @@ static int udplite_packet(struct nf_conn if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) { nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_udplite_timeout_stream); - /* Also, more likely to be important, and not a probe */ - if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status)) + /* Also, more likely to be important, and not a probe. + Test bit before using an atomic set. */ + if (!test_bit(IPS_ASSURED_BIT, &conntrack->status) && + !test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status)) nf_conntrack_event_cache(IPCT_STATUS, skb); } else nf_ct_refresh_acct(conntrack, ctinfo, skb,