aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/output.c')
-rw-r--r--net/sctp/output.c233
1 files changed, 136 insertions, 97 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c
index c3f417f7ec6e..5cbda8f1ddfd 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -49,13 +49,10 @@
49#include <linux/ipv6.h> 49#include <linux/ipv6.h>
50#include <linux/init.h> 50#include <linux/init.h>
51#include <net/inet_ecn.h> 51#include <net/inet_ecn.h>
52#include <net/ip.h>
52#include <net/icmp.h> 53#include <net/icmp.h>
53#include <net/net_namespace.h> 54#include <net/net_namespace.h>
54 55
55#ifndef TEST_FRAME
56#include <net/tcp.h>
57#endif /* TEST_FRAME (not defined) */
58
59#include <linux/socket.h> /* for sa_family_t */ 56#include <linux/socket.h> /* for sa_family_t */
60#include <net/sock.h> 57#include <net/sock.h>
61 58
@@ -64,8 +61,24 @@
64#include <net/sctp/checksum.h> 61#include <net/sctp/checksum.h>
65 62
66/* Forward declarations for private helpers. */ 63/* Forward declarations for private helpers. */
67static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, 64static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
65 struct sctp_chunk *chunk);
66static void sctp_packet_append_data(struct sctp_packet *packet,
68 struct sctp_chunk *chunk); 67 struct sctp_chunk *chunk);
68static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet,
69 struct sctp_chunk *chunk,
70 u16 chunk_len);
71
72static void sctp_packet_reset(struct sctp_packet *packet)
73{
74 packet->size = packet->overhead;
75 packet->has_cookie_echo = 0;
76 packet->has_sack = 0;
77 packet->has_data = 0;
78 packet->has_auth = 0;
79 packet->ipfragok = 0;
80 packet->auth = NULL;
81}
69 82
70/* Config a packet. 83/* Config a packet.
71 * This appears to be a followup set of initializations. 84 * This appears to be a followup set of initializations.
@@ -78,13 +91,8 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
78 SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__, 91 SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__,
79 packet, vtag); 92 packet, vtag);
80 93
94 sctp_packet_reset(packet);
81 packet->vtag = vtag; 95 packet->vtag = vtag;
82 packet->has_cookie_echo = 0;
83 packet->has_sack = 0;
84 packet->has_auth = 0;
85 packet->has_data = 0;
86 packet->ipfragok = 0;
87 packet->auth = NULL;
88 96
89 if (ecn_capable && sctp_packet_empty(packet)) { 97 if (ecn_capable && sctp_packet_empty(packet)) {
90 chunk = sctp_get_ecne_prepend(packet->transport->asoc); 98 chunk = sctp_get_ecne_prepend(packet->transport->asoc);
@@ -122,15 +130,9 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
122 } 130 }
123 overhead += sizeof(struct sctphdr); 131 overhead += sizeof(struct sctphdr);
124 packet->overhead = overhead; 132 packet->overhead = overhead;
125 packet->size = overhead; 133 sctp_packet_reset(packet);
126 packet->vtag = 0; 134 packet->vtag = 0;
127 packet->has_cookie_echo = 0;
128 packet->has_sack = 0;
129 packet->has_auth = 0;
130 packet->has_data = 0;
131 packet->ipfragok = 0;
132 packet->malloced = 0; 135 packet->malloced = 0;
133 packet->auth = NULL;
134 return packet; 136 return packet;
135} 137}
136 138
@@ -207,7 +209,7 @@ static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt,
207 /* See if this is an auth chunk we are bundling or if 209 /* See if this is an auth chunk we are bundling or if
208 * auth is already bundled. 210 * auth is already bundled.
209 */ 211 */
210 if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->auth) 212 if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->has_auth)
211 return retval; 213 return retval;
212 214
213 /* if the peer did not request this chunk to be authenticated, 215 /* if the peer did not request this chunk to be authenticated,
@@ -237,18 +239,19 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt,
237 if (sctp_chunk_is_data(chunk) && !pkt->has_sack && 239 if (sctp_chunk_is_data(chunk) && !pkt->has_sack &&
238 !pkt->has_cookie_echo) { 240 !pkt->has_cookie_echo) {
239 struct sctp_association *asoc; 241 struct sctp_association *asoc;
242 struct timer_list *timer;
240 asoc = pkt->transport->asoc; 243 asoc = pkt->transport->asoc;
244 timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
241 245
242 if (asoc->a_rwnd > asoc->rwnd) { 246 /* If the SACK timer is running, we have a pending SACK */
247 if (timer_pending(timer)) {
243 struct sctp_chunk *sack; 248 struct sctp_chunk *sack;
244 asoc->a_rwnd = asoc->rwnd; 249 asoc->a_rwnd = asoc->rwnd;
245 sack = sctp_make_sack(asoc); 250 sack = sctp_make_sack(asoc);
246 if (sack) { 251 if (sack) {
247 struct timer_list *timer;
248 retval = sctp_packet_append_chunk(pkt, sack); 252 retval = sctp_packet_append_chunk(pkt, sack);
249 asoc->peer.sack_needed = 0; 253 asoc->peer.sack_needed = 0;
250 timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK]; 254 if (del_timer(timer))
251 if (timer_pending(timer) && del_timer(timer))
252 sctp_association_put(asoc); 255 sctp_association_put(asoc);
253 } 256 }
254 } 257 }
@@ -264,13 +267,20 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
264{ 267{
265 sctp_xmit_t retval = SCTP_XMIT_OK; 268 sctp_xmit_t retval = SCTP_XMIT_OK;
266 __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length)); 269 __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length));
267 size_t psize;
268 size_t pmtu;
269 int too_big;
270 270
271 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet, 271 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet,
272 chunk); 272 chunk);
273 273
274 /* Data chunks are special. Before seeing what else we can
275 * bundle into this packet, check to see if we are allowed to
276 * send this DATA.
277 */
278 if (sctp_chunk_is_data(chunk)) {
279 retval = sctp_packet_can_append_data(packet, chunk);
280 if (retval != SCTP_XMIT_OK)
281 goto finish;
282 }
283
274 /* Try to bundle AUTH chunk */ 284 /* Try to bundle AUTH chunk */
275 retval = sctp_packet_bundle_auth(packet, chunk); 285 retval = sctp_packet_bundle_auth(packet, chunk);
276 if (retval != SCTP_XMIT_OK) 286 if (retval != SCTP_XMIT_OK)
@@ -281,57 +291,24 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
281 if (retval != SCTP_XMIT_OK) 291 if (retval != SCTP_XMIT_OK)
282 goto finish; 292 goto finish;
283 293
284 psize = packet->size; 294 /* Check to see if this chunk will fit into the packet */
285 pmtu = ((packet->transport->asoc) ? 295 retval = sctp_packet_will_fit(packet, chunk, chunk_len);
286 (packet->transport->asoc->pathmtu) : 296 if (retval != SCTP_XMIT_OK)
287 (packet->transport->pathmtu)); 297 goto finish;
288
289 too_big = (psize + chunk_len > pmtu);
290
291 /* Decide if we need to fragment or resubmit later. */
292 if (too_big) {
293 /* It's OK to fragmet at IP level if any one of the following
294 * is true:
295 * 1. The packet is empty (meaning this chunk is greater
296 * the MTU)
297 * 2. The chunk we are adding is a control chunk
298 * 3. The packet doesn't have any data in it yet and data
299 * requires authentication.
300 */
301 if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk) ||
302 (!packet->has_data && chunk->auth)) {
303 /* We no longer do re-fragmentation.
304 * Just fragment at the IP layer, if we
305 * actually hit this condition
306 */
307 packet->ipfragok = 1;
308 goto append;
309
310 } else {
311 retval = SCTP_XMIT_PMTU_FULL;
312 goto finish;
313 }
314 }
315
316append:
317 /* We believe that this chunk is OK to add to the packet (as
318 * long as we have the cwnd for it).
319 */
320 298
321 /* DATA is a special case since we must examine both rwnd and cwnd 299 /* We believe that this chunk is OK to add to the packet */
322 * before we send DATA.
323 */
324 switch (chunk->chunk_hdr->type) { 300 switch (chunk->chunk_hdr->type) {
325 case SCTP_CID_DATA: 301 case SCTP_CID_DATA:
326 retval = sctp_packet_append_data(packet, chunk); 302 /* Account for the data being in the packet */
303 sctp_packet_append_data(packet, chunk);
327 /* Disallow SACK bundling after DATA. */ 304 /* Disallow SACK bundling after DATA. */
328 packet->has_sack = 1; 305 packet->has_sack = 1;
329 /* Disallow AUTH bundling after DATA */ 306 /* Disallow AUTH bundling after DATA */
330 packet->has_auth = 1; 307 packet->has_auth = 1;
331 /* Let it be knows that packet has DATA in it */ 308 /* Let it be knows that packet has DATA in it */
332 packet->has_data = 1; 309 packet->has_data = 1;
333 if (SCTP_XMIT_OK != retval) 310 /* timestamp the chunk for rtx purposes */
334 goto finish; 311 chunk->sent_at = jiffies;
335 break; 312 break;
336 case SCTP_CID_COOKIE_ECHO: 313 case SCTP_CID_COOKIE_ECHO:
337 packet->has_cookie_echo = 1; 314 packet->has_cookie_echo = 1;
@@ -365,7 +342,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
365 struct sctp_transport *tp = packet->transport; 342 struct sctp_transport *tp = packet->transport;
366 struct sctp_association *asoc = tp->asoc; 343 struct sctp_association *asoc = tp->asoc;
367 struct sctphdr *sh; 344 struct sctphdr *sh;
368 __be32 crc32 = __constant_cpu_to_be32(0);
369 struct sk_buff *nskb; 345 struct sk_buff *nskb;
370 struct sctp_chunk *chunk, *tmp; 346 struct sctp_chunk *chunk, *tmp;
371 struct sock *sk; 347 struct sock *sk;
@@ -407,13 +383,14 @@ int sctp_packet_transmit(struct sctp_packet *packet)
407 sctp_assoc_sync_pmtu(asoc); 383 sctp_assoc_sync_pmtu(asoc);
408 } 384 }
409 } 385 }
410 nskb->dst = dst_clone(tp->dst); 386 dst = dst_clone(tp->dst);
411 if (!nskb->dst) 387 skb_dst_set(nskb, dst);
388 if (!dst)
412 goto no_route; 389 goto no_route;
413 dst = nskb->dst;
414 390
415 /* Build the SCTP header. */ 391 /* Build the SCTP header. */
416 sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); 392 sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
393 skb_reset_transport_header(nskb);
417 sh->source = htons(packet->source_port); 394 sh->source = htons(packet->source_port);
418 sh->dest = htons(packet->destination_port); 395 sh->dest = htons(packet->destination_port);
419 396
@@ -470,7 +447,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
470 } else 447 } else
471 chunk->resent = 1; 448 chunk->resent = 1;
472 449
473 chunk->sent_at = jiffies;
474 has_data = 1; 450 has_data = 1;
475 } 451 }
476 452
@@ -530,16 +506,25 @@ int sctp_packet_transmit(struct sctp_packet *packet)
530 * Note: Adler-32 is no longer applicable, as has been replaced 506 * Note: Adler-32 is no longer applicable, as has been replaced
531 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 507 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
532 */ 508 */
533 if (!(dst->dev->features & NETIF_F_NO_CSUM)) { 509 if (!sctp_checksum_disable &&
534 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); 510 !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) {
535 crc32 = sctp_end_cksum(crc32); 511 __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
536 } else 512
537 nskb->ip_summed = CHECKSUM_UNNECESSARY; 513 /* 3) Put the resultant value into the checksum field in the
538 514 * common header, and leave the rest of the bits unchanged.
539 /* 3) Put the resultant value into the checksum field in the 515 */
540 * common header, and leave the rest of the bits unchanged. 516 sh->checksum = sctp_end_cksum(crc32);
541 */ 517 } else {
542 sh->checksum = crc32; 518 if (dst->dev->features & NETIF_F_SCTP_CSUM) {
519 /* no need to seed psuedo checksum for SCTP */
520 nskb->ip_summed = CHECKSUM_PARTIAL;
521 nskb->csum_start = (skb_transport_header(nskb) -
522 nskb->head);
523 nskb->csum_offset = offsetof(struct sctphdr, checksum);
524 } else {
525 nskb->ip_summed = CHECKSUM_UNNECESSARY;
526 }
527 }
543 528
544 /* IP layer ECN support 529 /* IP layer ECN support
545 * From RFC 2481 530 * From RFC 2481
@@ -591,7 +576,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
591 (*tp->af_specific->sctp_xmit)(nskb, tp); 576 (*tp->af_specific->sctp_xmit)(nskb, tp);
592 577
593out: 578out:
594 packet->size = packet->overhead; 579 sctp_packet_reset(packet);
595 return err; 580 return err;
596no_route: 581no_route:
597 kfree_skb(nskb); 582 kfree_skb(nskb);
@@ -625,16 +610,15 @@ nomem:
625 * 2nd Level Abstractions 610 * 2nd Level Abstractions
626 ********************************************************************/ 611 ********************************************************************/
627 612
628/* This private function handles the specifics of appending DATA chunks. */ 613/* This private function check to see if a chunk can be added */
629static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, 614static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
630 struct sctp_chunk *chunk) 615 struct sctp_chunk *chunk)
631{ 616{
632 sctp_xmit_t retval = SCTP_XMIT_OK; 617 sctp_xmit_t retval = SCTP_XMIT_OK;
633 size_t datasize, rwnd, inflight; 618 size_t datasize, rwnd, inflight, flight_size;
634 struct sctp_transport *transport = packet->transport; 619 struct sctp_transport *transport = packet->transport;
635 __u32 max_burst_bytes; 620 __u32 max_burst_bytes;
636 struct sctp_association *asoc = transport->asoc; 621 struct sctp_association *asoc = transport->asoc;
637 struct sctp_sock *sp = sctp_sk(asoc->base.sk);
638 struct sctp_outq *q = &asoc->outqueue; 622 struct sctp_outq *q = &asoc->outqueue;
639 623
640 /* RFC 2960 6.1 Transmission of DATA Chunks 624 /* RFC 2960 6.1 Transmission of DATA Chunks
@@ -651,7 +635,8 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
651 */ 635 */
652 636
653 rwnd = asoc->peer.rwnd; 637 rwnd = asoc->peer.rwnd;
654 inflight = asoc->outqueue.outstanding_bytes; 638 inflight = q->outstanding_bytes;
639 flight_size = transport->flight_size;
655 640
656 datasize = sctp_data_size(chunk); 641 datasize = sctp_data_size(chunk);
657 642
@@ -674,8 +659,8 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
674 * cwnd = flightsize + Max.Burst * MTU 659 * cwnd = flightsize + Max.Burst * MTU
675 */ 660 */
676 max_burst_bytes = asoc->max_burst * asoc->pathmtu; 661 max_burst_bytes = asoc->max_burst * asoc->pathmtu;
677 if ((transport->flight_size + max_burst_bytes) < transport->cwnd) { 662 if ((flight_size + max_burst_bytes) < transport->cwnd) {
678 transport->cwnd = transport->flight_size + max_burst_bytes; 663 transport->cwnd = flight_size + max_burst_bytes;
679 SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: " 664 SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: "
680 "transport: %p, cwnd: %d, " 665 "transport: %p, cwnd: %d, "
681 "ssthresh: %d, flight_size: %d, " 666 "ssthresh: %d, flight_size: %d, "
@@ -700,7 +685,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
700 * ignore the value of cwnd and SHOULD NOT delay retransmission. 685 * ignore the value of cwnd and SHOULD NOT delay retransmission.
701 */ 686 */
702 if (chunk->fast_retransmit != SCTP_NEED_FRTX) 687 if (chunk->fast_retransmit != SCTP_NEED_FRTX)
703 if (transport->flight_size >= transport->cwnd) { 688 if (flight_size >= transport->cwnd) {
704 retval = SCTP_XMIT_RWND_FULL; 689 retval = SCTP_XMIT_RWND_FULL;
705 goto finish; 690 goto finish;
706 } 691 }
@@ -710,20 +695,36 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
710 * if any previously transmitted data on the connection remains 695 * if any previously transmitted data on the connection remains
711 * unacknowledged. 696 * unacknowledged.
712 */ 697 */
713 if (!sp->nodelay && sctp_packet_empty(packet) && 698 if (!sctp_sk(asoc->base.sk)->nodelay && sctp_packet_empty(packet) &&
714 q->outstanding_bytes && sctp_state(asoc, ESTABLISHED)) { 699 inflight && sctp_state(asoc, ESTABLISHED)) {
715 unsigned len = datasize + q->out_qlen; 700 unsigned max = transport->pathmtu - packet->overhead;
701 unsigned len = chunk->skb->len + q->out_qlen;
716 702
717 /* Check whether this chunk and all the rest of pending 703 /* Check whether this chunk and all the rest of pending
718 * data will fit or delay in hopes of bundling a full 704 * data will fit or delay in hopes of bundling a full
719 * sized packet. 705 * sized packet.
706 * Don't delay large message writes that may have been
707 * fragmeneted into small peices.
720 */ 708 */
721 if (len < asoc->frag_point) { 709 if ((len < max) && (chunk->msg->msg_size < max)) {
722 retval = SCTP_XMIT_NAGLE_DELAY; 710 retval = SCTP_XMIT_NAGLE_DELAY;
723 goto finish; 711 goto finish;
724 } 712 }
725 } 713 }
726 714
715finish:
716 return retval;
717}
718
719/* This private function does management things when adding DATA chunk */
720static void sctp_packet_append_data(struct sctp_packet *packet,
721 struct sctp_chunk *chunk)
722{
723 struct sctp_transport *transport = packet->transport;
724 size_t datasize = sctp_data_size(chunk);
725 struct sctp_association *asoc = transport->asoc;
726 u32 rwnd = asoc->peer.rwnd;
727
727 /* Keep track of how many bytes are in flight over this transport. */ 728 /* Keep track of how many bytes are in flight over this transport. */
728 transport->flight_size += datasize; 729 transport->flight_size += datasize;
729 730
@@ -746,7 +747,45 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
746 /* Has been accepted for transmission. */ 747 /* Has been accepted for transmission. */
747 if (!asoc->peer.prsctp_capable) 748 if (!asoc->peer.prsctp_capable)
748 chunk->msg->can_abandon = 0; 749 chunk->msg->can_abandon = 0;
750}
751
752static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet,
753 struct sctp_chunk *chunk,
754 u16 chunk_len)
755{
756 size_t psize;
757 size_t pmtu;
758 int too_big;
759 sctp_xmit_t retval = SCTP_XMIT_OK;
760
761 psize = packet->size;
762 pmtu = ((packet->transport->asoc) ?
763 (packet->transport->asoc->pathmtu) :
764 (packet->transport->pathmtu));
765
766 too_big = (psize + chunk_len > pmtu);
767
768 /* Decide if we need to fragment or resubmit later. */
769 if (too_big) {
770 /* It's OK to fragmet at IP level if any one of the following
771 * is true:
772 * 1. The packet is empty (meaning this chunk is greater
773 * the MTU)
774 * 2. The chunk we are adding is a control chunk
775 * 3. The packet doesn't have any data in it yet and data
776 * requires authentication.
777 */
778 if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk) ||
779 (!packet->has_data && chunk->auth)) {
780 /* We no longer do re-fragmentation.
781 * Just fragment at the IP layer, if we
782 * actually hit this condition
783 */
784 packet->ipfragok = 1;
785 } else {
786 retval = SCTP_XMIT_PMTU_FULL;
787 }
788 }
749 789
750finish:
751 return retval; 790 return retval;
752} 791}