On Sat, Sep 20, 2003 at 10:00:30AM +0200, Niclas Sodergard wrote:

> These are the rules that affect all connections for that
> interface and those IPs.

I suspect you didn't quote all relevant rules, there must be at least
one additional rule like

  pass out on rl2 keep state

Without that, routed-to packets wouldn't be able to pass out on rl2 at
all (due to the default block rules you quoted). Correct?

The problem is that your nat rule on rl0. The code path for nat and
route-to is quite complicated, but basically, pf tries to create two
different state entries for outgoing connections, once with the nat
translation (on rl0), then without nat on rl2 (as the first translation
prevents the second). And these two conflict, as they have colliding
keys (lan, gwy and ext address:port).

The route-to code path was changed in 3.4 to fix related problems, so
it's possible that some rulesets worked with 3.3 but don't with 3.4,
without adjustments.

Assuming you do have a rule allowing outgoing connections on rl2 (as
mentioned above), the effects you describe (state insert failures,
retransmission of the first SYN) make sense, given the code path.

In your case, there's two solutions.

First, try to use nat only on rl2. The route-to'd connections will pass
pf on both rl0 and rl2, so doing nat on rl2 is no problem:

  nat on rl2 from xxx.5.11.201 to any -> rl2
              
  block log
  pass in log quick on rl0 from xxx.5.11.201 to any keep state
  pass out log quick on rl0 route-to (rl2 yyy.253.135.161) \
        from xxx.5.11.201 to any label bp-traffic
  pass out log quick on rl2 from yyy.253.135.162 to any keep state

Note that the source address for connections passing out on rl0 is now
xxx.5.11.201 (not yyy.253.135.162), as they haven't been nat'ed yet
there. The last rule allows nat'ed connections out on rl2.

I'm not sure why you had nat rules on both rl0 and rl2, maybe that was
just the result of trying to get the ruleset to work in 3.3. In 3.4, the
route-to'd connections will cause a full ruleset evaluation on the final
interface (rl2), including nat translation, if specified. So there's no
reason for 'nat on rl0 -> rl2' that I can see.

A second approach would be to put 'route-to' on the 'pass in on rl0'
rule, shortcircuiting the TCP/IP stack (not relying on it to forward the
connection to the default gateway). In that case, the connections would
come in on rl0, and get routed to rl2 directly, so pf wouldn't see them
as outgoing on rl0 at all. But you could still translate and filter them
going out on rl2, of course.

So, in short, use nat only on rl2 or use route-to on the pass in rule
for rl0. Using nat during the intermediate step when the packet attempts
to go out through rl0, before it gets routed to rl2, is causing the
problems you see. If either of those two solutions doesn't work for you,
please let me know (I'll need the same kind of information you provided
for the current setup, then).

Daniel

Reply via email to