Date: Wed, 6 Jan 2010 16:51:58 +0000 (UTC) From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r201655 - stable/7/sys/netinet Message-ID: <201001061651.o06GpwhC082408@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bz Date: Wed Jan 6 16:51:57 2010 New Revision: 201655 URL: http://svn.freebsd.org/changeset/base/201655 Log: MFC r184722: Fix a bug introduced with r182851 (r201653 in stable/7) 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 Modified: stable/7/sys/netinet/tcp_input.c stable/7/sys/netinet/tcp_subr.c stable/7/sys/netinet/tcp_var.h Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/netinet/tcp_input.c ============================================================================== --- stable/7/sys/netinet/tcp_input.c Wed Jan 6 16:48:59 2010 (r201654) +++ stable/7/sys/netinet/tcp_input.c Wed Jan 6 16:51:57 2010 (r201655) @@ -2727,14 +2727,14 @@ 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) { int mss; u_long maxmtu; 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 ? @@ -2749,12 +2749,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 = tcp_v6mssdflt; } else #endif { - maxmtu = tcp_maxmtu(&inp->inp_inc, &mtuflags); + maxmtu = tcp_maxmtu(&inp->inp_inc, mtuflags); tp->t_maxopd = tp->t_maxseg = tcp_mssdflt; } @@ -2772,10 +2772,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: @@ -2894,12 +2890,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; @@ -3012,6 +3009,10 @@ tcp_mss(struct tcpcb *tp, int offer) tp->snd_cwnd = mss * ss_fltsz_local; else tp->snd_cwnd = mss * ss_fltsz; + + /* Check the interface for TSO capabilities. */ + if (mtuflags & CSUM_TSO) + tp->t_flags |= TF_TSO; } /* Modified: stable/7/sys/netinet/tcp_subr.c ============================================================================== --- stable/7/sys/netinet/tcp_subr.c Wed Jan 6 16:48:59 2010 (r201654) +++ stable/7/sys/netinet/tcp_subr.c Wed Jan 6 16:51:57 2010 (r201655) @@ -1519,7 +1519,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: stable/7/sys/netinet/tcp_var.h ============================================================================== --- stable/7/sys/netinet/tcp_var.h Wed Jan 6 16:48:59 2010 (r201654) +++ stable/7/sys/netinet/tcp_var.h Wed Jan 6 16:51:57 2010 (r201655) @@ -544,7 +544,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 *
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001061651.o06GpwhC082408>