Hello, > > ok. i don't know how to split up the rest of the change though. > > here's an updated diff that includes the rest of the kernel changes and > the pfctl and pf.conf tweaks. > > it's probably useful for me to try and explain at a high level what > i think the semantics should be, otherwise we might end up arguing about > which bits of the current config i broke. > > so, from an extremely high level point of view, and apologies if > this is condescending, pf sits between the network stack and an > interface that a packet travels on. for connections handled by the > local box, this means packets come from the stack and get an output > interface selected by a route lookup, then pf checks it, and then > it goes out the selected interface. replies come into an interface, > get checked by pf, and then enter the stack. when forwarding, a > packet comes into an interface, pf checks it, the stack does a route > lookup to pick an interface, pf checks it again, and then it goes > out the interface. > > so what does it mean when route-to (or reply-to) gets involved? i'm > saying that when route-to is applied to a packet, pf takes the packet > away from the stack and immediately forwards it toward to specified > destination address. for a packet entering the system, ie, when the > packet is going from the interface into the stack, route-to should > pretend that it is forwarding the packet and basically push it > straight out an interface. however, like normal forwarding via the > stack, there might be some policy on packets leaving that interface that > you want to apply, so pf should run pf_test in that situation so the > policy can be applied. this is especially useful if you need to apply > nat-to when packets leave a particular interface. > > however, if you route-to when a packet is on the way out of the > stack, i'm arguing that pf should not run again against that packet. > currently route-to rules run pf_test again if the interface the packet > is routed out of changes, which means pf runs multiple times against a > packet if rules keep changing which interface it goes out. this means > there's loop prevention in pf to mitigate against this, and weird > potentials for multiple states to be created when nat gets involved. > > for simplicity, both in terms of reasoning and code i think pf should > only be run once when a packet enters the system, and only once when it > leaves the system. the only reason i can come up with for running > pf_test multiple times when route-to changes the outgoing interface is > so you can check the packet with "pass out on $new_if" type rules. we > don't rerun pf again when nat/rdr changes addresses, so this feels > inconsistent to me.
I understand that simple is better here, so I won't object if we will lean towards simplified model above. However I still would like to share my view on current PF. the way I understand how things (should) work currently is fairly simple: we always run pf_test() as packet crosses interface. packet can cross interface either in outbound or inbound direction. this way we can always create a complex route-to loops, however it can also solve some route-to vs. NAT issues. consider those fairly innocent rules: --------8<---------------8<---------------8<------------------8<-------- table <hops> { 10.10.10.10, 172.16.1.1 } pass out on em0 from 192.168.1.0/24 to any route-to <hops> pass out on em1 from 192.168.1.0 to any nat-to (em1) pass out on em2 all --------8<---------------8<---------------8<------------------8<-------- Rules above should currently work, but will stop if we will go with simplified model. I'll be OK with your simplified model if it will make things more explicit: route-to option should be applied on inbound rules only reply-to option should be applied on outbound rule only dup-to option can go either way (in/out) does it make sense? IMO yes, because doing route-to on outbound path feels unnatural to me. </snip> > > this also breaks the ability to do route-to without states. is there a > reason to do that apart from the DSR type things? did we agree that > those use cases could be handled by sloppy states instead? If I remember correct we need to make 'keep state' mandatory for route-to so it can work well with pfsync(4), right? > > lastly, the "argument" or address specified with route-to (and > reply-to and dup-to) is a destination address, not a next-hop. this > has been discussed on the lists a couple of times before, so i won't > go over it again, except to reiterate that it allows pf to force > "sticky" path selection while opening up the possibility for ecmp > and failover for where that path traverses. I keep forgetting about it as I still stick to current interpretation. I've seen changes to pfctl. Diff below still allows rule: pass in on net0 from 192.168.1.0/24 to any route-to 10.10.10.10@em0 it also allows rule: pass in on net0 from 192.168.1.0/24 to any route-to em0 I think we don't want support those two anymore, is that correct? thanks and regards sashan