]> git.hungrycats.org Git - linux/commitdiff
[SCTP] Cleanup sctp_packet and sctp_outq infrastructure.
authorSridhar Samudrala <sri@us.ibm.com>
Mon, 19 Apr 2004 03:46:21 +0000 (20:46 -0700)
committerSridhar Samudrala <sri@us.ibm.com>
Mon, 19 Apr 2004 03:46:21 +0000 (20:46 -0700)
include/net/sctp/constants.h
include/net/sctp/structs.h
net/sctp/associola.c
net/sctp/output.c
net/sctp/outqueue.c
net/sctp/sm_statefuns.c
net/sctp/transport.c

index 3a5ad29201f876f2b6f2f000bd848bd18596e85c..fe40983df1b0debce3baf4abd42afb58cb65f400 100644 (file)
@@ -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;
 
index 1731d02dc83773a4759f728ce195308a168d13e3..0b7717a84ea6b69fd09699d9a0a4b7d0e1aa3cb3 100644 (file)
@@ -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 *,
index be9b31287b0ebb35742ff27baab57843be62231c..04cd2812dedafd19d8c29b5bdd27847cae42109c 100644 (file)
@@ -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
         *
index 3205cc30e45b3054545e66c9e1aa326db8c05c22..5f525f22f4fc5c355c0e0a4935beb92d90cea28d 100644 (file)
 #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)
index 6676a6e901c1455a84b024efdb9fc3d670fac842..f087dcc3003e021d66ccd31c7257ff1ec8e10862 100644 (file)
@@ -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)
index c6d52301a6b0804349380c52325f5146b776603d..474afa4b330ccfcba6d0dfd3e5be1dbdff5a7511 100644 (file)
@@ -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  */
index 026ffebb61d47b812ef88222226605095c300fbe..198ab7662c2e83cf44c4491276882d68eb94e1f6 100644 (file)
@@ -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);