From owner-svn-src-stable-8@FreeBSD.ORG Sat Nov 20 19:26:35 2010 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A3BF31065693; Sat, 20 Nov 2010 19:26:35 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 919B88FC19; Sat, 20 Nov 2010 19:26:35 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oAKJQZvE023102; Sat, 20 Nov 2010 19:26:35 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oAKJQZWr023100; Sat, 20 Nov 2010 19:26:35 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201011201926.oAKJQZWr023100@svn.freebsd.org> From: Michael Tuexen Date: Sat, 20 Nov 2010 19:26:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r215578 - stable/8/sys/netinet X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Nov 2010 19:26:35 -0000 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 */