Discussion:
stopping PF NAT state from "floating" ?
(too old to reply)
David Young
2007-05-07 06:01:47 UTC
Permalink
I am using PF for NAT. I would like to stop NAT states from floating
between interfaces. I have searched all day for a solution, but I have
not found one. Does anyone know how?

Details:

I have this translation rule on the ethernet admsw0,

nat on admsw0 inet from <cuwin> to ! <cuwin> -> 192.168.1.4 port 10000:20000

I have noticed that the translation states will "float" between admsw0 and
ath0. That is, if the routes change so that a flow that passes through
admsw0 passes through ath0, instead, then the address translations from
admsw0 continue to apply to the flow on ath0. I can see why that might
be desirable in some cases, but it is bad for my application.

Here is the NAT state:

self udp 10.0.246.46:65533 -> 192.168.1.4:14690 -> a.b.c.d:2524 SINGLE:NO_TRAFFIC
self udp 10.0.246.46:65531 -> 192.168.1.4:13794 -> a.b.c.d:2525 SINGLE:NO_TRAFFIC

I see those translations applied to traffic going out ath0 after the route
to a.b.c.d moves from admsw0 to ath0. As I say, that's not what I desire.

I thought that 'set state-policy if-bound' would help, but I have found
out in other experiments that it will not. I believe I understand why not
after reading the PF sources, especially sys/dist/pf/sbin/pfctl/parse.y
and sys/dist/pf/net/pf.c.

Is there a way to stop NAT states from "floating" that I have missed?

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Daniel Carosone
2007-05-07 06:40:40 UTC
Permalink
Post by David Young
I am using PF for NAT. I would like to stop NAT states from floating
between interfaces. I have searched all day for a solution, but I have
not found one. Does anyone know how?
First question, if this is a "flow" where changing the IP addressing
within the "flow" when the routing changes doesn't break the
application, is whether you need a persistent NAT state at all.

Ie, if they're udp packets that should be hidden behind the relevant
exit interface address, and each packet is essentially independent
from those that proceed and follow it, why do you need to keep much
state at all? You could play with really short timeouts for these NAT
states. Are there replies to these packets that must come back?
Maybe you want to kill the state immediately on that reply, and let
the next request create a new one-time state?

Alternately, could you try tagging these flows, and when the route
changes, flush all states with the tag. I don't know pf enough to say
whether there's a way to do that.
Post by David Young
I can see why that might
be desirable in some cases, but it is bad for my application.
Sure, for anything like a tcp connection, for example. As above, to
me, this seems that you don't want/need to be keeping state for these
packets.
Post by David Young
I thought that 'set state-policy if-bound' would help, but I have found
out in other experiments that it will not. I believe I understand why not
after reading the PF sources, especially sys/dist/pf/sbin/pfctl/parse.y
and sys/dist/pf/net/pf.c.
Hm, I'd have expected the same. Does it make any difference if you
specify it on the rule rather than as a global pref?

--
Dan.
David Young
2007-05-07 07:50:55 UTC
Permalink
Post by Daniel Carosone
Post by David Young
I am using PF for NAT. I would like to stop NAT states from floating
between interfaces. I have searched all day for a solution, but I have
not found one. Does anyone know how?
First question, if this is a "flow" where changing the IP addressing
within the "flow" when the routing changes doesn't break the
application, is whether you need a persistent NAT state at all.
For the application to work, the state does have to persist. What is
more important is the network, I think:

Router A Router B
| +---------+ +---------+
__ ___ | | | | | a.b.c.d
/ \___/ \ |--|admsw0 | | sip0|--+
\ the (ugly)| +----------+ | | | | (NAT)| |
/ Internet |-|NAT router|-| | ath0|-- 10.0/16 --|ath0 | |
| _ / +----------+ | |_________| |_________| |
\___/ \__/ | |
| | |
| 192.168.1/24 |
| |
+---------------------------------------------------------+

a.b.c.d is a globally routable IP address. Router B NATs 10/8 to a.b.c.d.
Router B neither knows a route to 192.168.1/24, nor should it. So there
is no sense in translating an address in 10.0/16 to 192.168.1.4 before
sending it out ath0 on Router A. Nevertheless, that is what is happening.
Post by Daniel Carosone
Alternately, could you try tagging these flows, and when the route
changes, flush all states with the tag. I don't know pf enough to say
whether there's a way to do that.
Letting the states time-out in the usual way is more desirable than
flushing them when the route changes. The route may change from sip0
to admsw0, and change back to sip0 a moment later; if that happens,
it is nice to have state on sip0.
Post by Daniel Carosone
Post by David Young
I thought that 'set state-policy if-bound' would help, but I have found
out in other experiments that it will not. I believe I understand why not
after reading the PF sources, especially sys/dist/pf/sbin/pfctl/parse.y
and sys/dist/pf/net/pf.c.
Hm, I'd have expected the same. Does it make any difference if you
specify it on the rule rather than as a global pref?
You cannot specify the state policy of a NAT rule. At least, not as
far as I can tell by reading pf.conf(5) and the source code.

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
David Young
2007-05-10 04:23:38 UTC
Permalink
Post by David Young
I am using PF for NAT. I would like to stop NAT states from floating
between interfaces. I have searched all day for a solution, but I have
not found one. Does anyone know how?
I have this translation rule on the ethernet admsw0,
nat on admsw0 inet from <cuwin> to ! <cuwin> -> 192.168.1.4 port 10000:20000
With a bit of hacking on dist/pf/sbin/pfctl/parse.y, now I can use pfctl
to add this rule---note the if-bound flag, which is new:

nat on admsw0 inet from <cuwin> to ! <cuwin> (if-bound) -> 192.168.1.4 port 10000:20000

That certainly looks like that rule I want. It did not work as I
expected: the rule created NAT states that "floated" from interface
Post by David Young
self udp 10.0.246.46:65533 -> 192.168.1.4:14690 -> a.b.c.d:2524 SINGLE:NO_TRAFFIC
self udp 10.0.246.46:65531 -> 192.168.1.4:13794 -> a.b.c.d:2525 SINGLE:NO_TRAFFIC
As a last-ditch effort to stop the state from floating, I redefined
the BOUND_IFACE macro, in this way hard-coding if-bound for ALL states:

#define BOUND_IFACE(r, k) (k)

That gave me the behavior I want. Here are the states I see, now:

admsw0 udp 10.0.246.46:65533 -> 192.168.1.4:17303 -> 64.198.255.12:2524 SINGLE:NO_TRAFFIC
admsw0 udp 10.0.246.46:65531 -> 192.168.1.4:17352 -> 64.198.255.12:2525 SINGLE:NO_TRAFFIC

pfctl seems to indicate, with 'admsw0' in the leftmost column, that the
state is bound to the interface. I have verified with tcpdump that even
though the NAT states persist, they are not affecting ath0.

Right now, I am at a loss to explain how pfctl can add a rule with an
if-bound flag, read the same rule back out with if-bound flag intact,
and nevertheless ignore the if-bound flag when it creates state.
Still investigating.

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
David Young
2007-05-10 07:04:39 UTC
Permalink
Post by David Young
Right now, I am at a loss to explain how pfctl can add a rule with an
if-bound flag, read the same rule back out with if-bound flag intact,
and nevertheless ignore the if-bound flag when it creates state.
Still investigating.
I figured it out. PF uses the if-bound flag from filter rules, only.
I have made PF use both the 'if-bound'/'gr-bound'/'floating' properties
from the filter rule and the translation rule (if available). Works so
far. See patch (attached).

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933
Loading...