diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2006-02-02 19:57:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-02-02 19:57:31 -0500 |
commit | 27852c26baab8b95fc9a2b3e8a18770ecd553f10 (patch) | |
tree | f07d3c696598ce6e7181ee30344bce899971e062 | |
parent | 4641e7a334adf6856300a98e7296dfc886c446af (diff) |
[SCTP]: Fix 'fast retransmit' to send a TSN only once.
SCTP used to "fast retransmit" a TSN every time we hit the number
of missing reports for the TSN. However the Implementers Guide
specifies that we should only "fast retransmit" a given TSN once.
Subsequent retransmits should be timeouts only. Also change the
number of missing reports to 3 as per the latest IG(similar to TCP).
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/sctp/structs.h | 2 | ||||
-rw-r--r-- | net/sctp/output.c | 2 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 12 |
3 files changed, 9 insertions, 7 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 8c522ae031bb..072f407848a6 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -700,7 +700,7 @@ struct sctp_chunk { | |||
700 | __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ | 700 | __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ |
701 | __u8 pdiscard; /* Discard the whole packet now? */ | 701 | __u8 pdiscard; /* Discard the whole packet now? */ |
702 | __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ | 702 | __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ |
703 | __u8 fast_retransmit; /* Is this chunk fast retransmitted? */ | 703 | __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ |
704 | __u8 tsn_missing_report; /* Data chunk missing counter. */ | 704 | __u8 tsn_missing_report; /* Data chunk missing counter. */ |
705 | }; | 705 | }; |
706 | 706 | ||
diff --git a/net/sctp/output.c b/net/sctp/output.c index a40991ef72c9..437cba7260a4 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -608,7 +608,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, | |||
608 | * When a Fast Retransmit is being performed the sender SHOULD | 608 | * When a Fast Retransmit is being performed the sender SHOULD |
609 | * ignore the value of cwnd and SHOULD NOT delay retransmission. | 609 | * ignore the value of cwnd and SHOULD NOT delay retransmission. |
610 | */ | 610 | */ |
611 | if (!chunk->fast_retransmit) | 611 | if (chunk->fast_retransmit <= 0) |
612 | if (transport->flight_size >= transport->cwnd) { | 612 | if (transport->flight_size >= transport->cwnd) { |
613 | retval = SCTP_XMIT_RWND_FULL; | 613 | retval = SCTP_XMIT_RWND_FULL; |
614 | goto finish; | 614 | goto finish; |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index efb72faba20c..f148f9576dd2 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -406,7 +406,7 @@ void sctp_retransmit_mark(struct sctp_outq *q, | |||
406 | * chunks that are not yet acked should be added to the | 406 | * chunks that are not yet acked should be added to the |
407 | * retransmit queue. | 407 | * retransmit queue. |
408 | */ | 408 | */ |
409 | if ((fast_retransmit && chunk->fast_retransmit) || | 409 | if ((fast_retransmit && (chunk->fast_retransmit > 0)) || |
410 | (!fast_retransmit && !chunk->tsn_gap_acked)) { | 410 | (!fast_retransmit && !chunk->tsn_gap_acked)) { |
411 | /* RFC 2960 6.2.1 Processing a Received SACK | 411 | /* RFC 2960 6.2.1 Processing a Received SACK |
412 | * | 412 | * |
@@ -603,7 +603,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
603 | /* Mark the chunk as ineligible for fast retransmit | 603 | /* Mark the chunk as ineligible for fast retransmit |
604 | * after it is retransmitted. | 604 | * after it is retransmitted. |
605 | */ | 605 | */ |
606 | chunk->fast_retransmit = 0; | 606 | if (chunk->fast_retransmit > 0) |
607 | chunk->fast_retransmit = -1; | ||
607 | 608 | ||
608 | *start_timer = 1; | 609 | *start_timer = 1; |
609 | q->empty = 0; | 610 | q->empty = 0; |
@@ -621,7 +622,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
621 | list_for_each(lchunk1, lqueue) { | 622 | list_for_each(lchunk1, lqueue) { |
622 | chunk1 = list_entry(lchunk1, struct sctp_chunk, | 623 | chunk1 = list_entry(lchunk1, struct sctp_chunk, |
623 | transmitted_list); | 624 | transmitted_list); |
624 | chunk1->fast_retransmit = 0; | 625 | if (chunk1->fast_retransmit > 0) |
626 | chunk1->fast_retransmit = -1; | ||
625 | } | 627 | } |
626 | } | 628 | } |
627 | } | 629 | } |
@@ -1562,11 +1564,11 @@ static void sctp_mark_missing(struct sctp_outq *q, | |||
1562 | /* | 1564 | /* |
1563 | * M4) If any DATA chunk is found to have a | 1565 | * M4) If any DATA chunk is found to have a |
1564 | * 'TSN.Missing.Report' | 1566 | * 'TSN.Missing.Report' |
1565 | * value larger than or equal to 4, mark that chunk for | 1567 | * value larger than or equal to 3, mark that chunk for |
1566 | * retransmission and start the fast retransmit procedure. | 1568 | * retransmission and start the fast retransmit procedure. |
1567 | */ | 1569 | */ |
1568 | 1570 | ||
1569 | if (chunk->tsn_missing_report >= 4) { | 1571 | if (chunk->tsn_missing_report >= 3) { |
1570 | chunk->fast_retransmit = 1; | 1572 | chunk->fast_retransmit = 1; |
1571 | do_fast_retransmit = 1; | 1573 | do_fast_retransmit = 1; |
1572 | } | 1574 | } |