Skip site navigation (1)Skip section navigation (2)
Date:       Fri, 29 Sep 2000 15:05:03 +1100
From:      Peter Jeremy <peter.jeremy@alcatel.com.au>
To:        freebsd-net@FreeBSD.ORG
Subject:   ipfw(8) divert handling
Message-ID:  <00Sep29.150454est.115252@border.alcanet.com.au>

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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?00Sep29.150454est.115252>