Loading include/net/sctp/structs.h +7 −13 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -1017,7 +1011,7 @@ 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. */ Loading @@ -1025,7 +1019,7 @@ struct sctp_outq { 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. Loading Loading @@ -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 * Loading net/sctp/associola.c +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading net/sctp/input.c +16 −10 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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); Loading @@ -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. Loading Loading @@ -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; Loading net/sctp/inqueue.c +12 −6 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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. Loading @@ -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); } Loading Loading @@ -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; Loading net/sctp/output.c +13 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading Loading @@ -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: Loading @@ -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? */ Loading @@ -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. */ Loading Loading @@ -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) { Loading Loading @@ -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); } Loading Loading
include/net/sctp/structs.h +7 −13 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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. */ Loading Loading @@ -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; Loading Loading @@ -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. */ Loading Loading @@ -1017,7 +1011,7 @@ 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. */ Loading @@ -1025,7 +1019,7 @@ struct sctp_outq { 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. Loading Loading @@ -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 * Loading
net/sctp/associola.c +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
net/sctp/input.c +16 −10 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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); Loading @@ -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. Loading Loading @@ -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; Loading
net/sctp/inqueue.c +12 −6 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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. Loading @@ -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); } Loading Loading @@ -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; Loading
net/sctp/output.c +13 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading Loading @@ -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: Loading @@ -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? */ Loading @@ -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. */ Loading Loading @@ -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) { Loading Loading @@ -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); } Loading