From owner-svn-src-head@FreeBSD.ORG Thu Nov 6 13:26:00 2008 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E45CF1065679; Thu, 6 Nov 2008 13:25:59 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D32BA8FC40; Thu, 6 Nov 2008 13:25:59 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mA6DPx33056621; Thu, 6 Nov 2008 13:25:59 GMT (envelope-from bz@svn.freebsd.org) Received: (from bz@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mA6DPxDW056618; Thu, 6 Nov 2008 13:25:59 GMT (envelope-from bz@svn.freebsd.org) Message-Id: <200811061325.mA6DPxDW056618@svn.freebsd.org> From: "Bjoern A. Zeeb" Date: Thu, 6 Nov 2008 13:25:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r184722 - head/sys/netinet X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Nov 2008 13:26:00 -0000 Author: bz Date: Thu Nov 6 13:25:59 2008 New Revision: 184722 URL: http://svn.freebsd.org/changeset/base/184722 Log: Fix a bug introduced with r182851 splitting tcp_mss() into tcp_mss() and tcp_mss_update() so that tcp_mtudisc() could re-use the same code. Move the TSO logic back to tcp_mss() and out of tcp_mss_update(). We tried to avoid that initially but if were are called from tcp_output() with EMSGSIZE, we cleared the TSO flag on the tcpcb there, called into tcp_mtudisc() and tcp_mss_update() which then would reenable TSO on the tcpcb based on TSO capabilities of the interface as learnt in tcp_maxmtu/6(). So if TSO was enabled on the (possibly new) outgoing interface it was turned back on, which lead to an endless loop between tcp_output() and tcp_mtudisc() until we overflew the stack. Reported by: kmacy MFC after: 2 months (along with r182851) Modified: head/sys/netinet/tcp_input.c head/sys/netinet/tcp_subr.c head/sys/netinet/tcp_var.h Modified: head/sys/netinet/tcp_input.c ============================================================================== --- head/sys/netinet/tcp_input.c Thu Nov 6 12:59:00 2008 (r184721) +++ head/sys/netinet/tcp_input.c Thu Nov 6 13:25:59 2008 (r184722) @@ -2812,7 +2812,8 @@ tcp_xmit_timer(struct tcpcb *tp, int rtt * segment. Outgoing SYN/ACK MSS settings are handled in tcp_mssopt(). */ void -tcp_mss_update(struct tcpcb *tp, int offer, struct hc_metrics_lite *metricptr) +tcp_mss_update(struct tcpcb *tp, int offer, + struct hc_metrics_lite *metricptr, int *mtuflags) { INIT_VNET_INET(tp->t_inpcb->inp_vnet); int mss; @@ -2820,7 +2821,6 @@ tcp_mss_update(struct tcpcb *tp, int off struct inpcb *inp = tp->t_inpcb; struct hc_metrics_lite metrics; int origoffer = offer; - int mtuflags = 0; #ifdef INET6 int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; size_t min_protoh = isipv6 ? @@ -2835,12 +2835,12 @@ tcp_mss_update(struct tcpcb *tp, int off /* Initialize. */ #ifdef INET6 if (isipv6) { - maxmtu = tcp_maxmtu6(&inp->inp_inc, &mtuflags); + maxmtu = tcp_maxmtu6(&inp->inp_inc, mtuflags); tp->t_maxopd = tp->t_maxseg = V_tcp_v6mssdflt; } else #endif { - maxmtu = tcp_maxmtu(&inp->inp_inc, &mtuflags); + maxmtu = tcp_maxmtu(&inp->inp_inc, mtuflags); tp->t_maxopd = tp->t_maxseg = V_tcp_mssdflt; } @@ -2858,10 +2858,6 @@ tcp_mss_update(struct tcpcb *tp, int off return; } - /* Check the interface for TSO capabilities. */ - if (mtuflags & CSUM_TSO) - tp->t_flags |= TF_TSO; - /* What have we got? */ switch (offer) { case 0: @@ -2980,12 +2976,13 @@ tcp_mss(struct tcpcb *tp, int offer) struct inpcb *inp; struct socket *so; struct hc_metrics_lite metrics; + int mtuflags = 0; #ifdef INET6 int isipv6; #endif KASSERT(tp != NULL, ("%s: tp == NULL", __func__)); - tcp_mss_update(tp, offer, &metrics); + tcp_mss_update(tp, offer, &metrics, &mtuflags); mss = tp->t_maxseg; inp = tp->t_inpcb; @@ -3098,6 +3095,10 @@ tcp_mss(struct tcpcb *tp, int offer) tp->snd_cwnd = mss * V_ss_fltsz_local; else tp->snd_cwnd = mss * V_ss_fltsz; + + /* Check the interface for TSO capabilities. */ + if (mtuflags & CSUM_TSO) + tp->t_flags |= TF_TSO; } /* Modified: head/sys/netinet/tcp_subr.c ============================================================================== --- head/sys/netinet/tcp_subr.c Thu Nov 6 12:59:00 2008 (r184721) +++ head/sys/netinet/tcp_subr.c Thu Nov 6 13:25:59 2008 (r184722) @@ -1562,7 +1562,7 @@ tcp_mtudisc(struct inpcb *inp, int errno tp = intotcpcb(inp); KASSERT(tp != NULL, ("tcp_mtudisc: tp == NULL")); - tcp_mss_update(tp, -1, NULL); + tcp_mss_update(tp, -1, NULL, NULL); so = inp->inp_socket; SOCKBUF_LOCK(&so->so_snd); Modified: head/sys/netinet/tcp_var.h ============================================================================== --- head/sys/netinet/tcp_var.h Thu Nov 6 12:59:00 2008 (r184721) +++ head/sys/netinet/tcp_var.h Thu Nov 6 13:25:59 2008 (r184722) @@ -546,7 +546,7 @@ void tcp_reass_init(void); void tcp_input(struct mbuf *, int); u_long tcp_maxmtu(struct in_conninfo *, int *); u_long tcp_maxmtu6(struct in_conninfo *, int *); -void tcp_mss_update(struct tcpcb *, int, struct hc_metrics_lite *); +void tcp_mss_update(struct tcpcb *, int, struct hc_metrics_lite *, int *); void tcp_mss(struct tcpcb *, int); int tcp_mssopt(struct in_conninfo *); struct inpcb *