Make 'ipfw tee' behave as inteded and designed. A tee'd packet is copied

and sent to the DIVERT socket while the original packet continues with the
next rule.  Unlike a normally diverted packet no IP reassembly attemts are
made on tee'd packets and they are passed upwards totally unmodified.

Note: This will not be MFC'd to 4.x because of major infrastucture changes.

PR:		kern/64240 (and many others collapsed into that one)
This commit is contained in:
Andre Oppermann 2004-09-13 16:46:05 +00:00
parent 08aa5a1ddb
commit 7c0102f575
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=135154
2 changed files with 13 additions and 24 deletions

View File

@ -1,7 +1,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd August 9, 2004 .Dd September 13, 2004
.Dt IPFW 8 .Dt IPFW 8
.Os .Os
.Sh NAME .Sh NAME
@ -672,10 +672,7 @@ Send a copy of packets matching this rule to the
.Xr divert 4 .Xr divert 4
socket bound to port socket bound to port
.Ar port . .Ar port .
The search terminates and the original packet is accepted The search continues with the next rule.
(but see Section
.Sx BUGS
below).
.It Cm unreach Ar code .It Cm unreach Ar code
Discard packets that match this rule, and try to send an ICMP Discard packets that match this rule, and try to send an ICMP
unreachable notice with code unreachable notice with code
@ -2297,18 +2294,10 @@ regain control of it.
.Pp .Pp
Incoming packet fragments diverted by Incoming packet fragments diverted by
.Cm divert .Cm divert
or
.Cm tee
are reassembled before delivery to the socket. are reassembled before delivery to the socket.
The action used on those packet is the one from the The action used on those packet is the one from the
rule which matches the first fragment of the packet. rule which matches the first fragment of the packet.
.Pp .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 Packets diverted to userland, and then reinserted by a userland process
may lose various packet attributes. may lose various packet attributes.
The packet source interface name The packet source interface name

View File

@ -100,6 +100,7 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
m_tag_delete(*m0, dn_tag); m_tag_delete(*m0, dn_tag);
} }
again:
args.m = *m0; args.m = *m0;
ipfw = ipfw_chk(&args); ipfw = ipfw_chk(&args);
*m0 = args.m; *m0 = args.m;
@ -127,7 +128,7 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
*m0 = NULL; *m0 = NULL;
return 0; /* packet consumed */ return 0; /* packet consumed */
} else } else
goto pass; /* continue with packet */ goto again; /* continue with packet */
} }
#ifdef IPFIREWALL_FORWARD #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); m_tag_delete(*m0, dn_tag);
} }
again:
args.m = *m0; args.m = *m0;
args.oif = ifp; args.oif = ifp;
ipfw = ipfw_chk(&args); ipfw = ipfw_chk(&args);
@ -209,7 +211,7 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
*m0 = NULL; *m0 = NULL;
return 0; /* packet consumed */ return 0; /* packet consumed */
} else } else
goto pass; /* continue with packet */ goto again; /* continue with packet */
} }
#ifdef IPFIREWALL_FORWARD #ifdef IPFIREWALL_FORWARD
@ -243,14 +245,12 @@ static int
ipfw_divert(struct mbuf **m, int incoming, int tee) ipfw_divert(struct mbuf **m, int incoming, int tee)
{ {
/* /*
* ipfw_chk() has already tagged the packet with the divert * ipfw_chk() has already tagged the packet with the divert tag.
* tag. For tee we need to remove the tag.
* If tee is set, copy packet and return original. * If tee is set, copy packet and return original.
* If not tee, consume packet and send it to divert socket. * If not tee, consume packet and send it to divert socket.
*/ */
#ifdef IPDIVERT #ifdef IPDIVERT
struct mbuf *clone, *reass; struct mbuf *clone, *reass;
struct m_tag *mtag;
struct ip *ip; struct ip *ip;
int hlen; int hlen;
@ -307,12 +307,12 @@ ipfw_divert(struct mbuf **m, int incoming, int tee)
divert_packet(clone, incoming); divert_packet(clone, incoming);
teeout: teeout:
if (tee) { /*
mtag = m_tag_find(*m, PACKET_TAG_DIVERT, NULL); * For tee we leave the divert tag attached to original packet.
if (mtag != NULL) * It will then continue rule evaluation after the tee rule.
m_tag_delete(*m, mtag); */
return 0; /* continue with original packet. */ if (tee)
} return 0;
/* Packet diverted and consumed */ /* Packet diverted and consumed */
return 1; return 1;