Date: Fri, 9 Mar 2018 00:08:43 +0000 (UTC) From: Sean Bruno <sbruno@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r330675 - head/sys/netinet Message-ID: <201803090008.w2908hUf078100@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sbruno Date: Fri Mar 9 00:08:43 2018 New Revision: 330675 URL: https://svnweb.freebsd.org/changeset/base/330675 Log: Update tcp_lro with tested bugfixes from Netflix and LLNW: rrs - Lets make the LRO code look for true dup-acks and window update acks fly on through and combine. rrs - Make the LRO engine a bit more aware of ack-only seq space. Lets not have it incorrectly wipe out newer acks for older acks when we have out-of-order acks (common in wifi environments). jeggleston - LRO eating window updates Based on all of the above I think we are RFC compliant doing it this way: https://tools.ietf.org/html/rfc1122 section 4.2.2.16 "Note that TCP has a heuristic to select the latest window update despite possible datagram reordering; as a result, it may ignore a window update with a smaller window than previously offered if neither the sequence number nor the acknowledgment number is increased." Submitted by: Kevin Bowling <kevin.bowling@kev009.com> Reviewed by: rstone gallatin Sponsored by: NetFlix and Limelight Networks Differential Revision: https://reviews.freebsd.org/D14540 Modified: head/sys/netinet/tcp_lro.c head/sys/netinet/tcp_seq.h Modified: head/sys/netinet/tcp_lro.c ============================================================================== --- head/sys/netinet/tcp_lro.c Thu Mar 8 22:54:50 2018 (r330674) +++ head/sys/netinet/tcp_lro.c Fri Mar 9 00:08:43 2018 (r330675) @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/ip.h> #include <netinet/ip_var.h> #include <netinet/tcp.h> +#include <netinet/tcp_seq.h> #include <netinet/tcp_lro.h> #include <netinet/tcp_var.h> @@ -794,7 +795,9 @@ tcp_lro_rx2(struct lro_ctrl *lc, struct mbuf *m, uint3 /* Try to append the new segment. */ if (__predict_false(seq != le->next_seq || - (tcp_data_len == 0 && le->ack_seq == th->th_ack))) { + (tcp_data_len == 0 && + le->ack_seq == th->th_ack && + le->window == th->th_win))) { /* Out of order packet or duplicate ACK. */ tcp_lro_active_remove(le); tcp_lro_flush(lc, le); @@ -811,12 +814,20 @@ tcp_lro_rx2(struct lro_ctrl *lc, struct mbuf *m, uint3 le->tsval = tsval; le->tsecr = *(ts_ptr + 2); } - - le->next_seq += tcp_data_len; - le->ack_seq = th->th_ack; - le->window = th->th_win; - le->append_cnt++; - + if (tcp_data_len || SEQ_GT(ntohl(th->th_ack), ntohl(le->ack_seq))) { + le->next_seq += tcp_data_len; + le->ack_seq = th->th_ack; + le->window = th->th_win; + le->append_cnt++; + } else if (th->th_ack == le->ack_seq) { + le->window = WIN_MAX(le->window, th->th_win); + le->append_cnt++; + } else { + /* no data and old ack */ + le->append_cnt++; + m_freem(m); + return (0); + } #ifdef TCP_LRO_UPDATE_CSUM le->ulp_csum += tcp_lro_rx_csum_fixup(le, l3hdr, th, tcp_data_len, ~csum); Modified: head/sys/netinet/tcp_seq.h ============================================================================== --- head/sys/netinet/tcp_seq.h Thu Mar 8 22:54:50 2018 (r330674) +++ head/sys/netinet/tcp_seq.h Fri Mar 9 00:08:43 2018 (r330675) @@ -47,6 +47,14 @@ #define SEQ_MIN(a, b) ((SEQ_LT(a, b)) ? (a) : (b)) #define SEQ_MAX(a, b) ((SEQ_GT(a, b)) ? (a) : (b)) +#define WIN_LT(a,b) ((short)(ntohs(a)-ntohs(b)) < 0) +#define WIN_LEQ(a,b) ((short)(ntohs(a)-ntohs(b)) <= 0) +#define WIN_GT(a,b) ((short)(ntohs(a)-ntohs(b)) > 0) +#define WIN_GEQ(a,b) ((short)(ntohs(a)-ntohs(b)) >= 0) + +#define WIN_MIN(a, b) ((WIN_LT(a, b)) ? (a) : (b)) +#define WIN_MAX(a, b) ((WIN_GT(a, b)) ? (a) : (b)) + /* for modulo comparisons of timestamps */ #define TSTMP_LT(a,b) ((int)((a)-(b)) < 0) #define TSTMP_GT(a,b) ((int)((a)-(b)) > 0)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803090008.w2908hUf078100>