From owner-freebsd-net@FreeBSD.ORG Mon Oct 17 15:29:57 2011 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D901E106566C for ; Mon, 17 Oct 2011 15:29:57 +0000 (UTC) (envelope-from bhutchings@solarflare.com) Received: from exchange.solarflare.com (mail.solarflare.com [216.237.3.220]) by mx1.freebsd.org (Postfix) with ESMTP id 9858D8FC14 for ; Mon, 17 Oct 2011 15:29:57 +0000 (UTC) Received: from [10.17.20.137] ([10.17.20.137]) by exchange.solarflare.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 17 Oct 2011 08:29:56 -0700 From: Ben Hutchings To: freebsd-net@freebsd.org In-Reply-To: <1317309906.2743.9.camel@bwh-desktop> References: <1317309906.2743.9.camel@bwh-desktop> Content-Type: text/plain; charset="UTF-8" Organization: Solarflare Communications Date: Mon, 17 Oct 2011 16:29:54 +0100 Message-ID: <1318865394.2784.4.camel@bwh-desktop> Mime-Version: 1.0 X-Mailer: Evolution 2.32.2 (2.32.2-1.fc14) Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 17 Oct 2011 15:29:56.0447 (UTC) FILETIME=[9FDCA6F0:01CC8CE1] X-TM-AS-Product-Ver: SMEX-8.0.0.1181-6.500.1024-18454.005 X-TM-AS-Result: No--8.580000-0.000000-31 X-TM-AS-User-Approved-Sender: Yes X-TM-AS-User-Blocked-Sender: No Subject: Re: TSO broken with jumbo MTU X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Oct 2011 15:29:57 -0000 This is the fix/workaround I used: --- a/netinet/tcp_output.c +++ b/netinet/tcp_output.c @@ -1062,9 +1062,7 @@ * The TCP pseudo header checksum is always provided. * XXX: Fixme: This is currently not the case for IPv6. */ - if (tso) { - KASSERT(len > tp->t_maxopd - optlen, - ("%s: len <= tso_segsz", __func__)); + if (tso && len > tp->t_maxopd - optlen) { m->m_pkthdr.csum_flags |= CSUM_TSO; m->m_pkthdr.tso_segsz = tp->t_maxopd - optlen; } --- END --- But the correct thing to do may be to change the calculation of t_maxopd (untested): --- a/netinet/tcp_input.c +++ b/netinet/tcp_input.c @@ -3087,7 +3087,7 @@ tcp_mss_update(struct tcpcb *tp, int offer, struct hc_metrics_lite *metricptr, int *mtuflags) { - int mss; + int mss, ts_len; u_long maxmtu; struct inpcb *inp = tp->t_inpcb; struct hc_metrics_lite metrics; @@ -3212,22 +3212,17 @@ mss = max(mss, 64); /* - * maxopd stores the maximum length of data AND options - * in a segment; maxseg is the amount of data in a normal - * segment. We need to store this value (maxopd) apart - * from maxseg, because now every segment carries options - * and thus we normally have somewhat less data in segments. - */ - tp->t_maxopd = mss; - - /* * origoffer==-1 indicates that no segments were received yet. * In this case we just guess. */ if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP && (origoffer == -1 || (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)) - mss -= TCPOLEN_TSTAMP_APPA; + ts_len = TCPOLEN_TSTAMP_APPA; + else + ts_len = 0; + + mss -= ts_len; #if (MCLBYTES & (MCLBYTES - 1)) == 0 if (mss > MCLBYTES) @@ -3237,6 +3232,15 @@ mss = mss / MCLBYTES * MCLBYTES; #endif tp->t_maxseg = mss; + + /* + * maxopd stores the maximum length of data AND options + * in a segment; maxseg is the amount of data in a normal + * segment. We need to store this value (maxopd) apart + * from maxseg, because now every segment carries options + * and thus we normally have somewhat less data in segments. + */ + tp->t_maxopd = mss + ts_len; } void --- END --- Ben. -- Ben Hutchings, Staff Engineer, Solarflare Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked.