]> err.no Git - linux-2.6/blobdiff - net/sctp/outqueue.c
[NETFILTER]: CLUSTERIP: fix memcpy() length typo
[linux-2.6] / net / sctp / outqueue.c
index 4eb81a1407b7e027c7da1302a8af43705be3015a..efb72faba20cd50aec065d4fe498c85ecae8d4ae 100644 (file)
@@ -75,7 +75,7 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn);
 static inline void sctp_outq_head_data(struct sctp_outq *q,
                                        struct sctp_chunk *ch)
 {
-       __skb_queue_head(&q->out, (struct sk_buff *)ch);
+       list_add(&ch->list, &q->out_chunk_list);
        q->out_qlen += ch->skb->len;
        return;
 }
@@ -83,17 +83,22 @@ static inline void sctp_outq_head_data(struct sctp_outq *q,
 /* Take data from the front of the queue. */
 static inline struct sctp_chunk *sctp_outq_dequeue_data(struct sctp_outq *q)
 {
-       struct sctp_chunk *ch;
-       ch = (struct sctp_chunk *)__skb_dequeue(&q->out);
-       if (ch)
+       struct sctp_chunk *ch = NULL;
+
+       if (!list_empty(&q->out_chunk_list)) {
+               struct list_head *entry = q->out_chunk_list.next;
+
+               ch = list_entry(entry, struct sctp_chunk, list);
+               list_del_init(entry);
                q->out_qlen -= ch->skb->len;
+       }
        return ch;
 }
 /* Add data chunk to the end of the queue. */
 static inline void sctp_outq_tail_data(struct sctp_outq *q,
                                       struct sctp_chunk *ch)
 {
-       __skb_queue_tail(&q->out, (struct sk_buff *)ch);
+       list_add_tail(&ch->list, &q->out_chunk_list);
        q->out_qlen += ch->skb->len;
        return;
 }
@@ -197,8 +202,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary,
 void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
 {
        q->asoc = asoc;
-       skb_queue_head_init(&q->out);
-       skb_queue_head_init(&q->control);
+       INIT_LIST_HEAD(&q->out_chunk_list);
+       INIT_LIST_HEAD(&q->control_chunk_list);
        INIT_LIST_HEAD(&q->retransmit);
        INIT_LIST_HEAD(&q->sacked);
        INIT_LIST_HEAD(&q->abandoned);
@@ -217,7 +222,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
 {
        struct sctp_transport *transport;
        struct list_head *lchunk, *pos, *temp;
-       struct sctp_chunk *chunk;
+       struct sctp_chunk *chunk, *tmp;
 
        /* Throw away unacknowledged chunks. */
        list_for_each(pos, &q->asoc->peer.transport_addr_list) {
@@ -269,8 +274,10 @@ void sctp_outq_teardown(struct sctp_outq *q)
        q->error = 0;
 
        /* Throw away any leftover control chunks. */
-       while ((chunk = (struct sctp_chunk *) skb_dequeue(&q->control)) != NULL)
+       list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
+               list_del_init(&chunk->list);
                sctp_chunk_free(chunk);
+       }
 }
 
 /* Free the outqueue structure and any related pending chunks.  */
@@ -333,7 +340,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk)
                        break;
                };
        } else {
-               __skb_queue_tail(&q->control, (struct sk_buff *) chunk);
+               list_add_tail(&chunk->list, &q->control_chunk_list);
                SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
        }
 
@@ -650,10 +657,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
        __u16 sport = asoc->base.bind_addr.port;
        __u16 dport = asoc->peer.port;
        __u32 vtag = asoc->peer.i.init_tag;
-       struct sk_buff_head *queue;
        struct sctp_transport *transport = NULL;
        struct sctp_transport *new_transport;
-       struct sctp_chunk *chunk;
+       struct sctp_chunk *chunk, *tmp;
        sctp_xmit_t status;
        int error = 0;
        int start_timer = 0;
@@ -675,8 +681,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
         *   ...
         */
 
-       queue = &q->control;
-       while ((chunk = (struct sctp_chunk *)skb_dequeue(queue)) != NULL) {
+       list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
+               list_del_init(&chunk->list);
+
                /* Pick the right transport to use. */
                new_transport = chunk->transport;
 
@@ -814,8 +821,6 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 
                /* Finally, transmit new packets.  */
                start_timer = 0;
-               queue = &q->out;
-
                while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
                        /* RFC 2960 6.5 Every DATA chunk MUST carry a valid
                         * stream identifier.
@@ -1149,8 +1154,9 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
        /* See if all chunks are acked.
         * Make sure the empty queue handler will get run later.
         */
-       q->empty = skb_queue_empty(&q->out) && skb_queue_empty(&q->control) &&
-                       list_empty(&q->retransmit);
+       q->empty = (list_empty(&q->out_chunk_list) &&
+                   list_empty(&q->control_chunk_list) &&
+                   list_empty(&q->retransmit));
        if (!q->empty)
                goto finish;
 
@@ -1679,9 +1685,9 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
                if (TSN_lte(tsn, ctsn)) {
                        list_del_init(lchunk);
                        if (!chunk->tsn_gap_acked) {
-                       chunk->transport->flight_size -=
-                                                sctp_data_size(chunk);
-                       q->outstanding_bytes -= sctp_data_size(chunk);
+                               chunk->transport->flight_size -=
+                                       sctp_data_size(chunk);
+                               q->outstanding_bytes -= sctp_data_size(chunk);
                        }
                        sctp_chunk_free(chunk);
                } else {
@@ -1729,7 +1735,7 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
                                              nskips, &ftsn_skip_arr[0]); 
 
        if (ftsn_chunk) {
-               __skb_queue_tail(&q->control, (struct sk_buff *)ftsn_chunk);
+               list_add_tail(&ftsn_chunk->list, &q->control_chunk_list);
                SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
        }
 }