[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

problem changing target interface with reply-to

I'm seeing a problem with reply-to when modifying the interface that
a packet would normally go out on from the one it would normally take.
The following (simplified) test case demonstrates the problem:
Host 1:
  - kernel OPENBSD_3_5 (stable)
  - fxp0:
  - fxp1:
  - interface routes only
  - pf rules:
      pass in log-all quick on fxp1 reply-to (fxp1 \
        proto icmp from to keep state
    pass all
Host 2:
  - fxp0:
  - fxp1:
  - interface routes only
Host 2 sends an ping packet to host 1 with "ping -I".  The packet is sent via host 2's fxp1 with source address and received successfully on host 1's fxp1.
No reply packet is sent over any interface by host 1.  The packet is
logged as "pass" over both fxp0 and fxp1 on host 1.
pf_route gets called three times for the mbuf, the third time
recursively, so the packet is dropped as it has been tagged with
PACKET_TAG_PF_ROUTED.  The calls are as follows:
pf_test creates state and calls pf_route for the incoming packet:
   - r->direction=PF_IN, dir=PF_IN, oifp=fxp1
   - pf_route returns and does nothing because it's an input rule.
pf_test finds calls pf_route for the outgoing packet:
   - r->direction=PF_IN, dir=PF_OUT, oifp=fxp0
   - this is before the reply-to rule has been applied, so oifp
     corresponds to the interface that the reply would normally
     go over.
   - ifp is loaded from the state entry
   - mbuf is tagged with PACKET_TAG_PF_ROUTED
   - oifp != ifp ==> pf_route calls pf_test with the new ifp
   - pf_test finds the state and calls pf_route once again:
       - r->direction=PF_IN, dir=PF_OUT, oifp=fxp1
       - ifp is loaded again from the state entry, etc
       - the packet already has a mbuf tag
         PACKET_TAG_PF_ROUTED, pf_route takes the "bad" path,
         frees the mbuf and returns.
   - m0 == NULL now, so pf_route is done and returns
   - the packet hasn't made an ifp->if_output anywhere.
It appears the the PACKET_TAG_PF_ROUTED is to prevent recursive calls of
pf_route, so I'm not sure what the correct fix is for this.  Moving that
mbuf tagging after the if (oifp != ifp) makes it do the right thing in
this test case with respect to the packet on the wire, but probably is
bad in other ways :).
Any advice as to how to fix this correctly would be appreciated.