From owner-svn-src-all@freebsd.org Tue Jan 24 21:30:32 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B961ACBDA12; Tue, 24 Jan 2017 21:30:32 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7A1DDF32; Tue, 24 Jan 2017 21:30:32 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v0OLUVgV028624; Tue, 24 Jan 2017 21:30:31 GMT (envelope-from tuexen@FreeBSD.org) Received: (from tuexen@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v0OLUVsC028623; Tue, 24 Jan 2017 21:30:31 GMT (envelope-from tuexen@FreeBSD.org) Message-Id: <201701242130.v0OLUVsC028623@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tuexen set sender to tuexen@FreeBSD.org using -f From: Michael Tuexen Date: Tue, 24 Jan 2017 21:30:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r312722 - head/sys/netinet X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Jan 2017 21:30:32 -0000 Author: tuexen Date: Tue Jan 24 21:30:31 2017 New Revision: 312722 URL: https://svnweb.freebsd.org/changeset/base/312722 Log: Fix a bug where the overhead of the I-DATA chunk was not considered. MFC after: 1 week Modified: head/sys/netinet/sctp_output.c Modified: head/sys/netinet/sctp_output.c ============================================================================== --- head/sys/netinet/sctp_output.c Tue Jan 24 21:07:13 2017 (r312721) +++ head/sys/netinet/sctp_output.c Tue Jan 24 21:30:31 2017 (r312722) @@ -7080,11 +7080,9 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb, } } - -static int -sctp_can_we_split_this(struct sctp_tcb *stcb, - uint32_t length, - uint32_t goal_mtu, uint32_t frag_point, int eeor_on) +static uint32_t +sctp_can_we_split_this(struct sctp_tcb *stcb, uint32_t length, + uint32_t space_left, uint32_t frag_point, int eeor_on) { /* * Make a decision on if I should split a msg into multiple parts. @@ -7096,7 +7094,7 @@ sctp_can_we_split_this(struct sctp_tcb * * entire thing, since it might be all the guy is putting in * the hopper. */ - if (goal_mtu >= length) { + if (space_left >= length) { /*- * If we have data outstanding, * we get another chance when the sack @@ -7113,7 +7111,7 @@ sctp_can_we_split_this(struct sctp_tcb * } else { /* You can fill the rest */ - return (goal_mtu); + return (space_left); } } /*- @@ -7124,28 +7122,27 @@ sctp_can_we_split_this(struct sctp_tcb * if (SCTP_SB_LIMIT_SND(stcb->sctp_socket) < frag_point) { return (length); } - if ((length <= goal_mtu) || - ((length - goal_mtu) < SCTP_BASE_SYSCTL(sctp_min_residual))) { + if ((length <= space_left) || + ((length - space_left) < SCTP_BASE_SYSCTL(sctp_min_residual))) { /* Sub-optimial residual don't split in non-eeor mode. */ return (0); } /* - * If we reach here length is larger than the goal_mtu. Do we wish + * If we reach here length is larger than the space_left. Do we wish * to split it for the sake of packet putting together? */ - if (goal_mtu >= min(SCTP_BASE_SYSCTL(sctp_min_split_point), frag_point)) { + if (space_left >= min(SCTP_BASE_SYSCTL(sctp_min_split_point), frag_point)) { /* Its ok to split it */ - return (min(goal_mtu, frag_point)); + return (min(space_left, frag_point)); } /* Nope, can't split */ return (0); - } static uint32_t sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_stream_out *strq, - uint32_t goal_mtu, + uint32_t space_left, uint32_t frag_point, int *giveup, int eeor_mode, @@ -7306,7 +7303,7 @@ re_look: sp->some_taken = 1; } } else { - to_move = sctp_can_we_split_this(stcb, length, goal_mtu, frag_point, eeor_mode); + to_move = sctp_can_we_split_this(stcb, length, space_left, frag_point, eeor_mode); if (to_move) { /*- * We use a snapshot of length in case it @@ -7701,56 +7698,66 @@ sctp_fill_outqueue(struct sctp_tcb *stcb { struct sctp_association *asoc; struct sctp_stream_out *strq; - int goal_mtu, moved_how_much, total_moved = 0, bail = 0; - int giveup; + uint32_t space_left, moved, total_moved; + int bail, giveup; SCTP_TCB_LOCK_ASSERT(stcb); asoc = &stcb->asoc; + total_moved = 0; switch (net->ro._l_addr.sa.sa_family) { #ifdef INET case AF_INET: - goal_mtu = net->mtu - SCTP_MIN_V4_OVERHEAD; + space_left = net->mtu - SCTP_MIN_V4_OVERHEAD; break; #endif #ifdef INET6 case AF_INET6: - goal_mtu = net->mtu - SCTP_MIN_OVERHEAD; + space_left = net->mtu - SCTP_MIN_OVERHEAD; break; #endif default: /* TSNH */ - goal_mtu = net->mtu; + space_left = net->mtu; break; } /* Need an allowance for the data chunk header too */ if (stcb->asoc.idata_supported == 0) { - goal_mtu -= sizeof(struct sctp_data_chunk); + space_left -= sizeof(struct sctp_data_chunk); } else { - goal_mtu -= sizeof(struct sctp_idata_chunk); + space_left -= sizeof(struct sctp_idata_chunk); } /* must make even word boundary */ - goal_mtu &= 0xfffffffc; + space_left &= 0xfffffffc; strq = stcb->asoc.ss_functions.sctp_ss_select_stream(stcb, net, asoc); - while ((goal_mtu > 0) && strq) { + while ((space_left > 0) && (strq != NULL)) { giveup = 0; bail = 0; - moved_how_much = sctp_move_to_outqueue(stcb, strq, goal_mtu, frag_point, + moved = sctp_move_to_outqueue(stcb, strq, space_left, frag_point, &giveup, eeor_mode, &bail, so_locked); - stcb->asoc.ss_functions.sctp_ss_scheduled(stcb, net, asoc, strq, moved_how_much); - - if ((giveup) || bail) { + stcb->asoc.ss_functions.sctp_ss_scheduled(stcb, net, asoc, strq, moved); + if ((giveup != 0) || (bail != 0)) { break; } strq = stcb->asoc.ss_functions.sctp_ss_select_stream(stcb, net, asoc); - if (strq == NULL) { - break; + total_moved += moved; + space_left -= moved; + if (stcb->asoc.idata_supported == 0) { + if (space_left >= sizeof(struct sctp_data_chunk)) { + space_left -= sizeof(struct sctp_data_chunk); + } else { + space_left = 0; + } + } else { + if (space_left >= sizeof(struct sctp_idata_chunk)) { + space_left -= sizeof(struct sctp_idata_chunk); + } else { + space_left = 0; + } } - total_moved += moved_how_much; - goal_mtu -= (moved_how_much + sizeof(struct sctp_data_chunk)); - goal_mtu &= 0xfffffffc; + space_left &= 0xfffffffc; } - if (bail) + if (bail != 0) *quit_now = 1; stcb->asoc.ss_functions.sctp_ss_packet_done(stcb, net, asoc);