aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_sack.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/tcp_sack.c')
-rw-r--r--sys/netinet/tcp_sack.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c
index f59cc5fe0d0b..53a181703fe9 100644
--- a/sys/netinet/tcp_sack.c
+++ b/sys/netinet/tcp_sack.c
@@ -137,6 +137,11 @@ SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, lrd, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(tcp_do_lrd), 1,
"Perform Lost Retransmission Detection");
+VNET_DEFINE(int, tcp_sack_tso) = 0;
+SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, tso, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(tcp_sack_tso), 0,
+ "Allow TSO during SACK loss recovery");
+
VNET_DEFINE(int, tcp_sack_maxholes) = 128;
SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO, maxholes, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(tcp_sack_maxholes), 0,
@@ -558,6 +563,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
int i, j, num_sack_blks;
sackstatus_t sack_changed;
int delivered_data, left_edge_delta;
+ int maxseg = tp->t_maxseg - MAX_TCPOPTLEN;
tcp_seq loss_hiack = 0;
int loss_thresh = 0;
@@ -604,7 +610,9 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
SEQ_GT(sack.start, th_ack) &&
SEQ_LT(sack.start, tp->snd_max) &&
SEQ_GT(sack.end, tp->snd_una) &&
- SEQ_LEQ(sack.end, tp->snd_max)) {
+ SEQ_LEQ(sack.end, tp->snd_max) &&
+ ((sack.end - sack.start) >= maxseg ||
+ SEQ_GEQ(sack.end, tp->snd_max))) {
sack_blocks[num_sack_blks++] = sack;
} else if (SEQ_LEQ(sack.start, th_ack) &&
SEQ_LEQ(sack.end, th_ack)) {