patch-2.4.27 linux-2.4.27/net/sctp/output.c
Next file: linux-2.4.27/net/sctp/outqueue.c
Previous file: linux-2.4.27/net/sctp/objcnt.c
Back to the patch index
Back to the overall index
- Lines: 244
- Date:
2004-08-07 16:26:07.094447038 -0700
- Orig file:
linux-2.4.26/net/sctp/output.c
- Orig date:
2004-04-14 06:05:41.000000000 -0700
diff -urN linux-2.4.26/net/sctp/output.c linux-2.4.27/net/sctp/output.c
@@ -62,29 +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)
{
- int packet_empty = (packet->size == SCTP_IP_OVERHEAD);
+ 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 (packet_empty)
- 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;
}
@@ -93,19 +99,30 @@
struct sctp_transport *transport,
__u16 sport, __u16 dport)
{
+ 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;
skb_queue_head_init(&packet->chunks);
- packet->size = SCTP_IP_OVERHEAD;
+ if (asoc) {
+ struct sctp_opt *sp = sctp_sk(asoc->base.sk);
+ overhead = sp->pf->af->net_header_len;
+ } else {
+ overhead = sizeof(struct ipv6hdr);
+ }
+ overhead += sizeof(struct sctphdr);
+ 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;
}
@@ -114,6 +131,8 @@
{
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);
@@ -134,6 +153,9 @@
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) {
@@ -148,7 +170,6 @@
}
break;
- case SCTP_XMIT_MUST_FRAG:
case SCTP_XMIT_RWND_FULL:
case SCTP_XMIT_OK:
case SCTP_XMIT_NAGLE_DELAY:
@@ -201,6 +222,9 @@
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;
@@ -215,17 +239,14 @@
/* Decide if we need to fragment or resubmit later. */
if (too_big) {
- int packet_empty = (packet->size == SCTP_IP_OVERHEAD);
-
/* Both control chunks and data chunks with TSNs are
* non-fragmentable.
*/
- if (packet_empty || !sctp_chunk_is_data(chunk)) {
+ if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk)) {
/* We no longer do re-fragmentation.
* Just fragment at the IP layer, if we
* actually hit this condition
*/
-
packet->ipfragok = 1;
goto append;
@@ -233,9 +254,6 @@
retval = SCTP_XMIT_PMTU_FULL;
goto finish;
}
- } else {
- /* The chunk fits in the packet. */
- goto append;
}
append:
@@ -260,6 +278,7 @@
/* It is OK to send this chunk. */
__skb_queue_tail(&packet->chunks, (struct sk_buff *)chunk);
packet->size += chunk_len;
+ chunk->transport = packet->transport;
finish:
return retval;
}
@@ -283,6 +302,8 @@
__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))
@@ -297,7 +318,7 @@
goto nomem;
/* Make sure the outbound skb has enough header room reserved. */
- skb_reserve(nskb, SCTP_IP_OVERHEAD);
+ skb_reserve(nskb, packet->overhead);
/* Set the owning socket so that we know where to get the
* destination IP address.
@@ -471,7 +492,7 @@
(*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
out:
- packet->size = SCTP_IP_OVERHEAD;
+ packet->size = packet->overhead;
return err;
no_route:
kfree_skb(nskb);
@@ -497,7 +518,6 @@
goto out;
nomem:
err = -ENOMEM;
- printk("%s alloc_skb failed.\n", __FUNCTION__);
goto err;
}
@@ -505,25 +525,6 @@
* 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 = SCTP_IP_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)
@@ -609,7 +610,7 @@
* if any previously transmitted data on the connection remains
* unacknowledged.
*/
- if (!sp->nodelay && SCTP_IP_OVERHEAD == packet->size &&
+ if (!sp->nodelay && sctp_packet_empty(packet) &&
q->outstanding_bytes && sctp_state(asoc, ESTABLISHED)) {
unsigned len = datasize + q->out_qlen;
@@ -617,7 +618,7 @@
* data will fit or delay in hopes of bundling a full
* sized packet.
*/
- if (len < asoc->pmtu - SCTP_IP_OVERHEAD) {
+ if (len < asoc->pmtu - packet->overhead) {
retval = SCTP_XMIT_NAGLE_DELAY;
goto finish;
}
@@ -637,7 +638,8 @@
asoc->peer.rwnd = rwnd;
/* Has been accepted for transmission. */
- chunk->msg->can_expire = 0;
+ if (!asoc->peer.prsctp_capable)
+ chunk->msg->can_abandon = 0;
finish:
return retval;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)