1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 29 unchanged lines hidden (view full) --- 38#include <netinet/sctp_input.h> 39#include <netinet/sctp_indata.h> 40#include <netinet/sctp_uio.h> 41#include <netinet/sctp_timer.h> 42#include <netinet/sctp_auth.h> 43#include <netinet/sctp_asconf.h> 44#include <netinet/sctp_cc_functions.h> 45#include <sys/cdefs.h> |
46__FBSDID("$FreeBSD: head/sys/netinet/sctp_cc_functions.c 179783 2008-06-14 07:58:05Z rrs $"); |
47void 48sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net) 49{ 50 /* 51 * We take the max of the burst limit times a MTU or the 52 * INITIAL_CWND. We then limit this to 4 MTU's of sending. cwnd must 53 * be at least 2 MTU. 54 */ 55 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND)); 56 net->ssthresh = stcb->asoc.peers_rwnd; 57 |
58 if (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_CWND_MONITOR_ENABLE | SCTP_CWND_LOGGING_ENABLE)) { |
59 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION); 60 } 61} 62 63void 64sctp_cwnd_update_after_fr(struct sctp_tcb *stcb, 65 struct sctp_association *asoc) 66{ 67 struct sctp_nets *net; 68 69 /*- 70 * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off == 1) && 71 * (net->fast_retran_loss_recovery == 0))) 72 */ 73 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { |
74 if ((asoc->fast_retran_loss_recovery == 0) || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 1)) { |
75 /* out of a RFC2582 Fast recovery window? */ 76 if (net->net_ack > 0) { 77 /* 78 * per section 7.2.3, are there any 79 * destinations that had a fast retransmit 80 * to them. If so what we need to do is 81 * adjust ssthresh and cwnd. 82 */ 83 struct sctp_tmit_chunk *lchk; 84 int old_cwnd = net->cwnd; 85 86 net->ssthresh = net->cwnd / 2; 87 if (net->ssthresh < (net->mtu * 2)) { 88 net->ssthresh = 2 * net->mtu; 89 } 90 net->cwnd = net->ssthresh; |
91 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
92 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), 93 SCTP_CWND_LOG_FROM_FR); 94 } 95 lchk = TAILQ_FIRST(&asoc->send_queue); 96 97 net->partial_bytes_acked = 0; 98 /* Turn on fast recovery window */ 99 asoc->fast_retran_loss_recovery = 1; --- 60 unchanged lines hidden (view full) --- 160 net->fast_recovery_tsn, MAX_TSN) || 161 (asoc->last_acked_seq == net->fast_recovery_tsn) || 162 compare_with_wrap(net->pseudo_cumack, net->fast_recovery_tsn, MAX_TSN) || 163 (net->pseudo_cumack == net->fast_recovery_tsn)) { 164 net->will_exit_fast_recovery = 1; 165 } 166 } 167#endif |
168 if (SCTP_BASE_SYSCTL(sctp_early_fr)) { |
169 /* 170 * So, first of all do we need to have a Early FR 171 * timer running? 172 */ 173 if (((TAILQ_FIRST(&asoc->sent_queue)) && 174 (net->ref_count > 1) && 175 (net->flight_size < net->cwnd)) || 176 (reneged_all)) { --- 19 unchanged lines hidden (view full) --- 196 SCTP_STAT_INCR(sctps_earlyfrstpidsck3); 197 sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net, 198 SCTP_FROM_SCTP_INDATA + SCTP_LOC_21); 199 } 200 } 201 } 202 /* if nothing was acked on this destination skip it */ 203 if (net->net_ack == 0) { |
204 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
205 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_LOG_FROM_SACK); 206 } 207 continue; 208 } 209 if (net->net_ack2 > 0) { 210 /* 211 * Karn's rule applies to clearing error count, this 212 * is optional. --- 14 unchanged lines hidden (view full) --- 227 /* 228 * JRS 5/14/07 - If CMT PF is on and the destination 229 * is in PF state, set the destination to active 230 * state and set the cwnd to one or two MTU's based 231 * on whether PF1 or PF2 is being used. 232 * 233 * Should we stop any running T3 timer here? 234 */ |
235 if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && 236 SCTP_BASE_SYSCTL(sctp_cmt_pf) && 237 ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) { |
238 net->dest_state &= ~SCTP_ADDR_PF; |
239 net->cwnd = net->mtu * SCTP_BASE_SYSCTL(sctp_cmt_pf); |
240 SCTPDBG(SCTP_DEBUG_INDATA1, "Destination %p moved from PF to reachable with cwnd %d.\n", 241 net, net->cwnd); 242 /* 243 * Since the cwnd value is explicitly set, 244 * skip the code that updates the cwnd 245 * value. 246 */ 247 goto skip_cwnd_update; --- 7 unchanged lines hidden (view full) --- 255 * if (sctp_cmt_on_off == 1 && 256 * net->fast_retran_loss_recovery && 257 * net->will_exit_fast_recovery == 0) { @@@ Do something } 258 * else if (sctp_cmt_on_off == 0 && 259 * asoc->fast_retran_loss_recovery && will_exit == 0) { 260 */ 261#endif 262 |
263 if (asoc->fast_retran_loss_recovery && will_exit == 0 && SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0) { |
264 /* 265 * If we are in loss recovery we skip any cwnd 266 * update 267 */ 268 goto skip_cwnd_update; 269 } 270 /* 271 * CMT: CUC algorithm. Update cwnd if pseudo-cumack has 272 * moved. 273 */ |
274 if (accum_moved || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && net->new_pseudo_cumack)) { |
275 /* If the cumulative ack moved we can proceed */ 276 if (net->cwnd <= net->ssthresh) { 277 /* We are in slow start */ 278 if (net->flight_size + net->net_ack >= net->cwnd) { |
279 if (net->net_ack > (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable))) { 280 net->cwnd += (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable)); 281 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
282 sctp_log_cwnd(stcb, net, net->mtu, 283 SCTP_CWND_LOG_FROM_SS); 284 } 285 } else { 286 net->cwnd += net->net_ack; |
287 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
288 sctp_log_cwnd(stcb, net, net->net_ack, 289 SCTP_CWND_LOG_FROM_SS); 290 } 291 } 292 } else { |
293 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
294 sctp_log_cwnd(stcb, net, net->net_ack, 295 SCTP_CWND_LOG_NOADV_SS); 296 } 297 } 298 } else { 299 /* We are in congestion avoidance */ 300 /* 301 * Add to pba 302 */ 303 net->partial_bytes_acked += net->net_ack; 304 305 if ((net->flight_size + net->net_ack >= net->cwnd) && 306 (net->partial_bytes_acked >= net->cwnd)) { 307 net->partial_bytes_acked -= net->cwnd; 308 net->cwnd += net->mtu; |
309 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
310 sctp_log_cwnd(stcb, net, net->mtu, 311 SCTP_CWND_LOG_FROM_CA); 312 } 313 } else { |
314 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
315 sctp_log_cwnd(stcb, net, net->net_ack, 316 SCTP_CWND_LOG_NOADV_CA); 317 } 318 } 319 } 320 } else { |
321 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
322 sctp_log_cwnd(stcb, net, net->mtu, 323 SCTP_CWND_LOG_NO_CUMACK); 324 } 325 } 326skip_cwnd_update: 327 /* 328 * NOW, according to Karn's rule do we need to restore the 329 * RTO timer back? Check our net_ack2. If not set then we --- 17 unchanged lines hidden (view full) --- 347sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net) 348{ 349 int old_cwnd = net->cwnd; 350 351 net->ssthresh = max(net->cwnd / 2, 2 * net->mtu); 352 net->cwnd = net->mtu; 353 net->partial_bytes_acked = 0; 354 |
355 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
356 sctp_log_cwnd(stcb, net, net->cwnd - old_cwnd, SCTP_CWND_LOG_FROM_RTX); 357 } 358} 359 360void 361sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net) 362{ 363 int old_cwnd = net->cwnd; 364 365 SCTP_STAT_INCR(sctps_ecnereducedcwnd); 366 net->ssthresh = net->cwnd / 2; 367 if (net->ssthresh < net->mtu) { 368 net->ssthresh = net->mtu; 369 /* here back off the timer as well, to slow us down */ 370 net->RTO <<= 1; 371 } 372 net->cwnd = net->ssthresh; |
373 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
374 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT); 375 } 376} 377 378void 379sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, 380 struct sctp_nets *net, struct sctp_pktdrop_chunk *cp, 381 uint32_t * bottle_bw, uint32_t * on_queue) --- 92 unchanged lines hidden (view full) --- 474 net->cwnd = bw_avail; 475 } 476 if (net->cwnd < net->mtu) { 477 /* We always have 1 MTU */ 478 net->cwnd = net->mtu; 479 } 480 if (net->cwnd - old_cwnd != 0) { 481 /* log only changes */ |
482 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
483 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), 484 SCTP_CWND_LOG_FROM_SAT); 485 } 486 } 487} 488 489void 490sctp_cwnd_update_after_output(struct sctp_tcb *stcb, 491 struct sctp_nets *net, int burst_limit) 492{ 493 int old_cwnd = net->cwnd; 494 495 if (net->ssthresh < net->cwnd) 496 net->ssthresh = net->cwnd; 497 net->cwnd = (net->flight_size + (burst_limit * net->mtu)); 498 |
499 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
500 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_BRST); 501 } 502} 503 504void 505sctp_cwnd_update_after_fr_timer(struct sctp_inpcb *inp, 506 struct sctp_tcb *stcb, struct sctp_nets *net) 507{ --- 4 unchanged lines hidden (view full) --- 512 * make a small adjustment to cwnd and force to CA. 513 */ 514 if (net->cwnd > net->mtu) 515 /* drop down one MTU after sending */ 516 net->cwnd -= net->mtu; 517 if (net->cwnd < net->ssthresh) 518 /* still in SS move to CA */ 519 net->ssthresh = net->cwnd - 1; |
520 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
521 sctp_log_cwnd(stcb, net, (old_cwnd - net->cwnd), SCTP_CWND_LOG_FROM_FR); 522 } 523} 524 525struct sctp_hs_raise_drop { 526 int32_t cwnd; 527 int32_t increase; 528 int32_t drop_percent; --- 86 unchanged lines hidden (view full) --- 615 indx = SCTP_HS_TABLE_SIZE - 1; 616#ifdef SCTP_DEBUG 617 printf("HS CC CAlled.\n"); 618#endif 619 if (cur_val < sctp_cwnd_adjust[0].cwnd) { 620 /* normal mode */ 621 if (net->net_ack > net->mtu) { 622 net->cwnd += net->mtu; |
623 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
624 sctp_log_cwnd(stcb, net, net->mtu, SCTP_CWND_LOG_FROM_SS); 625 } 626 } else { 627 net->cwnd += net->net_ack; |
628 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
629 sctp_log_cwnd(stcb, net, net->net_ack, SCTP_CWND_LOG_FROM_SS); 630 } 631 } 632 } else { 633 for (i = net->last_hs_used; i < SCTP_HS_TABLE_SIZE; i++) { 634 if (cur_val < sctp_cwnd_adjust[i].cwnd) { 635 indx = i; 636 break; 637 } 638 } 639 net->last_hs_used = indx; 640 incr = ((sctp_cwnd_adjust[indx].increase) << 10); 641 net->cwnd += incr; |
642 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
643 sctp_log_cwnd(stcb, net, incr, SCTP_CWND_LOG_FROM_SS); 644 } 645 } 646} 647 648static void 649sctp_hs_cwnd_decrease(struct sctp_tcb *stcb, struct sctp_nets *net) 650{ --- 25 unchanged lines hidden (view full) --- 676 for (i = indx; i >= 1; i--) { 677 if (cur_val > sctp_cwnd_adjust[i - 1].cwnd) { 678 break; 679 } 680 } 681 net->last_hs_used = indx; 682 } 683 } |
684 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
685 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_FR); 686 } 687} 688 689void 690sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb, 691 struct sctp_association *asoc) 692{ 693 struct sctp_nets *net; 694 695 /* 696 * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off == 1) && 697 * (net->fast_retran_loss_recovery == 0))) 698 */ 699 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { |
700 if ((asoc->fast_retran_loss_recovery == 0) || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 1)) { |
701 /* out of a RFC2582 Fast recovery window? */ 702 if (net->net_ack > 0) { 703 /* 704 * per section 7.2.3, are there any 705 * destinations that had a fast retransmit 706 * to them. If so what we need to do is 707 * adjust ssthresh and cwnd. 708 */ --- 69 unchanged lines hidden (view full) --- 778 net->fast_recovery_tsn, MAX_TSN) || 779 (asoc->last_acked_seq == net->fast_recovery_tsn) || 780 compare_with_wrap(net->pseudo_cumack, net->fast_recovery_tsn, MAX_TSN) || 781 (net->pseudo_cumack == net->fast_recovery_tsn)) { 782 net->will_exit_fast_recovery = 1; 783 } 784 } 785#endif |
786 if (SCTP_BASE_SYSCTL(sctp_early_fr)) { |
787 /* 788 * So, first of all do we need to have a Early FR 789 * timer running? 790 */ 791 if (((TAILQ_FIRST(&asoc->sent_queue)) && 792 (net->ref_count > 1) && 793 (net->flight_size < net->cwnd)) || 794 (reneged_all)) { --- 19 unchanged lines hidden (view full) --- 814 SCTP_STAT_INCR(sctps_earlyfrstpidsck3); 815 sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net, 816 SCTP_FROM_SCTP_INDATA + SCTP_LOC_21); 817 } 818 } 819 } 820 /* if nothing was acked on this destination skip it */ 821 if (net->net_ack == 0) { |
822 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
823 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_LOG_FROM_SACK); 824 } 825 continue; 826 } 827 if (net->net_ack2 > 0) { 828 /* 829 * Karn's rule applies to clearing error count, this 830 * is optional. --- 14 unchanged lines hidden (view full) --- 845 /* 846 * JRS 5/14/07 - If CMT PF is on and the destination 847 * is in PF state, set the destination to active 848 * state and set the cwnd to one or two MTU's based 849 * on whether PF1 or PF2 is being used. 850 * 851 * Should we stop any running T3 timer here? 852 */ |
853 if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && 854 SCTP_BASE_SYSCTL(sctp_cmt_pf) && 855 ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) { |
856 net->dest_state &= ~SCTP_ADDR_PF; |
857 net->cwnd = net->mtu * SCTP_BASE_SYSCTL(sctp_cmt_pf); |
858 SCTPDBG(SCTP_DEBUG_INDATA1, "Destination %p moved from PF to reachable with cwnd %d.\n", 859 net, net->cwnd); 860 /* 861 * Since the cwnd value is explicitly set, 862 * skip the code that updates the cwnd 863 * value. 864 */ 865 goto skip_cwnd_update; --- 7 unchanged lines hidden (view full) --- 873 * if (sctp_cmt_on_off == 1 && 874 * net->fast_retran_loss_recovery && 875 * net->will_exit_fast_recovery == 0) { @@@ Do something } 876 * else if (sctp_cmt_on_off == 0 && 877 * asoc->fast_retran_loss_recovery && will_exit == 0) { 878 */ 879#endif 880 |
881 if (asoc->fast_retran_loss_recovery && will_exit == 0 && SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0) { |
882 /* 883 * If we are in loss recovery we skip any cwnd 884 * update 885 */ 886 goto skip_cwnd_update; 887 } 888 /* 889 * CMT: CUC algorithm. Update cwnd if pseudo-cumack has 890 * moved. 891 */ |
892 if (accum_moved || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && net->new_pseudo_cumack)) { |
893 /* If the cumulative ack moved we can proceed */ 894 if (net->cwnd <= net->ssthresh) { 895 /* We are in slow start */ 896 if (net->flight_size + net->net_ack >= net->cwnd) { 897 898 sctp_hs_cwnd_increase(stcb, net); 899 900 } else { |
901 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
902 sctp_log_cwnd(stcb, net, net->net_ack, 903 SCTP_CWND_LOG_NOADV_SS); 904 } 905 } 906 } else { 907 /* We are in congestion avoidance */ 908 net->partial_bytes_acked += net->net_ack; 909 if ((net->flight_size + net->net_ack >= net->cwnd) && 910 (net->partial_bytes_acked >= net->cwnd)) { 911 net->partial_bytes_acked -= net->cwnd; 912 net->cwnd += net->mtu; |
913 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
914 sctp_log_cwnd(stcb, net, net->mtu, 915 SCTP_CWND_LOG_FROM_CA); 916 } 917 } else { |
918 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
919 sctp_log_cwnd(stcb, net, net->net_ack, 920 SCTP_CWND_LOG_NOADV_CA); 921 } 922 } 923 } 924 } else { |
925 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
926 sctp_log_cwnd(stcb, net, net->mtu, 927 SCTP_CWND_LOG_NO_CUMACK); 928 } 929 } 930skip_cwnd_update: 931 /* 932 * NOW, according to Karn's rule do we need to restore the 933 * RTO timer back? Check our net_ack2. If not set then we --- 214 unchanged lines hidden (view full) --- 1148 /*- 1149 * How to handle these functions? 1150 * if (!tcp_is_cwnd_limited(sk, in_flight)) RRS - good question. 1151 * return; 1152 */ 1153 if (net->cwnd <= net->ssthresh) { 1154 /* We are in slow start */ 1155 if (net->flight_size + net->net_ack >= net->cwnd) { |
1156 if (net->net_ack > (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable))) { 1157 net->cwnd += (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable)); 1158 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
1159 sctp_log_cwnd(stcb, net, net->mtu, 1160 SCTP_CWND_LOG_FROM_SS); 1161 } 1162 } else { 1163 net->cwnd += net->net_ack; |
1164 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
1165 sctp_log_cwnd(stcb, net, net->net_ack, 1166 SCTP_CWND_LOG_FROM_SS); 1167 } 1168 } 1169 } else { |
1170 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
1171 sctp_log_cwnd(stcb, net, net->net_ack, 1172 SCTP_CWND_LOG_NOADV_SS); 1173 } 1174 } 1175 } else { 1176 measure_rtt(stcb, net); 1177 1178 /* --- 4 unchanged lines hidden (view full) --- 1183 if (((net->partial_bytes_acked / net->mtu * net->htcp_ca.alpha) >> 7) * net->mtu >= net->cwnd) { 1184 /*- 1185 * Does SCTP have a cwnd clamp? 1186 * if (net->snd_cwnd < net->snd_cwnd_clamp) - Nope (RRS). 1187 */ 1188 net->cwnd += net->mtu; 1189 net->partial_bytes_acked = 0; 1190 htcp_alpha_update(&net->htcp_ca); |
1191 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
1192 sctp_log_cwnd(stcb, net, net->mtu, 1193 SCTP_CWND_LOG_FROM_CA); 1194 } 1195 } else { 1196 net->partial_bytes_acked += net->net_ack; |
1197 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
1198 sctp_log_cwnd(stcb, net, net->net_ack, 1199 SCTP_CWND_LOG_NOADV_CA); 1200 } 1201 } 1202 1203 net->htcp_ca.bytes_acked = net->mtu; 1204 } 1205} --- 24 unchanged lines hidden (view full) --- 1230 /* 1231 * We take the max of the burst limit times a MTU or the 1232 * INITIAL_CWND. We then limit this to 4 MTU's of sending. 1233 */ 1234 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND)); 1235 net->ssthresh = stcb->asoc.peers_rwnd; 1236 htcp_init(stcb, net); 1237 |
1238 if (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_CWND_MONITOR_ENABLE | SCTP_CWND_LOGGING_ENABLE)) { |
1239 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION); 1240 } 1241} 1242 1243void 1244sctp_htcp_cwnd_update_after_sack(struct sctp_tcb *stcb, 1245 struct sctp_association *asoc, 1246 int accum_moved, int reneged_all, int will_exit) --- 14 unchanged lines hidden (view full) --- 1261 net->fast_recovery_tsn, MAX_TSN) || 1262 (asoc->last_acked_seq == net->fast_recovery_tsn) || 1263 compare_with_wrap(net->pseudo_cumack, net->fast_recovery_tsn, MAX_TSN) || 1264 (net->pseudo_cumack == net->fast_recovery_tsn)) { 1265 net->will_exit_fast_recovery = 1; 1266 } 1267 } 1268#endif |
1269 if (SCTP_BASE_SYSCTL(sctp_early_fr)) { |
1270 /* 1271 * So, first of all do we need to have a Early FR 1272 * timer running? 1273 */ 1274 if (((TAILQ_FIRST(&asoc->sent_queue)) && 1275 (net->ref_count > 1) && 1276 (net->flight_size < net->cwnd)) || 1277 (reneged_all)) { --- 19 unchanged lines hidden (view full) --- 1297 SCTP_STAT_INCR(sctps_earlyfrstpidsck3); 1298 sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net, 1299 SCTP_FROM_SCTP_INDATA + SCTP_LOC_21); 1300 } 1301 } 1302 } 1303 /* if nothing was acked on this destination skip it */ 1304 if (net->net_ack == 0) { |
1305 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
1306 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_LOG_FROM_SACK); 1307 } 1308 continue; 1309 } 1310 if (net->net_ack2 > 0) { 1311 /* 1312 * Karn's rule applies to clearing error count, this 1313 * is optional. --- 14 unchanged lines hidden (view full) --- 1328 /* 1329 * JRS 5/14/07 - If CMT PF is on and the destination 1330 * is in PF state, set the destination to active 1331 * state and set the cwnd to one or two MTU's based 1332 * on whether PF1 or PF2 is being used. 1333 * 1334 * Should we stop any running T3 timer here? 1335 */ |
1336 if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && 1337 SCTP_BASE_SYSCTL(sctp_cmt_pf) && 1338 ((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) { |
1339 net->dest_state &= ~SCTP_ADDR_PF; |
1340 net->cwnd = net->mtu * SCTP_BASE_SYSCTL(sctp_cmt_pf); |
1341 SCTPDBG(SCTP_DEBUG_INDATA1, "Destination %p moved from PF to reachable with cwnd %d.\n", 1342 net, net->cwnd); 1343 /* 1344 * Since the cwnd value is explicitly set, 1345 * skip the code that updates the cwnd 1346 * value. 1347 */ 1348 goto skip_cwnd_update; --- 7 unchanged lines hidden (view full) --- 1356 * if (sctp_cmt_on_off == 1 && 1357 * net->fast_retran_loss_recovery && 1358 * net->will_exit_fast_recovery == 0) { @@@ Do something } 1359 * else if (sctp_cmt_on_off == 0 && 1360 * asoc->fast_retran_loss_recovery && will_exit == 0) { 1361 */ 1362#endif 1363 |
1364 if (asoc->fast_retran_loss_recovery && will_exit == 0 && SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0) { |
1365 /* 1366 * If we are in loss recovery we skip any cwnd 1367 * update 1368 */ 1369 goto skip_cwnd_update; 1370 } 1371 /* 1372 * CMT: CUC algorithm. Update cwnd if pseudo-cumack has 1373 * moved. 1374 */ |
1375 if (accum_moved || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && net->new_pseudo_cumack)) { |
1376 htcp_cong_avoid(stcb, net); 1377 measure_achieved_throughput(stcb, net); 1378 } else { |
1379 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { |
1380 sctp_log_cwnd(stcb, net, net->mtu, 1381 SCTP_CWND_LOG_NO_CUMACK); 1382 } 1383 } 1384skip_cwnd_update: 1385 /* 1386 * NOW, according to Karn's rule do we need to restore the 1387 * RTO timer back? Check our net_ack2. If not set then we --- 19 unchanged lines hidden (view full) --- 1407{ 1408 struct sctp_nets *net; 1409 1410 /* 1411 * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off == 1) && 1412 * (net->fast_retran_loss_recovery == 0))) 1413 */ 1414 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { |
1415 if ((asoc->fast_retran_loss_recovery == 0) || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 1)) { |
1416 /* out of a RFC2582 Fast recovery window? */ 1417 if (net->net_ack > 0) { 1418 /* 1419 * per section 7.2.3, are there any 1420 * destinations that had a fast retransmit 1421 * to them. If so what we need to do is 1422 * adjust ssthresh and cwnd. 1423 */ 1424 struct sctp_tmit_chunk *lchk; 1425 int old_cwnd = net->cwnd; 1426 1427 /* JRS - reset as if state were changed */ 1428 htcp_reset(&net->htcp_ca); 1429 net->ssthresh = htcp_recalc_ssthresh(stcb, net); 1430 net->cwnd = net->ssthresh; |
1431 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
1432 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), 1433 SCTP_CWND_LOG_FROM_FR); 1434 } 1435 lchk = TAILQ_FIRST(&asoc->send_queue); 1436 1437 net->partial_bytes_acked = 0; 1438 /* Turn on fast recovery window */ 1439 asoc->fast_retran_loss_recovery = 1; --- 45 unchanged lines hidden (view full) --- 1485{ 1486 int old_cwnd = net->cwnd; 1487 1488 /* JRS - reset as if the state were being changed to timeout */ 1489 htcp_reset(&net->htcp_ca); 1490 net->ssthresh = htcp_recalc_ssthresh(stcb, net); 1491 net->cwnd = net->mtu; 1492 net->partial_bytes_acked = 0; |
1493 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
1494 sctp_log_cwnd(stcb, net, net->cwnd - old_cwnd, SCTP_CWND_LOG_FROM_RTX); 1495 } 1496} 1497 1498void 1499sctp_htcp_cwnd_update_after_fr_timer(struct sctp_inpcb *inp, 1500 struct sctp_tcb *stcb, struct sctp_nets *net) 1501{ --- 7 unchanged lines hidden (view full) --- 1509 * make a small adjustment to cwnd and force to CA. 1510 */ 1511 if (net->cwnd > net->mtu) 1512 /* drop down one MTU after sending */ 1513 net->cwnd -= net->mtu; 1514 if (net->cwnd < net->ssthresh) 1515 /* still in SS move to CA */ 1516 net->ssthresh = net->cwnd - 1; |
1517 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
1518 sctp_log_cwnd(stcb, net, (old_cwnd - net->cwnd), SCTP_CWND_LOG_FROM_FR); 1519 } 1520} 1521 1522void 1523sctp_htcp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, 1524 struct sctp_nets *net) 1525{ --- 6 unchanged lines hidden (view full) --- 1532 SCTP_STAT_INCR(sctps_ecnereducedcwnd); 1533 net->ssthresh = htcp_recalc_ssthresh(stcb, net); 1534 if (net->ssthresh < net->mtu) { 1535 net->ssthresh = net->mtu; 1536 /* here back off the timer as well, to slow us down */ 1537 net->RTO <<= 1; 1538 } 1539 net->cwnd = net->ssthresh; |
1540 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) { |
1541 sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT); 1542 } 1543} |