Lines Matching refs:net

56 sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
65 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND));
73 net->cwnd = (net->mtu - sizeof(struct sctphdr)) * cwnd_in_mtu;
78 net->cwnd /= assoc->numnets;
79 if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) {
80 net->cwnd = net->mtu - sizeof(struct sctphdr);
83 net->ssthresh = assoc->peers_rwnd;
84 SDT_PROBE(sctp, cwnd, net, init,
85 stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
86 0, net->cwnd);
89 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION);
97 struct sctp_nets *net;
107 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
108 t_ssthresh += net->ssthresh;
109 t_cwnd += net->cwnd;
110 if (net->lastsa > 0) {
111 t_ucwnd_sbw += (uint64_t) net->cwnd / (uint64_t) net->lastsa;
120 * (net->fast_retran_loss_recovery == 0)))
122 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
126 if (net->net_ack > 0) {
134 int old_cwnd = net->cwnd;
139 net->ssthresh = (uint32_t) (((uint64_t) 4 *
140 (uint64_t) net->mtu *
141 (uint64_t) net->ssthresh) /
148 srtt = net->lastsa;
160 net->ssthresh = (uint32_t) (((uint64_t) 4 *
161 (uint64_t) net->mtu *
162 (uint64_t) net->cwnd) /
167 if ((net->cwnd > t_cwnd / 2) &&
168 (net->ssthresh < net->cwnd - t_cwnd / 2)) {
169 net->ssthresh = net->cwnd - t_cwnd / 2;
171 if (net->ssthresh < net->mtu) {
172 net->ssthresh = net->mtu;
175 net->ssthresh = net->cwnd / 2;
176 if (net->ssthresh < (net->mtu * 2)) {
177 net->ssthresh = 2 * net->mtu;
180 net->cwnd = net->ssthresh;
181 SDT_PROBE(sctp, cwnd, net, fr,
182 stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
183 old_cwnd, net->cwnd);
185 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd),
190 net->partial_bytes_acked = 0;
204 net->fast_retran_loss_recovery = 1;
208 net->fast_recovery_tsn = asoc->sending_seq - 1;
210 net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
214 stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32);
216 stcb->sctp_ep, stcb, net);
218 } else if (net->net_ack > 0) {
235 cc_bw_same(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw,
240 probepoint = (((uint64_t) net->cwnd) << 32);
241 if (net->rtt > net->cc_mod.rtcc.lbw_rtt + rtt_offset) {
248 SDT_PROBE(sctp, cwnd, net, rttvar,
250 ((net->cc_mod.rtcc.lbw << 32) | nbw),
251 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
252 net->flight_size,
254 if ((net->cc_mod.rtcc.steady_step) && (inst_ind != SCTP_INST_LOOSING)) {
255 if (net->cc_mod.rtcc.last_step_state == 5)
256 net->cc_mod.rtcc.step_cnt++;
258 net->cc_mod.rtcc.step_cnt = 1;
259 net->cc_mod.rtcc.last_step_state = 5;
260 if ((net->cc_mod.rtcc.step_cnt == net->cc_mod.rtcc.steady_step) ||
261 ((net->cc_mod.rtcc.step_cnt > net->cc_mod.rtcc.steady_step) &&
262 ((net->cc_mod.rtcc.step_cnt % net->cc_mod.rtcc.steady_step) == 0))) {
264 oth = net->cc_mod.rtcc.vol_reduce;
266 oth |= net->cc_mod.rtcc.step_cnt;
268 oth |= net->cc_mod.rtcc.last_step_state;
269 SDT_PROBE(sctp, cwnd, net, rttstep,
271 ((net->cc_mod.rtcc.lbw << 32) | nbw),
272 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
275 if (net->cwnd > (4 * net->mtu)) {
276 net->cwnd -= net->mtu;
277 net->cc_mod.rtcc.vol_reduce++;
279 net->cc_mod.rtcc.step_cnt = 0;
285 if (net->rtt < net->cc_mod.rtcc.lbw_rtt - rtt_offset) {
293 SDT_PROBE(sctp, cwnd, net, rttvar,
295 ((net->cc_mod.rtcc.lbw << 32) | nbw),
296 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
297 net->flight_size,
299 if (net->cc_mod.rtcc.steady_step) {
300 oth = net->cc_mod.rtcc.vol_reduce;
302 oth |= net->cc_mod.rtcc.step_cnt;
304 oth |= net->cc_mod.rtcc.last_step_state;
305 SDT_PROBE(sctp, cwnd, net, rttstep,
307 ((net->cc_mod.rtcc.lbw << 32) | nbw),
308 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
311 if ((net->cc_mod.rtcc.last_step_state == 5) &&
312 (net->cc_mod.rtcc.step_cnt > net->cc_mod.rtcc.steady_step)) {
314 net->cc_mod.rtcc.step_cnt = 0;
317 net->cc_mod.rtcc.last_step_state = 6;
318 net->cc_mod.rtcc.step_cnt = 0;
321 net->cc_mod.rtcc.lbw = nbw;
322 net->cc_mod.rtcc.lbw_rtt = net->rtt;
323 net->cc_mod.rtcc.cwnd_at_bw_set = net->cwnd;
335 probepoint |= ((7 << 16) | net->cc_mod.rtcc.ret_from_eq);
336 SDT_PROBE(sctp, cwnd, net, rttvar,
338 ((net->cc_mod.rtcc.lbw << 32) | nbw),
339 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
340 net->flight_size,
342 if ((net->cc_mod.rtcc.steady_step) && (inst_ind != SCTP_INST_LOOSING)) {
343 if (net->cc_mod.rtcc.last_step_state == 5)
344 net->cc_mod.rtcc.step_cnt++;
346 net->cc_mod.rtcc.step_cnt = 1;
347 net->cc_mod.rtcc.last_step_state = 5;
348 if ((net->cc_mod.rtcc.step_cnt == net->cc_mod.rtcc.steady_step) ||
349 ((net->cc_mod.rtcc.step_cnt > net->cc_mod.rtcc.steady_step) &&
350 ((net->cc_mod.rtcc.step_cnt % net->cc_mod.rtcc.steady_step) == 0))) {
352 if (net->cwnd > (4 * net->mtu)) {
353 net->cwnd -= net->mtu;
354 net->cc_mod.rtcc.vol_reduce++;
357 net->cc_mod.rtcc.step_cnt = 0;
366 return ((int)net->cc_mod.rtcc.ret_from_eq);
370 cc_bw_decrease(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint64_t rtt_offset,
376 probepoint = (((uint64_t) net->cwnd) << 32);
377 if (net->rtt > net->cc_mod.rtcc.lbw_rtt + rtt_offset) {
380 if ((net->cwnd > net->cc_mod.rtcc.cwnd_at_bw_set) &&
385 SDT_PROBE(sctp, cwnd, net, rttvar,
387 ((net->cc_mod.rtcc.lbw << 32) | nbw),
388 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
389 net->flight_size,
391 if (net->cc_mod.rtcc.ret_from_eq) {
396 net->ssthresh = net->cwnd - 1;
397 net->partial_bytes_acked = 0;
403 SDT_PROBE(sctp, cwnd, net, rttvar,
405 ((net->cc_mod.rtcc.lbw << 32) | nbw),
406 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
407 net->flight_size,
410 if (net->cc_mod.rtcc.steady_step) {
411 oth = net->cc_mod.rtcc.vol_reduce;
413 oth |= net->cc_mod.rtcc.step_cnt;
415 oth |= net->cc_mod.rtcc.last_step_state;
416 SDT_PROBE(sctp, cwnd, net, rttstep,
418 ((net->cc_mod.rtcc.lbw << 32) | nbw),
419 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
426 if ((net->cc_mod.rtcc.vol_reduce) &&
428 net->cwnd += net->mtu;
429 net->cc_mod.rtcc.vol_reduce--;
431 net->cc_mod.rtcc.last_step_state = 2;
432 net->cc_mod.rtcc.step_cnt = 0;
435 } else if (net->rtt < net->cc_mod.rtcc.lbw_rtt - rtt_offset) {
439 SDT_PROBE(sctp, cwnd, net, rttvar,
441 ((net->cc_mod.rtcc.lbw << 32) | nbw),
442 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
443 net->flight_size,
445 if (net->cc_mod.rtcc.steady_step) {
446 oth = net->cc_mod.rtcc.vol_reduce;
448 oth |= net->cc_mod.rtcc.step_cnt;
450 oth |= net->cc_mod.rtcc.last_step_state;
451 SDT_PROBE(sctp, cwnd, net, rttstep,
453 ((net->cc_mod.rtcc.lbw << 32) | nbw),
454 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
457 if ((net->cc_mod.rtcc.vol_reduce) &&
459 net->cwnd += net->mtu;
460 net->cc_mod.rtcc.vol_reduce--;
462 net->cc_mod.rtcc.last_step_state = 3;
463 net->cc_mod.rtcc.step_cnt = 0;
470 SDT_PROBE(sctp, cwnd, net, rttvar,
472 ((net->cc_mod.rtcc.lbw << 32) | nbw),
473 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
474 net->flight_size,
476 if (net->cc_mod.rtcc.steady_step) {
477 oth = net->cc_mod.rtcc.vol_reduce;
479 oth |= net->cc_mod.rtcc.step_cnt;
481 oth |= net->cc_mod.rtcc.last_step_state;
482 SDT_PROBE(sctp, cwnd, net, rttstep,
484 ((net->cc_mod.rtcc.lbw << 32) | nbw),
485 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
488 if ((net->cc_mod.rtcc.vol_reduce) &&
490 net->cwnd += net->mtu;
491 net->cc_mod.rtcc.vol_reduce--;
493 net->cc_mod.rtcc.last_step_state = 4;
494 net->cc_mod.rtcc.step_cnt = 0;
497 net->cc_mod.rtcc.lbw = nbw;
498 net->cc_mod.rtcc.lbw_rtt = net->rtt;
499 net->cc_mod.rtcc.cwnd_at_bw_set = net->cwnd;
508 cc_bw_increase(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint64_t vtag)
518 probepoint = (((uint64_t) net->cwnd) << 32);
519 SDT_PROBE(sctp, cwnd, net, rttvar,
521 ((net->cc_mod.rtcc.lbw << 32) | nbw),
522 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
523 net->flight_size,
525 if (net->cc_mod.rtcc.steady_step) {
526 oth = net->cc_mod.rtcc.vol_reduce;
528 oth |= net->cc_mod.rtcc.step_cnt;
530 oth |= net->cc_mod.rtcc.last_step_state;
531 SDT_PROBE(sctp, cwnd, net, rttstep,
533 ((net->cc_mod.rtcc.lbw << 32) | nbw),
534 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
537 net->cc_mod.rtcc.last_step_state = 0;
538 net->cc_mod.rtcc.step_cnt = 0;
539 net->cc_mod.rtcc.vol_reduce = 0;
541 net->cc_mod.rtcc.lbw = nbw;
542 net->cc_mod.rtcc.lbw_rtt = net->rtt;
543 net->cc_mod.rtcc.cwnd_at_bw_set = net->cwnd;
551 cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
601 probepoint = (((uint64_t) net->cwnd) << 32);
602 rtt = net->rtt;
603 if (net->cc_mod.rtcc.rtt_set_this_sack) {
604 net->cc_mod.rtcc.rtt_set_this_sack = 0;
605 bytes_for_this_rtt = net->cc_mod.rtcc.bw_bytes - net->cc_mod.rtcc.bw_bytes_at_last_rttc;
606 net->cc_mod.rtcc.bw_bytes_at_last_rttc = net->cc_mod.rtcc.bw_bytes;
607 if (net->rtt) {
608 div = net->rtt / 1000;
620 inst_ind = net->cc_mod.rtcc.last_inst_ind;
621 inst_bw = bytes_for_this_rtt / (uint64_t) (net->rtt);
626 inst_ind = net->cc_mod.rtcc.last_inst_ind;
631 SDT_PROBE(sctp, cwnd, net, rttvar,
634 ((net->cc_mod.rtcc.lbw_rtt << 32) | rtt),
635 net->flight_size,
639 inst_ind = net->cc_mod.rtcc.last_inst_ind;
641 bw_offset = net->cc_mod.rtcc.lbw >> bw_shift;
642 if (nbw > net->cc_mod.rtcc.lbw + bw_offset) {
643 ret = cc_bw_increase(stcb, net, nbw, vtag);
646 rtt_offset = net->cc_mod.rtcc.lbw_rtt >> SCTP_BASE_SYSCTL(sctp_rttvar_rtt);
647 if (nbw < net->cc_mod.rtcc.lbw - bw_offset) {
648 ret = cc_bw_decrease(stcb, net, nbw, rtt_offset, vtag, inst_ind);
655 ret = cc_bw_same(stcb, net, nbw, rtt_offset, vtag, inst_ind);
657 net->cc_mod.rtcc.last_inst_ind = inst_ind;
666 struct sctp_nets *net;
685 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
686 t_ssthresh += net->ssthresh;
687 t_cwnd += net->cwnd;
689 srtt = net->lastsa;
693 t_ucwnd_sbw += (uint64_t) net->cwnd / (uint64_t) srtt;
694 t_path_mptcp += (((uint64_t) net->cwnd) << SHIFT_MPTCP_MULTI_Z) /
695 (((uint64_t) net->mtu) * (uint64_t) srtt);
696 tmp = (((uint64_t) net->cwnd) << SHIFT_MPTCP_MULTI_N) /
697 ((uint64_t) net->mtu * (uint64_t) (srtt * srtt));
718 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
724 if (net->fast_retran_loss_recovery && net->new_pseudo_cumack) {
725 if (SCTP_TSN_GE(asoc->last_acked_seq, net->fast_recovery_tsn) ||
726 SCTP_TSN_GE(net->pseudo_cumack, net->fast_recovery_tsn)) {
727 net->will_exit_fast_recovery = 1;
732 if (net->net_ack == 0) {
734 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_LOG_FROM_SACK);
743 * if (sctp_cmt_on_off > 0 && net->fast_retran_loss_recovery
744 * && net->will_exit_fast_recovery == 0) { @@@ Do something
762 if (use_rtcc && (net->cc_mod.rtcc.tls_needs_set > 0)) {
772 if ((net->cc_mod.rtcc.new_tot_time / 1000) > 0) {
773 nbw = net->cc_mod.rtcc.bw_bytes / (net->cc_mod.rtcc.new_tot_time / 1000);
775 nbw = net->cc_mod.rtcc.bw_bytes;
777 if (net->cc_mod.rtcc.lbw) {
778 if (cc_bw_limit(stcb, net, nbw)) {
785 probepoint = (((uint64_t) net->cwnd) << 32);
787 vtag = (net->rtt << 32) |
791 SDT_PROBE(sctp, cwnd, net, rttvar,
794 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
795 net->flight_size,
797 net->cc_mod.rtcc.lbw = nbw;
798 net->cc_mod.rtcc.lbw_rtt = net->rtt;
799 if (net->cc_mod.rtcc.rtt_set_this_sack) {
800 net->cc_mod.rtcc.rtt_set_this_sack = 0;
801 net->cc_mod.rtcc.bw_bytes_at_last_rttc = net->cc_mod.rtcc.bw_bytes;
810 ((asoc->sctp_cmt_on_off > 0) && net->new_pseudo_cumack)) {
812 if (net->cwnd <= net->ssthresh) {
814 if (net->flight_size + net->net_ack >= net->cwnd) {
817 old_cwnd = net->cwnd;
820 limit = (uint32_t) (((uint64_t) net->mtu *
822 (uint64_t) net->ssthresh) /
824 incr = (uint32_t) (((uint64_t) net->net_ack *
825 (uint64_t) net->ssthresh) /
839 srtt = net->lastsa;
843 limit = (uint32_t) (((uint64_t) net->mtu *
845 (uint64_t) net->cwnd) /
848 incr = (uint32_t) (((uint64_t) net->net_ack *
849 (uint64_t) net->cwnd) /
860 limit = (uint32_t) (((uint64_t) net->mtu *
864 incr = (uint32_t) (((uint64_t) net->net_ack *
870 if (incr > net->net_ack) {
871 incr = net->net_ack;
873 if (incr > net->mtu) {
874 incr = net->mtu;
878 incr = net->net_ack;
879 if (incr > net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable)) {
880 incr = net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable);
884 net->cwnd += incr;
886 sctp_log_cwnd(stcb, net, incr,
889 SDT_PROBE(sctp, cwnd, net, ack,
892 net,
893 old_cwnd, net->cwnd);
896 sctp_log_cwnd(stcb, net, net->net_ack,
905 net->partial_bytes_acked += net->net_ack;
907 if ((net->flight_size + net->net_ack >= net->cwnd) &&
908 (net->partial_bytes_acked >= net->cwnd)) {
909 net->partial_bytes_acked -= net->cwnd;
910 old_cwnd = net->cwnd;
913 incr = (uint32_t) (((uint64_t) net->mtu *
914 (uint64_t) net->ssthresh) /
925 srtt = net->lastsa;
929 incr = (uint32_t) ((uint64_t) net->mtu *
930 (uint64_t) net->cwnd /
940 (uint64_t) net->cwnd) >>
942 if (incr > net->mtu) {
943 incr = net->mtu;
947 incr = net->mtu;
950 net->cwnd += incr;
951 SDT_PROBE(sctp, cwnd, net, ack,
954 net,
955 old_cwnd, net->cwnd);
957 sctp_log_cwnd(stcb, net, net->mtu,
962 sctp_log_cwnd(stcb, net, net->net_ack,
969 sctp_log_cwnd(stcb, net, net->mtu,
977 sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb, struct sctp_nets *net)
981 old_cwnd = net->cwnd;
982 net->cwnd = net->mtu;
983 SDT_PROBE(sctp, cwnd, net, ack,
984 stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
985 old_cwnd, net->cwnd);
987 (void *)net, net->cwnd);
992 sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
994 int old_cwnd = net->cwnd;
1023 net->ssthresh = (uint32_t) (((uint64_t) 4 *
1024 (uint64_t) net->mtu *
1025 (uint64_t) net->ssthresh) /
1030 srtt = net->lastsa;
1037 net->ssthresh = (uint32_t) ((uint64_t) t_cwnd - cc_delta);
1039 net->ssthresh = net->mtu;
1042 if ((net->cwnd > t_cwnd / 2) &&
1043 (net->ssthresh < net->cwnd - t_cwnd / 2)) {
1044 net->ssthresh = net->cwnd - t_cwnd / 2;
1046 if (net->ssthresh < net->mtu) {
1047 net->ssthresh = net->mtu;
1050 net->ssthresh = max(net->cwnd / 2, 4 * net->mtu);
1052 net->cwnd = net->mtu;
1053 net->partial_bytes_acked = 0;
1054 SDT_PROBE(sctp, cwnd, net, to,
1057 net,
1058 old_cwnd, net->cwnd);
1060 sctp_log_cwnd(stcb, net, net->cwnd - old_cwnd, SCTP_CWND_LOG_FROM_RTX);
1065 sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *net,
1068 int old_cwnd = net->cwnd;
1070 if ((use_rtcc) && (net->lan_type == SCTP_LAN_LOCAL) && (net->cc_mod.rtcc.use_dccc_ecn)) {
1077 if (net->ecn_prev_cwnd < net->cwnd) {
1079 net->cwnd = net->ecn_prev_cwnd - (net->mtu * num_pkt_lost);
1082 net->cwnd /= 2;
1085 net->ssthresh = net->cwnd - (num_pkt_lost * net->mtu);
1087 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);
1094 net->ssthresh -= (net->mtu * num_pkt_lost);
1095 net->cwnd -= (net->mtu * num_pkt_lost);
1097 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);
1104 net->ssthresh = net->cwnd / 2;
1105 if (net->ssthresh < net->mtu) {
1106 net->ssthresh = net->mtu;
1111 net->RTO <<= 1;
1113 net->cwnd = net->ssthresh;
1114 SDT_PROBE(sctp, cwnd, net, ecn,
1117 net,
1118 old_cwnd, net->cwnd);
1120 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);
1129 struct sctp_nets *net, struct sctp_pktdrop_chunk *cp,
1135 int old_cwnd = net->cwnd;
1138 rtt = net->rtt / 1000;
1147 if (*on_queue < net->flight_size)
1148 *on_queue = net->flight_size;
1169 net->partial_bytes_acked = 0;
1178 net->cwnd = net->prev_cwnd;
1181 seg_inflight = net->flight_size / net->mtu;
1182 seg_onqueue = *on_queue / net->mtu;
1186 if (net->cwnd > net->flight_size) {
1194 diff_adj = net->cwnd - net->flight_size;
1205 net->cwnd -= my_portion;
1208 if (net->cwnd <= net->mtu) {
1209 net->cwnd = net->mtu;
1212 net->ssthresh = net->cwnd - 1;
1220 (stcb->asoc.max_burst * net->mtu < incr)) {
1221 incr = stcb->asoc.max_burst * net->mtu;
1223 net->cwnd += incr;
1225 if (net->cwnd > bw_avail) {
1227 net->cwnd = bw_avail;
1229 if (net->cwnd < net->mtu) {
1231 net->cwnd = net->mtu;
1233 if (net->cwnd - old_cwnd != 0) {
1235 SDT_PROBE(sctp, cwnd, net, pd,
1238 net,
1239 old_cwnd, net->cwnd);
1241 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd),
1249 struct sctp_nets *net, int burst_limit)
1251 int old_cwnd = net->cwnd;
1253 if (net->ssthresh < net->cwnd)
1254 net->ssthresh = net->cwnd;
1256 net->cwnd = (net->flight_size + (burst_limit * net->mtu));
1257 SDT_PROBE(sctp, cwnd, net, bl,
1260 net,
1261 old_cwnd, net->cwnd);
1263 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_BRST);
1278 sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
1282 sctp_cwnd_update_after_ecn_echo_common(stcb, net, in_window, num_pkt_lost, 0);
1291 sctp_cwnd_update_rtcc_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
1294 sctp_cwnd_update_after_ecn_echo_common(stcb, net, in_window, num_pkt_lost, 1);
1300 sctp_cwnd_update_rtcc_tsn_acknowledged(struct sctp_nets *net,
1303 net->cc_mod.rtcc.bw_bytes += tp1->send_size;
1308 struct sctp_nets *net)
1310 if (net->cc_mod.rtcc.tls_needs_set > 0) {
1315 timevalsub(&ltls, &net->cc_mod.rtcc.tls);
1316 net->cc_mod.rtcc.new_tot_time = (ltls.tv_sec * 1000000) + ltls.tv_usec;
1322 struct sctp_nets *net)
1326 if (net->cc_mod.rtcc.lbw) {
1328 vtag = (net->rtt << 32) | (((uint32_t) (stcb->sctp_ep->sctp_lport)) << 16) |
1330 probepoint = (((uint64_t) net->cwnd) << 32);
1333 SDT_PROBE(sctp, cwnd, net, rttvar,
1335 ((net->cc_mod.rtcc.lbw << 32) | 0),
1336 ((net->cc_mod.rtcc.lbw_rtt << 32) | net->rtt),
1337 net->flight_size,
1339 net->cc_mod.rtcc.lbw_rtt = 0;
1340 net->cc_mod.rtcc.cwnd_at_bw_set = 0;
1341 net->cc_mod.rtcc.lbw = 0;
1342 net->cc_mod.rtcc.bw_bytes_at_last_rttc = 0;
1343 net->cc_mod.rtcc.vol_reduce = 0;
1344 net->cc_mod.rtcc.bw_tot_time = 0;
1345 net->cc_mod.rtcc.bw_bytes = 0;
1346 net->cc_mod.rtcc.tls_needs_set = 0;
1347 if (net->cc_mod.rtcc.steady_step) {
1348 net->cc_mod.rtcc.vol_reduce = 0;
1349 net->cc_mod.rtcc.step_cnt = 0;
1350 net->cc_mod.rtcc.last_step_state = 0;
1352 if (net->cc_mod.rtcc.ret_from_eq) {
1362 cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND));
1370 cwnd = (net->mtu - sizeof(struct sctphdr)) * cwnd_in_mtu;
1372 if (net->cwnd > cwnd) {
1377 net->cwnd = cwnd;
1385 struct sctp_nets *net)
1389 sctp_set_initial_cc_param(stcb, net);
1391 probepoint = (((uint64_t) net->cwnd) << 32);
1393 vtag = (net->rtt << 32) |
1396 SDT_PROBE(sctp, cwnd, net, rttvar,
1402 net->cc_mod.rtcc.lbw_rtt = 0;
1403 net->cc_mod.rtcc.cwnd_at_bw_set = 0;
1404 net->cc_mod.rtcc.vol_reduce = 0;
1405 net->cc_mod.rtcc.lbw = 0;
1406 net->cc_mod.rtcc.vol_reduce = 0;
1407 net->cc_mod.rtcc.bw_bytes_at_last_rttc = 0;
1408 net->cc_mod.rtcc.bw_tot_time = 0;
1409 net->cc_mod.rtcc.bw_bytes = 0;
1410 net->cc_mod.rtcc.tls_needs_set = 0;
1411 net->cc_mod.rtcc.ret_from_eq = SCTP_BASE_SYSCTL(sctp_rttvar_eqret);
1412 net->cc_mod.rtcc.steady_step = SCTP_BASE_SYSCTL(sctp_steady_step);
1413 net->cc_mod.rtcc.use_dccc_ecn = SCTP_BASE_SYSCTL(sctp_use_dccc_ecn);
1414 net->cc_mod.rtcc.step_cnt = 0;
1415 net->cc_mod.rtcc.last_step_state = 0;
1424 struct sctp_nets *net;
1433 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1434 net->cc_mod.rtcc.ret_from_eq = cc_opt->aid_value.assoc_value;
1441 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1442 net->cc_mod.rtcc.use_dccc_ecn = cc_opt->aid_value.assoc_value;
1445 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1446 net->cc_mod.rtcc.steady_step = cc_opt->aid_value.assoc_value;
1454 net = TAILQ_FIRST(&stcb->asoc.nets);
1455 if (net == NULL) {
1458 cc_opt->aid_value.assoc_value = net->cc_mod.rtcc.ret_from_eq;
1460 net = TAILQ_FIRST(&stcb->asoc.nets);
1461 if (net == NULL) {
1464 cc_opt->aid_value.assoc_value = net->cc_mod.rtcc.use_dccc_ecn;
1466 net = TAILQ_FIRST(&stcb->asoc.nets);
1467 if (net == NULL) {
1470 cc_opt->aid_value.assoc_value = net->cc_mod.rtcc.steady_step;
1480 struct sctp_nets *net)
1482 if (net->cc_mod.rtcc.tls_needs_set == 0) {
1483 SCTP_GETPTIME_TIMEVAL(&net->cc_mod.rtcc.tls);
1484 net->cc_mod.rtcc.tls_needs_set = 2;
1499 struct sctp_nets *net,
1502 net->cc_mod.rtcc.rtt_set_this_sack = 1;
1592 sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net)
1596 cur_val = net->cwnd >> 10;
1601 if (net->net_ack > net->mtu) {
1602 net->cwnd += net->mtu;
1604 sctp_log_cwnd(stcb, net, net->mtu, SCTP_CWND_LOG_FROM_SS);
1607 net->cwnd += net->net_ack;
1609 sctp_log_cwnd(stcb, net, net->net_ack, SCTP_CWND_LOG_FROM_SS);
1613 for (i = net->last_hs_used; i < SCTP_HS_TABLE_SIZE; i++) {
1619 net->last_hs_used = indx;
1621 net->cwnd += incr;
1623 sctp_log_cwnd(stcb, net, incr, SCTP_CWND_LOG_FROM_SS);
1629 sctp_hs_cwnd_decrease(struct sctp_tcb *stcb, struct sctp_nets *net)
1632 int old_cwnd = net->cwnd;
1634 cur_val = net->cwnd >> 10;
1637 net->ssthresh = net->cwnd / 2;
1638 if (net->ssthresh < (net->mtu * 2)) {
1639 net->ssthresh = 2 * net->mtu;
1641 net->cwnd = net->ssthresh;
1644 net->ssthresh = net->cwnd - (int)((net->cwnd / 100) *
1645 sctp_cwnd_adjust[net->last_hs_used].drop_percent);
1646 net->cwnd = net->ssthresh;
1648 indx = net->last_hs_used;
1649 cur_val = net->cwnd >> 10;
1653 net->last_hs_used = 0;
1660 net->last_hs_used = indx;
1664 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_FR);
1672 struct sctp_nets *net;
1676 * (net->fast_retran_loss_recovery == 0)))
1678 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
1682 if (net->net_ack > 0) {
1691 sctp_hs_cwnd_decrease(stcb, net);
1695 net->partial_bytes_acked = 0;
1709 net->fast_retran_loss_recovery = 1;
1713 net->fast_recovery_tsn = asoc->sending_seq - 1;
1715 net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
1719 stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32);
1721 stcb->sctp_ep, stcb, net);
1723 } else if (net->net_ack > 0) {
1738 struct sctp_nets *net;
1743 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
1749 if (net->fast_retran_loss_recovery && net->new_pseudo_cumack) {
1750 if (SCTP_TSN_GE(asoc->last_acked_seq, net->fast_recovery_tsn) ||
1751 SCTP_TSN_GE(net->pseudo_cumack, net->fast_recovery_tsn)) {
1752 net->will_exit_fast_recovery = 1;
1757 if (net->net_ack == 0) {
1759 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_LOG_FROM_SACK);
1768 * if (sctp_cmt_on_off > 0 && net->fast_retran_loss_recovery
1769 * && net->will_exit_fast_recovery == 0) { @@@ Do something
1789 ((asoc->sctp_cmt_on_off > 0) && net->new_pseudo_cumack)) {
1791 if (net->cwnd <= net->ssthresh) {
1793 if (net->flight_size + net->net_ack >= net->cwnd) {
1795 sctp_hs_cwnd_increase(stcb, net);
1799 sctp_log_cwnd(stcb, net, net->net_ack,
1805 net->partial_bytes_acked += net->net_ack;
1806 if ((net->flight_size + net->net_ack >= net->cwnd) &&
1807 (net->partial_bytes_acked >= net->cwnd)) {
1808 net->partial_bytes_acked -= net->cwnd;
1809 net->cwnd += net->mtu;
1811 sctp_log_cwnd(stcb, net, net->mtu,
1816 sctp_log_cwnd(stcb, net, net->net_ack,
1823 sctp_log_cwnd(stcb, net, net->mtu,
1836 * http://www.hamilton.ie/net/htcp3.pdf
1873 htcp_cwnd_undo(struct sctp_tcb *stcb, struct sctp_nets *net)
1875 net->cc_mod.htcp_ca.last_cong = net->cc_mod.htcp_ca.undo_last_cong;
1876 net->cc_mod.htcp_ca.maxRTT = net->cc_mod.htcp_ca.undo_maxRTT;
1877 net->cc_mod.htcp_ca.old_maxB = net->cc_mod.htcp_ca.undo_old_maxB;
1878 return (max(net->cwnd, ((net->ssthresh / net->mtu << 7) / net->cc_mod.htcp_ca.beta) * net->mtu));
1884 measure_rtt(struct sctp_nets *net)
1886 uint32_t srtt = net->lastsa >> SCTP_RTT_SHIFT;
1889 if (net->cc_mod.htcp_ca.minRTT > srtt || !net->cc_mod.htcp_ca.minRTT)
1890 net->cc_mod.htcp_ca.minRTT = srtt;
1893 if (net->fast_retran_ip == 0 && net->ssthresh < 0xFFFF && htcp_ccount(&net->cc_mod.htcp_ca) > 3) {
1894 if (net->cc_mod.htcp_ca.maxRTT < net->cc_mod.htcp_ca.minRTT)
1895 net->cc_mod.htcp_ca.maxRTT = net->cc_mod.htcp_ca.minRTT;
1896 if (net->cc_mod.htcp_ca.maxRTT < srtt && srtt <= net->cc_mod.htcp_ca.maxRTT + MSEC_TO_TICKS(20))
1897 net->cc_mod.htcp_ca.maxRTT = srtt;
1902 measure_achieved_throughput(struct sctp_nets *net)
1906 if (net->fast_retran_ip == 0)
1907 net->cc_mod.htcp_ca.bytes_acked = net->net_ack;
1914 if (net->fast_retran_ip == 1) {
1915 net->cc_mod.htcp_ca.bytecount = 0;
1916 net->cc_mod.htcp_ca.lasttime = now;
1919 net->cc_mod.htcp_ca.bytecount += net->net_ack;
1920 if ((net->cc_mod.htcp_ca.bytecount >= net->cwnd - (((net->cc_mod.htcp_ca.alpha >> 7) ? (net->cc_mod.htcp_ca.alpha >> 7) : 1) * net->mtu)) &&
1921 (now - net->cc_mod.htcp_ca.lasttime >= net->cc_mod.htcp_ca.minRTT) &&
1922 (net->cc_mod.htcp_ca.minRTT > 0)) {
1923 uint32_t cur_Bi = net->cc_mod.htcp_ca.bytecount / net->mtu * hz / (now - net->cc_mod.htcp_ca.lasttime);
1925 if (htcp_ccount(&net->cc_mod.htcp_ca) <= 3) {
1927 net->cc_mod.htcp_ca.minB = net->cc_mod.htcp_ca.maxB = net->cc_mod.htcp_ca.Bi = cur_Bi;
1929 net->cc_mod.htcp_ca.Bi = (3 * net->cc_mod.htcp_ca.Bi + cur_Bi) / 4;
1930 if (net->cc_mod.htcp_ca.Bi > net->cc_mod.htcp_ca.maxB)
1931 net->cc_mod.htcp_ca.maxB = net->cc_mod.htcp_ca.Bi;
1932 if (net->cc_mod.htcp_ca.minB > net->cc_mod.htcp_ca.maxB)
1933 net->cc_mod.htcp_ca.minB = net->cc_mod.htcp_ca.maxB;
1935 net->cc_mod.htcp_ca.bytecount = 0;
1936 net->cc_mod.htcp_ca.lasttime = now;
2001 htcp_param_update(struct sctp_nets *net)
2003 uint32_t minRTT = net->cc_mod.htcp_ca.minRTT;
2004 uint32_t maxRTT = net->cc_mod.htcp_ca.maxRTT;
2006 htcp_beta_update(&net->cc_mod.htcp_ca, minRTT, maxRTT);
2007 htcp_alpha_update(&net->cc_mod.htcp_ca);
2014 net->cc_mod.htcp_ca.maxRTT = minRTT + ((maxRTT - minRTT) * 95) / 100;
2018 htcp_recalc_ssthresh(struct sctp_nets *net)
2020 htcp_param_update(net);
2021 return (max(((net->cwnd / net->mtu * net->cc_mod.htcp_ca.beta) >> 7) * net->mtu, 2U * net->mtu));
2025 htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net)
2032 if (net->cwnd <= net->ssthresh) {
2034 if (net->flight_size + net->net_ack >= net->cwnd) {
2035 if (net->net_ack > (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable))) {
2036 net->cwnd += (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable));
2038 sctp_log_cwnd(stcb, net, net->mtu,
2042 net->cwnd += net->net_ack;
2044 sctp_log_cwnd(stcb, net, net->net_ack,
2050 sctp_log_cwnd(stcb, net, net->net_ack,
2055 measure_rtt(net);
2059 * net->cwnd += alpha / net->cwnd
2062 if (((net->partial_bytes_acked / net->mtu * net->cc_mod.htcp_ca.alpha) >> 7) * net->mtu >= net->cwnd) {
2065 * if (net->snd_cwnd < net->snd_cwnd_clamp) - Nope (RRS).
2067 net->cwnd += net->mtu;
2068 net->partial_bytes_acked = 0;
2069 htcp_alpha_update(&net->cc_mod.htcp_ca);
2071 sctp_log_cwnd(stcb, net, net->mtu,
2075 net->partial_bytes_acked += net->net_ack;
2077 sctp_log_cwnd(stcb, net, net->net_ack,
2082 net->cc_mod.htcp_ca.bytes_acked = net->mtu;
2089 htcp_min_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net)
2091 return (net->ssthresh);
2097 htcp_init(struct sctp_nets *net)
2099 memset(&net->cc_mod.htcp_ca, 0, sizeof(struct htcp));
2100 net->cc_mod.htcp_ca.alpha = ALPHA_BASE;
2101 net->cc_mod.htcp_ca.beta = BETA_MIN;
2102 net->cc_mod.htcp_ca.bytes_acked = net->mtu;
2103 net->cc_mod.htcp_ca.last_cong = sctp_get_tick_count();
2107 sctp_htcp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
2113 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND));
2114 net->ssthresh = stcb->asoc.peers_rwnd;
2115 htcp_init(net);
2118 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION);
2127 struct sctp_nets *net;
2132 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
2138 if (net->fast_retran_loss_recovery && net->new_pseudo_cumack) {
2139 if (SCTP_TSN_GE(asoc->last_acked_seq, net->fast_recovery_tsn) ||
2140 SCTP_TSN_GE(net->pseudo_cumack, net->fast_recovery_tsn)) {
2141 net->will_exit_fast_recovery = 1;
2146 if (net->net_ack == 0) {
2148 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_LOG_FROM_SACK);
2157 * if (sctp_cmt_on_off > 0 && net->fast_retran_loss_recovery
2158 * && net->will_exit_fast_recovery == 0) { @@@ Do something
2178 ((asoc->sctp_cmt_on_off > 0) && net->new_pseudo_cumack)) {
2179 htcp_cong_avoid(stcb, net);
2180 measure_achieved_throughput(net);
2183 sctp_log_cwnd(stcb, net, net->mtu,
2194 struct sctp_nets *net;
2198 * (net->fast_retran_loss_recovery == 0)))
2200 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
2204 if (net->net_ack > 0) {
2212 int old_cwnd = net->cwnd;
2215 htcp_reset(&net->cc_mod.htcp_ca);
2216 net->ssthresh = htcp_recalc_ssthresh(net);
2217 net->cwnd = net->ssthresh;
2219 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd),
2224 net->partial_bytes_acked = 0;
2238 net->fast_retran_loss_recovery = 1;
2242 net->fast_recovery_tsn = asoc->sending_seq - 1;
2244 net->fast_recovery_tsn = lchk->rec.data.TSN_seq - 1;
2248 stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32);
2250 stcb->sctp_ep, stcb, net);
2252 } else if (net->net_ack > 0) {
2264 struct sctp_nets *net)
2266 int old_cwnd = net->cwnd;
2269 htcp_reset(&net->cc_mod.htcp_ca);
2270 net->ssthresh = htcp_recalc_ssthresh(net);
2271 net->cwnd = net->mtu;
2272 net->partial_bytes_acked = 0;
2274 sctp_log_cwnd(stcb, net, net->cwnd - old_cwnd, SCTP_CWND_LOG_FROM_RTX);
2280 struct sctp_nets *net, int in_window, int num_pkt_lost SCTP_UNUSED)
2284 old_cwnd = net->cwnd;
2288 htcp_reset(&net->cc_mod.htcp_ca);
2290 net->ssthresh = htcp_recalc_ssthresh(net);
2291 if (net->ssthresh < net->mtu) {
2292 net->ssthresh = net->mtu;
2294 net->RTO <<= 1;
2296 net->cwnd = net->ssthresh;
2298 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);