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
2 changed files with 13 additions and 24 deletions

View File

@ -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

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);
}
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;