Commit 27852c26 authored by Vlad Yasevich's avatar Vlad Yasevich Committed by David S. Miller

[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: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: default avatarSridhar Samudrala <sri@us.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4641e7a3
...@@ -700,7 +700,7 @@ struct sctp_chunk { ...@@ -700,7 +700,7 @@ struct sctp_chunk {
__u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */
__u8 pdiscard; /* Discard the whole packet now? */ __u8 pdiscard; /* Discard the whole packet now? */
__u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */
__u8 fast_retransmit; /* Is this chunk fast retransmitted? */ __s8 fast_retransmit; /* Is this chunk fast retransmitted? */
__u8 tsn_missing_report; /* Data chunk missing counter. */ __u8 tsn_missing_report; /* Data chunk missing counter. */
}; };
......
...@@ -608,7 +608,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, ...@@ -608,7 +608,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
* When a Fast Retransmit is being performed the sender SHOULD * When a Fast Retransmit is being performed the sender SHOULD
* ignore the value of cwnd and SHOULD NOT delay retransmission. * ignore the value of cwnd and SHOULD NOT delay retransmission.
*/ */
if (!chunk->fast_retransmit) if (chunk->fast_retransmit <= 0)
if (transport->flight_size >= transport->cwnd) { if (transport->flight_size >= transport->cwnd) {
retval = SCTP_XMIT_RWND_FULL; retval = SCTP_XMIT_RWND_FULL;
goto finish; goto finish;
......
...@@ -406,7 +406,7 @@ void sctp_retransmit_mark(struct sctp_outq *q, ...@@ -406,7 +406,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
* chunks that are not yet acked should be added to the * chunks that are not yet acked should be added to the
* retransmit queue. * retransmit queue.
*/ */
if ((fast_retransmit && chunk->fast_retransmit) || if ((fast_retransmit && (chunk->fast_retransmit > 0)) ||
(!fast_retransmit && !chunk->tsn_gap_acked)) { (!fast_retransmit && !chunk->tsn_gap_acked)) {
/* RFC 2960 6.2.1 Processing a Received SACK /* RFC 2960 6.2.1 Processing a Received SACK
* *
...@@ -603,7 +603,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, ...@@ -603,7 +603,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
/* Mark the chunk as ineligible for fast retransmit /* Mark the chunk as ineligible for fast retransmit
* after it is retransmitted. * after it is retransmitted.
*/ */
chunk->fast_retransmit = 0; if (chunk->fast_retransmit > 0)
chunk->fast_retransmit = -1;
*start_timer = 1; *start_timer = 1;
q->empty = 0; q->empty = 0;
...@@ -621,7 +622,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, ...@@ -621,7 +622,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
list_for_each(lchunk1, lqueue) { list_for_each(lchunk1, lqueue) {
chunk1 = list_entry(lchunk1, struct sctp_chunk, chunk1 = list_entry(lchunk1, struct sctp_chunk,
transmitted_list); transmitted_list);
chunk1->fast_retransmit = 0; if (chunk1->fast_retransmit > 0)
chunk1->fast_retransmit = -1;
} }
} }
} }
...@@ -1562,11 +1564,11 @@ static void sctp_mark_missing(struct sctp_outq *q, ...@@ -1562,11 +1564,11 @@ static void sctp_mark_missing(struct sctp_outq *q,
/* /*
* M4) If any DATA chunk is found to have a * M4) If any DATA chunk is found to have a
* 'TSN.Missing.Report' * 'TSN.Missing.Report'
* value larger than or equal to 4, mark that chunk for * value larger than or equal to 3, mark that chunk for
* retransmission and start the fast retransmit procedure. * retransmission and start the fast retransmit procedure.
*/ */
if (chunk->tsn_missing_report >= 4) { if (chunk->tsn_missing_report >= 3) {
chunk->fast_retransmit = 1; chunk->fast_retransmit = 1;
do_fast_retransmit = 1; do_fast_retransmit = 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment