Date: Thu, 6 Nov 2008 13:25:59 +0000 (UTC) From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r184722 - head/sys/netinet Message-ID: <200811061325.mA6DPxDW056618@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 *
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811061325.mA6DPxDW056618>