From pkern@cns.utoronto.ca  Mon Jan 12 09:09:33 2004
Return-Path: <pkern@cns.utoronto.ca>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 128C216A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 12 Jan 2004 09:09:33 -0800 (PST)
Received: from rodent.utcs.utoronto.ca (rodent.utcs.utoronto.ca [128.100.102.5])
	by mx1.FreeBSD.org (Postfix) with SMTP id 0DA1443D46
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 12 Jan 2004 09:07:57 -0800 (PST)
	(envelope-from pkern@cns.utoronto.ca)
Received: by rodent.utcs.utoronto.ca id <1650961>; Mon, 12 Jan 2004 12:07:47 -0500
Message-Id: <04Jan12.120747est.1650961@rodent.utcs.utoronto.ca>
Date: Mon, 12 Jan 2004 12:07:47 -0500
From: pak@cns.utoronto.ca
Reply-To: pak@cns.utoronto.ca
To: FreeBSD-gnats-submit@freebsd.org
Cc: pak@cns.utoronto.ca
Subject: [patch] make "ipfw tee" work as intended under freebsd-5
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         61259
>Category:       kern
>Synopsis:       [patch] make "ipfw tee" work as intended under freebsd-5
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    andre
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 12 09:10:18 PST 2004
>Closed-Date:    Thu Sep 09 12:30:02 GMT 2004
>Last-Modified:  Thu Sep 09 12:30:02 GMT 2004
>Originator:     P Kern <pak@cns.utoronto.ca>
>Release:        FreeBSD 5.2-RC2 i386
>Organization:
U of Toronto Computing and Networking Services
>Environment:
System: FreeBSD work 5.2-RC2 FreeBSD 5.2-RC2 #2: Mon Jan 12 11:30:53 EST 2004 root@work:/usr/src/sys/i386/compile/WORK i386


>Description:

	[ This the FreeBSD-5 version of ...
		http://www.freebsd.org/cgi/query-pr.cgi?pr=60377
	  It differs only by shifts in line numbers.  ]

	Currently with "ipfw tee" [as noted in BUGS in ipfw(8) ...]
	  "the search terminates and the original packet is accepted."
	Here is a patch to make "ipfw tee" work as originally intended.
	With this patch, after a matching packet is sent to the divert
	socket, instead of terminating the search and accepting the
	packet, the search continues so that the packet is checked
	against any further IPFW rules.

	Files changed with this patch:
		sys/netinet/ip_input.c
		sys/netinet/ip_output.c
		sbin/ipfw/ipfw.8

	Hope this helps.
	P Kern.

>How-To-Repeat:
>Fix:

*** sys/netinet/ip_input.c	2004/01/12 16:04:35	1.1
--- sys/netinet/ip_input.c	2004/01/12 16:08:05
***************
*** 892,912 ****
  		divert_packet(m, 1, divert_info & 0xffff, args.divert_rule);
  		ipstat.ips_delivered++;
  
! 		/* If 'tee', continue with original packet */
! 		if (clone == NULL)
  			return;
! 		m = clone;
! 		ip = mtod(m, struct ip *);
! 		ip->ip_len += hlen;
! 		/*
! 		 * Jump backwards to complete processing of the
! 		 * packet. But first clear divert_info to avoid
! 		 * entering this block again.
! 		 * We do not need to clear args.divert_rule
! 		 * or args.next_hop as they will not be used.
! 		 */
! 		divert_info = 0;
! 		goto pass;
  	}
  #endif
  
--- 892,926 ----
  		divert_packet(m, 1, divert_info & 0xffff, args.divert_rule);
  		ipstat.ips_delivered++;
  
! 		/* If 'tee', restart the packet at this divert rule. */
! 		if (clone != NULL) {
! 			struct m_hdr divert_tag;
! 
! 			m = clone;
! 			ip = mtod(m, struct ip *);
! 
! 			/* Restore packet header fields to original values */
! 			ip->ip_len += hlen;
! 			ip->ip_len = htons(ip->ip_len);
! 			ip->ip_off = htons(ip->ip_off);
! 
! 			/*
! 			 * set the IPFW restart point.
! 			 * adapted from div_output() in ip_divert.c
! 			 */
! 			divert_tag.mh_type = MT_TAG;
! 			divert_tag.mh_flags = PACKET_TAG_DIVERT;
! 			divert_tag.mh_next = m;
! 			divert_tag.mh_data = (caddr_t)(int)args.divert_rule;	/* the matching rule # */
! 
! 			/*
! 			 * resubmit packet to input processing.
! 			 * XXX - need to decrement some ipstats
! 			 *	 to avoid overcounting?
! 			 */
! 			ip_input((struct mbuf *)&divert_tag);
  			return;
! 		}
  	}
  #endif
  
*** sys/netinet/ip_output.c	2004/01/12 16:04:35	1.1
--- sys/netinet/ip_output.c	2004/01/12 16:08:20
***************
*** 829,839 ****
  			/* Deliver packet to divert input routine */
  			divert_packet(m, 0, off & 0xffff, args.divert_rule);
  
! 			/* If 'tee', continue with original packet */
  			if (clone != NULL) {
! 				m = clone;
! 				ip = mtod(m, struct ip *);
! 				goto pass;
  			}
  			goto done;
  		}
--- 829,853 ----
  			/* Deliver packet to divert input routine */
  			divert_packet(m, 0, off & 0xffff, args.divert_rule);
  
! 			/* If 'tee', restart the packet at this divert rule. */
  			if (clone != NULL) {
! 				struct m_hdr divert_tag;
! 
! 				/*
! 				 * set the IPFW restart point.
! 				 * adapted from div_output() in ip_divert.c
! 				 */
! 				divert_tag.mh_type = MT_TAG;
! 				divert_tag.mh_flags = PACKET_TAG_DIVERT;
! 				divert_tag.mh_next = clone;
! 				divert_tag.mh_data = (caddr_t)(int)args.divert_rule;	/* the matching rule # */
! 
! 				/*
! 				 * resubmit packet to output processing
! 				 * XXX - need to decrement some ipstats
! 				 *	 to avoid overcounting?
! 				 */
! 				return (ip_output((struct mbuf *)&divert_tag, opt, ro, flags, imo, inp));
  			}
  			goto done;
  		}
*** sbin/ipfw/ipfw.8	2003/12/17 19:58:31	1.1
--- sbin/ipfw/ipfw.8	2003/12/18 14:33:25
***************
*** 654,663 ****
  .Xr divert 4
  socket bound to port
  .Ar port .
- The search terminates and the original packet is accepted
- (but see Section
- .Sx BUGS
- below).
  .It Cm unreach Ar code
  Discard packets that match this rule, and try to send an ICMP
  unreachable notice with code
--- 654,659 ----
***************
*** 2133,2144 ****
  are reassembled before delivery to the socket.
  The action used on those packet is the one from the
  rule which matches the first fragment of the packet.
- .Pp
- Packets that match a
- .Cm tee
- rule should not be immediately accepted, but should continue
- going through the rule list.
- This may be fixed in a later version.
  .Pp
  Packets diverted to userland, and then reinserted by a userland process
  may lose various packet attributes.
--- 2129,2134 ----


>Release-Note:
>Audit-Trail:

From: P Kern <pak@cns.utoronto.ca>
To: freebsd-gnats-submit@FreeBSD.org, pak@cns.utoronto.ca
Cc:  
Subject: Re: kern/61259: [patch] make "ipfw tee" work as intended under freebsd-5
Date: Thu, 15 Jan 2004 16:59:25 -0500

 Please see my follow-up to ...
 	http://www.freebsd.org/cgi/query-pr.cgi?pr=60377
 
 The patch for ip_input.c now reads ....
 
 	if (clone != NULL) {
 		...
 		ip_input(...);
 		return;
 	}
 
 ... but it should instead read ...
 
 	if (clone != NULL) {
 		...
 		ip_input(...);
 	}
 	return;
 
 Sorry about that. Hope this helps. pak.
 
Responsible-Changed-From-To: freebsd-bugs->ipfw 
Responsible-Changed-By: kris 
Responsible-Changed-When: Mon Mar 15 16:34:07 PST 2004 
Responsible-Changed-Why:  
Assign to ipfw mailing list 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61259 
Responsible-Changed-From-To: ipfw->andre 
Responsible-Changed-By: andre 
Responsible-Changed-When: Tue Aug 24 18:11:24 GMT 2004 
Responsible-Changed-Why:  
Take over. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61259 
State-Changed-From-To: open->closed 
State-Changed-By: andre 
State-Changed-When: Thu Sep 9 12:29:07 GMT 2004 
State-Changed-Why:  
A fix for the 'ipfw tee' problem is developed and tracked in 
kern/64240. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=61259 
>Unformatted:
