PF - Force 'sloppy' when establishing conflicting state
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 3 Sep 2014 04:19:15 +0000 (21:19 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 3 Sep 2014 04:19:15 +0000 (21:19 -0700)
commit9d0d81f910550be540a72ce262aee108ae351eb5
treea1b2456342bcca3c8538017f048f19e4ad3ea4a7
parent6a51c60cd79ddaef2d6c981494654e1e89d2fe27
PF - Force 'sloppy' when establishing conflicting state

* Check whether a PASS IN or PASS OUT conflicts with established translation
  state in the opposite direction.  When this situation is detected, one
  of the PASS rules can establish state (and with recent SMP work, both
  PASS rules will establish state).  This causes problems because the PASS
  rules may only see one direction of the connection due to the RDR or NAT.
  If strict TCP sequence space checking occurs the PASS state can generate
  RSTs.

  To fix this we force the SLOPPY flag to be set for any PASS state being
  established in the face of a conflict against a translation rule.  This
  allows packet flow to short-cut through the state table and is preferable
  to disallowing establishment of the state because that would force a
  full rules scan (and repeated conflict/failure) for every packet.

History

* PASS IN and PASS OUT rules can interfere with a RDR rule when strict
  sequence space tests are made for established TCP state.

  In pre-SMP PF, including in FreeBSD and probably also in other BSDs,
  two active states are generally established, one for RDR and one for the
  PASS IN.  PF attempts to establish state for the PASS OUT but hits a
  conflict against the established RDR state and fails.

  However, in this situation no short-cut state is established in one
  direction and ALL packets that would have matched the failed PASS OUT
  will cause a full rules scan.

* With the SMP work, the PASS OUT conflict was no longer detected because
  the RDR state is on a different RBTREE than the PASS OUT state.  This
  allowed conflicting state for both PASS IN and PASS OUT to be established.

* Conflicting state in either direction is capable of generating spurious
  RSTs against the RDR rule.  One direction for sure, the other will generate
  RSTs but possibly be obscured by the translation rule (that is, the RST
  ends up going somewhere unexpected), so the RDR rule still works.  But
  the problem remains.
sys/net/pf/pf.c
sys/net/pf/pfvar.h
usr.sbin/pfctl/pf_print_state.c