git: 93e28d6e89e9 - main - tcp: LRO code to deal with all 12 TCP header flags

From: Richard Scheffenegger <rscheff_at_FreeBSD.org>
Date: Tue, 01 Feb 2022 17:59:26 UTC
The branch main has been updated by rscheff:

URL: https://cgit.FreeBSD.org/src/commit/?id=93e28d6e89e9fe5e25313762ed248ea7e88c9345

commit 93e28d6e89e9fe5e25313762ed248ea7e88c9345
Author:     Richard Scheffenegger <rscheff@FreeBSD.org>
AuthorDate: 2022-02-01 16:25:49 +0000
Commit:     Richard Scheffenegger <rscheff@FreeBSD.org>
CommitDate: 2022-02-01 17:41:36 +0000

    tcp: LRO code to deal with all 12 TCP header flags
    
    TCP per RFC793 has 4 reserved flag bits for future use. One
    of those bits may be used for Accurate ECN.
    This patch is to include these bits in the LRO code to ease
    the extensibility if/when these bits are used.
    
    Reviewed By: hselasky, rrs, #transport
    Sponsored by:        NetApp, Inc.
    Differential Revision: https://reviews.freebsd.org/D34127
---
 sys/netinet/tcp.h     |  4 ++--
 sys/netinet/tcp_lro.c | 10 +++++-----
 sys/netinet/tcp_lro.h | 17 +++++++++--------
 3 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h
index 6dc7403aae28..6a3603287f5d 100644
--- a/sys/netinet/tcp.h
+++ b/sys/netinet/tcp.h
@@ -55,12 +55,12 @@ struct tcphdr {
 	tcp_seq	th_seq;			/* sequence number */
 	tcp_seq	th_ack;			/* acknowledgement number */
 #if BYTE_ORDER == LITTLE_ENDIAN
-	u_char	th_x2:4,		/* (unused) */
+	u_char	th_x2:4,		/* upper 4 (reserved) flags */
 		th_off:4;		/* data offset */
 #endif
 #if BYTE_ORDER == BIG_ENDIAN
 	u_char	th_off:4,		/* data offset */
-		th_x2:4;		/* (unused) */
+		th_x2:4;		/* upper 4 (reserved) flags */
 #endif
 	u_char	th_flags;
 #define	TH_FIN	0x01
diff --git a/sys/netinet/tcp_lro.c b/sys/netinet/tcp_lro.c
index b973c788d23e..c1d3b0d4f13f 100644
--- a/sys/netinet/tcp_lro.c
+++ b/sys/netinet/tcp_lro.c
@@ -921,7 +921,7 @@ tcp_set_entry_to_mbuf(struct lro_ctrl *lc, struct lro_entry *le,
 	le->next_seq = ntohl(th->th_seq) + tcp_data_len;
 	le->ack_seq = th->th_ack;
 	le->window = th->th_win;
-	le->flags = th->th_flags;
+	le->flags = (th->th_x2 << 8) | th->th_flags;
 	le->needs_merge = 0;
 
 	/* Setup new data pointers. */
@@ -1033,7 +1033,7 @@ again:
 		tcp_push_and_replace(lc, le, m);
 		goto again;
 	}
-	if ((th->th_flags & ~(TH_ACK | TH_PUSH)) != 0) {
+	if ((((th->th_x2 << 8) | th->th_flags) & ~(TH_ACK | TH_PUSH)) != 0) {
 		/*
 		 * Make sure that previously seen segments/ACKs are delivered
 		 * before this segment, e.g. FIN.
@@ -1077,7 +1077,7 @@ again:
 			tcp_push_and_replace(lc, le, m);
 			goto again;
 		}
-		if ((th->th_flags & ~(TH_ACK | TH_PUSH)) != 0) {
+		if ((((th->th_x2 << 8) | th->th_flags) & ~(TH_ACK | TH_PUSH)) != 0) {
 			tcp_push_and_replace(lc, le, m);
 			goto again;
 		}
@@ -1265,7 +1265,7 @@ tcp_lro_ack_valid(struct mbuf *m, struct tcphdr *th, uint32_t **ppts, bool *othe
 		break;
 	}
 	/* For ACKCMP we only accept ACK, PUSH, ECE and CWR. */
-	if ((th->th_flags & ~(TH_ACK | TH_PUSH | TH_ECE | TH_CWR)) != 0)
+	if ((((th->th_x2 << 8) | th->th_flags) & ~(TH_ACK | TH_PUSH | TH_ECE | TH_CWR)) != 0)
 		ret = false;
 	/* If it has data on it we cannot compress it */
 	if (m->m_pkthdr.lro_tcp_d_len)
@@ -1576,7 +1576,7 @@ build_ack_entry(struct tcp_ackent *ae, struct tcphdr *th, struct mbuf *m,
 		ae->flags = TSTMP_HDWR;
 	ae->seq = ntohl(th->th_seq);
 	ae->ack = ntohl(th->th_ack);
-	ae->flags |= th->th_flags;
+	ae->flags |= (th->th_x2 << 8) | th->th_flags;
 	if (ts_ptr != NULL) {
 		ae->ts_value = ntohl(ts_ptr[1]);
 		ae->ts_echo = ntohl(ts_ptr[2]);
diff --git a/sys/netinet/tcp_lro.h b/sys/netinet/tcp_lro.h
index b8abc2fa1ab3..dd2aa1148822 100644
--- a/sys/netinet/tcp_lro.h
+++ b/sys/netinet/tcp_lro.h
@@ -42,20 +42,20 @@
 
 /*
  * Flags for ACK entry for compression
- * the bottom 8 bits has the th_flags.
+ * the bottom 12 bits has the th_x2|th_flags.
  * LRO itself adds only the TSTMP flags
  * to indicate if either of the types
  * of timestamps are filled and the
  * HAS_TSTMP option to indicate if the
  * TCP timestamp option is valid.
  *
- * The other 5 flag bits are for processing
+ * The other 1 flag bits are for processing
  * by a stack.
  *
  */
-#define TSTMP_LRO		0x0100
-#define TSTMP_HDWR		0x0200
-#define HAS_TSTMP		0x0400
+#define TSTMP_LRO		0x1000
+#define TSTMP_HDWR		0x2000
+#define HAS_TSTMP		0x4000
 /*
  * Default number of interrupts on the same cpu in a row
  * that will cause us to declare a "affinity cpu".
@@ -146,9 +146,10 @@ struct lro_entry {
 	uint16_t		compressed;
 	uint16_t		uncompressed;
 	uint16_t		window;
-	uint8_t			flags;
-	uint8_t			timestamp : 1;
-	uint8_t			needs_merge : 1;
+	uint16_t		flags : 12,	/* 12 TCP header bits */
+				timestamp : 1,
+				needs_merge : 1,
+				reserved : 2;	/* unused */
 	struct bintime		alloc_time;	/* time when entry was allocated */
 };