From owner-freebsd-net@FreeBSD.ORG Mon Oct 17 16:09:51 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 8F312106566B for ; Mon, 17 Oct 2011 16:09:51 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.freebsd.org (Postfix) with ESMTP id E6F7E8FC08 for ; Mon, 17 Oct 2011 16:09:50 +0000 (UTC) Received: (qmail 83853 invoked from network); 17 Oct 2011 14:50:09 -0000 Received: from localhost (HELO [127.0.0.1]) ([127.0.0.1]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 17 Oct 2011 14:50:09 -0000 Message-ID: <4E9C534D.4090405@freebsd.org> Date: Mon, 17 Oct 2011 18:09:49 +0200 From: Andre Oppermann User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1 MIME-Version: 1.0 To: Ben Hutchings References: <1317309906.2743.9.camel@bwh-desktop> <1318865394.2784.4.camel@bwh-desktop> In-Reply-To: <1318865394.2784.4.camel@bwh-desktop> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org 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 16:09:51 -0000 On 17.10.2011 17:29, Ben Hutchings wrote: > This is the fix/workaround I used: Thanks for the fix. I'll review it and put it into FreeBSD maybe in a slightly different form. -- Andre > --- 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. >