Date: Tue, 20 Mar 2018 17:27:00 +0000 (UTC) From: Sean Bruno <sbruno@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r331249 - stable/11/sys/netinet Message-ID: <201803201727.w2KHR0rQ045501@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sbruno Date: Tue Mar 20 17:27:00 2018 New Revision: 331249 URL: https://svnweb.freebsd.org/changeset/base/331249 Log: MFC r330675 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> Sponsored by: NetFlix and Limelight Networks Modified: stable/11/sys/netinet/tcp_lro.c stable/11/sys/netinet/tcp_seq.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/netinet/tcp_lro.c ============================================================================== --- stable/11/sys/netinet/tcp_lro.c Tue Mar 20 17:05:23 2018 (r331248) +++ stable/11/sys/netinet/tcp_lro.c Tue Mar 20 17:27:00 2018 (r331249) @@ -55,6 +55,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> @@ -734,7 +735,9 @@ tcp_lro_rx(struct lro_ctrl *lc, struct mbuf *m, uint32 /* 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); @@ -751,12 +754,20 @@ tcp_lro_rx(struct lro_ctrl *lc, struct mbuf *m, uint32 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: stable/11/sys/netinet/tcp_seq.h ============================================================================== --- stable/11/sys/netinet/tcp_seq.h Tue Mar 20 17:05:23 2018 (r331248) +++ stable/11/sys/netinet/tcp_seq.h Tue Mar 20 17:27:00 2018 (r331249) @@ -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?201803201727.w2KHR0rQ045501>