Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Jan 2008 23:11:44 GMT
From:      Andre Oppermann <andre@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 134333 for review
Message-ID:  <200801282311.m0SNBioE048376@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=134333

Change 134333 by andre@andre_flirtbox on 2008/01/28 23:10:52

	Add tcptruncate rule option to ipfw.  It is used to test and exercise tcp
	reassembly queue processing and SACK block tracking.
	
	From its man page:
	
	tcptruncate
	    Modifies TCP packets by truncating their payload.  Positive num-
	    bers truncate from the tail of the packet, negative numbers from
	    the head.  At least one byte is left in the payload, even if the
	    truncate size is larger than the whole payload.
	
	The diff to /src/sbin/ipfw/ipfw2.[c8] is added as file because this
	branch doesn't contain userland bits.
	
	An example truncating 1% each of the incoming segments from tail and
	head:
	
	    ipfw add 100 prob 0.01 allow tcp from any to me tcptruncate 10
	    ipfw add 100 prob 0.0101 allow tcp from any to me tcptruncate -10

Affected files ...

.. //depot/projects/tcp_reass/netinet/ip_fw.h#2 edit
.. //depot/projects/tcp_reass/netinet/ip_fw2.c#2 edit
.. //depot/projects/tcp_reass/netinet/src-sbin-ipfw-tcptruncate.diff#1 add

Differences ...

==== //depot/projects/tcp_reass/netinet/ip_fw.h#2 (text+ko) ====

@@ -161,6 +161,7 @@
 	O_TAG,   		/* arg1=tag number */
 	O_TAGGED,		/* arg1=tag number */
 
+	O_TCPTRUNCATE,		/* arg1=truncate TCP segment */
 	O_LAST_OPCODE		/* not an opcode!		*/
 };
 

==== //depot/projects/tcp_reass/netinet/ip_fw2.c#2 (text+ko) ====

@@ -3025,6 +3025,71 @@
 				}
 				break;
 
+			case O_TCPTRUNCATE:
+				/* Cut off part of the tcp segment. */
+				if (proto == IPPROTO_TCP && offset == 0) {
+				    struct tcphdr *tcp;
+				    uint16_t datalen, hdrlen;
+				    int16_t trunc;
+				    int i;
+
+				    if (cmdlen != 1)
+					break;
+
+				    /* Initialize. */
+				    tcp = TCP(ulp);
+				    hdrlen = ((ip->ip_hl + tcp->th_off) << 2);
+				    datalen = ip_len - hdrlen;
+				    trunc = (int16_t)cmd->arg1;
+
+				    /* Never make a zero sized segment. */
+				    if (datalen < 2 || trunc == 0)
+					break;
+
+				    /*
+				     * Trim from end of segment.
+				     * Adjust ip->ip_len.
+				     * Update TCP checksum.
+				     */
+				    if (trunc > 0) {
+					/* Truncating from the tail always works. */
+					i = min(datalen - 1, datalen - trunc);
+					m_adj(m, -i);
+				    } else if (m->m_next == NULL) {
+					/* Single mbuf, the common case. */
+					i = min(datalen - 1, datalen - (+trunc));
+					bcopy(mtod(m, caddr_t) + hdrlen, mtod(m, caddr_t), i);
+					m_adj(m, -i);
+				    } else if (m->m_len == hdrlen && m->m_next != NULL) {
+					/* Header splitting. */
+					i = min(datalen - 1, datalen - (+trunc));
+					m_adj(m->m_next, i);
+				    } else
+					break;
+
+				    /* Accounting for the changes. */
+				    ip->ip_len = m->m_pkthdr.len;
+				    pktlen = ip_len = m->m_pkthdr.len;
+
+				    /* Updating checksum, not offloaded. */
+				    tcp->th_sum = 0;
+				    tcp->th_sum = in_pseudo(ip->ip_src.s_addr,
+					ip->ip_dst.s_addr,
+					htons(IPPROTO_TCP + ip_len -
+					(ip->ip_hl << 2)));
+				    tcp->th_sum = in_cksum_skip(m, ip->ip_len,
+					ip->ip_hl << 2);
+				    ip->ip_len = htons(ip->ip_len);
+				    ip->ip_off = htons(ip->ip_off);
+				    ip->ip_sum = 0;
+				    ip->ip_sum = in_cksum(m, hlen);
+				    ip->ip_len = htons(ip->ip_len);
+				    ip->ip_off = htons(ip->ip_off);
+
+				    match = 1;
+				}
+				break;
+
 			case O_TCPFLAGS:
 				match = (proto == IPPROTO_TCP && offset == 0 &&
 				    flags_match(cmd, TCP(ulp)->th_flags));
@@ -4133,6 +4198,7 @@
 #endif
 		case O_IP4:
 		case O_TAG:
+		case O_TCPTRUNCATE:
 			if (cmdlen != F_INSN_SIZE(ipfw_insn))
 				goto bad_size;
 			break;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801282311.m0SNBioE048376>