svn commit: r215578 - stable/8/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Sat Nov 20 19:26:35 UTC 2010
Author: tuexen
Date: Sat Nov 20 19:26:35 2010
New Revision: 215578
URL: http://svn.freebsd.org/changeset/base/215578
Log:
MFC r214876
* Fix an accounting bug regarding SACK/NR-SACK chunks.
* Fix the generation of the SACK/NR-SACK gap lists.
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 19:23:16 2010 (r215577)
+++ stable/8/sys/netinet/sctp_output.c Sat Nov 20 19:26:35 2010 (r215578)
@@ -9927,7 +9927,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
caddr_t limit;
uint32_t *dup;
int limit_reached = 0;
- unsigned int i, sel_start, siz, j, starting_index;
+ unsigned int i, sel_start, siz, j;
unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
int num_dups = 0;
int space_req;
@@ -9954,7 +9954,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
if (chk->rec.chunk_id.id == type) {
/* Hmm, found a sack already on queue, remove it */
TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
- asoc->ctrl_queue_cnt++;
+ asoc->ctrl_queue_cnt--;
a_chk = chk;
if (a_chk->data) {
sctp_m_freem(a_chk->data);
@@ -9993,15 +9993,13 @@ sctp_send_sack(struct sctp_tcb *stcb)
a_chk->whoTo = NULL;
if ((asoc->numduptsns) ||
- (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)
- ) {
+ (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)) {
/*-
* Ok, we have some duplicates or the destination for the
* sack is unreachable, lets see if we can select an
* alternate than asoc->last_data_chunk_from
*/
- if ((!(asoc->last_data_chunk_from->dest_state &
- SCTP_ADDR_NOT_REACHABLE)) &&
+ if ((!(asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)) &&
(asoc->used_alt_onsack > asoc->numnets)) {
/* We used an alt last time, don't this time */
a_chk->whoTo = NULL;
@@ -10120,53 +10118,25 @@ sctp_send_sack(struct sctp_tcb *stcb)
}
}
- if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
- offset = 1;
- /*-
- * The base TSN is intialized to be the first TSN the peer
- * will send us. If the cum-ack is behind this then when they
- * send us the next in sequence it will mark the base_tsn bit.
- * Thus we need to use the very first selector and the offset
- * is 1. Our table is built for this case.
- */
- starting_index = 0;
+ 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 {
- /*-
- * we skip the first selector when the cum-ack is at or above the
- * mapping array base. This is because the bits at the base or above
- * are turned on and our first selector in the table assumes they are
- * off. We thus will use the second selector (first is 0). We use
- * the reverse of our macro to fix the offset, in bits, that our
- * table is at. Note that this method assumes that the cum-tsn is
- * within the first bit, i.e. its value is 0-7 which means the
- * result to our offset will be either a 0 - -7. If the cumack
- * is NOT in the first byte (0) (which it should be since we did
- * a mapping array slide above) then we need to calculate the starting
- * index i.e. which byte of the mapping array we should start at. We
- * do this by dividing by 8 and pushing the remainder (mod) into offset.
- * then we multiply the offset to be negative, since we need a negative
- * offset into the selector table.
- */
- SCTP_CALC_TSN_TO_GAP(offset, asoc->cumulative_tsn, asoc->mapping_array_base_tsn);
- if (offset > 7) {
- starting_index = offset / 8;
- offset = offset % 8;
- printf("Strange starting index is %d offset:%d (not 0/x)\n",
- starting_index, offset);
- } else {
- starting_index = 0;
- }
- /* We need a negative offset in our table */
- offset *= -1;
sel_start = 1;
}
+ if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) {
+ offset = 1;
+ } else {
+ offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
+ }
if (((type == SCTP_SELECTIVE_ACK) &&
compare_with_wrap(highest_tsn, asoc->cumulative_tsn, MAX_TSN)) ||
((type == SCTP_NR_SELECTIVE_ACK) &&
compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN))) {
/* we have a gap .. maybe */
- for (i = starting_index; i < siz; i++) {
+ for (i = 0; i < siz; i++) {
if (type == SCTP_SELECTIVE_ACK) {
selector = &sack_array[asoc->mapping_array[i] | asoc->nr_mapping_array[i]];
} else {
@@ -10224,25 +10194,21 @@ sctp_send_sack(struct sctp_tcb *stcb)
mergeable = 0;
- if (asoc->highest_tsn_inside_nr_map > asoc->mapping_array_base_tsn)
+ if (asoc->highest_tsn_inside_nr_map > asoc->mapping_array_base_tsn) {
siz = (((asoc->highest_tsn_inside_nr_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8;
- else
+ } else {
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;
- /*-
- * cum-ack behind the mapping array, so we start and use all
- * entries.
- */
- sel_start = 0;
} else {
offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn;
- /*-
- * we skip the first one when the cum-ack is at or above the
- * mapping array base. Note this only works if
- */
- sel_start = 1;
}
if (compare_with_wrap(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn, MAX_TSN)) {
/* we have a gap .. maybe */
More information about the svn-src-stable
mailing list