svn commit: r312722 - head/sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Tue Jan 24 21:30:32 UTC 2017


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);


More information about the svn-src-head mailing list