Index: sbin/ipfw/ipfw.8 =================================================================== RCS file: /home/ncvs/src/sbin/ipfw/ipfw.8,v retrieving revision 1.139 diff -u -d -r1.139 ipfw.8 --- sbin/ipfw/ipfw.8 23 Jan 2004 06:37:19 -0000 1.139 +++ sbin/ipfw/ipfw.8 10 Mar 2004 09:03:06 -0000 @@ -658,10 +658,7 @@ .Xr divert 4 socket bound to port .Ar port . -The search terminates and the original packet is accepted -(but see Section -.Sx BUGS -below). +The search continues at the next rule. .It Cm unreach Ar code Discard packets that match this rule, and try to send an ICMP unreachable notice with code @@ -2169,12 +2166,6 @@ 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. Index: sys/netinet/ip_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v retrieving revision 1.266 diff -u -d -r1.266 ip_input.c --- sys/netinet/ip_input.c 1 Mar 2004 22:37:01 -0000 1.266 +++ sys/netinet/ip_input.c 10 Mar 2004 08:35:58 -0000 @@ -473,6 +473,9 @@ if (args.next_hop) goto ours; +#ifdef IPDIVERT +again: +#endif args.m = m; i = ip_fw_chk_ptr(&args); m = args.m; @@ -854,20 +857,22 @@ divert_packet(m, 1); ipstat.ips_delivered++; - /* If 'tee', continue with original packet */ + /* If 'tee', continue processing firewall rules + * with the 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. We do not need to clear args.next_hop * as that will not be used again and the cloned packet * doesn't contain a divert packet tag so we won't * re-entry this block. + * We must not clear args.divert_rule since it is + * used to maintain context for continued rule + * processing. */ - goto pass; + goto again; } #endif Index: sys/netinet/ip_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v retrieving revision 1.211 diff -u -d -r1.211 ip_output.c --- sys/netinet/ip_output.c 2 Mar 2004 14:37:23 -0000 1.211 +++ sys/netinet/ip_output.c 10 Mar 2004 08:35:32 -0000 @@ -731,6 +731,9 @@ if (fw_enable && IPFW_LOADED && !args.next_hop) { struct sockaddr_in *old = dst; +#ifdef IPDIVERT +again: +#endif args.m = m; args.next_hop = dst; args.oif = ifp; @@ -807,11 +810,10 @@ /* Deliver packet to divert input routine */ divert_packet(m, 0); - /* If 'tee', continue with original packet */ + /* If 'tee', continue processing firewall + * rules with the original packet */ if (clone != NULL) { - m = clone; - ip = mtod(m, struct ip *); - goto pass; + goto again; } goto done; }