From owner-svn-src-stable@FreeBSD.ORG Sat Apr 17 04:10:30 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 160CB106566B; Sat, 17 Apr 2010 04:10:30 +0000 (UTC) (envelope-from rrs@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id EB41C8FC1C; Sat, 17 Apr 2010 04:10:29 +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 o3H4ATAp043324; Sat, 17 Apr 2010 04:10:29 GMT (envelope-from rrs@svn.freebsd.org) Received: (from rrs@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o3H4AT8Y043321; Sat, 17 Apr 2010 04:10:29 GMT (envelope-from rrs@svn.freebsd.org) Message-Id: <201004170410.o3H4AT8Y043321@svn.freebsd.org> From: Randall Stewart Date: Sat, 17 Apr 2010 04:10:29 +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: r206739 - stable/8/sys/netinet X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 Apr 2010 04:10:30 -0000 Author: rrs Date: Sat Apr 17 04:10:29 2010 New Revision: 206739 URL: http://svn.freebsd.org/changeset/base/206739 Log: MFC of 205627 Part II (more to follow) of the great IETF hack-a-thon to fix the NR-Sack code. Modified: stable/8/sys/netinet/sctp_indata.c stable/8/sys/netinet/sctp_input.c stable/8/sys/netinet/sctp_output.c stable/8/sys/netinet/sctputil.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_indata.c ============================================================================== --- stable/8/sys/netinet/sctp_indata.c Sat Apr 17 04:08:51 2010 (r206738) +++ stable/8/sys/netinet/sctp_indata.c Sat Apr 17 04:10:29 2010 (r206739) @@ -46,24 +46,13 @@ __FBSDID("$FreeBSD$"); #include #define SCTP_CALC_TSN_TO_GAP(gap, tsn, mapping_tsn) do { \ - if ((compare_with_wrap(tsn, mapping_tsn, MAX_TSN)) || \ - (tsn == mapping_tsn)) { \ + if (tsn >= mapping_tsn) { \ gap = tsn - mapping_tsn; \ } else { \ gap = (MAX_TSN - mapping_tsn) + tsn + 1; \ } \ } while(0) -#define SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc) do { \ - if (asoc->mapping_array_base_tsn == asoc->nr_mapping_array_base_tsn) { \ - SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, nr_gap); \ - } else {\ - int lgap; \ - SCTP_CALC_TSN_TO_GAP(lgap, tsn, asoc->mapping_array_base_tsn); \ - SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, lgap); \ - } \ - } while(0) - /* * NOTES: On the outbound side of things I need to check the sack timer to * see if I should generate a sack into the chunk queue (if I have data to @@ -304,6 +293,44 @@ sctp_build_ctl_cchunk(struct sctp_inpcb return (buf); } +static void +sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn) +{ + uint32_t gap, i; + int fnd = 0; + + if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) { + return; + } + SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn); +#ifdef INVARIANTS + if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) { + printf("gap:%x tsn:%x\n", gap, tsn); + sctp_print_mapping_array(asoc); + panic("Things are really messed up now!!"); + } +#endif + SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); + SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap); + if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) { + asoc->highest_tsn_inside_nr_map = tsn; + } + if (tsn == asoc->highest_tsn_inside_map) { + /* We must back down to see what the new highest is */ + for (i = tsn - 1; compare_with_wrap(i, asoc->mapping_array_base_tsn, MAX_TSN); i--) { + SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn); + if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) { + asoc->highest_tsn_inside_map = i; + fnd = 1; + break; + } + } + if (!fnd) { + asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1; + } + } +} + /* * We are delivering currently from the reassembly queue. We must continue to @@ -319,9 +346,6 @@ sctp_service_reassembly(struct sctp_tcb int end = 0; int cntDel; - /* EY if any out-of-order delivered, then tag it nr on nr_map */ - uint32_t nr_tsn, nr_gap; - struct sctp_queued_to_read *control, *ctl, *ctlat; if (stcb == NULL) @@ -430,39 +454,7 @@ abandon: } /* pull it we did it */ TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next); - /* - * EY this is the chunk that should be tagged nr gapped - * calculate the gap and such then tag this TSN nr - * chk->rec.data.TSN_seq - */ - /* - * EY!-TODO- this tsn should be tagged nr only if it is - * out-of-order, the if statement should be modified - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack) { - nr_tsn = chk->rec.data.TSN_seq; - SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn); - if ((nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) { - /* - * EY The 1st should never happen, as in - * process_a_data_chunk method this check - * should be done - */ - /* - * EY The 2nd should never happen, because - * nr_mapping_array is always expanded when - * mapping_array is expanded - */ - printf("Impossible nr_gap ack range failed\n"); - } else { - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc); - if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) - asoc->highest_tsn_inside_nr_map = nr_tsn; - } - } + sctp_mark_non_revokable(asoc, chk->rec.data.TSN_seq); if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { asoc->fragmented_delivery_inprogress = 0; if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 0) { @@ -509,67 +501,11 @@ abandon: asoc->size_on_all_streams -= ctl->length; sctp_ucount_decr(asoc->cnt_on_all_streams); strm->last_sequence_delivered++; - /* - * EY will be used to - * calculate nr-gap - */ - nr_tsn = ctl->sinfo_tsn; sctp_add_to_readq(stcb->sctp_ep, stcb, ctl, &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - /* - * EY -now something is - * delivered, calculate - * nr_gap and tag this tsn - * NR - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack) { - SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn); - if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) || - (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) { - /* - * EY The - * 1st - * should - * never - * happen, - * as in - * process_a_ - * data_chunk - * method - * this - * check - * should be - * done - */ - /* - * EY The - * 2nd - * should - * never - * happen, - * because - * nr_mapping - * _array is - * always - * expanded - * when - * mapping_ar - * ray is - * expanded - */ - } else { - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc); - if (compare_with_wrap(nr_tsn, - asoc->highest_tsn_inside_nr_map, - MAX_TSN)) - asoc->highest_tsn_inside_nr_map = nr_tsn; - } - } + sctp_mark_non_revokable(asoc, ctl->sinfo_tsn); ctl = ctlat; } else { break; @@ -618,9 +554,6 @@ sctp_queue_data_to_stream(struct sctp_tc uint16_t nxt_todel; struct mbuf *oper; - /* EY- will be used to calculate nr-gap for a tsn */ - uint32_t nr_tsn, nr_gap; - queue_needed = 1; asoc->size_on_all_streams += control->length; sctp_ucount_incr(asoc->cnt_on_all_streams); @@ -682,41 +615,12 @@ protocol_error: asoc->size_on_all_streams -= control->length; sctp_ucount_decr(asoc->cnt_on_all_streams); strm->last_sequence_delivered++; - /* EY will be used to calculate nr-gap */ - nr_tsn = control->sinfo_tsn; + sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - /* - * EY this is the chunk that should be tagged nr gapped - * calculate the gap and such then tag this TSN nr - * chk->rec.data.TSN_seq - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack) { - SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn); - if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) || - (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) { - printf("Impossible nr_tsn set 2?\n"); - /* - * EY The 1st should never happen, as in - * process_a_data_chunk method this check - * should be done - */ - /* - * EY The 2nd should never happen, because - * nr_mapping_array is always expanded when - * mapping_array is expanded - */ - } else { - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc); - if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) - asoc->highest_tsn_inside_nr_map = nr_tsn; - } - } + sctp_mark_non_revokable(asoc, control->sinfo_tsn); control = TAILQ_FIRST(&strm->inqueue); while (control != NULL) { /* all delivered */ @@ -738,47 +642,12 @@ protocol_error: SCTP_STR_LOG_FROM_IMMED_DEL); } /* EY will be used to calculate nr-gap */ - nr_tsn = control->sinfo_tsn; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - /* - * EY this is the chunk that should be - * tagged nr gapped calculate the gap and - * such then tag this TSN nr - * chk->rec.data.TSN_seq - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack) { - SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn); - if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) || - (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) { - /* - * EY The 1st should never - * happen, as in - * process_a_data_chunk - * method this check should - * be done - */ - /* - * EY The 2nd should never - * happen, because - * nr_mapping_array is - * always expanded when - * mapping_array is expanded - */ - } else { - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap); - if (compare_with_wrap(nr_tsn, - asoc->highest_tsn_inside_nr_map, - MAX_TSN)) - asoc->highest_tsn_inside_nr_map = nr_tsn; - } - } + sctp_mark_non_revokable(asoc, control->sinfo_tsn); control = at; continue; } @@ -1586,9 +1455,6 @@ sctp_process_a_data_chunk(struct sctp_tc /* struct sctp_tmit_chunk *chk; */ struct sctp_tmit_chunk *chk; uint32_t tsn, gap; - - /* EY - for nr_sack */ - uint32_t nr_gap; struct mbuf *dmbuf; int indx, the_len; int need_reasm_check = 0; @@ -1640,14 +1506,12 @@ sctp_process_a_data_chunk(struct sctp_tc return (0); } } - /* EY - for nr_sack */ - nr_gap = gap; - if (compare_with_wrap(tsn, *high_tsn, MAX_TSN)) { *high_tsn = tsn; } /* See if we have received this one already */ - if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) { + if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap) || + SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, gap)) { SCTP_STAT_INCR(sctps_recvdupdata); if (asoc->numduptsns < SCTP_MAX_DUP_TSNS) { /* Record a dup for the next outbound sack */ @@ -1714,7 +1578,8 @@ sctp_process_a_data_chunk(struct sctp_tc #endif } /* now is it in the mapping array of what we have accepted? */ - if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) { + if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN) && + compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) { /* Nope not in the valid range dump it */ sctp_set_rwnd(stcb, asoc); if ((asoc->cnt_on_all_streams + @@ -1758,23 +1623,10 @@ sctp_process_a_data_chunk(struct sctp_tc } SCTP_STAT_INCR(sctps_badsid); SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap); - /* EY set this tsn present in nr_sack's nr_mapping_array */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack) { - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); - SCTP_REVERSE_OUT_TSN_PRES(gap, tsn, asoc); - } - if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) { - /* we have a new high score */ - asoc->highest_tsn_inside_map = tsn; - /* EY nr_sack version of the above */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) - asoc->highest_tsn_inside_nr_map = tsn; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) { - sctp_log_map(0, 2, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); - } + + SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); + if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) { + asoc->highest_tsn_inside_nr_map = tsn; } if (tsn == (asoc->cumulative_tsn + 1)) { /* Update cum-ack */ @@ -1925,48 +1777,6 @@ sctp_process_a_data_chunk(struct sctp_tc control, &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - /* - * EY here I should check if this delivered tsn is - * out_of_order, if yes then update the nr_map - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) { - /* - * EY check if the mapping_array and nr_mapping - * array are consistent - */ - if (asoc->mapping_array_base_tsn != asoc->nr_mapping_array_base_tsn) - /* - * printf("EY-IN - * sctp_process_a_data_chunk(5): Something - * is wrong the map base tsn" "\nEY-and - * nr_map base tsn should be equal."); - */ - /* EY debugging block */ - { - /* - * printf("\nEY-Calculating an - * nr_gap!!\nmapping_array_size = %d - * nr_mapping_array_size = %d" - * "\nEY-mapping_array_base = %d - * nr_mapping_array_base = - * %d\nEY-highest_tsn_inside_map = %d" - * "highest_tsn_inside_nr_map = %d\nEY-TSN = - * %d nr_gap = %d",asoc->mapping_array_size, - * asoc->nr_mapping_array_size, - * asoc->mapping_array_base_tsn, - * asoc->nr_mapping_array_base_tsn, - * asoc->highest_tsn_inside_map, - * asoc->highest_tsn_inside_nr_map,tsn,nr_gap - * ); - */ - } - /* EY - not %100 sure about the lock thing */ - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc); - if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) - asoc->highest_tsn_inside_nr_map = tsn; - } if ((chunk_flags & SCTP_DATA_UNORDERED) == 0) { /* for ordered, bump what we delivered */ asoc->strmin[strmno].last_sequence_delivered++; @@ -1977,6 +1787,10 @@ sctp_process_a_data_chunk(struct sctp_tc SCTP_STR_LOG_FROM_EXPRS_DEL); } control = NULL; + SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); + if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) { + asoc->highest_tsn_inside_nr_map = tsn; + } goto finish_express_del; } failed_express_del: @@ -2012,39 +1826,9 @@ failed_express_del: SCTP_PRINTF("Append fails end:%d\n", end); goto failed_pdapi_express_del; } - /* - * EY It is appended to the read queue in prev if - * block here I should check if this delivered tsn - * is out_of_order, if yes then update the nr_map - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack) { - /* EY debugging block */ - { - /* - * printf("\nEY-Calculating an - * nr_gap!!\nEY-mapping_array_size = - * %d nr_mapping_array_size = %d" - * "\nEY-mapping_array_base = %d - * nr_mapping_array_base = - * %d\nEY-highest_tsn_inside_map = - * %d" "highest_tsn_inside_nr_map = - * %d\nEY-TSN = %d nr_gap = - * %d",asoc->mapping_array_size, - * asoc->nr_mapping_array_size, - * asoc->mapping_array_base_tsn, - * asoc->nr_mapping_array_base_tsn, - * asoc->highest_tsn_inside_map, - * asoc->highest_tsn_inside_nr_map,ts - * n,nr_gap); - */ - } - /* EY - not %100 sure about the lock thing */ - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc); - if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) - asoc->highest_tsn_inside_nr_map = tsn; + SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); + if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) { + asoc->highest_tsn_inside_nr_map = tsn; } SCTP_STAT_INCR(sctps_recvexpressm); control->sinfo_tsn = tsn; @@ -2069,12 +1853,27 @@ failed_express_del: need_reasm_check = 1; } } + SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); + if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) { + asoc->highest_tsn_inside_nr_map = tsn; + } control = NULL; goto finish_express_del; } } failed_pdapi_express_del: control = NULL; + if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) { + SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); + if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) { + asoc->highest_tsn_inside_nr_map = tsn; + } + } else { + SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap); + if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) { + asoc->highest_tsn_inside_map = tsn; + } + } if ((chunk_flags & SCTP_DATA_NOT_FRAG) != SCTP_DATA_NOT_FRAG) { sctp_alloc_a_chunk(stcb, chk); if (chk == NULL) { @@ -2263,56 +2062,7 @@ failed_pdapi_express_del: sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - /* - * EY It is added to the read queue in prev if block - * here I should check if this delivered tsn is - * out_of_order, if yes then update the nr_map - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack) { - /* - * EY check if the mapping_array and - * nr_mapping array are consistent - */ - if (asoc->mapping_array_base_tsn != asoc->nr_mapping_array_base_tsn) - /* - * printf("EY-IN - * sctp_process_a_data_chunk(6): - * Something is wrong the map base - * tsn" "\nEY-and nr_map base tsn - * should be equal."); - */ - /* - * EY - not %100 sure about the lock - * thing, i think we don't need the - * below, - */ - /* SCTP_TCB_LOCK_ASSERT(stcb); */ - { - /* - * printf("\nEY-Calculating an - * nr_gap!!\nEY-mapping_array_size = - * %d nr_mapping_array_size = %d" - * "\nEY-mapping_array_base = %d - * nr_mapping_array_base = - * %d\nEY-highest_tsn_inside_map = - * %d" "highest_tsn_inside_nr_map = - * %d\nEY-TSN = %d nr_gap = - * %d",asoc->mapping_array_size, - * asoc->nr_mapping_array_size, - * asoc->mapping_array_base_tsn, - * asoc->nr_mapping_array_base_tsn, - * asoc->highest_tsn_inside_map, - * asoc->highest_tsn_inside_nr_map,ts - * n,nr_gap); - */ - } - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc); - if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) - asoc->highest_tsn_inside_nr_map = tsn; - } + } else { /* * Special check for when streams are resetting. We @@ -2384,13 +2134,6 @@ failed_pdapi_express_del: } } finish_express_del: - if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) { - /* we have a new high score */ - asoc->highest_tsn_inside_map = tsn; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) { - sctp_log_map(0, 2, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); - } - } if (tsn == (asoc->cumulative_tsn + 1)) { /* Update cum-ack */ asoc->cumulative_tsn = tsn; @@ -2412,22 +2155,6 @@ finish_express_del: sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, asoc->highest_tsn_inside_map, SCTP_MAP_PREPARE_SLIDE); } - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap); - - /* - * EY - set tsn present in nr-map if doing nr-sacks and the tsn is - * non-renegable - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack && - (SCTP_BASE_SYSCTL(sctp_do_drain) == 0)) { - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, tsn, asoc); - if (compare_with_wrap(tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN)) { - asoc->highest_tsn_inside_nr_map = tsn; - } - } /* check the special flag for stream resets */ if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) && ((compare_with_wrap(asoc->cumulative_tsn, liste->tsn, MAX_TSN)) || @@ -2532,7 +2259,6 @@ sctp_sack_check(struct sctp_tcb *stcb, i */ struct sctp_association *asoc; int at; - uint8_t comb_byte; int last_all_ones = 0; int slide_from, slide_end, lgap, distance; @@ -2540,7 +2266,7 @@ sctp_sack_check(struct sctp_tcb *stcb, i /* int nr_at; */ /* int nr_last_all_ones = 0; */ /* int nr_slide_from, nr_slide_end, nr_lgap, nr_distance; */ - uint32_t old_cumack, old_base, old_highest; + uint32_t old_cumack, old_base, old_highest, highest_tsn; asoc = &stcb->asoc; at = 0; @@ -2553,30 +2279,23 @@ sctp_sack_check(struct sctp_tcb *stcb, i * offset of the current cum-ack as the starting point. */ at = 0; - for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; slide_from++) { - /* - * We must combine the renegable and non-renegable arrays - * here to form a unified view of what is acked right now - * (since they are kept separate - */ - comb_byte = asoc->mapping_array[slide_from] | asoc->nr_mapping_array[slide_from]; - if (comb_byte == 0xff) { + for (slide_from = 0; slide_from < stcb->asoc.nr_mapping_array_size; slide_from++) { + if (asoc->nr_mapping_array[slide_from] == 0xff) { at += 8; last_all_ones = 1; } else { /* there is a 0 bit */ - at += sctp_map_lookup_tab[comb_byte]; + at += sctp_map_lookup_tab[asoc->nr_mapping_array[slide_from]]; last_all_ones = 0; break; } } - asoc->cumulative_tsn = asoc->mapping_array_base_tsn + (at - last_all_ones); - /* at is one off, since in the table a embedded -1 is present */ + asoc->cumulative_tsn = asoc->nr_mapping_array_base_tsn + (at - last_all_ones); at++; - if (compare_with_wrap(asoc->cumulative_tsn, - asoc->highest_tsn_inside_map, - MAX_TSN)) { + if (compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_map, MAX_TSN) && + compare_with_wrap(asoc->cumulative_tsn, asoc->highest_tsn_inside_nr_map, MAX_TSN) + ) { #ifdef INVARIANTS panic("huh, cumack 0x%x greater than high-tsn 0x%x in map", asoc->cumulative_tsn, asoc->highest_tsn_inside_map); @@ -2591,37 +2310,29 @@ sctp_sack_check(struct sctp_tcb *stcb, i asoc->highest_tsn_inside_nr_map = asoc->cumulative_tsn; #endif } - if ((asoc->cumulative_tsn == asoc->highest_tsn_inside_map) && (at >= 8)) { + if (compare_with_wrap(asoc->highest_tsn_inside_nr_map, + asoc->highest_tsn_inside_map, + MAX_TSN)) { + highest_tsn = asoc->highest_tsn_inside_nr_map; + } else { + highest_tsn = asoc->highest_tsn_inside_map; + } + if ((asoc->cumulative_tsn == highest_tsn) && (at >= 8)) { /* The complete array was completed by a single FR */ - /* higest becomes the cum-ack */ + /* highest becomes the cum-ack */ int clr; - asoc->cumulative_tsn = asoc->highest_tsn_inside_map; /* clear the array */ clr = (at >> 3) + 1; if (clr > asoc->mapping_array_size) { clr = asoc->mapping_array_size; } memset(asoc->mapping_array, 0, clr); - /* base becomes one ahead of the cum-ack */ - asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1; - - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) { - - if (clr > asoc->nr_mapping_array_size) - clr = asoc->nr_mapping_array_size; + memset(asoc->nr_mapping_array, 0, clr); - memset(asoc->nr_mapping_array, 0, clr); - /* base becomes one ahead of the cum-ack */ - asoc->nr_mapping_array_base_tsn = asoc->cumulative_tsn + 1; - asoc->highest_tsn_inside_nr_map = asoc->cumulative_tsn; - } - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) { - sctp_log_map(old_base, old_cumack, old_highest, - SCTP_MAP_PREPARE_SLIDE); - sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, - asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_CLEARED); - } + asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1; + asoc->nr_mapping_array_base_tsn = asoc->cumulative_tsn + 1; + asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map = asoc->cumulative_tsn; } else if (at >= 8) { /* we can slide the mapping array down */ /* slide_from holds where we hit the first NON 0xff byte */ @@ -2630,19 +2341,15 @@ sctp_sack_check(struct sctp_tcb *stcb, i * now calculate the ceiling of the move using our highest * TSN value */ - if (asoc->highest_tsn_inside_map >= asoc->mapping_array_base_tsn) { - lgap = asoc->highest_tsn_inside_map - - asoc->mapping_array_base_tsn; - } else { - lgap = (MAX_TSN - asoc->mapping_array_base_tsn) + - asoc->highest_tsn_inside_map + 1; - } - slide_end = lgap >> 3; + SCTP_CALC_TSN_TO_GAP(lgap, highest_tsn, asoc->mapping_array_base_tsn); + slide_end = (lgap >> 3); if (slide_end < slide_from) { + sctp_print_mapping_array(asoc); #ifdef INVARIANTS panic("impossible slide"); #else - printf("impossible slide?\n"); + printf("impossible slide lgap:%x slide_end:%x slide_from:%x? at:%d\n", + lgap, slide_end, slide_from, at); return; #endif } @@ -2682,30 +2389,21 @@ sctp_sack_check(struct sctp_tcb *stcb, i for (ii = 0; ii < distance; ii++) { asoc->mapping_array[ii] = asoc->mapping_array[slide_from + ii]; + asoc->nr_mapping_array[ii] = + asoc->nr_mapping_array[slide_from + ii]; + } for (ii = distance; ii <= slide_end; ii++) { asoc->mapping_array[ii] = 0; + asoc->nr_mapping_array[ii] = 0; } asoc->mapping_array_base_tsn += (slide_from << 3); + asoc->nr_mapping_array_base_tsn += (slide_from << 3); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) { sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); } - /* - * EY if doing nr_sacks then slide the - * nr_mapping_array accordingly please - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) { - for (ii = 0; ii < distance; ii++) { - asoc->nr_mapping_array[ii] = - asoc->nr_mapping_array[slide_from + ii]; - } - for (ii = distance; ii <= slide_end; ii++) { - asoc->nr_mapping_array[ii] = 0; - } - asoc->nr_mapping_array_base_tsn += (slide_from << 3); - } } } /* @@ -2736,8 +2434,7 @@ sctp_sack_check(struct sctp_tcb *stcb, i int is_a_gap; /* is there a gap now ? */ - is_a_gap = compare_with_wrap(stcb->asoc.highest_tsn_inside_map, - stcb->asoc.cumulative_tsn, MAX_TSN); + is_a_gap = compare_with_wrap(highest_tsn, stcb->asoc.cumulative_tsn, MAX_TSN); /* * CMT DAC algorithm: increase number of packets @@ -5742,9 +5439,6 @@ sctp_kick_prsctp_reorder_queue(struct sc struct sctp_association *asoc; int tt; - /* EY -used to calculate nr_gap information */ - uint32_t nr_tsn, nr_gap; - asoc = &stcb->asoc; tt = strmin->last_sequence_delivered; /* @@ -5764,82 +5458,10 @@ sctp_kick_prsctp_reorder_queue(struct sc /* deliver it to at least the delivery-q */ if (stcb->sctp_socket) { /* EY need the tsn info for calculating nr */ - nr_tsn = ctl->sinfo_tsn; sctp_add_to_readq(stcb->sctp_ep, stcb, ctl, &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED); - /* - * EY this is the chunk that should be - * tagged nr gapped calculate the gap and - * such then tag this TSN nr - * chk->rec.data.TSN_seq - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack) { - SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn); - if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) || - (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) { - /* - * EY These should never - * happen- explained before - */ - } else { - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc); - if (compare_with_wrap(nr_tsn, - asoc->highest_tsn_inside_nr_map, - MAX_TSN)) - asoc->highest_tsn_inside_nr_map = nr_tsn; - } - if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, nr_gap)) - /* - * printf("In - * sctp_kick_prsctp_reorder_q - * ueue(7): Something wrong, - * the TSN to be tagged" - * "\nas NR is not even in - * the mapping_array, or map - * and nr_map are - * inconsistent"); - */ - /* - * EY - not %100 sure about - * the lock thing, don't - * think its required - */ - /* - * SCTP_TCB_LOCK_ASSERT(stcb) - * ; - */ - { - /* - * printf("\nCalculating an - * nr_gap!!\nmapping_array_si - * ze = %d - * nr_mapping_array_size = - * %d" "\nmapping_array_base - * = %d - * nr_mapping_array_base = - * %d\nhighest_tsn_inside_map - * = %d" - * "highest_tsn_inside_nr_map - * = %d\nTSN = %d nr_gap = - * %d",asoc->mapping_array_si - * ze, - * asoc->nr_mapping_array_siz - * e, - * asoc->mapping_array_base_t - * sn, - * asoc->nr_mapping_array_bas - * e_tsn, - * asoc->highest_tsn_inside_m - * ap, - * asoc->highest_tsn_inside_n - * r_map,tsn,nr_gap); - */ - } - } + sctp_mark_non_revokable(asoc, ctl->sinfo_tsn); } } else { /* no more delivery now. */ @@ -5864,82 +5486,11 @@ sctp_kick_prsctp_reorder_queue(struct sc /* deliver it to at least the delivery-q */ strmin->last_sequence_delivered = ctl->sinfo_ssn; if (stcb->sctp_socket) { - /* EY */ - nr_tsn = ctl->sinfo_tsn; sctp_add_to_readq(stcb->sctp_ep, stcb, ctl, &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED); - /* - * EY this is the chunk that should be - * tagged nr gapped calculate the gap and - * such then tag this TSN nr - * chk->rec.data.TSN_seq - */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - asoc->peer_supports_nr_sack) { - SCTP_CALC_TSN_TO_GAP(nr_gap, nr_tsn, asoc->nr_mapping_array_base_tsn); - if ((nr_gap >= (SCTP_NR_MAPPING_ARRAY << 3)) || - (nr_gap >= (uint32_t) (asoc->nr_mapping_array_size << 3))) { - /* - * EY These should never - * happen, explained before - */ - } else { - SCTP_TCB_LOCK_ASSERT(stcb); - SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, nr_gap); - SCTP_REVERSE_OUT_TSN_PRES(nr_gap, nr_tsn, asoc); - if (compare_with_wrap(nr_tsn, asoc->highest_tsn_inside_nr_map, - MAX_TSN)) - asoc->highest_tsn_inside_nr_map = nr_tsn; - } - if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, nr_gap)) - /* - * printf("In - * sctp_kick_prsctp_reorder_q - * ueue(8): Something wrong, - * the TSN to be tagged" - * "\nas NR is not even in - * the mapping_array, or map - * and nr_map are - * inconsistent"); - */ - /* - * EY - not %100 sure about - * the lock thing, don't - * think its required - */ - /* - * SCTP_TCB_LOCK_ASSERT(stcb) - * ; - */ - { - /* - * printf("\nCalculating an - * nr_gap!!\nmapping_array_si - * ze = %d - * nr_mapping_array_size = - * %d" "\nmapping_array_base - * = %d - * nr_mapping_array_base = - * %d\nhighest_tsn_inside_map - * = %d" - * "highest_tsn_inside_nr_map - * = %d\nTSN = %d nr_gap = - * %d",asoc->mapping_array_si - * ze, - * asoc->nr_mapping_array_siz - * e, - * asoc->mapping_array_base_t - * sn, - * asoc->nr_mapping_array_bas - * e_tsn, - * asoc->highest_tsn_inside_m - * ap, - * asoc->highest_tsn_inside_n - * r_map,tsn,nr_gap); - */ - } - } + sctp_mark_non_revokable(asoc, ctl->sinfo_tsn); + } tt = strmin->last_sequence_delivered + 1; } else { @@ -6096,25 +5647,19 @@ sctp_handle_forward_tsn(struct sctp_tcb if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_map, MAX_TSN)) { asoc->highest_tsn_inside_map = new_cum_tsn; - /* EY nr_mapping_array version of the above */ - /* - * if(SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && - * asoc->peer_supports_nr_sack) - */ + + } + if (compare_with_wrap(new_cum_tsn, asoc->highest_tsn_inside_nr_map, + MAX_TSN)) { asoc->highest_tsn_inside_nr_map = new_cum_tsn; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) { - sctp_log_map(0, 0, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); - } } /* * now we know the new TSN is more advanced, let's find the actual * gap */ - SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->mapping_array_base_tsn); + SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->nr_mapping_array_base_tsn); + asoc->cumulative_tsn = new_cum_tsn; if (gap >= m_size) { - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) { - sctp_log_map(0, 0, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); - } if ((long)gap > sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv)) { struct mbuf *oper; @@ -6147,23 +5692,15 @@ sctp_handle_forward_tsn(struct sctp_tcb return; } SCTP_STAT_INCR(sctps_fwdtsn_map_over); + memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size); - cumack_set_flag = 1; asoc->mapping_array_base_tsn = new_cum_tsn + 1; - asoc->cumulative_tsn = asoc->highest_tsn_inside_map = new_cum_tsn; - /* EY - nr_sack: nr_mapping_array version of the above */ - if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && asoc->peer_supports_nr_sack) { - memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size); - asoc->nr_mapping_array_base_tsn = new_cum_tsn + 1; - asoc->highest_tsn_inside_nr_map = new_cum_tsn; - if (asoc->nr_mapping_array_size != asoc->mapping_array_size) { - /* - * printf("IN sctp_handle_forward_tsn: - * Something is wrong the size of" "map and - * nr_map should be equal!") - */ ; - } - } + asoc->highest_tsn_inside_map = new_cum_tsn; + + memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.nr_mapping_array_size); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***