1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <linux/types.h>
45#include <linux/kernel.h>
46#include <linux/wait.h>
47#include <linux/time.h>
48#include <linux/ip.h>
49#include <linux/ipv6.h>
50#include <linux/init.h>
51#include <net/inet_ecn.h>
52#include <net/ip.h>
53#include <net/icmp.h>
54#include <net/net_namespace.h>
55
56#include <linux/socket.h>
57#include <net/sock.h>
58
59#include <net/sctp/sctp.h>
60#include <net/sctp/sm.h>
61#include <net/sctp/checksum.h>
62
63
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,
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}
82
83
84
85
86struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
87 __u32 vtag, int ecn_capable)
88{
89 struct sctp_chunk *chunk = NULL;
90
91 SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__,
92 packet, vtag);
93
94 sctp_packet_reset(packet);
95 packet->vtag = vtag;
96
97 if (ecn_capable && sctp_packet_empty(packet)) {
98 chunk = sctp_get_ecne_prepend(packet->transport->asoc);
99
100
101
102
103 if (chunk)
104 sctp_packet_append_chunk(packet, chunk);
105 }
106
107 return packet;
108}
109
110
111struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
112 struct sctp_transport *transport,
113 __u16 sport, __u16 dport)
114{
115 struct sctp_association *asoc = transport->asoc;
116 size_t overhead;
117
118 SCTP_DEBUG_PRINTK("%s: packet:%p transport:%p\n", __func__,
119 packet, transport);
120
121 packet->transport = transport;
122 packet->source_port = sport;
123 packet->destination_port = dport;
124 INIT_LIST_HEAD(&packet->chunk_list);
125 if (asoc) {
126 struct sctp_sock *sp = sctp_sk(asoc->base.sk);
127 overhead = sp->pf->af->net_header_len;
128 } else {
129 overhead = sizeof(struct ipv6hdr);
130 }
131 overhead += sizeof(struct sctphdr);
132 packet->overhead = overhead;
133 sctp_packet_reset(packet);
134 packet->vtag = 0;
135 packet->malloced = 0;
136 return packet;
137}
138
139
140void sctp_packet_free(struct sctp_packet *packet)
141{
142 struct sctp_chunk *chunk, *tmp;
143
144 SCTP_DEBUG_PRINTK("%s: packet:%p\n", __func__, packet);
145
146 list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
147 list_del_init(&chunk->list);
148 sctp_chunk_free(chunk);
149 }
150
151 if (packet->malloced)
152 kfree(packet);
153}
154
155
156
157
158
159
160
161
162sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
163 struct sctp_chunk *chunk,
164 int one_packet)
165{
166 sctp_xmit_t retval;
167 int error = 0;
168
169 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__,
170 packet, chunk);
171
172 switch ((retval = (sctp_packet_append_chunk(packet, chunk)))) {
173 case SCTP_XMIT_PMTU_FULL:
174 if (!packet->has_cookie_echo) {
175 error = sctp_packet_transmit(packet);
176 if (error < 0)
177 chunk->skb->sk->sk_err = -error;
178
179
180
181
182 if (!one_packet)
183 retval = sctp_packet_append_chunk(packet,
184 chunk);
185 }
186 break;
187
188 case SCTP_XMIT_RWND_FULL:
189 case SCTP_XMIT_OK:
190 case SCTP_XMIT_NAGLE_DELAY:
191 break;
192 }
193
194 return retval;
195}
196
197
198static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt,
199 struct sctp_chunk *chunk)
200{
201 struct sctp_association *asoc = pkt->transport->asoc;
202 struct sctp_chunk *auth;
203 sctp_xmit_t retval = SCTP_XMIT_OK;
204
205
206 if (!asoc)
207 return retval;
208
209
210
211
212 if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->has_auth)
213 return retval;
214
215
216
217
218 if (!chunk->auth)
219 return retval;
220
221 auth = sctp_make_auth(asoc);
222 if (!auth)
223 return retval;
224
225 retval = sctp_packet_append_chunk(pkt, auth);
226
227 return retval;
228}
229
230
231static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt,
232 struct sctp_chunk *chunk)
233{
234 sctp_xmit_t retval = SCTP_XMIT_OK;
235
236
237
238
239 if (sctp_chunk_is_data(chunk) && !pkt->has_sack &&
240 !pkt->has_cookie_echo) {
241 struct sctp_association *asoc;
242 struct timer_list *timer;
243 asoc = pkt->transport->asoc;
244 timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
245
246
247 if (timer_pending(timer)) {
248 struct sctp_chunk *sack;
249 asoc->a_rwnd = asoc->rwnd;
250 sack = sctp_make_sack(asoc);
251 if (sack) {
252 retval = sctp_packet_append_chunk(pkt, sack);
253 asoc->peer.sack_needed = 0;
254 if (del_timer(timer))
255 sctp_association_put(asoc);
256 }
257 }
258 }
259 return retval;
260}
261
262
263
264
265sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
266 struct sctp_chunk *chunk)
267{
268 sctp_xmit_t retval = SCTP_XMIT_OK;
269 __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length));
270
271 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet,
272 chunk);
273
274
275
276
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
284
285 retval = sctp_packet_bundle_auth(packet, chunk);
286 if (retval != SCTP_XMIT_OK)
287 goto finish;
288
289
290 retval = sctp_packet_bundle_sack(packet, chunk);
291 if (retval != SCTP_XMIT_OK)
292 goto finish;
293
294
295 retval = sctp_packet_will_fit(packet, chunk, chunk_len);
296 if (retval != SCTP_XMIT_OK)
297 goto finish;
298
299
300 switch (chunk->chunk_hdr->type) {
301 case SCTP_CID_DATA:
302
303 sctp_packet_append_data(packet, chunk);
304
305 packet->has_sack = 1;
306
307 packet->has_auth = 1;
308
309 packet->has_data = 1;
310
311 chunk->sent_at = jiffies;
312 break;
313 case SCTP_CID_COOKIE_ECHO:
314 packet->has_cookie_echo = 1;
315 break;
316
317 case SCTP_CID_SACK:
318 packet->has_sack = 1;
319 break;
320
321 case SCTP_CID_AUTH:
322 packet->has_auth = 1;
323 packet->auth = chunk;
324 break;
325 }
326
327
328 list_add_tail(&chunk->list, &packet->chunk_list);
329 packet->size += chunk_len;
330 chunk->transport = packet->transport;
331finish:
332 return retval;
333}
334
335
336
337
338
339
340int sctp_packet_transmit(struct sctp_packet *packet)
341{
342 struct sctp_transport *tp = packet->transport;
343 struct sctp_association *asoc = tp->asoc;
344 struct sctphdr *sh;
345 struct sk_buff *nskb;
346 struct sctp_chunk *chunk, *tmp;
347 struct sock *sk;
348 int err = 0;
349 int padding;
350 __u8 has_data = 0;
351 struct dst_entry *dst = tp->dst;
352 unsigned char *auth = NULL;
353 __u32 cksum_buf_len = sizeof(struct sctphdr);
354
355 SCTP_DEBUG_PRINTK("%s: packet:%p\n", __func__, packet);
356
357
358 if (list_empty(&packet->chunk_list))
359 return err;
360
361
362 chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
363 sk = chunk->skb->sk;
364
365
366 nskb = alloc_skb(packet->size + LL_MAX_HEADER, GFP_ATOMIC);
367 if (!nskb)
368 goto nomem;
369
370
371 skb_reserve(nskb, packet->overhead + LL_MAX_HEADER);
372
373
374
375
376 skb_set_owner_w(nskb, sk);
377
378
379 if (!dst || (dst->obsolete > 1)) {
380 dst_release(dst);
381 sctp_transport_route(tp, NULL, sctp_sk(sk));
382 if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) {
383 sctp_assoc_sync_pmtu(asoc);
384 }
385 }
386 dst = dst_clone(tp->dst);
387 skb_dst_set(nskb, dst);
388 if (!dst)
389 goto no_route;
390
391
392 sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
393 skb_reset_transport_header(nskb);
394 sh->source = htons(packet->source_port);
395 sh->dest = htons(packet->destination_port);
396
397
398
399
400
401
402
403
404
405 sh->vtag = htonl(packet->vtag);
406 sh->checksum = 0;
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 SCTP_DEBUG_PRINTK("***sctp_transmit_packet***\n");
428 list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
429 list_del_init(&chunk->list);
430 if (sctp_chunk_is_data(chunk)) {
431
432 if (!chunk->has_tsn) {
433 sctp_chunk_assign_ssn(chunk);
434 sctp_chunk_assign_tsn(chunk);
435
436
437
438
439
440
441
442
443 if (!tp->rto_pending) {
444 chunk->rtt_in_progress = 1;
445 tp->rto_pending = 1;
446 }
447 } else
448 chunk->resent = 1;
449
450 has_data = 1;
451 }
452
453 padding = WORD_ROUND(chunk->skb->len) - chunk->skb->len;
454 if (padding)
455 memset(skb_put(chunk->skb, padding), 0, padding);
456
457
458
459
460
461 if (chunk == packet->auth)
462 auth = skb_tail_pointer(nskb);
463
464 cksum_buf_len += chunk->skb->len;
465 memcpy(skb_put(nskb, chunk->skb->len),
466 chunk->skb->data, chunk->skb->len);
467
468 SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n",
469 "*** Chunk", chunk,
470 sctp_cname(SCTP_ST_CHUNK(
471 chunk->chunk_hdr->type)),
472 chunk->has_tsn ? "TSN" : "No TSN",
473 chunk->has_tsn ?
474 ntohl(chunk->subh.data_hdr->tsn) : 0,
475 "length", ntohs(chunk->chunk_hdr->length),
476 "chunk->skb->len", chunk->skb->len,
477 "rtt_in_progress", chunk->rtt_in_progress);
478
479
480
481
482
483
484 if (!sctp_chunk_is_data(chunk))
485 sctp_chunk_free(chunk);
486 }
487
488
489
490
491
492
493
494
495
496
497 if (auth)
498 sctp_auth_calculate_hmac(asoc, nskb,
499 (struct sctp_auth_chunk *)auth,
500 GFP_ATOMIC);
501
502
503
504
505
506
507
508
509 if (!sctp_checksum_disable &&
510 !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) {
511 __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
512
513
514
515
516 sh->checksum = sctp_end_cksum(crc32);
517 } else {
518 if (dst->dev->features & NETIF_F_SCTP_CSUM) {
519
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 }
528
529
530
531
532
533
534
535
536
537
538
539
540
541 (*tp->af_specific->ecn_capable)(nskb->sk);
542
543
544
545
546
547
548
549 if (asoc && asoc->peer.last_sent_to != tp) {
550
551
552
553 asoc->peer.last_sent_to = tp;
554 }
555
556 if (has_data) {
557 struct timer_list *timer;
558 unsigned long timeout;
559
560 tp->last_time_used = jiffies;
561
562
563 if (sctp_state(asoc, ESTABLISHED) && asoc->autoclose) {
564 timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
565 timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
566
567 if (!mod_timer(timer, jiffies + timeout))
568 sctp_association_hold(asoc);
569 }
570 }
571
572 SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
573 nskb->len);
574
575 nskb->local_df = packet->ipfragok;
576 (*tp->af_specific->sctp_xmit)(nskb, tp);
577
578out:
579 sctp_packet_reset(packet);
580 return err;
581no_route:
582 kfree_skb(nskb);
583 IP_INC_STATS_BH(&init_net, IPSTATS_MIB_OUTNOROUTES);
584
585
586
587
588
589
590
591
592
593err:
594
595
596
597
598 list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
599 list_del_init(&chunk->list);
600 if (!sctp_chunk_is_data(chunk))
601 sctp_chunk_free(chunk);
602 }
603 goto out;
604nomem:
605 err = -ENOMEM;
606 goto err;
607}
608
609
610
611
612
613
614static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
615 struct sctp_chunk *chunk)
616{
617 sctp_xmit_t retval = SCTP_XMIT_OK;
618 size_t datasize, rwnd, inflight, flight_size;
619 struct sctp_transport *transport = packet->transport;
620 __u32 max_burst_bytes;
621 struct sctp_association *asoc = transport->asoc;
622 struct sctp_outq *q = &asoc->outqueue;
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637 rwnd = asoc->peer.rwnd;
638 inflight = q->outstanding_bytes;
639 flight_size = transport->flight_size;
640
641 datasize = sctp_data_size(chunk);
642
643 if (datasize > rwnd) {
644 if (inflight > 0) {
645
646
647
648 retval = SCTP_XMIT_RWND_FULL;
649 goto finish;
650 }
651 }
652
653
654
655
656
657
658
659
660
661 max_burst_bytes = asoc->max_burst * asoc->pathmtu;
662 if ((flight_size + max_burst_bytes) < transport->cwnd) {
663 transport->cwnd = flight_size + max_burst_bytes;
664 SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: "
665 "transport: %p, cwnd: %d, "
666 "ssthresh: %d, flight_size: %d, "
667 "pba: %d\n",
668 __func__, transport,
669 transport->cwnd,
670 transport->ssthresh,
671 transport->flight_size,
672 transport->partial_bytes_acked);
673 }
674
675
676
677
678
679
680
681
682
683
684
685
686
687 if (chunk->fast_retransmit != SCTP_NEED_FRTX)
688 if (flight_size >= transport->cwnd) {
689 retval = SCTP_XMIT_RWND_FULL;
690 goto finish;
691 }
692
693
694
695
696
697
698 if (!sctp_sk(asoc->base.sk)->nodelay && sctp_packet_empty(packet) &&
699 inflight && sctp_state(asoc, ESTABLISHED)) {
700 unsigned max = transport->pathmtu - packet->overhead;
701 unsigned len = chunk->skb->len + q->out_qlen;
702
703
704
705
706
707
708
709 if ((len < max) && (chunk->msg->msg_size < max)) {
710 retval = SCTP_XMIT_NAGLE_DELAY;
711 goto finish;
712 }
713 }
714
715finish:
716 return retval;
717}
718
719
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
728
729 transport->flight_size += datasize;
730
731
732 asoc->outqueue.outstanding_bytes += datasize;
733
734
735
736
737
738
739
740 datasize += sizeof(struct sk_buff);
741 if (datasize < rwnd)
742 rwnd -= datasize;
743 else
744 rwnd = 0;
745
746 asoc->peer.rwnd = rwnd;
747
748 if (!asoc->peer.prsctp_capable)
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
769 if (too_big) {
770
771
772
773
774
775
776
777
778 if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk) ||
779 (!packet->has_data && chunk->auth)) {
780
781
782
783
784 packet->ipfragok = 1;
785 } else {
786 retval = SCTP_XMIT_PMTU_FULL;
787 }
788 }
789
790 return retval;
791}
792