Skip to content

Commit

Permalink
[SCTP]: Use struct list_head for chunk lists, not sk_buff_head.
Browse files Browse the repository at this point in the history
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 9, 2005
1 parent 9c05989 commit 79af02c
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 66 deletions.
20 changes: 7 additions & 13 deletions include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,6 @@ void sctp_datamsg_track(struct sctp_chunk *);
void sctp_chunk_fail(struct sctp_chunk *, int error);
int sctp_chunk_abandoned(struct sctp_chunk *);


/* RFC2960 1.4 Key Terms
*
* o Chunk: A unit of information within an SCTP packet, consisting of
Expand All @@ -592,13 +591,8 @@ int sctp_chunk_abandoned(struct sctp_chunk *);
* each chunk as well as a few other header pointers...
*/
struct sctp_chunk {
/* These first three elements MUST PRECISELY match the first
* three elements of struct sk_buff. This allows us to reuse
* all the skb_* queue management functions.
*/
struct sctp_chunk *next;
struct sctp_chunk *prev;
struct sk_buff_head *list;
struct list_head list;

atomic_t refcnt;

/* This is our link to the per-transport transmitted list. */
Expand Down Expand Up @@ -717,7 +711,7 @@ struct sctp_packet {
__u32 vtag;

/* This contains the payload chunks. */
struct sk_buff_head chunks;
struct list_head chunk_list;

/* This is the overhead of the sctp and ip headers. */
size_t overhead;
Expand Down Expand Up @@ -974,7 +968,7 @@ struct sctp_inq {
/* This is actually a queue of sctp_chunk each
* containing a partially decoded packet.
*/
struct sk_buff_head in;
struct list_head in_chunk_list;
/* This is the packet which is currently off the in queue and is
* being worked on through the inbound chunk processing.
*/
Expand Down Expand Up @@ -1017,15 +1011,15 @@ struct sctp_outq {
struct sctp_association *asoc;

/* Data pending that has never been transmitted. */
struct sk_buff_head out;
struct list_head out_chunk_list;

unsigned out_qlen; /* Total length of queued data chunks. */

/* Error of send failed, may used in SCTP_SEND_FAILED event. */
unsigned error;

/* These are control chunks we want to send. */
struct sk_buff_head control;
struct list_head control_chunk_list;

/* These are chunks that have been sacked but are above the
* CTSN, or cumulative tsn ack point.
Expand Down Expand Up @@ -1672,7 +1666,7 @@ struct sctp_association {
* which already resides in sctp_outq. Please move this
* queue and its supporting logic down there. --piggy]
*/
struct sk_buff_head addip_chunks;
struct list_head addip_chunk_list;

/* ADDIP Section 4.1 ASCONF Chunk Procedures
*
Expand Down
2 changes: 1 addition & 1 deletion net/sctp/associola.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
*/
asoc->addip_serial = asoc->c.initial_tsn;

skb_queue_head_init(&asoc->addip_chunks);
INIT_LIST_HEAD(&asoc->addip_chunk_list);

/* Make an empty list of remote transport addresses. */
INIT_LIST_HEAD(&asoc->peer.transport_addr_list);
Expand Down
26 changes: 16 additions & 10 deletions net/sctp/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ static void sctp_rcv_set_owner_r(struct sk_buff *skb, struct sock *sk)
atomic_add(sizeof(struct sctp_chunk),&sk->sk_rmem_alloc);
}

struct sctp_input_cb {
union {
struct inet_skb_parm h4;
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
struct inet6_skb_parm h6;
#endif
} header;
struct sctp_chunk *chunk;
};
#define SCTP_INPUT_CB(__skb) ((struct sctp_input_cb *)&((__skb)->cb[0]))

/*
* This is the routine which IP calls when receiving an SCTP packet.
*/
Expand Down Expand Up @@ -243,6 +254,7 @@ int sctp_rcv(struct sk_buff *skb)
ret = -ENOMEM;
goto discard_release;
}
SCTP_INPUT_CB(skb)->chunk = chunk;

sctp_rcv_set_owner_r(skb,sk);

Expand All @@ -265,9 +277,9 @@ int sctp_rcv(struct sk_buff *skb)
sctp_bh_lock_sock(sk);

if (sock_owned_by_user(sk))
sk_add_backlog(sk, (struct sk_buff *) chunk);
sk_add_backlog(sk, skb);
else
sctp_backlog_rcv(sk, (struct sk_buff *) chunk);
sctp_backlog_rcv(sk, skb);

/* Release the sock and any reference counts we took in the
* lookup calls.
Expand Down Expand Up @@ -302,14 +314,8 @@ int sctp_rcv(struct sk_buff *skb)
*/
int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
struct sctp_chunk *chunk;
struct sctp_inq *inqueue;

/* One day chunk will live inside the skb, but for
* now this works.
*/
chunk = (struct sctp_chunk *) skb;
inqueue = &chunk->rcvr->inqueue;
struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
struct sctp_inq *inqueue = &chunk->rcvr->inqueue;

sctp_inq_push(inqueue, chunk);
return 0;
Expand Down
18 changes: 12 additions & 6 deletions net/sctp/inqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
/* Initialize an SCTP inqueue. */
void sctp_inq_init(struct sctp_inq *queue)
{
skb_queue_head_init(&queue->in);
INIT_LIST_HEAD(&queue->in_chunk_list);
queue->in_progress = NULL;

/* Create a task for delivering data. */
Expand All @@ -62,11 +62,13 @@ void sctp_inq_init(struct sctp_inq *queue)
/* Release the memory associated with an SCTP inqueue. */
void sctp_inq_free(struct sctp_inq *queue)
{
struct sctp_chunk *chunk;
struct sctp_chunk *chunk, *tmp;

/* Empty the queue. */
while ((chunk = (struct sctp_chunk *) skb_dequeue(&queue->in)) != NULL)
list_for_each_entry_safe(chunk, tmp, &queue->in_chunk_list, list) {
list_del_init(&chunk->list);
sctp_chunk_free(chunk);
}

/* If there is a packet which is currently being worked on,
* free it as well.
Expand All @@ -92,7 +94,7 @@ void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *packet)
* Eventually, we should clean up inqueue to not rely
* on the BH related data structures.
*/
skb_queue_tail(&(q->in), (struct sk_buff *) packet);
list_add_tail(&packet->list, &q->in_chunk_list);
q->immediate.func(q->immediate.data);
}

Expand Down Expand Up @@ -131,12 +133,16 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)

/* Do we need to take the next packet out of the queue to process? */
if (!chunk) {
struct list_head *entry;

/* Is the queue empty? */
if (skb_queue_empty(&queue->in))
if (list_empty(&queue->in_chunk_list))
return NULL;

entry = queue->in_chunk_list.next;
chunk = queue->in_progress =
(struct sctp_chunk *) skb_dequeue(&queue->in);
list_entry(entry, struct sctp_chunk, list);
list_del_init(entry);

/* This is the first chunk in the packet. */
chunk->singleton = 1;
Expand Down
22 changes: 13 additions & 9 deletions net/sctp/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
packet->transport = transport;
packet->source_port = sport;
packet->destination_port = dport;
skb_queue_head_init(&packet->chunks);
INIT_LIST_HEAD(&packet->chunk_list);
if (asoc) {
struct sctp_sock *sp = sctp_sk(asoc->base.sk);
overhead = sp->pf->af->net_header_len;
Expand All @@ -129,12 +129,14 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
/* Free a packet. */
void sctp_packet_free(struct sctp_packet *packet)
{
struct sctp_chunk *chunk;
struct sctp_chunk *chunk, *tmp;

SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);

while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)) != NULL)
list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
list_del_init(&chunk->list);
sctp_chunk_free(chunk);
}

if (packet->malloced)
kfree(packet);
Expand Down Expand Up @@ -276,7 +278,7 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
packet->has_sack = 1;

/* It is OK to send this chunk. */
__skb_queue_tail(&packet->chunks, (struct sk_buff *)chunk);
list_add_tail(&chunk->list, &packet->chunk_list);
packet->size += chunk_len;
chunk->transport = packet->transport;
finish:
Expand All @@ -295,7 +297,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
struct sctphdr *sh;
__u32 crc32;
struct sk_buff *nskb;
struct sctp_chunk *chunk;
struct sctp_chunk *chunk, *tmp;
struct sock *sk;
int err = 0;
int padding; /* How much padding do we need? */
Expand All @@ -305,11 +307,11 @@ int sctp_packet_transmit(struct sctp_packet *packet)
SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);

/* Do NOT generate a chunkless packet. */
chunk = (struct sctp_chunk *)skb_peek(&packet->chunks);
if (unlikely(!chunk))
if (list_empty(&packet->chunk_list))
return err;

/* Set up convenience variables... */
chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
sk = chunk->skb->sk;

/* Allocate the new skb. */
Expand Down Expand Up @@ -370,7 +372,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* [This whole comment explains WORD_ROUND() below.]
*/
SCTP_DEBUG_PRINTK("***sctp_transmit_packet***\n");
while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)) != NULL) {
list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
list_del_init(&chunk->list);
if (sctp_chunk_is_data(chunk)) {

if (!chunk->has_tsn) {
Expand Down Expand Up @@ -511,7 +514,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* will get resent or dropped later.
*/

while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)) != NULL) {
list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
list_del_init(&chunk->list);
if (!sctp_chunk_is_data(chunk))
sctp_chunk_free(chunk);
}
Expand Down
Loading

0 comments on commit 79af02c

Please sign in to comment.