svn commit: r215590 - stable/8/sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Sat Nov 20 21:20:39 UTC 2010


Author: tuexen
Date: Sat Nov 20 21:20:39 2010
New Revision: 215590
URL: http://svn.freebsd.org/changeset/base/215590

Log:
  MFC r215134,r215198:
  Fix issues with the SACK/NR-SACK generation code.

Modified:
  stable/8/sys/netinet/sctp_output.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/netinet/sctp_output.c
==============================================================================
--- stable/8/sys/netinet/sctp_output.c	Sat Nov 20 21:15:44 2010	(r215589)
+++ stable/8/sys/netinet/sctp_output.c	Sat Nov 20 21:20:39 2010	(r215590)
@@ -9927,13 +9927,14 @@ sctp_send_sack(struct sctp_tcb *stcb)
 	caddr_t limit;
 	uint32_t *dup;
 	int limit_reached = 0;
-	unsigned int i, sel_start, siz, j;
+	unsigned int i, siz, j;
 	unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
 	int num_dups = 0;
 	int space_req;
 	uint32_t highest_tsn;
 	uint8_t flags;
 	uint8_t type;
+	uint8_t tsn_map;
 
 	if ((stcb->asoc.sctp_nr_sack_on_off == 1) &&
 	    (stcb->asoc.peer_supports_nr_sack == 1)) {
@@ -10118,14 +10119,6 @@ sctp_send_sack(struct sctp_tcb *stcb)
 		}
 	}
 
-	if (((type == SCTP_SELECTIVE_ACK) &&
-	    (((asoc->mapping_array[0] | asoc->nr_mapping_array[0]) & 0x01) == 0x00)) ||
-	    ((type == SCTP_NR_SELECTIVE_ACK) &&
-	    ((asoc->mapping_array[0] & 0x01) == 0x00))) {
-		sel_start = 0;
-	} else {
-		sel_start = 1;
-	}
 	if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
 		offset = 1;
 	} else {
@@ -10137,11 +10130,18 @@ sctp_send_sack(struct sctp_tcb *stcb)
 	    compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN))) {
 		/* we have a gap .. maybe */
 		for (i = 0; i < siz; i++) {
+			tsn_map = asoc->mapping_array[i];
 			if (type == SCTP_SELECTIVE_ACK) {
-				selector = &sack_array[asoc->mapping_array[i] | asoc->nr_mapping_array[i]];
-			} else {
-				selector = &sack_array[asoc->mapping_array[i]];
+				tsn_map |= asoc->nr_mapping_array[i];
 			}
+			if (i == 0) {
+				/*
+				 * Clear all bits corresponding to TSNs
+				 * smaller or equal to the cumulative TSN.
+				 */
+				tsn_map &= (~0 << (1 - offset));
+			}
+			selector = &sack_array[tsn_map];
 			if (mergeable && selector->right_edge) {
 				/*
 				 * Backup, left and right edges were ok to
@@ -10153,7 +10153,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
 			if (selector->num_entries == 0)
 				mergeable = 0;
 			else {
-				for (j = sel_start; j < selector->num_entries; j++) {
+				for (j = 0; j < selector->num_entries; j++) {
 					if (mergeable && selector->right_edge) {
 						/*
 						 * do a merge by NOT setting
@@ -10185,7 +10185,6 @@ sctp_send_sack(struct sctp_tcb *stcb)
 				/* Reached the limit stop */
 				break;
 			}
-			sel_start = 0;
 			offset += 8;
 		}
 	}
@@ -10200,11 +10199,6 @@ sctp_send_sack(struct sctp_tcb *stcb)
 			siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_nr_map + 7) / 8;
 		}
 
-		if ((asoc->nr_mapping_array[0] & 0x01) == 0x00) {
-			sel_start = 0;
-		} else {
-			sel_start = 1;
-		}
 		if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
 			offset = 1;
 		} else {
@@ -10213,7 +10207,16 @@ sctp_send_sack(struct sctp_tcb *stcb)
 		if (compare_with_wrap(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn, MAX_TSN)) {
 			/* we have a gap .. maybe */
 			for (i = 0; i < siz; i++) {
-				selector = &sack_array[asoc->nr_mapping_array[i]];
+				tsn_map = asoc->nr_mapping_array[i];
+				if (i == 0) {
+					/*
+					 * Clear all bits corresponding to
+					 * TSNs smaller or equal to the
+					 * cumulative TSN.
+					 */
+					tsn_map &= (~0 << (1 - offset));
+				}
+				selector = &sack_array[tsn_map];
 				if (mergeable && selector->right_edge) {
 					/*
 					 * Backup, left and right edges were
@@ -10225,7 +10228,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
 				if (selector->num_entries == 0)
 					mergeable = 0;
 				else {
-					for (j = sel_start; j < selector->num_entries; j++) {
+					for (j = 0; j < selector->num_entries; j++) {
 						if (mergeable && selector->right_edge) {
 							/*
 							 * do a merge by NOT
@@ -10258,7 +10261,6 @@ sctp_send_sack(struct sctp_tcb *stcb)
 					/* Reached the limit stop */
 					break;
 				}
-				sel_start = 0;
 				offset += 8;
 			}
 		}


More information about the svn-src-stable-8 mailing list