[Bug 257106] [pf] Local-origin connections matching 'pass out' rules with 'route-to' fail

From: <bugzilla-noreply_at_freebsd.org>
Date: Sun, 11 Jul 2021 10:28:01 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=257106

            Bug ID: 257106
           Summary: [pf] Local-origin connections matching 'pass out'
                    rules with 'route-to' fail
           Product: Base System
           Version: 12.2-STABLE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: fbsd@peralex.com

Running FreeBSD 12-stable, I'm running into a problem with commit 369643
(41063b40168b69b38e92d8da3af3b45e58fd98ca) and later from Subversion, which
appears to have been.  The previous revision (369642 in SVN) works fine.

I have a rule that says:

pass out log (all) quick route-to (em1 172.29.29.2) inet proto tcp from
172.29.29.1 to any flags S/SA keep state

This is to route traffic that originates on the local machine, with a source
address of 172.29.29.1, to the router at 172.29.29.2  My particular use-case is
to divide local traffic between WAN connections based on their source
addresses.

Note that this, while similar, differs from the case mentioned in
8ca8248886af583fa2010badfe03e472d8505db8 (r369645) in that the matched
connections originate locally rather than remotely, so the rule is an OUT rule
rather than an IN rule.

Connections that match this rule get established and exchange a bit of data,
but then stall.  The corresponding state gets stuck as follows:

all tcp 172.29.29.1:25564 -> 172.67.29.179:443       ESTABLISHED:SYN_SENT

The address 172.67.29.179 is an arbitrary remote address.  The remote end never
goes to ESTABLISHED.  Replies from the remote end are matching the rule and
correctly and getting logged, until the connection stalls.

This is the if() statement that changed in
41063b40168b69b38e92d8da3af3b45e58fd98ca.  It seems to make sense that this
would break with packets that only go out?

    if (dir == PF_IN) {
        if (pf_test(PF_OUT, 0, ifp, &m0, inp) != PF_PASS)
            goto bad;


The tests in route_to.sh from r369646
(8ca8248886af583fa2010badfe03e472d8505db8) pass.

sys/netpfil/pf/route_to:multiwan  ->  passed  [0.109s]
sys/netpfil/pf/route_to:v4  ->  passed  [3.045s]
sys/netpfil/pf/route_to:v6  ->  passed  [3.105s]

I should be able to conjure up an updated route_to.sh test script to test for
the local-origin + route-to scenario, which I'll attach in due course.

I'm happy to test fixes, provide packet dumps, etc.

Thanks
Mark

-- 
You are receiving this mail because:
You are the assignee for the bug.