Skip site navigation (1)Skip section navigation (2)
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>