diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index e0c8055d17da..43c2b5284001 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 9, 2004 +.Dd September 13, 2004 .Dt IPFW 8 .Os .Sh NAME @@ -672,10 +672,7 @@ Send a copy of packets matching this rule to the .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 with the next rule. .It Cm unreach Ar code Discard packets that match this rule, and try to send an ICMP unreachable notice with code @@ -2297,18 +2294,10 @@ regain control of it. .Pp Incoming packet fragments diverted by .Cm divert -or -.Cm tee 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. The packet source interface name diff --git a/sys/netinet/ip_fw_pfil.c b/sys/netinet/ip_fw_pfil.c index 77ba4b6337bb..7a326d98850e 100644 --- a/sys/netinet/ip_fw_pfil.c +++ b/sys/netinet/ip_fw_pfil.c @@ -100,6 +100,7 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir) m_tag_delete(*m0, dn_tag); } +again: args.m = *m0; ipfw = ipfw_chk(&args); *m0 = args.m; @@ -127,7 +128,7 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir) *m0 = NULL; return 0; /* packet consumed */ } else - goto pass; /* continue with packet */ + goto again; /* continue with packet */ } #ifdef IPFIREWALL_FORWARD @@ -182,6 +183,7 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir) m_tag_delete(*m0, dn_tag); } +again: args.m = *m0; args.oif = ifp; ipfw = ipfw_chk(&args); @@ -209,7 +211,7 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir) *m0 = NULL; return 0; /* packet consumed */ } else - goto pass; /* continue with packet */ + goto again; /* continue with packet */ } #ifdef IPFIREWALL_FORWARD @@ -243,14 +245,12 @@ static int ipfw_divert(struct mbuf **m, int incoming, int tee) { /* - * ipfw_chk() has already tagged the packet with the divert - * tag. For tee we need to remove the tag. + * ipfw_chk() has already tagged the packet with the divert tag. * If tee is set, copy packet and return original. * If not tee, consume packet and send it to divert socket. */ #ifdef IPDIVERT struct mbuf *clone, *reass; - struct m_tag *mtag; struct ip *ip; int hlen; @@ -307,12 +307,12 @@ ipfw_divert(struct mbuf **m, int incoming, int tee) divert_packet(clone, incoming); teeout: - if (tee) { - mtag = m_tag_find(*m, PACKET_TAG_DIVERT, NULL); - if (mtag != NULL) - m_tag_delete(*m, mtag); - return 0; /* continue with original packet. */ - } + /* + * For tee we leave the divert tag attached to original packet. + * It will then continue rule evaluation after the tee rule. + */ + if (tee) + return 0; /* Packet diverted and consumed */ return 1;