Hello,

my apologize to resend the same diff [1]. I'm not sure I got OK or not.
It can be the case the privately received OK got lost.

The change is required to allow multiple instances of pf_test() running
concurrently. Without this change in, PF trips 'KASSERT(sk->reverse == NULL);'

thanks and
regards
sashan


[1] 
http://openbsd-archive.7691.n7.nabble.com/pf-state-key-link-reverse-needs-atomic-ops-td367859.html

--------8<---------------8<---------------8<------------------8<--------
diff --git a/sys/net/pf.c b/sys/net/pf.c
index ebe339921fa..738759e556c 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -7398,11 +7398,20 @@ pf_inp_unlink(struct inpcb *inp)
 void
 pf_state_key_link_reverse(struct pf_state_key *sk, struct pf_state_key *skrev)
 {
-       /* Note that sk and skrev may be equal, then we refcount twice. */
-       KASSERT(sk->reverse == NULL);
-       KASSERT(skrev->reverse == NULL);
-       sk->reverse = pf_state_key_ref(skrev);
-       skrev->reverse = pf_state_key_ref(sk);
+       struct pf_state_key *old_reverse;
+
+       old_reverse = atomic_cas_ptr(&sk->reverse, NULL, skrev);
+       if (old_reverse != NULL)
+               KASSERT(old_reverse == skrev);
+       else
+               pf_state_key_ref(skrev);
+
+
+       old_reverse = atomic_cas_ptr(&skrev->reverse, NULL, sk);
+       if (old_reverse != NULL)
+               KASSERT(old_reverse == sk);
+       else
+               pf_state_key_ref(sk);
 }
 
 #if NPFLOG > 0

Reply via email to