pf route-to breaks pfil processing order

Алексей Гуськов adg at
Mon Jul 5 14:37:45 UTC 2010

  Hello everyone.

Here's the problem: I need to forward some outgoing traffic to some 
local service. Traffic goes from my machine, not from local network, so 
i cannot use pf rdr rule, because it handles only incoming traffic. So, 
i'm using ipfw fwd rule for that:

# ipfw add 100 fwd,3127 ip from me to any 80 out

Here i redirect all outgoing traffic to another local proxy. (Nope, i 
can not use parent proxy). Everything is fine and works ok until I turn 
on pf and create route-to rule:

pass out on le0 out route-to (le0 from any to

Besides i'm using dummynet pipes for traffic shaping, so i need ipfw to 
process incoming packets before pf (and after pf for outgoing packets):

# ipfw disable firewall
# ipfw enable firewall

So, the problem goes here:

Here's the path of the outgoing packet inside the kernel:
ip_output() -> ... -> pfil_run_hooks() -> ... -> pf_test()

pf_test checks the packets, searches for state etc. Finally it checks if 
the packet should be redirected by "route-to", "reply-to" or "dup-to" 

pf.c, line 7125, pf_test():
   if (r->rt)
         /* pf_route can free the mbuf causing *m0 to become NULL */
         pf_route(m0, r, dir, ifp, s, &pd);

pf_route() itself performs some routing actions, rewrites nexthop and 
if, and (sic!) sends the packet _directly_ to the specified interface:

pf.c, line 6239, pf_route()
   error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro->ro_rt);

Original packet is deleted as if it's been blocked by firewall. So, any 
packet that is processed by pf_route would not then be processed with 
ipfw, would not be diverted into pipes etc. (actually i believe it 
wouldn't also be processed by altq). For example in my case the tcp 
connection wouldn't be redirected by ipfw.

So' heres the questions:
1) for what purpose pf_route invokes if_output by itself?
2) why rewritten packets can't be left intact so they would be normally 
processed by ipfw, altq etc and send to interfaces by uip_output()? I'm 
asking that because when ipfw redirects packets they are processed this 
way and nothing bad happens.


Alexey Guskov
Areal company

More information about the freebsd-pf mailing list