From owner-svn-src-all@freebsd.org Tue Mar 20 17:27:01 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5263CF5F03C; Tue, 20 Mar 2018 17:27:01 +0000 (UTC) (envelope-from sbruno@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id EE30B7DCC2; Tue, 20 Mar 2018 17:27:00 +0000 (UTC) (envelope-from sbruno@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E40FC1FBD4; Tue, 20 Mar 2018 17:27:00 +0000 (UTC) (envelope-from sbruno@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w2KHR0Nf045504; Tue, 20 Mar 2018 17:27:00 GMT (envelope-from sbruno@FreeBSD.org) Received: (from sbruno@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w2KHR0rQ045501; Tue, 20 Mar 2018 17:27:00 GMT (envelope-from sbruno@FreeBSD.org) Message-Id: <201803201727.w2KHR0rQ045501@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sbruno set sender to sbruno@FreeBSD.org using -f From: Sean Bruno Date: Tue, 20 Mar 2018 17:27:00 +0000 (UTC) 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 X-SVN-Group: stable-11 X-SVN-Commit-Author: sbruno X-SVN-Commit-Paths: stable/11/sys/netinet X-SVN-Commit-Revision: 331249 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Mar 2018 17:27:01 -0000 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 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 #include #include +#include #include #include @@ -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)