RFC: documented and actual behaviour of "ipfw tee"

Julian Elischer julian at elischer.org
Wed Dec 30 23:55:09 UTC 2009


Luigi Rizzo wrote:
> On Wed, Dec 30, 2009 at 01:30:01PM -0800, Julian Elischer wrote:
>> Ian Smith wrote:
>>> On Tue, 29 Dec 2009, Julian Elischer wrote:
>>>> Luigi Rizzo wrote:
>>>>> There a difference between the documented and actual behaviour of
>>>>> "ipfw tee" which occurs when there are multiple rules with the same
>>>>> number, e.g.
>>>>>
>>>>> 	rule_id number  body
>>>>> 	r1      500     tee port1 dst-ip 1.2.3.0/24
>>>>> 	r2      500     tee port2 dst-ip 1.2.4.0/24
>>>>> 	r3      500     accept ip from any to any
>>>>> 	r4      510     count ip from any to any
>>>>>
>>>>> + the manpage says "processing continues with the NEXT RULE"
>>>>>   (so after r1 we have r2, then r3, ...);
>>>>> + the implementation behaves as "processing continues with the
>>>>>   NEXT NUMBERED RULE" (ie. after 500 continues with 510).
>>>>>
>>>> TEE should go to the next RULE with the original packet, but if
>>>> you reinject the tee'd copy of the packet it should go to the
>>>> next rule NUMBER.
>>> Which is what happens now, right?  Same behaviour on tee reinjection as 
>>> divert does seem consistent.  So if there is a problem, it's only with 
>>> the original packet continuing with the next rule if same-numbered?
>> from Luigi's description I'm not sure what happens now.. :-)
> 
> fair enough, let me explain again:
> A. with "divert" the packet is passed to the divert
>   socket, and when/if reinjected processing continues no earlier
>   than the the NEXT NUMBERED rule. This is a restriction due to the
>   current divert socket API that I have no intention to change.
>   
> B. with "tee", the copy of the packet that goes to the socket
>    behaves the same as above. The original, which remains in
>    the kernel, continues processing from the NEXT NUMBERED RULE.


This is unexpected. It should  continue at the next rule
are you sure?

> 
> C. with "netgraph", the packet is passed to the netgraph node,
>    and when/if reinjected processing continues with the NEXT RULE.
>    This is different from #A

AHHHHH
now I understand.
to me this does make some sense.
Think of the RULE as a netgraph node.
it has a hook to the outside netgraph graph through which
packets may come and go.
they are coming to that RULE and the only place they can go
thereafter is the next rule.
(I have not looked at the code nor have I ever used a netgraph rule in 
ipfw, I didn't write it but I can see how this may come about.)
(goes off to read netgraph/ipfw interface code)


>  
> D. with "ngtee", the copy of the packet that goes to the netgraph
>    node behaves as in #C. The original packet, continues processing
>    with the NEXT RULE (again, different from "tee" processing in #B)

This I would expect


> 
> E. For the records, packets going through dummynet and reinjected
>    because net.inet.ip.fw.one_pass=0, continue from the NEXT RULE.

what if someone rewrites the firewall while they are 'away'?

> 
> I think there is some agreement that "tee" and "ngtee" should do
> the same thing for the original packet (the one that continues
> processing), and i believe the correct approach is #D (i.e. continue
> from the NEXT RULE). The point of my original question was to correct
> what is done in case #B above.
> 
> I am less clear on what to do for the packets passed to the divert
> socket or netgraph node (cases #A and #B above), but i would vote
> for keeping things unchanged because it is the best we can do.
> (Ideally, I think that all forms of
> diversion should continue by default from the NEXT RULE -- this is
> what currently happens with netgraph #B and dummynet #E.
> But we cannot change "divert" #A because of API limitations,
> and I think we cannot change dummynet #E to continue with the next
> numbered rule because it breaks existing configurations.


the golden standard is ot continue at the next rule, but in
divert's case the best it can do is the next "identifiable" rule.

The design goal on divert sockets was that if the application
gets a sockaddr from a divert socket and use it unchanged to
pass the packet back it will do as close to the right thing as
possible. The sockaddr gives you the rule number that sent the packet
to you.  sending hte packet back to THAT number would casue a loop,
so the best we can do is the NEXT number, (whatever that is).
the problem comes because numbers may not be unique, but
I had to "live with that" as we have no other way to identify a rule 
from user land.


> 
> 	cheers
> 	luigi



More information about the freebsd-net mailing list