aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2009-03-02 04:46:14 -0500
committerDavid S. Miller <davem@davemloft.net>2009-03-03 01:49:18 -0500
commit7e99013a5043cacd375375c3efad35b57c3afdba (patch)
tree52b66988e7f49c644731acfa616afe9b4e1501c1
parentf61f6f82c90cbaa85270f26b89e3309a8c6e2e88 (diff)
sctp: Fix broken RTO-doubling for data retransmits
Commit faee47cdbfe8d74a1573c2f81ea6dbb08d735be6 (sctp: Fix the RTO-doubling on idle-link heartbeats) broke the RTO doubling for data retransmits. If the heartbeat was sent before the data T3-rtx time, the the RTO will not double upon the T3-rtx expiration. Distingish between the operations by passing an argument to the function. Additionally, Wei Youngjun pointed out that our treatment of requested HEARTBEATS and timer HEARTBEATS is the same wrt resetting congestion window. That needs to be separated, since user requested HEARTBEATS should not treat the link as idle. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/sctp/command.h3
-rw-r--r--net/sctp/sm_sideeffect.c32
-rw-r--r--net/sctp/sm_statefuns.c6
3 files changed, 19 insertions, 22 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index 88988ab03d75..3b966802e05d 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -77,7 +77,8 @@ typedef enum {
77 SCTP_CMD_HB_TIMERS_START, /* Start the heartbeat timers. */ 77 SCTP_CMD_HB_TIMERS_START, /* Start the heartbeat timers. */
78 SCTP_CMD_HB_TIMER_UPDATE, /* Update a heartbeat timers. */ 78 SCTP_CMD_HB_TIMER_UPDATE, /* Update a heartbeat timers. */
79 SCTP_CMD_HB_TIMERS_STOP, /* Stop the heartbeat timers. */ 79 SCTP_CMD_HB_TIMERS_STOP, /* Stop the heartbeat timers. */
80 SCTP_CMD_TRANSPORT_RESET, /* Reset the status of a transport. */ 80 SCTP_CMD_TRANSPORT_HB_SENT, /* Reset the status of a transport. */
81 SCTP_CMD_TRANSPORT_IDLE, /* Do manipulations on idle transport */
81 SCTP_CMD_TRANSPORT_ON, /* Mark the transport as active. */ 82 SCTP_CMD_TRANSPORT_ON, /* Mark the transport as active. */
82 SCTP_CMD_REPORT_ERROR, /* Pass this error back out of the sm. */ 83 SCTP_CMD_REPORT_ERROR, /* Pass this error back out of the sm. */
83 SCTP_CMD_REPORT_BAD_TAG, /* Verification tags didn't match. */ 84 SCTP_CMD_REPORT_BAD_TAG, /* Verification tags didn't match. */
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 0146cfb1f182..5385150df296 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -434,7 +434,8 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
434 * 434 *
435 */ 435 */
436static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, 436static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
437 struct sctp_transport *transport) 437 struct sctp_transport *transport,
438 int is_hb)
438{ 439{
439 /* The check for association's overall error counter exceeding the 440 /* The check for association's overall error counter exceeding the
440 * threshold is done in the state function. 441 * threshold is done in the state function.
@@ -466,7 +467,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
466 * The first unacknowleged HB triggers it. We do this with a flag 467 * The first unacknowleged HB triggers it. We do this with a flag
467 * that indicates that we have an outstanding HB. 468 * that indicates that we have an outstanding HB.
468 */ 469 */
469 if (transport->hb_sent) { 470 if (!is_hb || transport->hb_sent) {
470 transport->last_rto = transport->rto; 471 transport->last_rto = transport->rto;
471 transport->rto = min((transport->rto * 2), transport->asoc->rto_max); 472 transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
472 } 473 }
@@ -657,20 +658,6 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
657 sctp_transport_hold(t); 658 sctp_transport_hold(t);
658} 659}
659 660
660/* Helper function to do a transport reset at the expiry of the hearbeat
661 * timer.
662 */
663static void sctp_cmd_transport_reset(sctp_cmd_seq_t *cmds,
664 struct sctp_association *asoc,
665 struct sctp_transport *t)
666{
667 sctp_transport_lower_cwnd(t, SCTP_LOWER_CWND_INACTIVE);
668
669 /* Mark one strike against a transport. */
670 sctp_do_8_2_transport_strike(asoc, t);
671
672 t->hb_sent = 1;
673}
674 661
675/* Helper function to process the process SACK command. */ 662/* Helper function to process the process SACK command. */
676static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds, 663static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
@@ -1459,12 +1446,19 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1459 1446
1460 case SCTP_CMD_STRIKE: 1447 case SCTP_CMD_STRIKE:
1461 /* Mark one strike against a transport. */ 1448 /* Mark one strike against a transport. */
1462 sctp_do_8_2_transport_strike(asoc, cmd->obj.transport); 1449 sctp_do_8_2_transport_strike(asoc, cmd->obj.transport,
1450 0);
1451 break;
1452
1453 case SCTP_CMD_TRANSPORT_IDLE:
1454 t = cmd->obj.transport;
1455 sctp_transport_lower_cwnd(t, SCTP_LOWER_CWND_INACTIVE);
1463 break; 1456 break;
1464 1457
1465 case SCTP_CMD_TRANSPORT_RESET: 1458 case SCTP_CMD_TRANSPORT_HB_SENT:
1466 t = cmd->obj.transport; 1459 t = cmd->obj.transport;
1467 sctp_cmd_transport_reset(commands, asoc, t); 1460 sctp_do_8_2_transport_strike(asoc, t, 1);
1461 t->hb_sent = 1;
1468 break; 1462 break;
1469 1463
1470 case SCTP_CMD_TRANSPORT_ON: 1464 case SCTP_CMD_TRANSPORT_ON:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 3a0cd075914f..a907bab0963d 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -988,7 +988,9 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
988 /* Set transport error counter and association error counter 988 /* Set transport error counter and association error counter
989 * when sending heartbeat. 989 * when sending heartbeat.
990 */ 990 */
991 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET, 991 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_IDLE,
992 SCTP_TRANSPORT(transport));
993 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_HB_SENT,
992 SCTP_TRANSPORT(transport)); 994 SCTP_TRANSPORT(transport));
993 } 995 }
994 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE, 996 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE,
@@ -4967,7 +4969,7 @@ sctp_disposition_t sctp_sf_do_prm_requestheartbeat(
4967 * to that address and not acknowledged within one RTO. 4969 * to that address and not acknowledged within one RTO.
4968 * 4970 *
4969 */ 4971 */
4970 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET, 4972 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_HB_SENT,
4971 SCTP_TRANSPORT(arg)); 4973 SCTP_TRANSPORT(arg));
4972 return SCTP_DISPOSITION_CONSUME; 4974 return SCTP_DISPOSITION_CONSUME;
4973} 4975}