Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 31 Dec 2009 00:53:15 +1100 (EST)
From:      Ian Smith <smithi@nimnet.asn.au>
To:        Julian Elischer <julian@elischer.org>
Cc:        Luigi Rizzo <rizzo@iet.unipi.it>, net@freebsd.org
Subject:   Re: RFC: documented and actual behaviour of "ipfw tee"
Message-ID:  <20091230221119.L81420@sola.nimnet.asn.au>
In-Reply-To: <4B3AA290.8000508@elischer.org>
References:  <20091230002447.GA55727@onelab2.iet.unipi.it> <4B3AA290.8000508@elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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?

 > > The actual behaviour is an artifact of how "divert" is implemented:
 > > diverted packet only carry the rule number so we cannot tell, on a
 > > reinject, which of the rules numbered "500" matched, and we restart
 > > from the next one. Tee was implemented as an extension of divert.

It seems fair that tee act the same as divert on reinjection, and this 
can't be changed without breaking existing divert socket code eg natd?

 > > Skipping rules in my opinion is very unintuitive, but there is
 > > no way to fix it (unless we extend the API) as the rule_id is only
 > > known within the kernel.
 > > 
 > > For 'tee', however, packets  the situation is different because the
 > > copy of the packet that remains in the kernel does not lose knowledge
 > > of the matching rule so we can easily continue from the very next
 > > rule, same as it happens for dummynet packets with one_pass=0 (and
 > > tee'd netgraph packets, which I think already do "the right thing").

Hmm.  After divert you can match 'diverted' to distinguish reinjected 
packets later.  Does/can/should this apply to reinjected tee'd packets?

Similarly perhaps, with a set of same-numbered nat rules, are mapped 
packets 'reinjected' at the next rule, or the next higher-numbered rule?

 > > Since I am doing some work in this are of the code, I'd like to ask
 > > opinions on how to proceed:
 > > 
 > >     A. preserve the current behaviour and fix the manpage;

I tend to this, though probably not knowing all the ramifications, 
especially not having played with ng_ipfw stuff at all.

So for A, here's what we have, with suggested clarification in []:

     divert port
             Divert packets that match this rule to the divert(4) socket bound
             to port port.  The search terminates.  [Reinjected packets continue
             at the next higher-numbered rule.]

     tee port
             Send a copy of packets matching this rule to the divert(4) socket
             bound to port port.  The search continues with the next rule.
             [Reinjected packets continue at the next higher-numbered rule.]

 > >     B. fix the code to behave as the manpage says;

Seems it's already correct regarding the original packet, and just needs 
clarifying re the reinjected packets, if I'm following this right?

 > >     C. introduce a sysctl to choose between A and B.
 > > 	Of course this moves the problem on which default
 > > 	to choose :)
 > > 
 > > Because it is a very special case that I doubt many people have hit,
 > > I'd be inclined to do B and consider the old behaviour a bug.

Mike Makonnen's ipfw-classifyd can reinject packets at specified rule 
numbers by tcp/udp port classification by updating the tag/number, and 
has the same issue.  There was some confusion there too regarding this,
that I think a man clarification may have helped avoid.

I'm also a bit confused by apparent overloading of one_pass function for 
dummynet pipe, netgraph, ng_tee and now nat too.  What if you want to 
do kernel nat but wanted one_pass behaviour for pipes?  Separate issue 
but similar distinction between divert vs in-kernel behaviour maybe?

FWIW, Ian



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20091230221119.L81420>