aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Stone <rstone@FreeBSD.org>2022-02-08 15:08:50 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2022-02-08 15:08:50 +0000
commit4287b7caa921131845837dd394581d0246f38eb1 (patch)
treee492872cc8341bc0e21cec2d268a665fcd51386b
parent22b24dc1abb3bc41c9b54054c2242b525daa5bfc (diff)
downloadsrc-4287b7caa921131845837dd394581d0246f38eb1.tar.gz
src-4287b7caa921131845837dd394581d0246f38eb1.zip
LRO: Don't merge ACK and non-ACK packets together
LRO was willing to merge ACK and non-ACK packets together. This can cause incorrect th_ack values to be reported up the stack. While non-ACKs are quite unlikely to appear in practice, LRO's behaviour is against the spec. Make LRO unwilling to merge packets with different TH_ACK flag values in order to fix the issue. Found by: Sysunit test Differential Revision: https://reviews.freebsd.org/D33775 Reviewed by: rrs (cherry picked from commit 3284f4925f697ad7cc2aa4761ff5cf6ce98fd623)
-rw-r--r--sys/netinet/tcp_lro.c5
-rw-r--r--sys/netinet/tcp_lro.h5
2 files changed, 7 insertions, 3 deletions
diff --git a/sys/netinet/tcp_lro.c b/sys/netinet/tcp_lro.c
index feec8c36ab69..cfc84707abd2 100644
--- a/sys/netinet/tcp_lro.c
+++ b/sys/netinet/tcp_lro.c
@@ -895,6 +895,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->needs_merge = 0;
/* Setup new data pointers. */
@@ -1066,10 +1067,12 @@ again:
}
/* Try to append the new segment. */
if (__predict_false(ntohl(th->th_seq) != le->next_seq ||
+ ((th->th_flags & TH_ACK) !=
+ (le->flags & TH_ACK)) ||
(tcp_data_len == 0 &&
le->ack_seq == th->th_ack &&
le->window == th->th_win))) {
- /* Out of order packet or duplicate ACK. */
+ /* Out of order packet, non-ACK + ACK or dup ACK. */
tcp_push_and_replace(lc, le, m);
goto again;
}
diff --git a/sys/netinet/tcp_lro.h b/sys/netinet/tcp_lro.h
index 97819596231e..b8abc2fa1ab3 100644
--- a/sys/netinet/tcp_lro.h
+++ b/sys/netinet/tcp_lro.h
@@ -146,8 +146,9 @@ struct lro_entry {
uint16_t compressed;
uint16_t uncompressed;
uint16_t window;
- uint16_t timestamp : 1;
- uint16_t needs_merge : 1;
+ uint8_t flags;
+ uint8_t timestamp : 1;
+ uint8_t needs_merge : 1;
struct bintime alloc_time; /* time when entry was allocated */
};