]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/sctp/outqueue.c
sctp: use sctp_chunk_is_data macro to decide a chunk is data chunk
[net-next-2.6.git] / net / sctp / outqueue.c
index abfc0b8dee74ea171c9f974e7a10fe4b9c66b2b9..a4fe7dee76e89d1a67f01c16a1057f33adf0d9fe 100644 (file)
@@ -308,7 +308,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
        /* If it is data, queue it up, otherwise, send it
         * immediately.
         */
-       if (SCTP_CID_DATA == chunk->chunk_hdr->type) {
+       if (sctp_chunk_is_data(chunk)) {
                /* Is it OK to queue data chunks?  */
                /* From 9. Termination of Association
                 *
@@ -598,11 +598,23 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
                if (fast_rtx && !chunk->fast_retransmit)
                        continue;
 
+redo:
                /* Attempt to append this chunk to the packet. */
                status = sctp_packet_append_chunk(pkt, chunk);
 
                switch (status) {
                case SCTP_XMIT_PMTU_FULL:
+                       if (!pkt->has_data && !pkt->has_cookie_echo) {
+                               /* If this packet did not contain DATA then
+                                * retransmission did not happen, so do it
+                                * again.  We'll ignore the error here since
+                                * control chunks are already freed so there
+                                * is nothing we can do.
+                                */
+                               sctp_packet_transmit(pkt);
+                               goto redo;
+                       }
+
                        /* Send this packet.  */
                        error = sctp_packet_transmit(pkt);
 
@@ -854,6 +866,12 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
                        if (status  != SCTP_XMIT_OK) {
                                /* put the chunk back */
                                list_add(&chunk->list, &q->control_chunk_list);
+                       } else if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) {
+                               /* PR-SCTP C5) If a FORWARD TSN is sent, the
+                                * sender MUST assure that at least one T3-rtx
+                                * timer is running.
+                                */
+                               sctp_transport_reset_timers(transport, 0);
                        }
                        break;