aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2010-04-30 22:41:10 -0400
committerVlad Yasevich <vladislav.yasevich@hp.com>2010-04-30 22:41:10 -0400
commitcf9b4812e18aab6f86ff998bd7425a9e823269c3 (patch)
tree51181bd38679112d3abc32ba6dc4266acad9251c
parentb2cf9b6bd93af1cc047d3356f1c6cc9367fe3731 (diff)
sctp: fast recovery algorithm is per association.
SCTP fast recovery algorithm really applies per association and impacts all transports. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
-rw-r--r--include/net/sctp/structs.h12
-rw-r--r--net/sctp/transport.c32
2 files changed, 23 insertions, 21 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 9072dd67d8ad..d463296d9f79 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -895,9 +895,6 @@ struct sctp_transport {
895 */ 895 */
896 hb_sent:1, 896 hb_sent:1,
897 897
898 /* Flag to track the current fast recovery state */
899 fast_recovery:1,
900
901 /* Is the Path MTU update pending on this tranport */ 898 /* Is the Path MTU update pending on this tranport */
902 pmtu_pending:1, 899 pmtu_pending:1,
903 900
@@ -952,9 +949,6 @@ struct sctp_transport {
952 949
953 __u32 burst_limited; /* Holds old cwnd when max.burst is applied */ 950 __u32 burst_limited; /* Holds old cwnd when max.burst is applied */
954 951
955 /* TSN marking the fast recovery exit point */
956 __u32 fast_recovery_exit;
957
958 /* Destination */ 952 /* Destination */
959 struct dst_entry *dst; 953 struct dst_entry *dst;
960 /* Source address. */ 954 /* Source address. */
@@ -1723,6 +1717,12 @@ struct sctp_association {
1723 /* Highest TSN that is acknowledged by incoming SACKs. */ 1717 /* Highest TSN that is acknowledged by incoming SACKs. */
1724 __u32 highest_sacked; 1718 __u32 highest_sacked;
1725 1719
1720 /* TSN marking the fast recovery exit point */
1721 __u32 fast_recovery_exit;
1722
1723 /* Flag to track the current fast recovery state */
1724 __u8 fast_recovery;
1725
1726 /* The number of unacknowledged data chunks. Reported through 1726 /* The number of unacknowledged data chunks. Reported through
1727 * the SCTP_STATUS sockopt. 1727 * the SCTP_STATUS sockopt.
1728 */ 1728 */
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 854228bf3f34..fccf4947aff1 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -378,15 +378,16 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
378void sctp_transport_raise_cwnd(struct sctp_transport *transport, 378void sctp_transport_raise_cwnd(struct sctp_transport *transport,
379 __u32 sack_ctsn, __u32 bytes_acked) 379 __u32 sack_ctsn, __u32 bytes_acked)
380{ 380{
381 struct sctp_association *asoc = transport->asoc;
381 __u32 cwnd, ssthresh, flight_size, pba, pmtu; 382 __u32 cwnd, ssthresh, flight_size, pba, pmtu;
382 383
383 cwnd = transport->cwnd; 384 cwnd = transport->cwnd;
384 flight_size = transport->flight_size; 385 flight_size = transport->flight_size;
385 386
386 /* See if we need to exit Fast Recovery first */ 387 /* See if we need to exit Fast Recovery first */
387 if (transport->fast_recovery && 388 if (asoc->fast_recovery &&
388 TSN_lte(transport->fast_recovery_exit, sack_ctsn)) 389 TSN_lte(asoc->fast_recovery_exit, sack_ctsn))
389 transport->fast_recovery = 0; 390 asoc->fast_recovery = 0;
390 391
391 /* The appropriate cwnd increase algorithm is performed if, and only 392 /* The appropriate cwnd increase algorithm is performed if, and only
392 * if the cumulative TSN whould advanced and the congestion window is 393 * if the cumulative TSN whould advanced and the congestion window is
@@ -415,7 +416,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport,
415 * 2) the destination's path MTU. This upper bound protects 416 * 2) the destination's path MTU. This upper bound protects
416 * against the ACK-Splitting attack outlined in [SAVAGE99]. 417 * against the ACK-Splitting attack outlined in [SAVAGE99].
417 */ 418 */
418 if (transport->fast_recovery) 419 if (asoc->fast_recovery)
419 return; 420 return;
420 421
421 if (bytes_acked > pmtu) 422 if (bytes_acked > pmtu)
@@ -466,6 +467,8 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport,
466void sctp_transport_lower_cwnd(struct sctp_transport *transport, 467void sctp_transport_lower_cwnd(struct sctp_transport *transport,
467 sctp_lower_cwnd_t reason) 468 sctp_lower_cwnd_t reason)
468{ 469{
470 struct sctp_association *asoc = transport->asoc;
471
469 switch (reason) { 472 switch (reason) {
470 case SCTP_LOWER_CWND_T3_RTX: 473 case SCTP_LOWER_CWND_T3_RTX:
471 /* RFC 2960 Section 7.2.3, sctpimpguide 474 /* RFC 2960 Section 7.2.3, sctpimpguide
@@ -476,11 +479,11 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
476 * partial_bytes_acked = 0 479 * partial_bytes_acked = 0
477 */ 480 */
478 transport->ssthresh = max(transport->cwnd/2, 481 transport->ssthresh = max(transport->cwnd/2,
479 4*transport->asoc->pathmtu); 482 4*asoc->pathmtu);
480 transport->cwnd = transport->asoc->pathmtu; 483 transport->cwnd = asoc->pathmtu;
481 484
482 /* T3-rtx also clears fast recovery on the transport */ 485 /* T3-rtx also clears fast recovery */
483 transport->fast_recovery = 0; 486 asoc->fast_recovery = 0;
484 break; 487 break;
485 488
486 case SCTP_LOWER_CWND_FAST_RTX: 489 case SCTP_LOWER_CWND_FAST_RTX:
@@ -496,15 +499,15 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
496 * cwnd = ssthresh 499 * cwnd = ssthresh
497 * partial_bytes_acked = 0 500 * partial_bytes_acked = 0
498 */ 501 */
499 if (transport->fast_recovery) 502 if (asoc->fast_recovery)
500 return; 503 return;
501 504
502 /* Mark Fast recovery */ 505 /* Mark Fast recovery */
503 transport->fast_recovery = 1; 506 asoc->fast_recovery = 1;
504 transport->fast_recovery_exit = transport->asoc->next_tsn - 1; 507 asoc->fast_recovery_exit = asoc->next_tsn - 1;
505 508
506 transport->ssthresh = max(transport->cwnd/2, 509 transport->ssthresh = max(transport->cwnd/2,
507 4*transport->asoc->pathmtu); 510 4*asoc->pathmtu);
508 transport->cwnd = transport->ssthresh; 511 transport->cwnd = transport->ssthresh;
509 break; 512 break;
510 513
@@ -524,7 +527,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
524 if (time_after(jiffies, transport->last_time_ecne_reduced + 527 if (time_after(jiffies, transport->last_time_ecne_reduced +
525 transport->rtt)) { 528 transport->rtt)) {
526 transport->ssthresh = max(transport->cwnd/2, 529 transport->ssthresh = max(transport->cwnd/2,
527 4*transport->asoc->pathmtu); 530 4*asoc->pathmtu);
528 transport->cwnd = transport->ssthresh; 531 transport->cwnd = transport->ssthresh;
529 transport->last_time_ecne_reduced = jiffies; 532 transport->last_time_ecne_reduced = jiffies;
530 } 533 }
@@ -540,7 +543,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
540 * interval. 543 * interval.
541 */ 544 */
542 transport->cwnd = max(transport->cwnd/2, 545 transport->cwnd = max(transport->cwnd/2,
543 4*transport->asoc->pathmtu); 546 4*asoc->pathmtu);
544 break; 547 break;
545 } 548 }
546 549
@@ -625,7 +628,6 @@ void sctp_transport_reset(struct sctp_transport *t)
625 t->error_count = 0; 628 t->error_count = 0;
626 t->rto_pending = 0; 629 t->rto_pending = 0;
627 t->hb_sent = 0; 630 t->hb_sent = 0;
628 t->fast_recovery = 0;
629 631
630 /* Initialize the state information for SFR-CACC */ 632 /* Initialize the state information for SFR-CACC */
631 t->cacc.changeover_active = 0; 633 t->cacc.changeover_active = 0;