kern/136695: fwd reached after skipto in dynamic rules does not work in every case [PATCH]

Nicolas Rachinsky nicolas-2009 at rachinsky.de
Sun Jul 12 16:30:02 UTC 2009


>Number:         136695
>Category:       kern
>Synopsis:       fwd reached after skipto in dynamic rules does not work in every case [PATCH]
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 12 16:30:01 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Nicolas Rachinsky
>Release:        FreeBSD 6.4-p5 (does probably apply to 8)
>Organization:
>Environment:
FreeBSD somehost 6.4-RELEASE-p5 FreeBSD 6.4-RELEASE-p5 #4: Sun Jul 12 18:03:33 CEST 2009     somebody:/usr/exported/src/sys/i386/compile/PC5  i386

>Description:
I have an pptp-tunnel with an static IP. I want to use this for incoming and outgoing services together with keep-state. So instead of allow I use "skipto 4040", where the rules following 4040 decide wether to forward the packet via pptp 
or use the normal uplink.

04040 fwd <pptp_peer> ip from <my_pptp_ip> to any out
04050 allow ip from any to any


Now I want incoming smtp on both the normal uplink and via pptp, so I have the rule:
skipto 4040 tcp from me to any dst-port 25 out setup keep-state

This does not work, the fwd rule is just an accept rule for the packets returned by my machine.

fwd is ignored after an dynamic rule matched in the "reverse" direction. I think, fwd should work even after a dynamic rule matched in the reverse direction, when the action of the dynamic rule is a skipto.

The attached patch changes this behaviour. The current code looks quite similar.
>How-To-Repeat:
see above
>Fix:
apply the attached patch

Patch attached with submission follows:

Index: ip_fw2.c
===================================================================
RCS file: /usr/cvs-freebsd/src/sys/netinet/Attic/ip_fw2.c,v
retrieving revision 1.106.2.41.2.1
diff -u -r1.106.2.41.2.1 ip_fw2.c
--- ip_fw2.c	2 Oct 2008 02:57:24 -0000	1.106.2.41.2.1
+++ ip_fw2.c	12 Jul 2009 16:15:37 -0000
@@ -2215,9 +2215,14 @@
 	/*
 	 * dyn_dir = MATCH_UNKNOWN when rules unchecked,
 	 * 	MATCH_NONE when checked and not matched (q = NULL),
-	 *	MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL)
+	 	MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL)
 	 */
 	int dyn_dir = MATCH_UNKNOWN;
+	/*
+	 * skip_after_dyn set to 1 if the action of
+	   a dynamic rule is skipto
+	 */
+	int skip_after_dyn = 0;
 	ipfw_dyn_rule *q = NULL;
 	struct ip_fw_chain *chain = &layer3_chain;
 	struct m_tag *mtag;
@@ -3255,6 +3260,8 @@
 				if (f->next_rule == NULL)
 					lookup_next_rule(f);
 				f = f->next_rule;
+				if ( dyn_dir != MATCH_UNKNOWN && dyn_dir != MATCH_NONE)
+					skip_after_dyn = 1;
 				goto again;
 
 			case O_REJECT:
@@ -3295,7 +3302,7 @@
 				sa = &(((ipfw_insn_sa *)cmd)->sa);
 				if (args->eh)	/* not valid on layer2 pkts */
 					break;
-				if (!q || dyn_dir == MATCH_FORWARD) {
+				if (!q || dyn_dir == MATCH_FORWARD || skip_after_dyn) {
 					if (sa->sin_addr.s_addr == INADDR_ANY) {
 						bcopy(sa, &args->hopstore,
 							sizeof(*sa));


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list