Index: sys/netinet/tcp.h =================================================================== --- sys/netinet/tcp.h +++ sys/netinet/tcp.h @@ -55,12 +55,12 @@ 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 Index: sys/netinet/tcp_lro.h =================================================================== --- sys/netinet/tcp_lro.h +++ 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,9 @@ 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, + timestamp : 1, + needs_merge : 1; struct bintime alloc_time; /* time when entry was allocated */ }; Index: sys/netinet/tcp_lro.c =================================================================== --- sys/netinet/tcp_lro.c +++ sys/netinet/tcp_lro.c @@ -921,7 +921,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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]);