Hi, I have seen a problem with pf divert when the dynamic port in a nat rule got reused. The function pf_state_key_attach() reused the state as it was in TCPS_FIN_WAIT_2. The corresponding socket was not reused, as the the TCPS_TIME_WAIT case in tcp_input() has additional checks for timestamps and sequence numbers. When I port the condition SEQ_GT(th->th_seq, tp->rcv_nxt) from the stack to pf, the socket and state are kept in sync. Then divert works fine.
ok? bluhm Index: net/pf.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v retrieving revision 1.977 diff -u -p -r1.977 pf.c --- net/pf.c 15 Jun 2016 11:49:34 -0000 1.977 +++ net/pf.c 20 Jun 2016 21:18:53 -0000 @@ -671,7 +671,8 @@ pf_state_key_attach(struct pf_state_key si->s->direction != s->direction))) { if (sk->proto == IPPROTO_TCP && si->s->src.state >= TCPS_FIN_WAIT_2 && - si->s->dst.state >= TCPS_FIN_WAIT_2) { + si->s->dst.state >= TCPS_FIN_WAIT_2 && + SEQ_GT(s->src.seqlo, si->s->src.seqlo)) { si->s->src.state = si->s->dst.state = TCPS_CLOSED; /* remove late or sks can go away */