Commit 982f0efd authored by Sridhar Samudrala's avatar Sridhar Samudrala

[SCTP] Cleanup sctp_packet and sctp_outq infrastructure.

parent fe276637
...@@ -346,7 +346,6 @@ typedef enum { ...@@ -346,7 +346,6 @@ typedef enum {
SCTP_XMIT_OK, SCTP_XMIT_OK,
SCTP_XMIT_PMTU_FULL, SCTP_XMIT_PMTU_FULL,
SCTP_XMIT_RWND_FULL, SCTP_XMIT_RWND_FULL,
SCTP_XMIT_MUST_FRAG,
SCTP_XMIT_NAGLE_DELAY, SCTP_XMIT_NAGLE_DELAY,
} sctp_xmit_t; } sctp_xmit_t;
......
...@@ -679,16 +679,6 @@ struct sctp_packet { ...@@ -679,16 +679,6 @@ struct sctp_packet {
*/ */
struct sctp_transport *transport; 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. */ /* This packet contains a COOKIE-ECHO chunk. */
char has_cookie_echo; char has_cookie_echo;
...@@ -701,27 +691,15 @@ struct sctp_packet { ...@@ -701,27 +691,15 @@ struct sctp_packet {
int malloced; int malloced;
}; };
typedef int (sctp_outq_thandler_t)(struct sctp_outq *, void *); struct sctp_packet *sctp_packet_init(struct sctp_packet *,
typedef int (sctp_outq_ehandler_t)(struct sctp_outq *); struct sctp_transport *,
typedef struct sctp_packet *(sctp_outq_ohandler_init_t) __u16 sport, __u16 dport);
(struct sctp_packet *, struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
struct sctp_transport *, sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *,
__u16 sport, struct sctp_chunk *);
__u16 dport); sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *,
typedef struct sctp_packet *(sctp_outq_ohandler_config_t) struct sctp_chunk *);
(struct sctp_packet *, int sctp_packet_transmit(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;
void sctp_packet_free(struct sctp_packet *); void sctp_packet_free(struct sctp_packet *);
static inline int sctp_packet_empty(struct sctp_packet *packet) static inline int sctp_packet_empty(struct sctp_packet *packet)
...@@ -1015,16 +993,6 @@ struct sctp_outq { ...@@ -1015,16 +993,6 @@ struct sctp_outq {
*/ */
struct list_head retransmit; 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? */ /* How many unackd bytes do we have in-flight? */
__u32 outstanding_bytes; __u32 outstanding_bytes;
...@@ -1046,12 +1014,6 @@ int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk); ...@@ -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_flush(struct sctp_outq *, int);
int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *); int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *);
int sctp_outq_is_empty(const struct sctp_outq *); 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_outq_restart(struct sctp_outq *);
void sctp_retransmit(struct sctp_outq *, struct sctp_transport *, void sctp_retransmit(struct sctp_outq *, struct sctp_transport *,
......
...@@ -261,12 +261,6 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc, ...@@ -261,12 +261,6 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
/* Create an output queue. */ /* Create an output queue. */
sctp_outq_init(asoc, &asoc->outqueue); 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)) if (!sctp_ulpq_init(&asoc->ulpq, asoc))
goto fail_init; goto fail_init;
...@@ -482,10 +476,8 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, ...@@ -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 /* The asoc->peer.port might not be meaningful yet, but
* initialize the packet structure anyway. * initialize the packet structure anyway.
*/ */
(asoc->outqueue.init_output)(&peer->packet, sctp_packet_init(&peer->packet, peer, asoc->base.bind_addr.port,
peer, asoc->peer.port);
asoc->base.bind_addr.port,
asoc->peer.port);
/* 7.2.1 Slow-Start /* 7.2.1 Slow-Start
* *
......
...@@ -62,27 +62,35 @@ ...@@ -62,27 +62,35 @@
#include <net/sctp/sm.h> #include <net/sctp/sm.h>
/* Forward declarations for private helpers. */ /* 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, static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
struct sctp_chunk *chunk); struct sctp_chunk *chunk);
/* Config a packet. /* 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, struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
__u32 vtag, int ecn_capable, __u32 vtag, int ecn_capable)
sctp_packet_phandler_t *prepend_handler)
{ {
struct sctp_chunk *chunk = NULL;
SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __FUNCTION__,
packet, vtag);
packet->vtag = vtag; packet->vtag = vtag;
packet->ecn_capable = ecn_capable;
packet->get_prepend_chunk = prepend_handler;
packet->has_cookie_echo = 0; packet->has_cookie_echo = 0;
packet->has_sack = 0; packet->has_sack = 0;
packet->ipfragok = 0; packet->ipfragok = 0;
/* We might need to call the prepend_handler right away. */ if (ecn_capable && sctp_packet_empty(packet)) {
if (sctp_packet_empty(packet)) chunk = sctp_get_ecne_prepend(packet->transport->asoc);
sctp_packet_reset(packet);
/* 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; return packet;
} }
...@@ -94,6 +102,9 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, ...@@ -94,6 +102,9 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
struct sctp_association *asoc = transport->asoc; struct sctp_association *asoc = transport->asoc;
size_t overhead; size_t overhead;
SCTP_DEBUG_PRINTK("%s: packet:%p transport:%p\n", __FUNCTION__,
packet, transport);
packet->transport = transport; packet->transport = transport;
packet->source_port = sport; packet->source_port = sport;
packet->destination_port = dport; packet->destination_port = dport;
...@@ -108,13 +119,10 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, ...@@ -108,13 +119,10 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
packet->overhead = overhead; packet->overhead = overhead;
packet->size = overhead; packet->size = overhead;
packet->vtag = 0; packet->vtag = 0;
packet->ecn_capable = 0;
packet->get_prepend_chunk = NULL;
packet->has_cookie_echo = 0; packet->has_cookie_echo = 0;
packet->has_sack = 0; packet->has_sack = 0;
packet->ipfragok = 0; packet->ipfragok = 0;
packet->malloced = 0; packet->malloced = 0;
sctp_packet_reset(packet);
return packet; return packet;
} }
...@@ -123,6 +131,8 @@ void sctp_packet_free(struct sctp_packet *packet) ...@@ -123,6 +131,8 @@ void sctp_packet_free(struct sctp_packet *packet)
{ {
struct sctp_chunk *chunk; struct sctp_chunk *chunk;
SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);
while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks))) while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)))
sctp_chunk_free(chunk); sctp_chunk_free(chunk);
...@@ -143,6 +153,9 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, ...@@ -143,6 +153,9 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
sctp_xmit_t retval; sctp_xmit_t retval;
int error = 0; int error = 0;
SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__,
packet, chunk);
switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) { switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) {
case SCTP_XMIT_PMTU_FULL: case SCTP_XMIT_PMTU_FULL:
if (!packet->has_cookie_echo) { if (!packet->has_cookie_echo) {
...@@ -157,7 +170,6 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet, ...@@ -157,7 +170,6 @@ sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
} }
break; break;
case SCTP_XMIT_MUST_FRAG:
case SCTP_XMIT_RWND_FULL: case SCTP_XMIT_RWND_FULL:
case SCTP_XMIT_OK: case SCTP_XMIT_OK:
case SCTP_XMIT_NAGLE_DELAY: case SCTP_XMIT_NAGLE_DELAY:
...@@ -210,6 +222,9 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, ...@@ -210,6 +222,9 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
size_t pmtu; size_t pmtu;
int too_big; int too_big;
SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__, packet,
chunk);
retval = sctp_packet_bundle_sack(packet, chunk); retval = sctp_packet_bundle_sack(packet, chunk);
psize = packet->size; psize = packet->size;
...@@ -239,9 +254,6 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, ...@@ -239,9 +254,6 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
retval = SCTP_XMIT_PMTU_FULL; retval = SCTP_XMIT_PMTU_FULL;
goto finish; goto finish;
} }
} else {
/* The chunk fits in the packet. */
goto append;
} }
append: append:
...@@ -289,6 +301,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) ...@@ -289,6 +301,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
__u8 has_data = 0; __u8 has_data = 0;
struct dst_entry *dst; struct dst_entry *dst;
SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);
/* Do NOT generate a chunkless packet. */ /* Do NOT generate a chunkless packet. */
chunk = (struct sctp_chunk *)skb_peek(&packet->chunks); chunk = (struct sctp_chunk *)skb_peek(&packet->chunks);
if (unlikely(!chunk)) if (unlikely(!chunk))
...@@ -510,25 +524,6 @@ int sctp_packet_transmit(struct sctp_packet *packet) ...@@ -510,25 +524,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
* 2nd Level Abstractions * 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. */ /* This private function handles the specifics of appending DATA chunks. */
static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
struct sctp_chunk *chunk) struct sctp_chunk *chunk)
......
...@@ -223,12 +223,6 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) ...@@ -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->retransmit);
INIT_LIST_HEAD(&q->sacked); 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->outstanding_bytes = 0;
q->empty = 1; q->empty = 1;
q->cork = 0; q->cork = 0;
...@@ -552,12 +546,12 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, ...@@ -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. */ /* Attempt to append this chunk to the packet. */
status = (*q->append_output)(pkt, chunk); status = sctp_packet_append_chunk(pkt, chunk);
switch (status) { switch (status) {
case SCTP_XMIT_PMTU_FULL: case SCTP_XMIT_PMTU_FULL:
/* Send this packet. */ /* Send this packet. */
if ((error = (*q->force_output)(pkt)) == 0) if ((error = sctp_packet_transmit(pkt)) == 0)
*start_timer = 1; *start_timer = 1;
/* If we are retransmitting, we should only /* 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, ...@@ -573,7 +567,7 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
case SCTP_XMIT_RWND_FULL: case SCTP_XMIT_RWND_FULL:
/* Send this packet. */ /* Send this packet. */
if ((error = (*q->force_output)(pkt)) == 0) if ((error = sctp_packet_transmit(pkt)) == 0)
*start_timer = 1; *start_timer = 1;
/* Stop sending DATA as there is no more room /* 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, ...@@ -583,6 +577,16 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
lchunk = NULL; lchunk = NULL;
break; 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: default:
/* The append was successful, so add this chunk to /* The append was successful, so add this chunk to
* the transmitted list. * the transmitted list.
...@@ -625,13 +629,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -625,13 +629,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
struct sctp_packet *packet; struct sctp_packet *packet;
struct sctp_packet singleton; struct sctp_packet singleton;
struct sctp_association *asoc = q->asoc; struct sctp_association *asoc = q->asoc;
int ecn_capable = asoc->peer.ecn_capable;
__u16 sport = asoc->base.bind_addr.port; __u16 sport = asoc->base.bind_addr.port;
__u16 dport = asoc->peer.port; __u16 dport = asoc->peer.port;
__u32 vtag = asoc->peer.i.init_tag; __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 sk_buff_head *queue;
struct sctp_transport *transport = NULL; struct sctp_transport *transport = NULL;
struct sctp_transport *new_transport; struct sctp_transport *new_transport;
...@@ -656,10 +656,6 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -656,10 +656,6 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
* within a SCTP packet in increasing order of TSN. * 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; queue = &q->control;
while ((chunk = (struct sctp_chunk *)skb_dequeue(queue))) { while ((chunk = (struct sctp_chunk *)skb_dequeue(queue))) {
...@@ -686,8 +682,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -686,8 +682,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
&transport_list); &transport_list);
} }
packet = &transport->packet; packet = &transport->packet;
(*q->config_output)(packet, vtag, sctp_packet_config(packet, vtag,
ecn_capable, ecne_handler); asoc->peer.ecn_capable);
} }
switch (chunk->chunk_hdr->type) { switch (chunk->chunk_hdr->type) {
...@@ -700,11 +696,10 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -700,11 +696,10 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
case SCTP_CID_INIT: case SCTP_CID_INIT:
case SCTP_CID_INIT_ACK: case SCTP_CID_INIT_ACK:
case SCTP_CID_SHUTDOWN_COMPLETE: case SCTP_CID_SHUTDOWN_COMPLETE:
(*q->init_output)(&singleton, transport, sport, dport); sctp_packet_init(&singleton, transport, sport, dport);
(*q->config_output)(&singleton, vtag, ecn_capable, sctp_packet_config(&singleton, vtag, 0);
s_ecne_handler); sctp_packet_append_chunk(&singleton, chunk);
(void) (*q->build_output)(&singleton, chunk); error = sctp_packet_transmit(&singleton);
error = (*q->force_output)(&singleton);
if (error < 0) if (error < 0)
return error; return error;
break; break;
...@@ -720,12 +715,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -720,12 +715,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
case SCTP_CID_COOKIE_ACK: case SCTP_CID_COOKIE_ACK:
case SCTP_CID_ECN_ECNE: case SCTP_CID_ECN_ECNE:
case SCTP_CID_ECN_CWR: case SCTP_CID_ECN_CWR:
(void) (*q->build_output)(packet, chunk);
break;
case SCTP_CID_ASCONF: case SCTP_CID_ASCONF:
case SCTP_CID_ASCONF_ACK: case SCTP_CID_ASCONF_ACK:
(void) (*q->build_output)(packet, chunk); sctp_packet_transmit_chunk(packet, chunk);
break; break;
default: default:
...@@ -770,8 +762,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -770,8 +762,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
} }
packet = &transport->packet; packet = &transport->packet;
(*q->config_output)(packet, vtag, sctp_packet_config(packet, vtag,
ecn_capable, ecne_handler); asoc->peer.ecn_capable);
retran: retran:
error = sctp_outq_flush_rtx(q, packet, error = sctp_outq_flush_rtx(q, packet,
rtx_timeout, &start_timer); rtx_timeout, &start_timer);
...@@ -836,11 +828,11 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -836,11 +828,11 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
} }
packet = &transport->packet; packet = &transport->packet;
(*q->config_output)(packet, vtag, sctp_packet_config(packet, vtag,
ecn_capable, ecne_handler); asoc->peer.ecn_capable);
} }
SCTP_DEBUG_PRINTK("sctp_transmit_packet(%p, %p[%s]), ", SCTP_DEBUG_PRINTK("sctp_outq_flush(%p, %p[%s]), ",
q, chunk, q, chunk,
chunk && chunk->chunk_hdr ? chunk && chunk->chunk_hdr ?
sctp_cname(SCTP_ST_CHUNK( sctp_cname(SCTP_ST_CHUNK(
...@@ -855,7 +847,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -855,7 +847,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
atomic_read(&chunk->skb->users) : -1); atomic_read(&chunk->skb->users) : -1);
/* Add the chunk to the packet. */ /* Add the chunk to the packet. */
status = (*q->build_output)(packet, chunk); status = sctp_packet_transmit_chunk(packet, chunk);
switch (status) { switch (status) {
case SCTP_XMIT_PMTU_FULL: case SCTP_XMIT_PMTU_FULL:
...@@ -879,7 +871,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -879,7 +871,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
BUG(); 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 * call below will succeed all the time and add the
* chunk to the transmitted list and restart the * chunk to the transmitted list and restart the
* timers. * timers.
...@@ -922,33 +914,14 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) ...@@ -922,33 +914,14 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
struct sctp_transport *t = list_entry(ltransport, struct sctp_transport *t = list_entry(ltransport,
struct sctp_transport, struct sctp_transport,
send_ready); send_ready);
if (t != transport) packet = &t->packet;
transport = t;
packet = &transport->packet;
if (!sctp_packet_empty(packet)) if (!sctp_packet_empty(packet))
error = (*q->force_output)(packet); error = sctp_packet_transmit(packet);
} }
return error; 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 */ /* Update unack_data based on the incoming SACK chunk */
static void sctp_sack_update_unack_data(struct sctp_association *assoc, static void sctp_sack_update_unack_data(struct sctp_association *assoc,
struct sctp_sackhdr *sack) struct sctp_sackhdr *sack)
......
...@@ -4671,28 +4671,20 @@ struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc, ...@@ -4671,28 +4671,20 @@ struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
/* Make a transport for the bucket, Eliza... */ /* Make a transport for the bucket, Eliza... */
transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC); transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC);
if (!transport) if (!transport)
goto nomem; 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 /* Cache a route for the transport with the chunk's destination as
* the source address. * the source address.
*/ */
sctp_transport_route(transport, (union sctp_addr *)&chunk->dest, sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
sctp_sk(sctp_get_ctl_sock())); sctp_sk(sctp_get_ctl_sock()));
packet = sctp_packet_init(packet, transport, sport, dport); packet = sctp_packet_init(&transport->packet, transport, sport, dport);
packet = sctp_packet_config(packet, vtag, 0, NULL); packet = sctp_packet_config(packet, vtag, 0);
return packet; return packet;
nomem_packet:
sctp_transport_free(transport);
nomem: nomem:
return NULL; return NULL;
} }
...@@ -4701,7 +4693,6 @@ struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc, ...@@ -4701,7 +4693,6 @@ struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
void sctp_ootb_pkt_free(struct sctp_packet *packet) void sctp_ootb_pkt_free(struct sctp_packet *packet)
{ {
sctp_transport_free(packet->transport); sctp_transport_free(packet->transport);
sctp_packet_free(packet);
} }
/* Send a stale cookie error when a invalid COOKIE ECHO chunk is found */ /* Send a stale cookie error when a invalid COOKIE ECHO chunk is found */
......
...@@ -118,7 +118,6 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, ...@@ -118,7 +118,6 @@ struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
INIT_LIST_HEAD(&peer->transmitted); INIT_LIST_HEAD(&peer->transmitted);
INIT_LIST_HEAD(&peer->send_ready); INIT_LIST_HEAD(&peer->send_ready);
INIT_LIST_HEAD(&peer->transports); INIT_LIST_HEAD(&peer->transports);
sctp_packet_init(&peer->packet, peer, 0, 0);
/* Set up the retransmission timer. */ /* Set up the retransmission timer. */
init_timer(&peer->T3_rtx_timer); init_timer(&peer->T3_rtx_timer);
...@@ -169,6 +168,8 @@ void sctp_transport_destroy(struct sctp_transport *transport) ...@@ -169,6 +168,8 @@ void sctp_transport_destroy(struct sctp_transport *transport)
if (transport->asoc) if (transport->asoc)
sctp_association_put(transport->asoc); sctp_association_put(transport->asoc);
sctp_packet_free(&transport->packet);
dst_release(transport->dst); dst_release(transport->dst);
kfree(transport); kfree(transport);
SCTP_DBG_OBJCNT_DEC(transport); SCTP_DBG_OBJCNT_DEC(transport);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment