[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>
This commit is contained in:
parent
4641e7a334
commit
27852c26ba
|
@ -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,
|
||||||
* 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,
|
||||||
* 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,
|
||||||
/* 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,
|
||||||
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,
|
||||||
/*
|
/*
|
||||||
* 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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue