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