Author: rrs Date: Mon Jan 31 11:50:11 2011 New Revision: 218129 URL: http://svn.freebsd.org/changeset/base/218129
Log: More ECN fixes: 1) We now remove ECN-Nonce since it will no longer continue as a I-D 2) Eliminate last_tsn_echo, this tied us to an assoc not the net and thus we were not doing m-homing on the ECN-Echo senders side right. 3) Increment the count going out even if the TSN in lower in the pending ECN-Echo, this way the receiver knows exactly how many packets were marked even with network re-ordering 4) Fix so we DO NOT stop doing delayed sack if a ECN Echo is in queue MFC after: 1 month Modified: head/sys/netinet/sctp_cc_functions.c head/sys/netinet/sctp_constants.h head/sys/netinet/sctp_header.h head/sys/netinet/sctp_indata.c head/sys/netinet/sctp_indata.h head/sys/netinet/sctp_input.c head/sys/netinet/sctp_output.c head/sys/netinet/sctp_pcb.c head/sys/netinet/sctp_structs.h head/sys/netinet/sctp_sysctl.c head/sys/netinet/sctp_sysctl.h head/sys/netinet/sctp_timer.c head/sys/netinet/sctputil.c Modified: head/sys/netinet/sctp_cc_functions.c ============================================================================== --- head/sys/netinet/sctp_cc_functions.c Mon Jan 31 11:30:26 2011 (r218128) +++ head/sys/netinet/sctp_cc_functions.c Mon Jan 31 11:50:11 2011 (r218129) @@ -168,13 +168,6 @@ sctp_cwnd_update_after_fr(struct sctp_tc net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1; } - /* - * Disable Nonce Sum Checking and store the - * resync tsn - */ - asoc->nonce_sum_check = 0; - asoc->nonce_resync_tsn = asoc->fast_recovery_tsn + 1; - sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32); sctp_timer_start(SCTP_TIMER_TYPE_SEND, @@ -489,25 +482,28 @@ sctp_cwnd_update_after_timeout(struct sc } static void -sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net) +sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net, + int in_window, int num_pkt_lost) { int old_cwnd = net->cwnd; - SCTP_STAT_INCR(sctps_ecnereducedcwnd); - net->ssthresh = net->cwnd / 2; - if (net->ssthresh < net->mtu) { - net->ssthresh = net->mtu; - /* here back off the timer as well, to slow us down */ - net->RTO <<= 1; - } - net->cwnd = net->ssthresh; - SDT_PROBE(sctp, cwnd, net, ecn, - stcb->asoc.my_vtag, - ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), - net, - old_cwnd, net->cwnd); - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { - sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT); + if (in_window == 0) { + SCTP_STAT_INCR(sctps_ecnereducedcwnd); + net->ssthresh = net->cwnd / 2; + if (net->ssthresh < net->mtu) { + net->ssthresh = net->mtu; + /* here back off the timer as well, to slow us down */ + net->RTO <<= 1; + } + net->cwnd = net->ssthresh; + SDT_PROBE(sctp, cwnd, net, ecn, + stcb->asoc.my_vtag, + ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), + net, + old_cwnd, net->cwnd); + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { + sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT); + } } } @@ -888,13 +884,6 @@ sctp_hs_cwnd_update_after_fr(struct sctp net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1; } - /* - * Disable Nonce Sum Checking and store the - * resync tsn - */ - asoc->nonce_sum_check = 0; - asoc->nonce_resync_tsn = asoc->fast_recovery_tsn + 1; - sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32); sctp_timer_start(SCTP_TIMER_TYPE_SEND, @@ -1609,13 +1598,6 @@ sctp_htcp_cwnd_update_after_fr(struct sc net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1; } - /* - * Disable Nonce Sum Checking and store the - * resync tsn - */ - asoc->nonce_sum_check = 0; - asoc->nonce_resync_tsn = asoc->fast_recovery_tsn + 1; - sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32); sctp_timer_start(SCTP_TIMER_TYPE_SEND, @@ -1673,24 +1655,26 @@ sctp_htcp_cwnd_update_after_fr_timer(str static void sctp_htcp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, - struct sctp_nets *net) + struct sctp_nets *net, int in_window, int num_pkt_lost) { int old_cwnd; old_cwnd = net->cwnd; /* JRS - reset hctp as if state changed */ - htcp_reset(&net->htcp_ca); - SCTP_STAT_INCR(sctps_ecnereducedcwnd); - net->ssthresh = htcp_recalc_ssthresh(stcb, net); - if (net->ssthresh < net->mtu) { - net->ssthresh = net->mtu; - /* here back off the timer as well, to slow us down */ - net->RTO <<= 1; - } - net->cwnd = net->ssthresh; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { - sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT); + if (in_window == 0) { + htcp_reset(&net->htcp_ca); + SCTP_STAT_INCR(sctps_ecnereducedcwnd); + net->ssthresh = htcp_recalc_ssthresh(stcb, net); + if (net->ssthresh < net->mtu) { + net->ssthresh = net->mtu; + /* here back off the timer as well, to slow us down */ + net->RTO <<= 1; + } + net->cwnd = net->ssthresh; + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { + sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT); + } } } Modified: head/sys/netinet/sctp_constants.h ============================================================================== --- head/sys/netinet/sctp_constants.h Mon Jan 31 11:30:26 2011 (r218128) +++ head/sys/netinet/sctp_constants.h Mon Jan 31 11:50:11 2011 (r218129) @@ -411,8 +411,7 @@ __FBSDID("$FreeBSD$"); /*************0x8000 series*************/ #define SCTP_ECN_CAPABLE 0x8000 -/* ECN Nonce: draft-ladha-sctp-ecn-nonce */ -#define SCTP_ECN_NONCE_SUPPORTED 0x8001 + /* draft-ietf-tsvwg-auth-xxx */ #define SCTP_RANDOM 0x8002 #define SCTP_CHUNK_LIST 0x8003 Modified: head/sys/netinet/sctp_header.h ============================================================================== --- head/sys/netinet/sctp_header.h Mon Jan 31 11:30:26 2011 (r218128) +++ head/sys/netinet/sctp_header.h Mon Jan 31 11:50:11 2011 (r218129) @@ -142,12 +142,6 @@ struct sctp_supported_chunk_types_param } SCTP_PACKED; -/* ECN Nonce: draft-ladha-sctp-ecn-nonce */ -struct sctp_ecn_nonce_supported_param { - struct sctp_paramhdr ph;/* type = 0x8001 len = 4 */ -} SCTP_PACKED; - - /* * Structures for DATA chunks */ Modified: head/sys/netinet/sctp_indata.c ============================================================================== --- head/sys/netinet/sctp_indata.c Mon Jan 31 11:30:26 2011 (r218128) +++ head/sys/netinet/sctp_indata.c Mon Jan 31 11:50:11 2011 (r218129) @@ -2386,7 +2386,6 @@ sctp_slide_mapping_arrays(struct sctp_tc } } - void sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap, int *abort_flag) { @@ -2857,11 +2856,6 @@ sctp_process_segment_range(struct sctp_t * must be held until * cum-ack passes */ - /*- - * ECN Nonce: Add the nonce - * value to the sender's - * nonce sum - */ if (tp1->sent < SCTP_DATAGRAM_RESEND) { /*- * If it is less than RESEND, it is @@ -2967,8 +2961,6 @@ sctp_process_segment_range(struct sctp_t } } if (tp1->sent <= SCTP_DATAGRAM_RESEND) { - (*ecn_seg_sums) += tp1->rec.data.ect_nonce; - (*ecn_seg_sums) &= SCTP_SACK_NONCE_SUM; if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, stcb->asoc.this_sack_highest_gap)) { stcb->asoc.this_sack_highest_gap = @@ -3152,23 +3144,6 @@ sctp_check_for_revoked(struct sctp_tcb * if (tp1->sent == SCTP_DATAGRAM_UNSENT) break; } - if (tot_revoked > 0) { - /* - * Setup the ecn nonce re-sync point. We do this since once - * data is revoked we begin to retransmit things, which do - * NOT have the ECN bits set. This means we are now out of - * sync and must wait until we get back in sync with the - * peer to check ECN bits. - */ - tp1 = TAILQ_FIRST(&asoc->send_queue); - if (tp1 == NULL) { - asoc->nonce_resync_tsn = asoc->sending_seq; - } else { - asoc->nonce_resync_tsn = tp1->rec.data.TSN_seq; - } - asoc->nonce_wait_for_ecne = 0; - asoc->nonce_sum_check = 0; - } } @@ -3604,17 +3579,6 @@ sctp_strike_gap_ack_chunks(struct sctp_t } } } - - if (tot_retrans > 0) { - /* - * Setup the ecn nonce re-sync point. We do this since once - * we go to FR something we introduce a Karn's rule scenario - * and won't know the totals for the ECN bits. - */ - asoc->nonce_resync_tsn = sending_seq; - asoc->nonce_wait_for_ecne = 0; - asoc->nonce_sum_check = 0; - } } struct sctp_tmit_chunk * @@ -3787,7 +3751,7 @@ sctp_window_probe_recovery(struct sctp_t void sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, - uint32_t rwnd, int nonce_sum_flag, int *abort_now) + uint32_t rwnd, int *abort_now) { struct sctp_nets *net; struct sctp_association *asoc; @@ -3901,11 +3865,6 @@ sctp_express_handle_sack(struct sctp_tcb if (tp1->sent == SCTP_DATAGRAM_UNSENT) { printf("Warning, an unsent is now acked?\n"); } - /* - * ECN Nonce: Add the nonce to the sender's - * nonce sum - */ - asoc->nonce_sum_expect_base += tp1->rec.data.ect_nonce; if (tp1->sent < SCTP_DATAGRAM_ACKED) { /* * If it is less than ACKED, it is @@ -4049,53 +4008,6 @@ sctp_express_handle_sack(struct sctp_tcb asoc->total_flight = 0; asoc->total_flight_count = 0; } - /* ECN Nonce updates */ - if (asoc->ecn_nonce_allowed) { - if (asoc->nonce_sum_check) { - if (nonce_sum_flag != ((asoc->nonce_sum_expect_base) & SCTP_SACK_NONCE_SUM)) { - if (asoc->nonce_wait_for_ecne == 0) { - struct sctp_tmit_chunk *lchk; - - lchk = TAILQ_FIRST(&asoc->send_queue); - asoc->nonce_wait_for_ecne = 1; - if (lchk) { - asoc->nonce_wait_tsn = lchk->rec.data.TSN_seq; - } else { - asoc->nonce_wait_tsn = asoc->sending_seq; - } - } else { - if (SCTP_TSN_GE(asoc->last_acked_seq, asoc->nonce_wait_tsn)) { - /* - * Misbehaving peer. We need - * to react to this guy - */ - asoc->ecn_allowed = 0; - asoc->ecn_nonce_allowed = 0; - } - } - } - } else { - /* See if Resynchronization Possible */ - if (SCTP_TSN_GT(asoc->last_acked_seq, asoc->nonce_resync_tsn)) { - asoc->nonce_sum_check = 1; - /* - * Now we must calculate what the base is. - * We do this based on two things, we know - * the total's for all the segments - * gap-acked in the SACK (none). We also - * know the SACK's nonce sum, its in - * nonce_sum_flag. So we can build a truth - * table to back-calculate the new value of - * asoc->nonce_sum_expect_base: - * - * SACK-flag-Value Seg-Sums Base 0 0 0 - * 1 0 1 0 1 1 1 - * 1 0 - */ - asoc->nonce_sum_expect_base = (0 ^ nonce_sum_flag) & SCTP_SACK_NONCE_SUM; - } - } - } /* RWND update */ asoc->peers_rwnd = sctp_sbspace_sub(rwnd, (uint32_t) (asoc->total_flight + (asoc->total_flight_count * SCTP_BASE_SYSCTL(sctp_peer_chunk_oh)))); @@ -4297,18 +4209,10 @@ again: /* C3. See if we need to send a Fwd-TSN */ if (SCTP_TSN_GT(asoc->advanced_peer_ack_point, cumack)) { /* - * ISSUE with ECN, see FWD-TSN processing for notes - * on issues that will occur when the ECN NONCE - * stuff is put into SCTP for cross checking. + * ISSUE with ECN, see FWD-TSN processing. */ if (SCTP_TSN_GT(asoc->advanced_peer_ack_point, old_adv_peer_ack_point)) { send_forward_tsn(stcb, asoc); - /* - * ECN Nonce: Disable Nonce Sum check when - * FWD TSN is sent and store resync tsn - */ - asoc->nonce_sum_check = 0; - asoc->nonce_resync_tsn = asoc->advanced_peer_ack_point; } else if (lchk) { /* try to FR fwd-tsn's that get lost too */ if (lchk->rec.data.fwd_tsn_cnt >= 3) { @@ -4351,7 +4255,7 @@ sctp_handle_sack(struct mbuf *m, int off int win_probe_recovery = 0; int win_probe_recovered = 0; struct sctp_nets *net = NULL; - int nonce_sum_flag, ecn_seg_sums = 0; + int ecn_seg_sums = 0; int done_once; uint8_t reneged_all = 0; uint8_t cmt_dac_flag; @@ -4383,7 +4287,6 @@ sctp_handle_sack(struct mbuf *m, int off j = 0; SCTP_STAT_INCR(sctps_slowpath_sack); last_tsn = cum_ack; - nonce_sum_flag = flags & SCTP_SACK_NONCE_SUM; cmt_dac_flag = flags & SCTP_SACK_CMT_DAC; #ifdef SCTP_ASOCLOG_OF_TSNS stcb->asoc.cumack_log[stcb->asoc.cumack_log_at] = cum_ack; @@ -4545,11 +4448,6 @@ sctp_handle_sack(struct mbuf *m, int off TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { if (SCTP_TSN_GE(last_tsn, tp1->rec.data.TSN_seq)) { if (tp1->sent != SCTP_DATAGRAM_UNSENT) { - /* - * ECN Nonce: Add the nonce to the sender's - * nonce sum - */ - asoc->nonce_sum_expect_base += tp1->rec.data.ect_nonce; accum_moved = 1; if (tp1->sent < SCTP_DATAGRAM_ACKED) { /* @@ -4999,60 +4897,6 @@ sctp_handle_sack(struct mbuf *m, int off /* JRS - Use the congestion control given in the CC module */ asoc->cc_functions.sctp_cwnd_update_after_fr(stcb, asoc); - /****************************************************************** - * Here we do the stuff with ECN Nonce checking. - * We basically check to see if the nonce sum flag was incorrect - * or if resynchronization needs to be done. Also if we catch a - * misbehaving receiver we give him the kick. - ******************************************************************/ - - if (asoc->ecn_nonce_allowed) { - if (asoc->nonce_sum_check) { - if (nonce_sum_flag != ((asoc->nonce_sum_expect_base + ecn_seg_sums) & SCTP_SACK_NONCE_SUM)) { - if (asoc->nonce_wait_for_ecne == 0) { - struct sctp_tmit_chunk *lchk; - - lchk = TAILQ_FIRST(&asoc->send_queue); - asoc->nonce_wait_for_ecne = 1; - if (lchk) { - asoc->nonce_wait_tsn = lchk->rec.data.TSN_seq; - } else { - asoc->nonce_wait_tsn = asoc->sending_seq; - } - } else { - if (SCTP_TSN_GE(asoc->last_acked_seq, asoc->nonce_wait_tsn)) { - /* - * Misbehaving peer. We need - * to react to this guy - */ - asoc->ecn_allowed = 0; - asoc->ecn_nonce_allowed = 0; - } - } - } - } else { - /* See if Resynchronization Possible */ - if (SCTP_TSN_GT(asoc->last_acked_seq, asoc->nonce_resync_tsn)) { - asoc->nonce_sum_check = 1; - /* - * now we must calculate what the base is. - * We do this based on two things, we know - * the total's for all the segments - * gap-acked in the SACK, its stored in - * ecn_seg_sums. We also know the SACK's - * nonce sum, its in nonce_sum_flag. So we - * can build a truth table to back-calculate - * the new value of - * asoc->nonce_sum_expect_base: - * - * SACK-flag-Value Seg-Sums Base 0 0 0 - * 1 0 1 0 1 1 1 - * 1 0 - */ - asoc->nonce_sum_expect_base = (ecn_seg_sums ^ nonce_sum_flag) & SCTP_SACK_NONCE_SUM; - } - } - } /* Now are we exiting loss recovery ? */ if (will_exit_fast_recovery) { /* Ok, we must exit fast recovery */ @@ -5190,9 +5034,7 @@ again: /* C3. See if we need to send a Fwd-TSN */ if (SCTP_TSN_GT(asoc->advanced_peer_ack_point, cum_ack)) { /* - * ISSUE with ECN, see FWD-TSN processing for notes - * on issues that will occur when the ECN NONCE - * stuff is put into SCTP for cross checking. + * ISSUE with ECN, see FWD-TSN processing. */ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_TRY_ADVANCE) { sctp_misc_ints(SCTP_FWD_TSN_CHECK, @@ -5200,14 +5042,7 @@ again: old_adv_peer_ack_point); } if (SCTP_TSN_GT(asoc->advanced_peer_ack_point, old_adv_peer_ack_point)) { - send_forward_tsn(stcb, asoc); - /* - * ECN Nonce: Disable Nonce Sum check when - * FWD TSN is sent and store resync tsn - */ - asoc->nonce_sum_check = 0; - asoc->nonce_resync_tsn = asoc->advanced_peer_ack_point; } else if (lchk) { /* try to FR fwd-tsn's that get lost too */ if (lchk->rec.data.fwd_tsn_cnt >= 3) { @@ -5242,7 +5077,7 @@ sctp_update_acked(struct sctp_tcb *stcb, a_rwnd = stcb->asoc.peers_rwnd + stcb->asoc.total_flight; /* Now call the express sack handling */ - sctp_express_handle_sack(stcb, cum_ack, a_rwnd, 0, abort_flag); + sctp_express_handle_sack(stcb, cum_ack, a_rwnd, abort_flag); } static void @@ -5384,17 +5219,6 @@ sctp_handle_forward_tsn(struct sctp_tcb struct sctp_forward_tsn_chunk *fwd, int *abort_flag, struct mbuf *m, int offset) { - /* - * ISSUES that MUST be fixed for ECN! When we are the sender of the - * forward TSN, when the SACK comes back that acknowledges the - * FWD-TSN we must reset the NONCE sum to match correctly. This will - * get quite tricky since we may have sent more data interveneing - * and must carefully account for what the SACK says on the nonce - * and any gaps that are reported. This work will NOT be done here, - * but I note it here since it is really related to PR-SCTP and - * FWD-TSN's - */ - /* The pr-sctp fwd tsn */ /* * here we will perform all the data receiver side steps for @@ -5482,7 +5306,6 @@ sctp_handle_forward_tsn(struct sctp_tcb if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) { sctp_log_map(0, 3, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); } - asoc->last_echo_tsn = asoc->highest_tsn_inside_map; } else { SCTP_TCB_LOCK_ASSERT(stcb); for (i = 0; i <= gap; i++) { Modified: head/sys/netinet/sctp_indata.h ============================================================================== --- head/sys/netinet/sctp_indata.h Mon Jan 31 11:30:26 2011 (r218128) +++ head/sys/netinet/sctp_indata.h Mon Jan 31 11:50:11 2011 (r218129) @@ -93,7 +93,7 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, st void sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, - uint32_t rwnd, int nonce_sum_flag, int *abort_now); + uint32_t rwnd, int *abort_now); void sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, Modified: head/sys/netinet/sctp_input.c ============================================================================== --- head/sys/netinet/sctp_input.c Mon Jan 31 11:30:26 2011 (r218128) +++ head/sys/netinet/sctp_input.c Mon Jan 31 11:50:11 2011 (r218129) @@ -264,11 +264,13 @@ sctp_process_init(struct sctp_init_chunk /* save off parameters */ asoc->peer_vtag = ntohl(init->initiate_tag); asoc->peers_rwnd = ntohl(init->a_rwnd); + /* init tsn's */ + asoc->highest_tsn_inside_map = asoc->asconf_seq_in = ntohl(init->initial_tsn) - 1; + if (!TAILQ_EMPTY(&asoc->nets)) { /* update any ssthresh's that may have a default */ TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) { lnet->ssthresh = asoc->peers_rwnd; - if (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_CWND_MONITOR_ENABLE | SCTP_CWND_LOGGING_ENABLE)) { sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_INITIALIZATION); } @@ -328,8 +330,7 @@ sctp_process_init(struct sctp_init_chunk } SCTP_TCB_SEND_UNLOCK(stcb); asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams; - /* init tsn's */ - asoc->highest_tsn_inside_map = asoc->asconf_seq_in = ntohl(init->initial_tsn) - 1; + /* EY - nr_sack: initialize highest tsn in nr_mapping_array */ asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map; if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) { @@ -340,7 +341,7 @@ sctp_process_init(struct sctp_init_chunk asoc->mapping_array_base_tsn = ntohl(init->initial_tsn); asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->asconf_seq_in; - asoc->last_echo_tsn = asoc->asconf_seq_in; + asoc->advanced_peer_ack_point = asoc->last_acked_seq; /* open the requested streams */ @@ -1044,11 +1045,6 @@ sctp_process_unrecog_param(struct sctp_t case SCTP_HAS_NAT_SUPPORT: stcb->asoc.peer_supports_nat = 0; break; - case SCTP_ECN_NONCE_SUPPORTED: - stcb->asoc.peer_supports_ecn_nonce = 0; - stcb->asoc.ecn_nonce_allowed = 0; - stcb->asoc.ecn_allowed = 0; - break; case SCTP_ADD_IP_ADDRESS: case SCTP_DEL_IP_ADDRESS: case SCTP_SET_PRIM_ADDR: @@ -2931,16 +2927,12 @@ sctp_handle_ecn_echo(struct sctp_ecne_ch SCTP_STAT_INCR(sctps_recvecne); tsn = ntohl(cp->tsn); pkt_cnt = ntohl(cp->num_pkts_since_cwr); - /* ECN Nonce stuff: need a resync and disable the nonce sum check */ - /* Also we make sure we disable the nonce_wait */ lchk = TAILQ_LAST(&stcb->asoc.send_queue, sctpchunk_listhead); if (lchk == NULL) { - window_data_tsn = stcb->asoc.nonce_resync_tsn = stcb->asoc.sending_seq - 1; + window_data_tsn = stcb->asoc.sending_seq - 1; } else { - window_data_tsn = stcb->asoc.nonce_resync_tsn = lchk->rec.data.TSN_seq; + window_data_tsn = lchk->rec.data.TSN_seq; } - stcb->asoc.nonce_wait_for_ecne = 0; - stcb->asoc.nonce_sum_check = 0; /* Find where it was sent to if possible. */ net = NULL; @@ -2974,7 +2966,8 @@ sctp_handle_ecn_echo(struct sctp_ecne_ch override_bit = SCTP_CWR_REDUCE_OVERRIDE; } out: - if (SCTP_TSN_GT(tsn, net->cwr_window_tsn)) { + if (SCTP_TSN_GT(tsn, net->cwr_window_tsn) && + ((override_bit & SCTP_CWR_REDUCE_OVERRIDE) == 0)) { /* * JRS - Use the congestion control given in the pluggable * CC module @@ -2982,7 +2975,7 @@ out: int ocwnd; ocwnd = net->cwnd; - stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net); + stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 0, pkt_cnt); /* * We reduce once every RTT. So we will only lower cwnd at * the next sending seq i.e. the window_data_tsn @@ -2993,18 +2986,26 @@ out: net->last_cwr_tsn = tsn; } else { override_bit |= SCTP_CWR_IN_SAME_WINDOW; - if (SCTP_TSN_GT(tsn, net->last_cwr_tsn)) { + if (SCTP_TSN_GT(tsn, net->last_cwr_tsn) && + ((override_bit & SCTP_CWR_REDUCE_OVERRIDE) == 0)) { /* - * Another loss in the same window update how man - * marks we have had + * Another loss in the same window update how many + * marks/packets lost we have had. */ + int cnt = 1; if (pkt_cnt > net->lost_cnt) { /* Should be the case */ - net->ecn_ce_pkt_cnt += (pkt_cnt - net->lost_cnt); - net->lost_cnt = pkt_cnt; + cnt = (pkt_cnt - net->lost_cnt); + net->ecn_ce_pkt_cnt += cnt; } + net->lost_cnt = pkt_cnt; net->last_cwr_tsn = tsn; + /* + * Most CC functions will ignore this call, since we + * are in-window yet of the initial CE the peer saw. + */ + stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 1, cnt); } } /* @@ -3184,11 +3185,6 @@ process_chunk_drop(struct sctp_tcb *stcb } } } - /* - * We zero out the nonce so resync not - * needed - */ - tp1->rec.data.ect_nonce = 0; if (tp1->do_rtt) { /* @@ -4643,7 +4639,6 @@ process_control_chunks: uint16_t num_seg, num_dup; uint8_t flags; int offset_seg, offset_dup; - int nonce_sum_flag; SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK\n"); SCTP_STAT_INCR(sctps_recvsacks); @@ -4665,7 +4660,6 @@ process_control_chunks: } sack = (struct sctp_sack_chunk *)ch; flags = ch->chunk_flags; - nonce_sum_flag = flags & SCTP_SACK_NONCE_SUM; cum_ack = ntohl(sack->sack.cum_tsn_ack); num_seg = ntohs(sack->sack.num_gap_ack_blks); num_dup = ntohs(sack->sack.num_dup_tsns); @@ -4697,8 +4691,7 @@ process_control_chunks: * with no missing segments to go * this way too. */ - sctp_express_handle_sack(stcb, cum_ack, a_rwnd, nonce_sum_flag, - &abort_now); + sctp_express_handle_sack(stcb, cum_ack, a_rwnd, &abort_now); } else { if (netp && *netp) sctp_handle_sack(m, offset_seg, offset_dup, @@ -4730,7 +4723,6 @@ process_control_chunks: uint16_t num_seg, num_nr_seg, num_dup; uint8_t flags; int offset_seg, offset_dup; - int nonce_sum_flag; SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK\n"); SCTP_STAT_INCR(sctps_recvsacks); @@ -4756,8 +4748,6 @@ process_control_chunks: } nr_sack = (struct sctp_nr_sack_chunk *)ch; flags = ch->chunk_flags; - nonce_sum_flag = flags & SCTP_SACK_NONCE_SUM; - cum_ack = ntohl(nr_sack->nr_sack.cum_tsn_ack); num_seg = ntohs(nr_sack->nr_sack.num_gap_ack_blks); num_nr_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks); @@ -4789,7 +4779,7 @@ process_control_chunks: * missing segments to go this way * too. */ - sctp_express_handle_sack(stcb, cum_ack, a_rwnd, nonce_sum_flag, + sctp_express_handle_sack(stcb, cum_ack, a_rwnd, &abort_now); } else { if (netp && *netp) @@ -5395,66 +5385,6 @@ next_chunk: } -/* - * Process the ECN bits we have something set so we must look to see if it is - * ECN(0) or ECN(1) or CE - */ -static void -sctp_process_ecn_marked_a(struct sctp_tcb *stcb, struct sctp_nets *net, - uint8_t ecn_bits) -{ - if ((ecn_bits & SCTP_CE_BITS) == SCTP_CE_BITS) { - ; - } else if ((ecn_bits & SCTP_ECT1_BIT) == SCTP_ECT1_BIT) { - /* - * we only add to the nonce sum for ECT1, ECT0 does not - * change the NS bit (that we have yet to find a way to send - * it yet). - */ - - /* ECN Nonce stuff */ - stcb->asoc.receiver_nonce_sum++; - stcb->asoc.receiver_nonce_sum &= SCTP_SACK_NONCE_SUM; - - /* - * Drag up the last_echo point if cumack is larger since we - * don't want the point falling way behind by more than - * 2^^31 and then having it be incorrect. - */ - if (SCTP_TSN_GT(stcb->asoc.cumulative_tsn, stcb->asoc.last_echo_tsn)) { - stcb->asoc.last_echo_tsn = stcb->asoc.cumulative_tsn; - } - } else if ((ecn_bits & SCTP_ECT0_BIT) == SCTP_ECT0_BIT) { - /* - * Drag up the last_echo point if cumack is larger since we - * don't want the point falling way behind by more than - * 2^^31 and then having it be incorrect. - */ - if (SCTP_TSN_GT(stcb->asoc.cumulative_tsn, stcb->asoc.last_echo_tsn)) { - stcb->asoc.last_echo_tsn = stcb->asoc.cumulative_tsn; - } - } -} - -static void -sctp_process_ecn_marked_b(struct sctp_tcb *stcb, struct sctp_nets *net, - uint32_t high_tsn, uint8_t ecn_bits) -{ - if ((ecn_bits & SCTP_CE_BITS) == SCTP_CE_BITS) { - /* - * we possibly must notify the sender that a congestion - * window reduction is in order. We do this by adding a ECNE - * chunk to the output chunk queue. The incoming CWR will - * remove this chunk. - */ - if (SCTP_TSN_GT(high_tsn, stcb->asoc.last_echo_tsn)) { - /* Yep, we need to add a ECNE */ - sctp_send_ecn_echo(stcb, net, high_tsn); - stcb->asoc.last_echo_tsn = high_tsn; - } - } -} - #ifdef INVARIANTS #ifdef __GNUC__ __attribute__((noinline)) @@ -5496,6 +5426,7 @@ sctp_common_input_processing(struct mbuf struct mbuf *m = *mm; int abort_flag = 0; int un_sent; + int cnt_ctrl_ready = 0; SCTP_STAT_INCR(sctps_recvdatagrams); #ifdef SCTP_AUDITING_ENABLED @@ -5653,11 +5584,6 @@ sctp_common_input_processing(struct mbuf case SCTP_STATE_SHUTDOWN_SENT: break; } - /* take care of ECN, part 1. */ - if (stcb->asoc.ecn_allowed && - (ecn_bits & (SCTP_ECT0_BIT | SCTP_ECT1_BIT))) { - sctp_process_ecn_marked_a(stcb, net, ecn_bits); - } /* plow through the data chunks while length > offset */ retval = sctp_process_data(mm, iphlen, &offset, length, sh, inp, stcb, net, &high_tsn); @@ -5669,19 +5595,16 @@ sctp_common_input_processing(struct mbuf goto out_now; } data_processed = 1; - if (retval == 0) { - /* take care of ecn part 2. */ - if (stcb->asoc.ecn_allowed && - (ecn_bits & (SCTP_ECT0_BIT | SCTP_ECT1_BIT))) { - sctp_process_ecn_marked_b(stcb, net, high_tsn, - ecn_bits); - } - } /* * Anything important needs to have been m_copy'ed in * process_data */ } + /* take care of ecn */ + if (stcb->asoc.ecn_allowed && ((ecn_bits & SCTP_CE_BITS) == SCTP_CE_BITS)) { + /* Yep, we need to add a ECNE */ + sctp_send_ecn_echo(stcb, net, high_tsn); + } if ((data_processed == 0) && (fwd_tsn_seen)) { int was_a_gap; uint32_t highest_tsn; @@ -5713,8 +5636,10 @@ trigger_send: TAILQ_EMPTY(&stcb->asoc.control_send_queue), stcb->asoc.total_flight); un_sent = (stcb->asoc.total_output_queue_size - stcb->asoc.total_flight); - - if (!TAILQ_EMPTY(&stcb->asoc.control_send_queue) || + if (!TAILQ_EMPTY(&stcb->asoc.control_send_queue)) { + cnt_ctrl_ready = stcb->asoc.ctrl_queue_cnt - stcb->asoc.ecn_echo_cnt_onq; + } + if (cnt_ctrl_ready || ((un_sent) && (stcb->asoc.peers_rwnd > 0 || (stcb->asoc.peers_rwnd <= 0 && stcb->asoc.total_flight == 0)))) { Modified: head/sys/netinet/sctp_output.c ============================================================================== --- head/sys/netinet/sctp_output.c Mon Jan 31 11:30:26 2011 (r218128) +++ head/sys/netinet/sctp_output.c Mon Jan 31 11:50:11 2011 (r218129) @@ -3389,55 +3389,10 @@ static uint8_t sctp_get_ect(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk) { - uint8_t this_random; - - /* Huh? */ if (SCTP_BASE_SYSCTL(sctp_ecn_enable) == 0) return (0); - if (SCTP_BASE_SYSCTL(sctp_ecn_nonce) == 0) - /* no nonce, always return ECT0 */ - return (SCTP_ECT0_BIT); - - if (stcb->asoc.peer_supports_ecn_nonce == 0) { - /* Peer does NOT support it, so we send a ECT0 only */ - return (SCTP_ECT0_BIT); - } - if (chk == NULL) - return (SCTP_ECT0_BIT); - - if ((stcb->asoc.hb_random_idx > 3) || - ((stcb->asoc.hb_random_idx == 3) && - (stcb->asoc.hb_ect_randombit > 7))) { - uint32_t rndval; - -warp_drive_sa: - rndval = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep); - memcpy(stcb->asoc.hb_random_values, &rndval, - sizeof(stcb->asoc.hb_random_values)); - this_random = stcb->asoc.hb_random_values[0]; - stcb->asoc.hb_random_idx = 0; - stcb->asoc.hb_ect_randombit = 0; - } else { - if (stcb->asoc.hb_ect_randombit > 7) { - stcb->asoc.hb_ect_randombit = 0; - stcb->asoc.hb_random_idx++; - if (stcb->asoc.hb_random_idx > 3) { - goto warp_drive_sa; - } - } - this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx]; - } - if ((this_random >> stcb->asoc.hb_ect_randombit) & 0x01) { - if (chk != NULL) - /* ECN Nonce stuff */ - chk->rec.data.ect_nonce = SCTP_ECT1_BIT; - stcb->asoc.hb_ect_randombit++; - return (SCTP_ECT1_BIT); - } else { - stcb->asoc.hb_ect_randombit++; - return (SCTP_ECT0_BIT); - } + return (SCTP_ECT0_BIT); } static int @@ -4167,7 +4122,6 @@ sctp_send_initiate(struct sctp_inpcb *in struct sctp_adaptation_layer_indication *ali; struct sctp_ecn_supported_param *ecn; struct sctp_prsctp_supported_param *prsctp; - struct sctp_ecn_nonce_supported_param *ecn_nonce; struct sctp_supported_chunk_types_param *pr_supported; int cnt_inits_to = 0; int padval, ret; @@ -4326,14 +4280,6 @@ sctp_send_initiate(struct sctp_inpcb *in SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len); - /* ECN nonce: And now tell the peer we support ECN nonce */ - if (SCTP_BASE_SYSCTL(sctp_ecn_nonce)) { - ecn_nonce = (struct sctp_ecn_nonce_supported_param *) - ((caddr_t)pr_supported + SCTP_SIZE32(p_len)); - ecn_nonce->ph.param_type = htons(SCTP_ECN_NONCE_SUPPORTED); - ecn_nonce->ph.param_length = htons(sizeof(*ecn_nonce)); - SCTP_BUF_LEN(m) += sizeof(*ecn_nonce); - } /* add authentication parameters */ if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) { struct sctp_auth_random *randp; @@ -4555,11 +4501,10 @@ sctp_arethere_unrecognized_parameters(st case SCTP_HAS_NAT_SUPPORT: *nat_friendly = 1; /* fall through */ - case SCTP_ECN_NONCE_SUPPORTED: case SCTP_PRSCTP_SUPPORTED: if (padded_size != sizeof(struct sctp_paramhdr)) { - SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error ecnnonce/prsctp/nat support %d\n", plen); + SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error prsctp/nat support %d\n", plen); goto invalid_size; } at += padded_size; @@ -4960,7 +4905,6 @@ sctp_send_initiate_ack(struct sctp_inpcb struct sctp_adaptation_layer_indication *ali; struct sctp_ecn_supported_param *ecn; struct sctp_prsctp_supported_param *prsctp; - struct sctp_ecn_nonce_supported_param *ecn_nonce; struct sctp_supported_chunk_types_param *pr_supported; union sctp_sockstore store, store1, *over_addr; struct sockaddr_in *sin, *to_sin; @@ -5444,14 +5388,6 @@ do_a_abort: bzero((caddr_t)pr_supported + p_len, SCTP_SIZE32(p_len) - p_len); SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len); - /* ECN nonce: And now tell the peer we support ECN nonce */ - if (SCTP_BASE_SYSCTL(sctp_ecn_nonce)) { - ecn_nonce = (struct sctp_ecn_nonce_supported_param *) - ((caddr_t)pr_supported + SCTP_SIZE32(p_len)); - ecn_nonce->ph.param_type = htons(SCTP_ECN_NONCE_SUPPORTED); - ecn_nonce->ph.param_length = htons(sizeof(*ecn_nonce)); - SCTP_BUF_LEN(m) += sizeof(*ecn_nonce); - } /* add authentication parameters */ if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) { struct sctp_auth_random *randp; @@ -7009,7 +6945,6 @@ dont_do_it: chk->rec.data.payloadtype = sp->ppid; chk->rec.data.context = sp->context; chk->rec.data.doing_fast_retransmit = 0; - chk->rec.data.ect_nonce = 0; /* ECN Nonce */ chk->rec.data.timetodrop = sp->ts; chk->flags = sp->act_flags; @@ -10000,13 +9935,7 @@ sctp_send_sack(struct sctp_tcb *stcb) limit = mtod(a_chk->data, caddr_t); limit += space; - /* 0x01 is used by nonce for ecn */ - if ((SCTP_BASE_SYSCTL(sctp_ecn_enable)) && - (SCTP_BASE_SYSCTL(sctp_ecn_nonce)) && - (asoc->peer_supports_ecn_nonce)) - flags = (asoc->receiver_nonce_sum & SCTP_SACK_NONCE_SUM); - else - flags = 0; + flags = 0; if ((asoc->sctp_cmt_on_off > 0) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) { @@ -10809,11 +10738,11 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb ctsn = ntohl(ecne->tsn); if (SCTP_TSN_GT(high_tsn, ctsn)) { ecne->tsn = htonl(high_tsn); - cnt = ntohl(ecne->num_pkts_since_cwr); - cnt++; - ecne->num_pkts_since_cwr = htonl(cnt); SCTP_STAT_INCR(sctps_queue_upd_ecne); } + cnt = ntohl(ecne->num_pkts_since_cwr); + cnt++; + ecne->num_pkts_since_cwr = htonl(cnt); return; } } Modified: head/sys/netinet/sctp_pcb.c ============================================================================== --- head/sys/netinet/sctp_pcb.c Mon Jan 31 11:30:26 2011 (r218128) +++ head/sys/netinet/sctp_pcb.c Mon Jan 31 11:50:11 2011 (r218129) @@ -6139,10 +6139,6 @@ sctp_load_addresses_from_init(struct sct } } - } else if (ptype == SCTP_ECN_NONCE_SUPPORTED) { - /* Peer supports ECN-nonce */ - stcb->asoc.peer_supports_ecn_nonce = 1; - stcb->asoc.ecn_nonce_allowed = 1; } else if (ptype == SCTP_RANDOM) { if (plen > sizeof(random_store)) break; Modified: head/sys/netinet/sctp_structs.h ============================================================================== --- head/sys/netinet/sctp_structs.h Mon Jan 31 11:30:26 2011 (r218128) +++ head/sys/netinet/sctp_structs.h Mon Jan 31 11:50:11 2011 (r218129) @@ -330,8 +330,6 @@ struct sctp_data_chunkrec { uint32_t payloadtype; uint32_t context; /* from send */ - /* ECN Nonce: Nonce Value for this chunk */ - uint8_t ect_nonce; uint8_t fwd_tsn_cnt; /* * part of the Highest sacked algorithm to be able to stroke counts @@ -607,7 +605,7 @@ struct sctp_cc_functions { void (*sctp_cwnd_update_after_timeout) (struct sctp_tcb *stcb, struct sctp_nets *net); void (*sctp_cwnd_update_after_ecn_echo) (struct sctp_tcb *stcb, - struct sctp_nets *net); + struct sctp_nets *net, int in_window, int num_pkt_lost); void (*sctp_cwnd_update_after_packet_dropped) (struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_pktdrop_chunk *cp, uint32_t * bottle_bw, uint32_t * on_queue); @@ -866,7 +864,6 @@ struct sctp_association { uint8_t *nr_mapping_array; uint32_t highest_tsn_inside_nr_map; - uint32_t last_echo_tsn; uint32_t fast_recovery_tsn; uint32_t sat_t3_recovery_tsn; uint32_t tsn_last_delivered; @@ -921,12 +918,9 @@ struct sctp_association { uint32_t sb_send_resv; /* amount reserved on a send */ uint32_t my_rwnd_control_len; /* shadow of sb_mbcnt used for rwnd * control */ - /* 32 bit nonce stuff */ - uint32_t nonce_resync_tsn; - uint32_t nonce_wait_tsn; uint32_t default_flowlabel; uint32_t pr_sctp_cnt; - int ctrl_queue_cnt; /* could be removed REM */ + int ctrl_queue_cnt; /* could be removed REM - NO IT CAN'T!! RRS */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"