From: Neil Horman <nhorman@redhat.com> Date: Mon, 9 Nov 2009 21:22:48 -0500 Subject: [sctp] assign tsns earlier to avoid reordering Message-id: <20091109212248.GA12774@hmsreliant.think-freely.org> Patchwork-id: 21339 O-Subject: [RHEL 5.5 PATCH] sctp: assign tsns earlier to avoid reordering (bz 517504) Bugzilla: 517504 RH-Acked-by: Anton Arapov <Anton@redhat.com> RH-Acked-by: Thomas Graf <tgraf@redhat.com> RH-Acked-by: David S. Miller <davem@redhat.com> Hey all- sctp packtes, when sent over multiple network interfaces with varying mtus can get reordered in the send queue prior to the assignment of tsn values (the sctp equivalent of sequence numbers in tcp). As a result, even if sctp messages are sent in order and delivered in order in respect to the tsn sequence, the recevier will see a differen message order than the sender sent. This patch recently got taken by the sctp maintainer (no commit id as of yet, but on his list). Fixes the problem by assigning tsn when data chunks are appended to an offered packet, which is prior to the point where misordering can occur (in sctp_packet_transmit_chunk and sctp_outq_flush for those interested). Solves bz 517504. Neil diff --git a/net/sctp/output.c b/net/sctp/output.c index cdc5a39..ce896e1 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -279,6 +279,10 @@ append: /* It is OK to send this chunk. */ list_add_tail(&chunk->list, &packet->chunk_list); + if (sctp_chunk_is_data(chunk)) { + sctp_chunk_assign_tsn(chunk); + sctp_chunk_assign_ssn(chunk); + } packet->size += chunk_len; chunk->transport = packet->transport; finish: @@ -390,23 +394,22 @@ int sctp_packet_transmit(struct sctp_packet *packet) list_del_init(&chunk->list); if (sctp_chunk_is_data(chunk)) { - if (!chunk->has_tsn) { - sctp_chunk_assign_ssn(chunk); - sctp_chunk_assign_tsn(chunk); + if (!chunk->resent) { - /* 6.3.1 C4) When data is in flight and when allowed - * by rule C5, a new RTT measurement MUST be made each - * round trip. Furthermore, new RTT measurements - * SHOULD be made no more than once per round-trip - * for a given destination transport address. - */ + /* 6.3.1 C4) When data is in flight and when allowed + * by rule C5, a new RTT measurement MUST be made each + * round trip. Furthermore, new RTT measurements + * SHOULD be made no more than once per round-trip + * for a given destination transport address. + */ if (!tp->rto_pending) { chunk->rtt_in_progress = 1; tp->rto_pending = 1; } - } else - chunk->resent = 1; + } + + chunk->resent = 1; chunk->sent_at = jiffies; has_data = 1;