summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXufeng Zhang <xufeng.zhang@windriver.com>2013-11-25 11:26:57 +0800
committerDavid S. Miller <davem@davemloft.net>2013-11-28 18:29:58 -0500
commit6eabca54d6781f61c7318517c1463a098acb7a87 (patch)
treeb546ca46b835a418c3e80d55c3fdcb86dade25b3
parent5e53e689b737526308db2b5c9f56e9d0371a1676 (diff)
downloadlinux-stable-6eabca54d6781f61c7318517c1463a098acb7a87.tar.gz
linux-stable-6eabca54d6781f61c7318517c1463a098acb7a87.tar.bz2
linux-stable-6eabca54d6781f61c7318517c1463a098acb7a87.zip
sctp: Restore 'resent' bit to avoid retransmitted chunks for RTT measurements
Currently retransmitted DATA chunks could also be used for RTT measurements since there are no flag to identify whether the transmitted DATA chunk is a new one or a retransmitted one. This problem is introduced by commit ae19c5486 ("sctp: remove 'resent' bit from the chunk") which inappropriately removed the 'resent' bit completely, instead of doing this, we should set the resent bit only for the retransmitted DATA chunks. Signed-off-by: Xufeng Zhang <xufeng.zhang@windriver.com> Acked-by: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/sctp/structs.h1
-rw-r--r--net/sctp/output.c3
-rw-r--r--net/sctp/outqueue.c3
3 files changed, 6 insertions, 1 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 2174d8da0770..ea0ca5f6e629 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -629,6 +629,7 @@ struct sctp_chunk {
#define SCTP_NEED_FRTX 0x1
#define SCTP_DONT_FRTX 0x2
__u16 rtt_in_progress:1, /* This chunk used for RTT calc? */
+ resent:1, /* Has this chunk ever been resent. */
has_tsn:1, /* Does this chunk have a TSN yet? */
has_ssn:1, /* Does this chunk have a SSN yet? */
singleton:1, /* Only chunk in the packet? */
diff --git a/net/sctp/output.c b/net/sctp/output.c
index e650978daf27..0e2644d0a773 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -474,10 +474,11 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* for a given destination transport address.
*/
- if (!tp->rto_pending) {
+ if (!chunk->resent && !tp->rto_pending) {
chunk->rtt_in_progress = 1;
tp->rto_pending = 1;
}
+
has_data = 1;
}
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index abb6db008df1..f51ba985a36e 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -446,6 +446,8 @@ void sctp_retransmit_mark(struct sctp_outq *q,
transport->rto_pending = 0;
}
+ chunk->resent = 1;
+
/* Move the chunk to the retransmit queue. The chunks
* on the retransmit queue are always kept in order.
*/
@@ -1375,6 +1377,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
* instance).
*/
if (!tchunk->tsn_gap_acked &&
+ !tchunk->resent &&
tchunk->rtt_in_progress) {
tchunk->rtt_in_progress = 0;
rtt = jiffies - tchunk->sent_at;