kern/60377: [patch] to make "ipfw tee" behave as intended.

pak at cns.utoronto.ca pak at cns.utoronto.ca
Thu Dec 18 14:50:45 PST 2003


>Number:         60377
>Category:       kern
>Synopsis:       [patch] to make "ipfw tee" behave as intended.
>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:   Thu Dec 18 14:50:20 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     P Kern <pak at cns.utoronto.ca>
>Release:        FreeBSD 4.9-RELEASE i386
>Organization:
U of Toronto Computing and Networking Services
>Environment:
System: FreeBSD work 4.9-RELEASE FreeBSD 4.9-RELEASE #14: Wed Dec 17 16:05:21 EST 2003 root at work:/usr/src/sys/compile/WORK i386


>Description:

	Currently with "ipfw tee" [as noted in ipfw(8)]
	  "the search terminates and the original packet is accepted."
	Here is a patch to make "ipfw tee" behave as 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.

	Hope this helps.

>How-To-Repeat:
>Fix:

*** sys/netinet/ip_input.c	2003/12/17 16:20:23	1.1
--- sys/netinet/ip_input.c	2003/12/17 19:49:21
***************
*** 845,865 ****
		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
  
--- 845,879 ----
		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	2003/12/17 16:31:48	1.1
--- sys/netinet/ip_output.c	2003/12/17 19:54:31
***************
*** 812,822 ****
			/* 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;
		}
--- 812,836 ----
			/* 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:
>Unformatted:


More information about the freebsd-bugs mailing list