Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Sep 2000 22:03:10 -0700 (PDT)
From:      Julian Elischer <julian@elischer.org>
To:        freebsd-net@FreeBSD.ORG, peter.jeremy@alcatel.com.au
Subject:   Re: ipfw(8) divert handling
Message-ID:  <Pine.BSF.4.10.10009282136500.21594-100000@InterJet.elischer.org>
In-Reply-To: <00Sep29.150454est.115252@border.alcanet.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help
Your confusion results from considering the adtions after the divert and
before the divert as being the same pass.

on diversion, the pass through the ipfw filter is finished. The search is
terminated. (as the man page states). 
However some state information is returned to the divert socket when the
packet is passed out of the  kernel.

Divert also allows packets to be injected into the kernel. It also allows
some state to be associated with the initial state of that packet.. 

It so happens, (what a coincidence!) that the state coming out and the
state sent in are identical in format and semantics. The result of this is
that if you re-submit a received packet, along with the state information
that was received with it, the filtering is started at the next higher
rule number than that at which the original divert occured.

So the man page is correct . The search DID terminate.
As far as the kernel is concerned, the packet that is re-injected is a
DIFFERENT packet. Only the external daemon knows the relationship between
the two.


I have no idea what "one_pass" is trying to achieve.. it wasn't there when
we wrote 'divert'. From my perspective I don't believe it should affect
packets injected via divert. If the daemon wants to inject a packet that
does not pass through any more ipfw rules it can specify the rule number
of an 'accept rule' directly. (prefereably with a low rule number to
reduce overhead). As I mentionned before, a packet injected into teh
system is a NEW packet. it cannot and should not be considerred to be the
same packet as one that was previously diverted..

Julian



On Fri, 29 Sep 2000, Peter Jeremy wrote:

> [Please include me in any replies]
> 
> The behaviour of the ipfw divert rule in both 4-STABLE and -CURRENT is
> different to the ipfw(8) man page.
> 
> The actual behaviour is that if the diverted packet is written back
> into the IP stack, it will re-enter ipfw rule processing at the rule
> number following the divert rule[1].  According to my reading of the
> code, the same thing happens for a tee rule.
> 
> The man page describes two different actions:
> - In the section RULE FORMAT.action.divert, it states "[t]he search
>   terminates".
> - In the section SYSCTL VARIABLES, net.inet.ip.fw.one_pass is
>   described as controlling divert action as well as pipe action, with
>   the packet being re-injected at the next rule.
> 
> The term "next rule", used in several places in the man page, is
> also slightly misleading:  For pipe and queue rules it is the next
> rule in sequence.  For divert and tee, it is the next rule with a
> higher rule number (ie subsequent rules with the same rule number
> are skipped).
> 
> IMHO, there should be a way to make the rule search terminate
> following a successful divert (which fw.one_pass does for pipes).
> The patch below does this, except when the divert process changes
> the rule number to 0 - in which case it restarts processing.
> Comments please.
> 
> On a different topic, I notice that struct ip_fw includes a field
> next_rule_ptr which is documented as "next rule in case of match".
> The code in ip_fw_chk() checks this field on skipto's (to avoid
> needing to do a linear search for skipto rules).  There's even a
> function flush_rule_ptrs() which back this use up.  Unfortunately,
> the code to actually assign next_rule_ptr is missing...  Is there
> some reason why this isn't used?
> 
> [1] If the divert application uses recvfrom(2)/sendto(2), it can change
>     the rule number, but the most common divert application (natd)
>     don't support this.
> 
> Index: ip_fw.c
> ===================================================================
> RCS file: /home/CVSROOT/src/sys/netinet/ip_fw.c,v
> retrieving revision 1.140
> diff -u -r1.140 ip_fw.c
> --- ip_fw.c	2000/09/12 02:38:05	1.140
> +++ ip_fw.c	2000/09/29 04:01:41
> @@ -1017,6 +1017,9 @@
>  		 */
>  		chain = LIST_FIRST(&ip_fw_chain);
>  		if (skipto != 0) {
> +			/* Accept if passed first test */
> +			if (fw_one_pass)
> +				return 0;
>  			if (skipto >= IPFW_DEFAULT_RULE)
>  				goto dropit;
>  			while (chain && chain->rule->fw_number <= skipto)
> 
> Peter
> 
> 
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-net" in the body of the message
> 



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.10.10009282136500.21594-100000>