diff options
| author | Sridhar Samudrala <sri@us.ibm.com> | 2004-04-18 20:46:21 -0700 |
|---|---|---|
| committer | Sridhar Samudrala <sri@us.ibm.com> | 2004-04-18 20:46:21 -0700 |
| commit | 982f0efd698f3a93257aab8fc50d002e46611e21 (patch) | |
| tree | 2e650a2e16691f872d07bbd36a1b424fe63a5647 | |
| parent | fe27663798f93789f23b7bcafcb5f8c9da09ec17 (diff) | |
[SCTP] Cleanup sctp_packet and sctp_outq infrastructure.
| -rw-r--r-- | include/net/sctp/constants.h | 1 | ||||
| -rw-r--r-- | include/net/sctp/structs.h | 56 | ||||
| -rw-r--r-- | net/sctp/associola.c | 12 | ||||
| -rw-r--r-- | net/sctp/output.c | 65 | ||||
| -rw-r--r-- | net/sctp/outqueue.c | 85 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 13 | ||||
| -rw-r--r-- | net/sctp/transport.c | 3 |
7 files changed, 74 insertions, 161 deletions
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 3a5ad29201f8..fe40983df1b0 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -346,7 +346,6 @@ typedef enum { SCTP_XMIT_OK, SCTP_XMIT_PMTU_FULL, SCTP_XMIT_RWND_FULL, - SCTP_XMIT_MUST_FRAG, SCTP_XMIT_NAGLE_DELAY, } sctp_xmit_t; diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 1731d02dc837..0b7717a84ea6 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -679,16 +679,6 @@ struct sctp_packet { */ struct sctp_transport *transport; - /* Allow a callback for getting a high priority chunk - * bundled early into the packet (This is used for ECNE). - */ - sctp_packet_phandler_t *get_prepend_chunk; - - /* This packet should advertise ECN capability to the network - * via the ECT bit. - */ - char ecn_capable; - /* This packet contains a COOKIE-ECHO chunk. */ char has_cookie_echo; @@ -701,27 +691,15 @@ struct sctp_packet { int malloced; }; -typedef int (sctp_outq_thandler_t)(struct sctp_outq *, void *); -typedef int (sctp_outq_ehandler_t)(struct sctp_outq *); -typedef struct sctp_packet *(sctp_outq_ohandler_init_t) - (struct sctp_packet *, - struct sctp_transport *, - __u16 sport, - __u16 dport); -typedef struct sctp_packet *(sctp_outq_ohandler_config_t) - (struct sctp_packet *, - __u32 vtag, - int ecn_capable, - sctp_packet_phandler_t *get_prepend_chunk); -typedef sctp_xmit_t (sctp_outq_ohandler_t)(struct sctp_packet *, - struct sctp_chunk *); -typedef int (sctp_outq_ohandler_force_t)(struct sctp_packet *); - -sctp_outq_ohandler_init_t sctp_packet_init; -sctp_outq_ohandler_config_t sctp_packet_config; -sctp_outq_ohandler_t sctp_packet_append_chunk; -sctp_outq_ohandler_t sctp_packet_transmit_chunk; -sctp_outq_ohandler_force_t sctp_packet_transmit; +struct sctp_packet *sctp_packet_init(struct sctp_packet *, + struct sctp_transport *, + __u16 sport, __u16 dport); +struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int); +sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *, + struct sctp_chunk *); +sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *, + struct sctp_chunk *); +int sctp_packet_transmit(struct sctp_packet *); void sctp_packet_free(struct sctp_packet *); static inline int sctp_packet_empty(struct sctp_packet *packet) @@ -1015,16 +993,6 @@ struct sctp_outq { */ struct list_head retransmit; - /* Call these functions to send chunks down to the next lower - * layer. This is always sctp_packet, but we separate the two - * structures to make testing simpler. - */ - sctp_outq_ohandler_init_t *init_output; - sctp_outq_ohandler_config_t *config_output; - sctp_outq_ohandler_t *append_output; - sctp_outq_ohandler_t *build_output; - sctp_outq_ohandler_force_t *force_output; - /* How many unackd bytes do we have in-flight? */ __u32 outstanding_bytes; @@ -1046,12 +1014,6 @@ int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk); int sctp_outq_flush(struct sctp_outq *, int); int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *); int sctp_outq_is_empty(const struct sctp_outq *); -int sctp_outq_set_output_handlers(struct sctp_outq *, - sctp_outq_ohandler_init_t init, - sctp_outq_ohandler_config_t config, - sctp_outq_ohandler_t append, - sctp_outq_ohandler_t build, - sctp_outq_ohandler_force_t force); void sctp_outq_restart(struct sctp_outq *); void sctp_retransmit(struct sctp_outq *, struct sctp_transport *, diff --git a/net/sctp/associola.c b/net/sctp/associola.c index be9b31287b0e..04cd2812deda 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -261,12 +261,6 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc, /* Create an output queue. */ sctp_outq_init(asoc, &asoc->outqueue); - sctp_outq_set_output_handlers(&asoc->outqueue, - sctp_packet_init, - sctp_packet_config, - sctp_packet_append_chunk, - sctp_packet_transmit_chunk, - sctp_packet_transmit); if (!sctp_ulpq_init(&asoc->ulpq, asoc)) goto fail_init; @@ -482,10 +476,8 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, /* The asoc->peer.port might not be meaningful yet, but * initialize the packet structure anyway. */ - (asoc->outqueue.init_output)(&peer->packet, - peer, - asoc->base.bind_addr.port, - asoc->peer.port); + sctp_packet_init(&peer->packet, peer, asoc->base.bind_addr.port, + asoc->peer.port); /* 7.2.1 Slow-Start * diff --git a/net/sctp/output.c b/net/sctp/output.c index 3205cc30e45b..5f525f22f4fc 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -62,27 +62,35 @@ #include <net/sctp/sm.h> /* Forward declarations for private helpers. */ -static void sctp_packet_reset(struct sctp_packet *packet); static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, struct sctp_chunk *chunk); /* Config a packet. - * This appears to be a followup set of initializations.) + * This appears to be a followup set of initializations. */ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet, - __u32 vtag, int ecn_capable, - sctp_packet_phandler_t *prepend_handler) + __u32 vtag, int ecn_capable) { + struct sctp_chunk *chunk = NULL; + + SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __FUNCTION__, + packet, vtag); + packet->vtag = vtag; - packet->ecn_capable = ecn_capable; - packet->get_prepend_chunk = prepend_handler; packet->has_cookie_echo = 0; packet->has_sack = 0; packet->ipfragok = 0; - /* We might need to call the prepend_handler right away. */ - if (sctp_packet_empty(packet)) - sctp_packet_reset(packet); + if (ecn_capable && sctp_packet_empty(packet)) { + chunk = sctp_get_ecne_prepend(packet->transport->asoc); + + /* If there a is a prepend chunk stick it on the list before + * any other chunks get appended. + */ + if (chunk) + sctp_packet_append_chunk(packet, chunk); + } + return packet; } @@ -94,6 +102,9 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, struct sctp_association *asoc = transport->asoc; size_t overhead; + SCTP_DEBUG_PRINTK("%s: packet:%p transport:%p\n", __FUNCTION__, + packet, transport); + packet->transport = transport; packet->source_port = sport; packet->destination_port = dport; @@ -108,13 +119,10 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, packet->overhead = overhead; packet->size = overhead; packet->vtag = 0; - packet->ecn_capable = 0; - packet->get_prepend_chunk = NULL; packet->has_cookie_echo = 0; packet->has_sack = 0; packet->ipfragok = 0; packet->malloced = 0; - sctp_packet_reset(packet); return packet; } @@ -123,6 +131,8 @@ void sctp_packet_free(struct sctp_packet *packet) { struct sctp_chunk *chunk; + SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); + while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks))) sctp_chunk_free(chunk); @@ -143,6 +153,9 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, sctp_xmit_t retval; int error = 0; + SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__, + packet, chunk); + switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) { case SCTP_XMIT_PMTU_FULL: if (!packet->has_cookie_echo) { @@ -157,7 +170,6 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, } break; - case SCTP_XMIT_MUST_FRAG: case SCTP_XMIT_RWND_FULL: case SCTP_XMIT_OK: case SCTP_XMIT_NAGLE_DELAY: @@ -210,6 +222,9 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, size_t pmtu; int too_big; + SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__, packet, + chunk); + retval = sctp_packet_bundle_sack(packet, chunk); psize = packet->size; @@ -239,9 +254,6 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, retval = SCTP_XMIT_PMTU_FULL; goto finish; } - } else { - /* The chunk fits in the packet. */ - goto append; } append: @@ -289,6 +301,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) __u8 has_data = 0; struct dst_entry *dst; + 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)) @@ -510,25 +524,6 @@ nomem: * 2nd Level Abstractions ********************************************************************/ -/* - * This private function resets the packet to a fresh state. - */ -static void sctp_packet_reset(struct sctp_packet *packet) -{ - struct sctp_chunk *chunk = NULL; - - packet->size = packet->overhead; - - if (packet->get_prepend_chunk) - chunk = packet->get_prepend_chunk(packet->transport->asoc); - - /* If there a is a prepend chunk stick it on the list before - * any other chunks get appended. - */ - if (chunk) - sctp_packet_append_chunk(packet, chunk); -} - /* This private function handles the specifics of appending DATA chunks. */ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, struct sctp_chunk *chunk) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 6676a6e901c1..f087dcc3003e 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -223,12 +223,6 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) INIT_LIST_HEAD(&q->retransmit); INIT_LIST_HEAD(&q->sacked); - q->init_output = NULL; - q->config_output = NULL; - q->append_output = NULL; - q->build_output = NULL; - q->force_output = NULL; - q->outstanding_bytes = 0; q->empty = 1; q->cork = 0; @@ -552,12 +546,12 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, } /* Attempt to append this chunk to the packet. */ - status = (*q->append_output)(pkt, chunk); + status = sctp_packet_append_chunk(pkt, chunk); switch (status) { case SCTP_XMIT_PMTU_FULL: /* Send this packet. */ - if ((error = (*q->force_output)(pkt)) == 0) + if ((error = sctp_packet_transmit(pkt)) == 0) *start_timer = 1; /* If we are retransmitting, we should only @@ -573,7 +567,7 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, case SCTP_XMIT_RWND_FULL: /* Send this packet. */ - if ((error = (*q->force_output)(pkt)) == 0) + if ((error = sctp_packet_transmit(pkt)) == 0) *start_timer = 1; /* Stop sending DATA as there is no more room @@ -583,6 +577,16 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, lchunk = NULL; break; + case SCTP_XMIT_NAGLE_DELAY: + /* Send this packet. */ + if ((error = sctp_packet_transmit(pkt)) == 0) + *start_timer = 1; + + /* Stop sending DATA because of nagle delay. */ + list_add(lchunk, lqueue); + lchunk = NULL; + break; + default: /* The append was successful, so add this chunk to * the transmitted list. @@ -625,13 +629,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) struct sctp_packet *packet; struct sctp_packet singleton; struct sctp_association *asoc = q->asoc; - int ecn_capable = asoc->peer.ecn_capable; __u16 sport = asoc->base.bind_addr.port; __u16 dport = asoc->peer.port; __u32 vtag = asoc->peer.i.init_tag; - /* This is the ECNE handler for singleton packets. */ - sctp_packet_phandler_t *s_ecne_handler = NULL; - sctp_packet_phandler_t *ecne_handler = NULL; struct sk_buff_head *queue; struct sctp_transport *transport = NULL; struct sctp_transport *new_transport; @@ -656,10 +656,6 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) * within a SCTP packet in increasing order of TSN. * ... */ - if (ecn_capable) { - s_ecne_handler = &sctp_get_no_prepend; - ecne_handler = &sctp_get_ecne_prepend; - } queue = &q->control; while ((chunk = (struct sctp_chunk *)skb_dequeue(queue))) { @@ -686,8 +682,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) &transport_list); } packet = &transport->packet; - (*q->config_output)(packet, vtag, - ecn_capable, ecne_handler); + sctp_packet_config(packet, vtag, + asoc->peer.ecn_capable); } switch (chunk->chunk_hdr->type) { @@ -700,11 +696,10 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) case SCTP_CID_INIT: case SCTP_CID_INIT_ACK: case SCTP_CID_SHUTDOWN_COMPLETE: - (*q->init_output)(&singleton, transport, sport, dport); - (*q->config_output)(&singleton, vtag, ecn_capable, - s_ecne_handler); - (void) (*q->build_output)(&singleton, chunk); - error = (*q->force_output)(&singleton); + sctp_packet_init(&singleton, transport, sport, dport); + sctp_packet_config(&singleton, vtag, 0); + sctp_packet_append_chunk(&singleton, chunk); + error = sctp_packet_transmit(&singleton); if (error < 0) return error; break; @@ -720,12 +715,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) case SCTP_CID_COOKIE_ACK: case SCTP_CID_ECN_ECNE: case SCTP_CID_ECN_CWR: - (void) (*q->build_output)(packet, chunk); - break; - case SCTP_CID_ASCONF: case SCTP_CID_ASCONF_ACK: - (void) (*q->build_output)(packet, chunk); + sctp_packet_transmit_chunk(packet, chunk); break; default: @@ -770,8 +762,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) } packet = &transport->packet; - (*q->config_output)(packet, vtag, - ecn_capable, ecne_handler); + sctp_packet_config(packet, vtag, + asoc->peer.ecn_capable); retran: error = sctp_outq_flush_rtx(q, packet, rtx_timeout, &start_timer); @@ -836,11 +828,11 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) } packet = &transport->packet; - (*q->config_output)(packet, vtag, - ecn_capable, ecne_handler); + sctp_packet_config(packet, vtag, + asoc->peer.ecn_capable); } - SCTP_DEBUG_PRINTK("sctp_transmit_packet(%p, %p[%s]), ", + SCTP_DEBUG_PRINTK("sctp_outq_flush(%p, %p[%s]), ", q, chunk, chunk && chunk->chunk_hdr ? sctp_cname(SCTP_ST_CHUNK( @@ -855,7 +847,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) atomic_read(&chunk->skb->users) : -1); /* Add the chunk to the packet. */ - status = (*q->build_output)(packet, chunk); + status = sctp_packet_transmit_chunk(packet, chunk); switch (status) { case SCTP_XMIT_PMTU_FULL: @@ -879,7 +871,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) BUG(); } - /* BUG: We assume that the (*q->force_output()) + /* BUG: We assume that the sctp_packet_transmit() * call below will succeed all the time and add the * chunk to the transmitted list and restart the * timers. @@ -922,33 +914,14 @@ sctp_flush_out: struct sctp_transport *t = list_entry(ltransport, struct sctp_transport, send_ready); - if (t != transport) - transport = t; - - packet = &transport->packet; + packet = &t->packet; if (!sctp_packet_empty(packet)) - error = (*q->force_output)(packet); + error = sctp_packet_transmit(packet); } return error; } -/* Set the various output handling callbacks. */ -int sctp_outq_set_output_handlers(struct sctp_outq *q, - sctp_outq_ohandler_init_t init, - sctp_outq_ohandler_config_t config, - sctp_outq_ohandler_t append, - sctp_outq_ohandler_t build, - sctp_outq_ohandler_force_t force) -{ - q->init_output = init; - q->config_output = config; - q->append_output = append; - q->build_output = build; - q->force_output = force; - return 0; -} - /* Update unack_data based on the incoming SACK chunk */ static void sctp_sack_update_unack_data(struct sctp_association *assoc, struct sctp_sackhdr *sack) diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index c6d52301a6b0..474afa4b330c 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -4671,28 +4671,20 @@ struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc, /* Make a transport for the bucket, Eliza... */ transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC); - if (!transport) goto nomem; - /* Allocate a new packet for sending the response. */ - packet = t_new(struct sctp_packet, GFP_ATOMIC); - if (!packet) - goto nomem_packet; - /* Cache a route for the transport with the chunk's destination as * the source address. */ sctp_transport_route(transport, (union sctp_addr *)&chunk->dest, sctp_sk(sctp_get_ctl_sock())); - packet = sctp_packet_init(packet, transport, sport, dport); - packet = sctp_packet_config(packet, vtag, 0, NULL); + packet = sctp_packet_init(&transport->packet, transport, sport, dport); + packet = sctp_packet_config(packet, vtag, 0); return packet; -nomem_packet: - sctp_transport_free(transport); nomem: return NULL; } @@ -4701,7 +4693,6 @@ nomem: void sctp_ootb_pkt_free(struct sctp_packet *packet) { sctp_transport_free(packet->transport); - sctp_packet_free(packet); } /* Send a stale cookie error when a invalid COOKIE ECHO chunk is found */ diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 026ffebb61d4..198ab7662c2e 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -118,7 +118,6 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, INIT_LIST_HEAD(&peer->transmitted); INIT_LIST_HEAD(&peer->send_ready); INIT_LIST_HEAD(&peer->transports); - sctp_packet_init(&peer->packet, peer, 0, 0); /* Set up the retransmission timer. */ init_timer(&peer->T3_rtx_timer); @@ -169,6 +168,8 @@ void sctp_transport_destroy(struct sctp_transport *transport) if (transport->asoc) sctp_association_put(transport->asoc); + sctp_packet_free(&transport->packet); + dst_release(transport->dst); kfree(transport); SCTP_DBG_OBJCNT_DEC(transport); |
