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
45
46
47
48
49
50
51
52
53#include <linux/types.h>
54#include <linux/kernel.h>
55#include <linux/ip.h>
56#include <linux/ipv6.h>
57#include <linux/net.h>
58#include <linux/inet.h>
59#include <net/sock.h>
60#include <net/inet_ecn.h>
61#include <linux/skbuff.h>
62#include <net/sctp/sctp.h>
63#include <net/sctp/sm.h>
64#include <net/sctp/structs.h>
65
66static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
67 const struct sctp_association *asoc,
68 struct sctp_chunk *chunk,
69 const void *payload,
70 size_t paylen);
71static int sctp_eat_data(const struct sctp_association *asoc,
72 struct sctp_chunk *chunk,
73 sctp_cmd_seq_t *commands);
74static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
75 const struct sctp_chunk *chunk);
76static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
77 const struct sctp_association *asoc,
78 const struct sctp_chunk *chunk,
79 sctp_cmd_seq_t *commands,
80 struct sctp_chunk *err_chunk);
81static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
82 const struct sctp_association *asoc,
83 const sctp_subtype_t type,
84 void *arg,
85 sctp_cmd_seq_t *commands);
86static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
87 const struct sctp_association *asoc,
88 const sctp_subtype_t type,
89 void *arg,
90 sctp_cmd_seq_t *commands);
91static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
92 const struct sctp_association *asoc,
93 const sctp_subtype_t type,
94 void *arg,
95 sctp_cmd_seq_t *commands);
96static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
97
98static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
99 __be16 error, int sk_err,
100 const struct sctp_association *asoc,
101 struct sctp_transport *transport);
102
103static sctp_disposition_t sctp_sf_abort_violation(
104 const struct sctp_endpoint *ep,
105 const struct sctp_association *asoc,
106 void *arg,
107 sctp_cmd_seq_t *commands,
108 const __u8 *payload,
109 const size_t paylen);
110
111static sctp_disposition_t sctp_sf_violation_chunklen(
112 const struct sctp_endpoint *ep,
113 const struct sctp_association *asoc,
114 const sctp_subtype_t type,
115 void *arg,
116 sctp_cmd_seq_t *commands);
117
118static sctp_disposition_t sctp_sf_violation_paramlen(
119 const struct sctp_endpoint *ep,
120 const struct sctp_association *asoc,
121 const sctp_subtype_t type,
122 void *arg,
123 sctp_cmd_seq_t *commands);
124
125static sctp_disposition_t sctp_sf_violation_ctsn(
126 const struct sctp_endpoint *ep,
127 const struct sctp_association *asoc,
128 const sctp_subtype_t type,
129 void *arg,
130 sctp_cmd_seq_t *commands);
131
132static sctp_disposition_t sctp_sf_violation_chunk(
133 const struct sctp_endpoint *ep,
134 const struct sctp_association *asoc,
135 const sctp_subtype_t type,
136 void *arg,
137 sctp_cmd_seq_t *commands);
138
139static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep,
140 const struct sctp_association *asoc,
141 const sctp_subtype_t type,
142 struct sctp_chunk *chunk);
143
144static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
145 const struct sctp_association *asoc,
146 const sctp_subtype_t type,
147 void *arg,
148 sctp_cmd_seq_t *commands);
149
150
151
152
153
154
155
156
157static inline int
158sctp_chunk_length_valid(struct sctp_chunk *chunk,
159 __u16 required_length)
160{
161 __u16 chunk_length = ntohs(chunk->chunk_hdr->length);
162
163 if (unlikely(chunk_length < required_length))
164 return 0;
165
166 return 1;
167}
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
205 const struct sctp_association *asoc,
206 const sctp_subtype_t type,
207 void *arg,
208 sctp_cmd_seq_t *commands)
209{
210 struct sctp_chunk *chunk = arg;
211 struct sctp_ulpevent *ev;
212
213 if (!sctp_vtag_verify_either(chunk, asoc))
214 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
215
216
217
218
219
220
221 if (!chunk->singleton)
222 return sctp_sf_violation_chunk(ep, asoc, type, arg, commands);
223
224
225 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
226 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
227 commands);
228
229
230
231
232
233
234
235
236 ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP,
237 0, 0, 0, NULL, GFP_ATOMIC);
238 if (ev)
239 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
240 SCTP_ULPEVENT(ev));
241
242
243
244
245
246
247
248
249
250 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
251 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
252
253 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
254 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
255
256 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
257 SCTP_STATE(SCTP_STATE_CLOSED));
258
259 SCTP_INC_STATS(SCTP_MIB_SHUTDOWNS);
260 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
261
262 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
263
264 return SCTP_DISPOSITION_DELETE_TCB;
265}
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
290 const struct sctp_association *asoc,
291 const sctp_subtype_t type,
292 void *arg,
293 sctp_cmd_seq_t *commands)
294{
295 struct sctp_chunk *chunk = arg;
296 struct sctp_chunk *repl;
297 struct sctp_association *new_asoc;
298 struct sctp_chunk *err_chunk;
299 struct sctp_packet *packet;
300 sctp_unrecognized_param_t *unk_param;
301 int len;
302
303
304
305
306
307
308
309
310
311
312 if (!chunk->singleton)
313 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
314
315
316
317
318 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
319 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
320
321
322
323
324 if (chunk->sctp_hdr->vtag != 0)
325 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
326
327
328
329
330
331
332 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
333 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
334
335
336 err_chunk = NULL;
337 if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
338 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
339 &err_chunk)) {
340
341
342
343 if (err_chunk) {
344 packet = sctp_abort_pkt_new(ep, asoc, arg,
345 (__u8 *)(err_chunk->chunk_hdr) +
346 sizeof(sctp_chunkhdr_t),
347 ntohs(err_chunk->chunk_hdr->length) -
348 sizeof(sctp_chunkhdr_t));
349
350 sctp_chunk_free(err_chunk);
351
352 if (packet) {
353 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
354 SCTP_PACKET(packet));
355 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
356 return SCTP_DISPOSITION_CONSUME;
357 } else {
358 return SCTP_DISPOSITION_NOMEM;
359 }
360 } else {
361 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
362 commands);
363 }
364 }
365
366
367 chunk->subh.init_hdr = (sctp_inithdr_t *)chunk->skb->data;
368
369
370 chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
371
372 new_asoc = sctp_make_temp_asoc(ep, chunk, GFP_ATOMIC);
373 if (!new_asoc)
374 goto nomem;
375
376
377 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
378 sctp_source(chunk),
379 (sctp_init_chunk_t *)chunk->chunk_hdr,
380 GFP_ATOMIC))
381 goto nomem_init;
382
383
384
385
386
387
388 len = 0;
389 if (err_chunk)
390 len = ntohs(err_chunk->chunk_hdr->length) -
391 sizeof(sctp_chunkhdr_t);
392
393 if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
394 goto nomem_init;
395
396 repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
397 if (!repl)
398 goto nomem_init;
399
400
401
402
403
404 if (err_chunk) {
405
406
407
408
409
410
411
412 unk_param = (sctp_unrecognized_param_t *)
413 ((__u8 *)(err_chunk->chunk_hdr) +
414 sizeof(sctp_chunkhdr_t));
415
416
417
418 sctp_addto_chunk(repl, len, unk_param);
419 sctp_chunk_free(err_chunk);
420 }
421
422 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
423
424 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
425
426
427
428
429
430
431
432 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
433
434 return SCTP_DISPOSITION_DELETE_TCB;
435
436nomem_init:
437 sctp_association_free(new_asoc);
438nomem:
439 if (err_chunk)
440 sctp_chunk_free(err_chunk);
441 return SCTP_DISPOSITION_NOMEM;
442}
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
473 const struct sctp_association *asoc,
474 const sctp_subtype_t type,
475 void *arg,
476 sctp_cmd_seq_t *commands)
477{
478 struct sctp_chunk *chunk = arg;
479 sctp_init_chunk_t *initchunk;
480 struct sctp_chunk *err_chunk;
481 struct sctp_packet *packet;
482
483 if (!sctp_vtag_verify(chunk, asoc))
484 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
485
486
487
488
489
490 if (!chunk->singleton)
491 return sctp_sf_violation_chunk(ep, asoc, type, arg, commands);
492
493
494 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t)))
495 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
496 commands);
497
498 chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
499
500
501 err_chunk = NULL;
502 if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
503 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
504 &err_chunk)) {
505
506 sctp_error_t error = SCTP_ERROR_NO_RESOURCE;
507
508
509
510
511
512
513 if (err_chunk) {
514 packet = sctp_abort_pkt_new(ep, asoc, arg,
515 (__u8 *)(err_chunk->chunk_hdr) +
516 sizeof(sctp_chunkhdr_t),
517 ntohs(err_chunk->chunk_hdr->length) -
518 sizeof(sctp_chunkhdr_t));
519
520 sctp_chunk_free(err_chunk);
521
522 if (packet) {
523 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
524 SCTP_PACKET(packet));
525 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
526 error = SCTP_ERROR_INV_PARAM;
527 }
528 }
529
530
531
532
533
534
535
536
537
538
539
540
541 if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
542 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
543
544 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
545 return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED,
546 asoc, chunk->transport);
547 }
548
549
550
551
552 chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
553
554 initchunk = (sctp_init_chunk_t *) chunk->chunk_hdr;
555
556 sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT,
557 SCTP_PEER_INIT(initchunk));
558
559
560 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
561
562
563
564
565
566 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
567 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
568 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
569 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
570 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
571 SCTP_STATE(SCTP_STATE_COOKIE_ECHOED));
572
573
574
575
576 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL());
577
578
579
580
581
582
583
584 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_COOKIE_ECHO,
585 SCTP_CHUNK(err_chunk));
586
587 return SCTP_DISPOSITION_CONSUME;
588}
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
622 const struct sctp_association *asoc,
623 const sctp_subtype_t type, void *arg,
624 sctp_cmd_seq_t *commands)
625{
626 struct sctp_chunk *chunk = arg;
627 struct sctp_association *new_asoc;
628 sctp_init_chunk_t *peer_init;
629 struct sctp_chunk *repl;
630 struct sctp_ulpevent *ev, *ai_ev = NULL;
631 int error = 0;
632 struct sctp_chunk *err_chk_p;
633 struct sock *sk;
634
635
636
637
638 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
639 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
640
641
642
643
644
645
646 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
647 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
648
649
650
651
652
653 sk = ep->base.sk;
654 if (!sctp_sstate(sk, LISTENING) ||
655 (sctp_style(sk, TCP) && sk_acceptq_is_full(sk)))
656 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
657
658
659
660
661 chunk->subh.cookie_hdr =
662 (struct sctp_signed_cookie *)chunk->skb->data;
663 if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
664 sizeof(sctp_chunkhdr_t)))
665 goto nomem;
666
667
668
669
670
671 new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error,
672 &err_chk_p);
673
674
675
676
677
678
679
680 if (!new_asoc) {
681
682
683
684 switch (error) {
685 case -SCTP_IERROR_NOMEM:
686 goto nomem;
687
688 case -SCTP_IERROR_STALE_COOKIE:
689 sctp_send_stale_cookie_err(ep, asoc, chunk, commands,
690 err_chk_p);
691 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
692
693 case -SCTP_IERROR_BAD_SIG:
694 default:
695 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
696 }
697 }
698
699
700
701
702
703
704
705
706
707
708 peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
709
710 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
711 &chunk->subh.cookie_hdr->c.peer_addr,
712 peer_init, GFP_ATOMIC))
713 goto nomem_init;
714
715
716
717
718
719 error = sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC);
720 if (error)
721 goto nomem_init;
722
723
724
725
726
727
728
729 if (chunk->auth_chunk) {
730 struct sctp_chunk auth;
731 sctp_ierror_t ret;
732
733
734 auth.skb = chunk->auth_chunk;
735 auth.asoc = chunk->asoc;
736 auth.sctp_hdr = chunk->sctp_hdr;
737 auth.chunk_hdr = (sctp_chunkhdr_t *)skb_push(chunk->auth_chunk,
738 sizeof(sctp_chunkhdr_t));
739 skb_pull(chunk->auth_chunk, sizeof(sctp_chunkhdr_t));
740 auth.transport = chunk->transport;
741
742 ret = sctp_sf_authenticate(ep, new_asoc, type, &auth);
743
744
745 kfree_skb(chunk->auth_chunk);
746
747 if (ret != SCTP_IERROR_NO_ERROR) {
748 sctp_association_free(new_asoc);
749 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
750 }
751 }
752
753 repl = sctp_make_cookie_ack(new_asoc, chunk);
754 if (!repl)
755 goto nomem_init;
756
757
758
759
760
761
762
763 ev = sctp_ulpevent_make_assoc_change(new_asoc, 0, SCTP_COMM_UP, 0,
764 new_asoc->c.sinit_num_ostreams,
765 new_asoc->c.sinit_max_instreams,
766 NULL, GFP_ATOMIC);
767 if (!ev)
768 goto nomem_ev;
769
770
771
772
773
774
775 if (new_asoc->peer.adaptation_ind) {
776 ai_ev = sctp_ulpevent_make_adaptation_indication(new_asoc,
777 GFP_ATOMIC);
778 if (!ai_ev)
779 goto nomem_aiev;
780 }
781
782
783
784
785
786
787 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
788 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
789 SCTP_STATE(SCTP_STATE_ESTABLISHED));
790 SCTP_INC_STATS(SCTP_MIB_CURRESTAB);
791 SCTP_INC_STATS(SCTP_MIB_PASSIVEESTABS);
792 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
793
794 if (new_asoc->autoclose)
795 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
796 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
797
798 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
799
800
801 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
802
803
804 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
805
806
807 if (ai_ev)
808 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
809 SCTP_ULPEVENT(ai_ev));
810
811 return SCTP_DISPOSITION_CONSUME;
812
813nomem_aiev:
814 sctp_ulpevent_free(ev);
815nomem_ev:
816 sctp_chunk_free(repl);
817nomem_init:
818 sctp_association_free(new_asoc);
819nomem:
820 return SCTP_DISPOSITION_NOMEM;
821}
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
845 const struct sctp_association *asoc,
846 const sctp_subtype_t type, void *arg,
847 sctp_cmd_seq_t *commands)
848{
849 struct sctp_chunk *chunk = arg;
850 struct sctp_ulpevent *ev;
851
852 if (!sctp_vtag_verify(chunk, asoc))
853 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
854
855
856
857
858 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
859 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
860 commands);
861
862
863
864
865
866
867
868 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
869
870
871
872
873
874
875
876 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
877 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
878 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
879 SCTP_STATE(SCTP_STATE_ESTABLISHED));
880 SCTP_INC_STATS(SCTP_MIB_CURRESTAB);
881 SCTP_INC_STATS(SCTP_MIB_ACTIVEESTABS);
882 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
883 if (asoc->autoclose)
884 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
885 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
886 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
887
888
889
890
891
892 ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_UP,
893 0, asoc->c.sinit_num_ostreams,
894 asoc->c.sinit_max_instreams,
895 NULL, GFP_ATOMIC);
896
897 if (!ev)
898 goto nomem;
899
900 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
901
902
903
904
905
906
907 if (asoc->peer.adaptation_ind) {
908 ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
909 if (!ev)
910 goto nomem;
911
912 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
913 SCTP_ULPEVENT(ev));
914 }
915
916 return SCTP_DISPOSITION_CONSUME;
917nomem:
918 return SCTP_DISPOSITION_NOMEM;
919}
920
921
922static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
923 const struct sctp_association *asoc,
924 const sctp_subtype_t type,
925 void *arg,
926 sctp_cmd_seq_t *commands)
927{
928 struct sctp_transport *transport = (struct sctp_transport *) arg;
929 struct sctp_chunk *reply;
930 sctp_sender_hb_info_t hbinfo;
931 size_t paylen = 0;
932
933 hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO;
934 hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t));
935 hbinfo.daddr = transport->ipaddr;
936 hbinfo.sent_at = jiffies;
937 hbinfo.hb_nonce = transport->hb_nonce;
938
939
940 paylen = sizeof(sctp_sender_hb_info_t);
941 reply = sctp_make_heartbeat(asoc, transport, &hbinfo, paylen);
942 if (!reply)
943 return SCTP_DISPOSITION_NOMEM;
944
945
946
947
948 sctp_add_cmd_sf(commands, SCTP_CMD_RTO_PENDING,
949 SCTP_TRANSPORT(transport));
950
951 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
952 return SCTP_DISPOSITION_CONSUME;
953}
954
955
956sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
957 const struct sctp_association *asoc,
958 const sctp_subtype_t type,
959 void *arg,
960 sctp_cmd_seq_t *commands)
961{
962 struct sctp_transport *transport = (struct sctp_transport *) arg;
963
964 if (asoc->overall_error_count > asoc->max_retrans) {
965 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
966 SCTP_ERROR(ETIMEDOUT));
967
968 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
969 SCTP_PERR(SCTP_ERROR_NO_ERROR));
970 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
971 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
972 return SCTP_DISPOSITION_DELETE_TCB;
973 }
974
975
976
977
978
979
980
981
982 if (transport->param_flags & SPP_HB_ENABLE) {
983 if (SCTP_DISPOSITION_NOMEM ==
984 sctp_sf_heartbeat(ep, asoc, type, arg,
985 commands))
986 return SCTP_DISPOSITION_NOMEM;
987
988
989
990 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET,
991 SCTP_TRANSPORT(transport));
992 }
993 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE,
994 SCTP_TRANSPORT(transport));
995
996 return SCTP_DISPOSITION_CONSUME;
997}
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
1024 const struct sctp_association *asoc,
1025 const sctp_subtype_t type,
1026 void *arg,
1027 sctp_cmd_seq_t *commands)
1028{
1029 struct sctp_chunk *chunk = arg;
1030 struct sctp_chunk *reply;
1031 size_t paylen = 0;
1032
1033 if (!sctp_vtag_verify(chunk, asoc))
1034 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
1035
1036
1037 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
1038 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
1039 commands);
1040
1041
1042
1043
1044
1045 chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
1046 paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
1047 if (!pskb_pull(chunk->skb, paylen))
1048 goto nomem;
1049
1050 reply = sctp_make_heartbeat_ack(asoc, chunk,
1051 chunk->subh.hb_hdr, paylen);
1052 if (!reply)
1053 goto nomem;
1054
1055 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
1056 return SCTP_DISPOSITION_CONSUME;
1057
1058nomem:
1059 return SCTP_DISPOSITION_NOMEM;
1060}
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
1091 const struct sctp_association *asoc,
1092 const sctp_subtype_t type,
1093 void *arg,
1094 sctp_cmd_seq_t *commands)
1095{
1096 struct sctp_chunk *chunk = arg;
1097 union sctp_addr from_addr;
1098 struct sctp_transport *link;
1099 sctp_sender_hb_info_t *hbinfo;
1100 unsigned long max_interval;
1101
1102 if (!sctp_vtag_verify(chunk, asoc))
1103 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
1104
1105
1106 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
1107 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
1108 commands);
1109
1110 hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
1111
1112 if (ntohs(hbinfo->param_hdr.length) !=
1113 sizeof(sctp_sender_hb_info_t)) {
1114 return SCTP_DISPOSITION_DISCARD;
1115 }
1116
1117 from_addr = hbinfo->daddr;
1118 link = sctp_assoc_lookup_paddr(asoc, &from_addr);
1119
1120
1121 if (unlikely(!link)) {
1122 if (from_addr.sa.sa_family == AF_INET6) {
1123 if (net_ratelimit())
1124 printk(KERN_WARNING
1125 "%s association %p could not find address "
1126 NIP6_FMT "\n",
1127 __FUNCTION__,
1128 asoc,
1129 NIP6(from_addr.v6.sin6_addr));
1130 } else {
1131 if (net_ratelimit())
1132 printk(KERN_WARNING
1133 "%s association %p could not find address "
1134 NIPQUAD_FMT "\n",
1135 __FUNCTION__,
1136 asoc,
1137 NIPQUAD(from_addr.v4.sin_addr.s_addr));
1138 }
1139 return SCTP_DISPOSITION_DISCARD;
1140 }
1141
1142
1143 if (hbinfo->hb_nonce != link->hb_nonce)
1144 return SCTP_DISPOSITION_DISCARD;
1145
1146 max_interval = link->hbinterval + link->rto;
1147
1148
1149 if (time_after(hbinfo->sent_at, jiffies) ||
1150 time_after(jiffies, hbinfo->sent_at + max_interval)) {
1151 SCTP_DEBUG_PRINTK("%s: HEARTBEAT ACK with invalid timestamp "
1152 "received for transport: %p\n",
1153 __FUNCTION__, link);
1154 return SCTP_DISPOSITION_DISCARD;
1155 }
1156
1157
1158
1159
1160
1161
1162
1163 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_ON, SCTP_TRANSPORT(link));
1164
1165 return SCTP_DISPOSITION_CONSUME;
1166}
1167
1168
1169
1170
1171static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
1172 struct sctp_chunk *init,
1173 sctp_cmd_seq_t *commands)
1174{
1175 int len;
1176 struct sctp_packet *pkt;
1177 union sctp_addr_param *addrparm;
1178 struct sctp_errhdr *errhdr;
1179 struct sctp_endpoint *ep;
1180 char buffer[sizeof(struct sctp_errhdr)+sizeof(union sctp_addr_param)];
1181 struct sctp_af *af = sctp_get_af_specific(ssa->v4.sin_family);
1182
1183
1184
1185
1186 errhdr = (struct sctp_errhdr *)buffer;
1187 addrparm = (union sctp_addr_param *)errhdr->variable;
1188
1189
1190 len = af->to_addr_param(ssa, addrparm);
1191 len += sizeof(sctp_errhdr_t);
1192
1193 errhdr->cause = SCTP_ERROR_RESTART;
1194 errhdr->length = htons(len);
1195
1196
1197 ep = sctp_sk((sctp_get_ctl_sock()))->ep;
1198
1199
1200
1201
1202 pkt = sctp_abort_pkt_new(ep, NULL, init, errhdr, len);
1203
1204 if (!pkt)
1205 goto out;
1206 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, SCTP_PACKET(pkt));
1207
1208 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
1209
1210
1211 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
1212
1213out:
1214
1215
1216
1217 return 0;
1218}
1219
1220
1221
1222
1223static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
1224 const struct sctp_association *asoc,
1225 struct sctp_chunk *init,
1226 sctp_cmd_seq_t *commands)
1227{
1228 struct sctp_transport *new_addr, *addr;
1229 struct list_head *pos, *pos2;
1230 int found;
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243 new_addr = NULL;
1244 found = 0;
1245
1246 list_for_each(pos, &new_asoc->peer.transport_addr_list) {
1247 new_addr = list_entry(pos, struct sctp_transport, transports);
1248 found = 0;
1249 list_for_each(pos2, &asoc->peer.transport_addr_list) {
1250 addr = list_entry(pos2, struct sctp_transport,
1251 transports);
1252 if (sctp_cmp_addr_exact(&new_addr->ipaddr,
1253 &addr->ipaddr)) {
1254 found = 1;
1255 break;
1256 }
1257 }
1258 if (!found)
1259 break;
1260 }
1261
1262
1263 if (!found && new_addr) {
1264 sctp_sf_send_restart_abort(&new_addr->ipaddr, init, commands);
1265 }
1266
1267
1268 return found;
1269}
1270
1271
1272
1273
1274
1275
1276static void sctp_tietags_populate(struct sctp_association *new_asoc,
1277 const struct sctp_association *asoc)
1278{
1279 switch (asoc->state) {
1280
1281
1282
1283 case SCTP_STATE_COOKIE_WAIT:
1284 new_asoc->c.my_vtag = asoc->c.my_vtag;
1285 new_asoc->c.my_ttag = asoc->c.my_vtag;
1286 new_asoc->c.peer_ttag = 0;
1287 break;
1288
1289 case SCTP_STATE_COOKIE_ECHOED:
1290 new_asoc->c.my_vtag = asoc->c.my_vtag;
1291 new_asoc->c.my_ttag = asoc->c.my_vtag;
1292 new_asoc->c.peer_ttag = asoc->c.peer_vtag;
1293 break;
1294
1295
1296
1297
1298 default:
1299 new_asoc->c.my_ttag = asoc->c.my_vtag;
1300 new_asoc->c.peer_ttag = asoc->c.peer_vtag;
1301 break;
1302 }
1303
1304
1305
1306
1307
1308 new_asoc->rwnd = asoc->rwnd;
1309 new_asoc->c.sinit_num_ostreams = asoc->c.sinit_num_ostreams;
1310 new_asoc->c.sinit_max_instreams = asoc->c.sinit_max_instreams;
1311 new_asoc->c.initial_tsn = asoc->c.initial_tsn;
1312}
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323static char sctp_tietags_compare(struct sctp_association *new_asoc,
1324 const struct sctp_association *asoc)
1325{
1326
1327 if ((asoc->c.my_vtag != new_asoc->c.my_vtag) &&
1328 (asoc->c.peer_vtag != new_asoc->c.peer_vtag) &&
1329 (asoc->c.my_vtag == new_asoc->c.my_ttag) &&
1330 (asoc->c.peer_vtag == new_asoc->c.peer_ttag))
1331 return 'A';
1332
1333
1334 if ((asoc->c.my_vtag == new_asoc->c.my_vtag) &&
1335 ((asoc->c.peer_vtag != new_asoc->c.peer_vtag) ||
1336 (0 == asoc->c.peer_vtag))) {
1337 return 'B';
1338 }
1339
1340
1341 if ((asoc->c.my_vtag == new_asoc->c.my_vtag) &&
1342 (asoc->c.peer_vtag == new_asoc->c.peer_vtag))
1343 return 'D';
1344
1345
1346 if ((asoc->c.my_vtag != new_asoc->c.my_vtag) &&
1347 (asoc->c.peer_vtag == new_asoc->c.peer_vtag) &&
1348 (0 == new_asoc->c.my_ttag) &&
1349 (0 == new_asoc->c.peer_ttag))
1350 return 'C';
1351
1352
1353 return 'E';
1354}
1355
1356
1357
1358
1359static sctp_disposition_t sctp_sf_do_unexpected_init(
1360 const struct sctp_endpoint *ep,
1361 const struct sctp_association *asoc,
1362 const sctp_subtype_t type,
1363 void *arg, sctp_cmd_seq_t *commands)
1364{
1365 sctp_disposition_t retval;
1366 struct sctp_chunk *chunk = arg;
1367 struct sctp_chunk *repl;
1368 struct sctp_association *new_asoc;
1369 struct sctp_chunk *err_chunk;
1370 struct sctp_packet *packet;
1371 sctp_unrecognized_param_t *unk_param;
1372 int len;
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383 if (!chunk->singleton)
1384 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
1385
1386
1387
1388
1389 if (chunk->sctp_hdr->vtag != 0)
1390 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
1391
1392
1393
1394
1395
1396 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
1397 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
1398 commands);
1399
1400 chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
1401
1402
1403 chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
1404
1405
1406 err_chunk = NULL;
1407 if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
1408 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
1409 &err_chunk)) {
1410
1411
1412
1413 if (err_chunk) {
1414 packet = sctp_abort_pkt_new(ep, asoc, arg,
1415 (__u8 *)(err_chunk->chunk_hdr) +
1416 sizeof(sctp_chunkhdr_t),
1417 ntohs(err_chunk->chunk_hdr->length) -
1418 sizeof(sctp_chunkhdr_t));
1419
1420 if (packet) {
1421 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
1422 SCTP_PACKET(packet));
1423 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
1424 retval = SCTP_DISPOSITION_CONSUME;
1425 } else {
1426 retval = SCTP_DISPOSITION_NOMEM;
1427 }
1428 goto cleanup;
1429 } else {
1430 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
1431 commands);
1432 }
1433 }
1434
1435
1436
1437
1438
1439
1440
1441
1442 new_asoc = sctp_make_temp_asoc(ep, chunk, GFP_ATOMIC);
1443 if (!new_asoc)
1444 goto nomem;
1445
1446
1447
1448
1449
1450 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
1451 sctp_source(chunk),
1452 (sctp_init_chunk_t *)chunk->chunk_hdr,
1453 GFP_ATOMIC))
1454 goto nomem;
1455
1456
1457
1458
1459
1460
1461 if (!sctp_state(asoc, COOKIE_WAIT)) {
1462 if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk,
1463 commands)) {
1464 retval = SCTP_DISPOSITION_CONSUME;
1465 goto nomem_retval;
1466 }
1467 }
1468
1469 sctp_tietags_populate(new_asoc, asoc);
1470
1471
1472
1473
1474
1475
1476 len = 0;
1477 if (err_chunk) {
1478 len = ntohs(err_chunk->chunk_hdr->length) -
1479 sizeof(sctp_chunkhdr_t);
1480 }
1481
1482 if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
1483 goto nomem;
1484
1485 repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
1486 if (!repl)
1487 goto nomem;
1488
1489
1490
1491
1492
1493 if (err_chunk) {
1494
1495
1496
1497
1498
1499
1500
1501 unk_param = (sctp_unrecognized_param_t *)
1502 ((__u8 *)(err_chunk->chunk_hdr) +
1503 sizeof(sctp_chunkhdr_t));
1504
1505
1506
1507 sctp_addto_chunk(repl, len, unk_param);
1508 }
1509
1510 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
1511 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1512
1513
1514
1515
1516
1517
1518 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
1519 retval = SCTP_DISPOSITION_CONSUME;
1520
1521 return retval;
1522
1523nomem:
1524 retval = SCTP_DISPOSITION_NOMEM;
1525nomem_retval:
1526 if (new_asoc)
1527 sctp_association_free(new_asoc);
1528cleanup:
1529 if (err_chunk)
1530 sctp_chunk_free(err_chunk);
1531 return retval;
1532}
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572sctp_disposition_t sctp_sf_do_5_2_1_siminit(const struct sctp_endpoint *ep,
1573 const struct sctp_association *asoc,
1574 const sctp_subtype_t type,
1575 void *arg,
1576 sctp_cmd_seq_t *commands)
1577{
1578
1579
1580
1581 return sctp_sf_do_unexpected_init(ep, asoc, type, arg, commands);
1582}
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625sctp_disposition_t sctp_sf_do_5_2_2_dupinit(const struct sctp_endpoint *ep,
1626 const struct sctp_association *asoc,
1627 const sctp_subtype_t type,
1628 void *arg,
1629 sctp_cmd_seq_t *commands)
1630{
1631
1632
1633
1634 return sctp_sf_do_unexpected_init(ep, asoc, type, arg, commands);
1635}
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647sctp_disposition_t sctp_sf_do_5_2_3_initack(const struct sctp_endpoint *ep,
1648 const struct sctp_association *asoc,
1649 const sctp_subtype_t type,
1650 void *arg, sctp_cmd_seq_t *commands)
1651{
1652
1653
1654
1655 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
1656 return sctp_sf_ootb(ep, asoc, type, arg, commands);
1657 else
1658 return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
1659}
1660
1661
1662
1663
1664
1665
1666static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
1667 const struct sctp_association *asoc,
1668 struct sctp_chunk *chunk,
1669 sctp_cmd_seq_t *commands,
1670 struct sctp_association *new_asoc)
1671{
1672 sctp_init_chunk_t *peer_init;
1673 struct sctp_ulpevent *ev;
1674 struct sctp_chunk *repl;
1675 struct sctp_chunk *err;
1676 sctp_disposition_t disposition;
1677
1678
1679
1680
1681 peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
1682
1683 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
1684 sctp_source(chunk), peer_init,
1685 GFP_ATOMIC))
1686 goto nomem;
1687
1688
1689
1690
1691
1692 if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) {
1693 return SCTP_DISPOSITION_CONSUME;
1694 }
1695
1696
1697
1698
1699
1700
1701
1702 if (sctp_state(asoc, SHUTDOWN_ACK_SENT)) {
1703 disposition = sctp_sf_do_9_2_reshutack(ep, asoc,
1704 SCTP_ST_CHUNK(chunk->chunk_hdr->type),
1705 chunk, commands);
1706 if (SCTP_DISPOSITION_NOMEM == disposition)
1707 goto nomem;
1708
1709 err = sctp_make_op_error(asoc, chunk,
1710 SCTP_ERROR_COOKIE_IN_SHUTDOWN,
1711 NULL, 0);
1712 if (err)
1713 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
1714 SCTP_CHUNK(err));
1715
1716 return SCTP_DISPOSITION_CONSUME;
1717 }
1718
1719
1720
1721
1722 sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL());
1723
1724 repl = sctp_make_cookie_ack(new_asoc, chunk);
1725 if (!repl)
1726 goto nomem;
1727
1728
1729 ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0,
1730 new_asoc->c.sinit_num_ostreams,
1731 new_asoc->c.sinit_max_instreams,
1732 NULL, GFP_ATOMIC);
1733 if (!ev)
1734 goto nomem_ev;
1735
1736
1737 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
1738 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1739 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
1740 return SCTP_DISPOSITION_CONSUME;
1741
1742nomem_ev:
1743 sctp_chunk_free(repl);
1744nomem:
1745 return SCTP_DISPOSITION_NOMEM;
1746}
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
1757 const struct sctp_association *asoc,
1758 struct sctp_chunk *chunk,
1759 sctp_cmd_seq_t *commands,
1760 struct sctp_association *new_asoc)
1761{
1762 sctp_init_chunk_t *peer_init;
1763 struct sctp_chunk *repl;
1764
1765
1766
1767
1768 peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
1769 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
1770 sctp_source(chunk), peer_init,
1771 GFP_ATOMIC))
1772 goto nomem;
1773
1774
1775 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
1776 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
1777 SCTP_STATE(SCTP_STATE_ESTABLISHED));
1778 SCTP_INC_STATS(SCTP_MIB_CURRESTAB);
1779 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
1780
1781 repl = sctp_make_cookie_ack(new_asoc, chunk);
1782 if (!repl)
1783 goto nomem;
1784
1785 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1786 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_CHANGE, SCTP_U8(SCTP_COMM_UP));
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810 if (asoc->peer.adaptation_ind)
1811 sctp_add_cmd_sf(commands, SCTP_CMD_ADAPTATION_IND, SCTP_NULL());
1812
1813 return SCTP_DISPOSITION_CONSUME;
1814
1815nomem:
1816 return SCTP_DISPOSITION_NOMEM;
1817}
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828static sctp_disposition_t sctp_sf_do_dupcook_c(const struct sctp_endpoint *ep,
1829 const struct sctp_association *asoc,
1830 struct sctp_chunk *chunk,
1831 sctp_cmd_seq_t *commands,
1832 struct sctp_association *new_asoc)
1833{
1834
1835
1836
1837
1838 return SCTP_DISPOSITION_DISCARD;
1839}
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
1850 const struct sctp_association *asoc,
1851 struct sctp_chunk *chunk,
1852 sctp_cmd_seq_t *commands,
1853 struct sctp_association *new_asoc)
1854{
1855 struct sctp_ulpevent *ev = NULL, *ai_ev = NULL;
1856 struct sctp_chunk *repl;
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866 if (asoc->state < SCTP_STATE_ESTABLISHED) {
1867 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
1868 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
1869 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
1870 SCTP_STATE(SCTP_STATE_ESTABLISHED));
1871 SCTP_INC_STATS(SCTP_MIB_CURRESTAB);
1872 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START,
1873 SCTP_NULL());
1874
1875
1876
1877
1878
1879
1880
1881
1882 ev = sctp_ulpevent_make_assoc_change(asoc, 0,
1883 SCTP_COMM_UP, 0,
1884 asoc->c.sinit_num_ostreams,
1885 asoc->c.sinit_max_instreams,
1886 NULL, GFP_ATOMIC);
1887 if (!ev)
1888 goto nomem;
1889
1890
1891
1892
1893
1894
1895 if (asoc->peer.adaptation_ind) {
1896 ai_ev = sctp_ulpevent_make_adaptation_indication(asoc,
1897 GFP_ATOMIC);
1898 if (!ai_ev)
1899 goto nomem;
1900
1901 }
1902 }
1903 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
1904
1905 repl = sctp_make_cookie_ack(new_asoc, chunk);
1906 if (!repl)
1907 goto nomem;
1908
1909 if (ev)
1910 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
1911 SCTP_ULPEVENT(ev));
1912 if (ai_ev)
1913 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
1914 SCTP_ULPEVENT(ai_ev));
1915
1916 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
1917 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
1918
1919 return SCTP_DISPOSITION_CONSUME;
1920
1921nomem:
1922 if (ai_ev)
1923 sctp_ulpevent_free(ai_ev);
1924 if (ev)
1925 sctp_ulpevent_free(ev);
1926 return SCTP_DISPOSITION_NOMEM;
1927}
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
1946 const struct sctp_association *asoc,
1947 const sctp_subtype_t type,
1948 void *arg,
1949 sctp_cmd_seq_t *commands)
1950{
1951 sctp_disposition_t retval;
1952 struct sctp_chunk *chunk = arg;
1953 struct sctp_association *new_asoc;
1954 int error = 0;
1955 char action;
1956 struct sctp_chunk *err_chk_p;
1957
1958
1959
1960
1961
1962
1963 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
1964 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
1965 commands);
1966
1967
1968
1969
1970 chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
1971 if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
1972 sizeof(sctp_chunkhdr_t)))
1973 goto nomem;
1974
1975
1976
1977
1978
1979
1980 new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error,
1981 &err_chk_p);
1982
1983
1984
1985
1986
1987
1988
1989 if (!new_asoc) {
1990
1991
1992
1993 switch (error) {
1994 case -SCTP_IERROR_NOMEM:
1995 goto nomem;
1996
1997 case -SCTP_IERROR_STALE_COOKIE:
1998 sctp_send_stale_cookie_err(ep, asoc, chunk, commands,
1999 err_chk_p);
2000 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2001 case -SCTP_IERROR_BAD_SIG:
2002 default:
2003 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2004 }
2005 }
2006
2007
2008
2009
2010 action = sctp_tietags_compare(new_asoc, asoc);
2011
2012 switch (action) {
2013 case 'A':
2014 retval = sctp_sf_do_dupcook_a(ep, asoc, chunk, commands,
2015 new_asoc);
2016 break;
2017
2018 case 'B':
2019 retval = sctp_sf_do_dupcook_b(ep, asoc, chunk, commands,
2020 new_asoc);
2021 break;
2022
2023 case 'C':
2024 retval = sctp_sf_do_dupcook_c(ep, asoc, chunk, commands,
2025 new_asoc);
2026 break;
2027
2028 case 'D':
2029 retval = sctp_sf_do_dupcook_d(ep, asoc, chunk, commands,
2030 new_asoc);
2031 break;
2032
2033 default:
2034 retval = sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2035 break;
2036 }
2037
2038
2039 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
2040 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
2041
2042 return retval;
2043
2044nomem:
2045 return SCTP_DISPOSITION_NOMEM;
2046}
2047
2048
2049
2050
2051
2052
2053sctp_disposition_t sctp_sf_shutdown_pending_abort(
2054 const struct sctp_endpoint *ep,
2055 const struct sctp_association *asoc,
2056 const sctp_subtype_t type,
2057 void *arg,
2058 sctp_cmd_seq_t *commands)
2059{
2060 struct sctp_chunk *chunk = arg;
2061
2062 if (!sctp_vtag_verify_either(chunk, asoc))
2063 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
2076 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2077
2078
2079
2080
2081
2082
2083 if (SCTP_ADDR_DEL ==
2084 sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
2085 return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
2086
2087
2088 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
2089 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
2090
2091 return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
2092}
2093
2094
2095
2096
2097
2098
2099sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
2100 const struct sctp_association *asoc,
2101 const sctp_subtype_t type,
2102 void *arg,
2103 sctp_cmd_seq_t *commands)
2104{
2105 struct sctp_chunk *chunk = arg;
2106
2107 if (!sctp_vtag_verify_either(chunk, asoc))
2108 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
2121 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2122
2123
2124
2125
2126
2127
2128 if (SCTP_ADDR_DEL ==
2129 sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
2130 return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
2131
2132
2133 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
2134 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
2135
2136
2137 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
2138 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
2139
2140 return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
2141}
2142
2143
2144
2145
2146
2147
2148sctp_disposition_t sctp_sf_shutdown_ack_sent_abort(
2149 const struct sctp_endpoint *ep,
2150 const struct sctp_association *asoc,
2151 const sctp_subtype_t type,
2152 void *arg,
2153 sctp_cmd_seq_t *commands)
2154{
2155
2156
2157
2158 return sctp_sf_shutdown_sent_abort(ep, asoc, type, arg, commands);
2159}
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
2176 const struct sctp_association *asoc,
2177 const sctp_subtype_t type,
2178 void *arg,
2179 sctp_cmd_seq_t *commands)
2180{
2181 struct sctp_chunk *chunk = arg;
2182 sctp_errhdr_t *err;
2183
2184 if (!sctp_vtag_verify(chunk, asoc))
2185 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2186
2187
2188
2189
2190 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
2191 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2192 commands);
2193
2194
2195
2196
2197
2198
2199 sctp_walk_errors(err, chunk->chunk_hdr) {
2200 if (SCTP_ERROR_STALE_COOKIE == err->cause)
2201 return sctp_sf_do_5_2_6_stale(ep, asoc, type,
2202 arg, commands);
2203 }
2204
2205
2206
2207
2208
2209
2210 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2211}
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
2239 const struct sctp_association *asoc,
2240 const sctp_subtype_t type,
2241 void *arg,
2242 sctp_cmd_seq_t *commands)
2243{
2244 struct sctp_chunk *chunk = arg;
2245 time_t stale;
2246 sctp_cookie_preserve_param_t bht;
2247 sctp_errhdr_t *err;
2248 struct sctp_chunk *reply;
2249 struct sctp_bind_addr *bp;
2250 int attempts = asoc->init_err_counter + 1;
2251
2252 if (attempts > asoc->max_init_attempts) {
2253 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
2254 SCTP_ERROR(ETIMEDOUT));
2255 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
2256 SCTP_PERR(SCTP_ERROR_STALE_COOKIE));
2257 return SCTP_DISPOSITION_DELETE_TCB;
2258 }
2259
2260 err = (sctp_errhdr_t *)(chunk->skb->data);
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276 stale = ntohl(*(__be32 *)((u8 *)err + sizeof(sctp_errhdr_t)));
2277 stale = (stale * 2) / 1000;
2278
2279 bht.param_hdr.type = SCTP_PARAM_COOKIE_PRESERVATIVE;
2280 bht.param_hdr.length = htons(sizeof(bht));
2281 bht.lifespan_increment = htonl(stale);
2282
2283
2284 bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
2285 reply = sctp_make_init(asoc, bp, GFP_ATOMIC, sizeof(bht));
2286 if (!reply)
2287 goto nomem;
2288
2289 sctp_addto_chunk(reply, sizeof(bht), &bht);
2290
2291
2292 sctp_add_cmd_sf(commands, SCTP_CMD_CLEAR_INIT_TAG, SCTP_NULL());
2293
2294
2295 sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL());
2296 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
2297
2298
2299
2300
2301 sctp_add_cmd_sf(commands, SCTP_CMD_DEL_NON_PRIMARY, SCTP_NULL());
2302
2303
2304
2305
2306 sctp_add_cmd_sf(commands, SCTP_CMD_T1_RETRAN,
2307 SCTP_TRANSPORT(asoc->peer.primary_path));
2308
2309
2310
2311
2312 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_INC, SCTP_NULL());
2313
2314 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
2315 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
2316 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
2317 SCTP_STATE(SCTP_STATE_COOKIE_WAIT));
2318 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
2319 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
2320
2321 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
2322
2323 return SCTP_DISPOSITION_CONSUME;
2324
2325nomem:
2326 return SCTP_DISPOSITION_NOMEM;
2327}
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
2361 const struct sctp_association *asoc,
2362 const sctp_subtype_t type,
2363 void *arg,
2364 sctp_cmd_seq_t *commands)
2365{
2366 struct sctp_chunk *chunk = arg;
2367
2368 if (!sctp_vtag_verify_either(chunk, asoc))
2369 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
2382 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2383
2384
2385
2386
2387
2388
2389 if (SCTP_ADDR_DEL ==
2390 sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
2391 return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
2392
2393 return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
2394}
2395
2396static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
2397 const struct sctp_association *asoc,
2398 const sctp_subtype_t type,
2399 void *arg,
2400 sctp_cmd_seq_t *commands)
2401{
2402 struct sctp_chunk *chunk = arg;
2403 unsigned len;
2404 __be16 error = SCTP_ERROR_NO_ERROR;
2405
2406
2407 len = ntohs(chunk->chunk_hdr->length);
2408 if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
2409 error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
2410
2411 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET));
2412
2413 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_PERR(error));
2414 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
2415 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
2416
2417 return SCTP_DISPOSITION_ABORT;
2418}
2419
2420
2421
2422
2423
2424
2425sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
2426 const struct sctp_association *asoc,
2427 const sctp_subtype_t type,
2428 void *arg,
2429 sctp_cmd_seq_t *commands)
2430{
2431 struct sctp_chunk *chunk = arg;
2432 unsigned len;
2433 __be16 error = SCTP_ERROR_NO_ERROR;
2434
2435 if (!sctp_vtag_verify_either(chunk, asoc))
2436 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
2449 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2450
2451
2452 len = ntohs(chunk->chunk_hdr->length);
2453 if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
2454 error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
2455
2456 return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, asoc,
2457 chunk->transport);
2458}
2459
2460
2461
2462
2463sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep,
2464 const struct sctp_association *asoc,
2465 const sctp_subtype_t type,
2466 void *arg,
2467 sctp_cmd_seq_t *commands)
2468{
2469 return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR,
2470 ENOPROTOOPT, asoc,
2471 (struct sctp_transport *)arg);
2472}
2473
2474
2475
2476
2477sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
2478 const struct sctp_association *asoc,
2479 const sctp_subtype_t type,
2480 void *arg,
2481 sctp_cmd_seq_t *commands)
2482{
2483
2484
2485
2486 return sctp_sf_cookie_wait_abort(ep, asoc, type, arg, commands);
2487}
2488
2489
2490
2491
2492
2493
2494static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
2495 __be16 error, int sk_err,
2496 const struct sctp_association *asoc,
2497 struct sctp_transport *transport)
2498{
2499 SCTP_DEBUG_PRINTK("ABORT received (INIT).\n");
2500 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
2501 SCTP_STATE(SCTP_STATE_CLOSED));
2502 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
2503 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
2504 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
2505 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(sk_err));
2506
2507 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
2508 SCTP_PERR(error));
2509 return SCTP_DISPOSITION_ABORT;
2510}
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
2546 const struct sctp_association *asoc,
2547 const sctp_subtype_t type,
2548 void *arg,
2549 sctp_cmd_seq_t *commands)
2550{
2551 struct sctp_chunk *chunk = arg;
2552 sctp_shutdownhdr_t *sdh;
2553 sctp_disposition_t disposition;
2554 struct sctp_ulpevent *ev;
2555
2556 if (!sctp_vtag_verify(chunk, asoc))
2557 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2558
2559
2560 if (!sctp_chunk_length_valid(chunk,
2561 sizeof(struct sctp_shutdown_chunk_t)))
2562 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2563 commands);
2564
2565
2566 sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
2567 skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
2568 chunk->subh.shutdown_hdr = sdh;
2569
2570
2571
2572
2573
2574 ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC);
2575 if (!ev) {
2576 disposition = SCTP_DISPOSITION_NOMEM;
2577 goto out;
2578 }
2579 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
2580
2581
2582
2583
2584
2585
2586
2587 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
2588 SCTP_STATE(SCTP_STATE_SHUTDOWN_RECEIVED));
2589 disposition = SCTP_DISPOSITION_CONSUME;
2590
2591 if (sctp_outq_is_empty(&asoc->outqueue)) {
2592 disposition = sctp_sf_do_9_2_shutdown_ack(ep, asoc, type,
2593 arg, commands);
2594 }
2595
2596 if (SCTP_DISPOSITION_NOMEM == disposition)
2597 goto out;
2598
2599
2600
2601
2602
2603 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN,
2604 SCTP_BE32(chunk->subh.shutdown_hdr->cum_tsn_ack));
2605
2606out:
2607 return disposition;
2608}
2609
2610
2611
2612
2613
2614
2615
2616
2617sctp_disposition_t sctp_sf_do_9_2_reshutack(const struct sctp_endpoint *ep,
2618 const struct sctp_association *asoc,
2619 const sctp_subtype_t type,
2620 void *arg,
2621 sctp_cmd_seq_t *commands)
2622{
2623 struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
2624 struct sctp_chunk *reply;
2625
2626
2627 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
2628 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2629 commands);
2630
2631
2632
2633
2634
2635 reply = sctp_make_shutdown_ack(asoc, chunk);
2636 if (NULL == reply)
2637 goto nomem;
2638
2639
2640
2641
2642 sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
2643
2644
2645 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
2646 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
2647
2648 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
2649
2650 return SCTP_DISPOSITION_CONSUME;
2651nomem:
2652 return SCTP_DISPOSITION_NOMEM;
2653}
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
2681 const struct sctp_association *asoc,
2682 const sctp_subtype_t type,
2683 void *arg,
2684 sctp_cmd_seq_t *commands)
2685{
2686 sctp_cwrhdr_t *cwr;
2687 struct sctp_chunk *chunk = arg;
2688 u32 lowest_tsn;
2689
2690 if (!sctp_vtag_verify(chunk, asoc))
2691 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2692
2693 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t)))
2694 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2695 commands);
2696
2697 cwr = (sctp_cwrhdr_t *) chunk->skb->data;
2698 skb_pull(chunk->skb, sizeof(sctp_cwrhdr_t));
2699
2700 lowest_tsn = ntohl(cwr->lowest_tsn);
2701
2702
2703 if (TSN_lte(asoc->last_ecne_tsn, lowest_tsn)) {
2704
2705 sctp_add_cmd_sf(commands,
2706 SCTP_CMD_ECN_CWR,
2707 SCTP_U32(lowest_tsn));
2708 }
2709 return SCTP_DISPOSITION_CONSUME;
2710}
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
2736 const struct sctp_association *asoc,
2737 const sctp_subtype_t type,
2738 void *arg,
2739 sctp_cmd_seq_t *commands)
2740{
2741 sctp_ecnehdr_t *ecne;
2742 struct sctp_chunk *chunk = arg;
2743
2744 if (!sctp_vtag_verify(chunk, asoc))
2745 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2746
2747 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t)))
2748 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2749 commands);
2750
2751 ecne = (sctp_ecnehdr_t *) chunk->skb->data;
2752 skb_pull(chunk->skb, sizeof(sctp_ecnehdr_t));
2753
2754
2755 sctp_add_cmd_sf(commands, SCTP_CMD_ECN_ECNE,
2756 SCTP_U32(ntohl(ecne->lowest_tsn)));
2757
2758 return SCTP_DISPOSITION_CONSUME;
2759}
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
2792 const struct sctp_association *asoc,
2793 const sctp_subtype_t type,
2794 void *arg,
2795 sctp_cmd_seq_t *commands)
2796{
2797 struct sctp_chunk *chunk = arg;
2798 int error;
2799
2800 if (!sctp_vtag_verify(chunk, asoc)) {
2801 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
2802 SCTP_NULL());
2803 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2804 }
2805
2806 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_data_chunk_t)))
2807 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2808 commands);
2809
2810 error = sctp_eat_data(asoc, chunk, commands );
2811 switch (error) {
2812 case SCTP_IERROR_NO_ERROR:
2813 break;
2814 case SCTP_IERROR_HIGH_TSN:
2815 case SCTP_IERROR_BAD_STREAM:
2816 SCTP_INC_STATS(SCTP_MIB_IN_DATA_CHUNK_DISCARDS);
2817 goto discard_noforce;
2818 case SCTP_IERROR_DUP_TSN:
2819 case SCTP_IERROR_IGNORE_TSN:
2820 SCTP_INC_STATS(SCTP_MIB_IN_DATA_CHUNK_DISCARDS);
2821 goto discard_force;
2822 case SCTP_IERROR_NO_DATA:
2823 goto consume;
2824 default:
2825 BUG();
2826 }
2827
2828 if (asoc->autoclose) {
2829 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
2830 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
2831 }
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855 if (chunk->end_of_packet)
2856 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
2857
2858 return SCTP_DISPOSITION_CONSUME;
2859
2860discard_force:
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875 if (chunk->end_of_packet)
2876 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
2877 return SCTP_DISPOSITION_DISCARD;
2878
2879discard_noforce:
2880 if (chunk->end_of_packet)
2881 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
2882
2883 return SCTP_DISPOSITION_DISCARD;
2884consume:
2885 return SCTP_DISPOSITION_CONSUME;
2886
2887}
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
2906 const struct sctp_association *asoc,
2907 const sctp_subtype_t type,
2908 void *arg,
2909 sctp_cmd_seq_t *commands)
2910{
2911 struct sctp_chunk *chunk = arg;
2912 int error;
2913
2914 if (!sctp_vtag_verify(chunk, asoc)) {
2915 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
2916 SCTP_NULL());
2917 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2918 }
2919
2920 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_data_chunk_t)))
2921 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2922 commands);
2923
2924 error = sctp_eat_data(asoc, chunk, commands );
2925 switch (error) {
2926 case SCTP_IERROR_NO_ERROR:
2927 case SCTP_IERROR_HIGH_TSN:
2928 case SCTP_IERROR_DUP_TSN:
2929 case SCTP_IERROR_IGNORE_TSN:
2930 case SCTP_IERROR_BAD_STREAM:
2931 break;
2932 case SCTP_IERROR_NO_DATA:
2933 goto consume;
2934 default:
2935 BUG();
2936 }
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946 if (chunk->end_of_packet) {
2947
2948
2949
2950 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SHUTDOWN, SCTP_NULL());
2951 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
2952 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
2953 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
2954 }
2955
2956consume:
2957 return SCTP_DISPOSITION_CONSUME;
2958}
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
2993 const struct sctp_association *asoc,
2994 const sctp_subtype_t type,
2995 void *arg,
2996 sctp_cmd_seq_t *commands)
2997{
2998 struct sctp_chunk *chunk = arg;
2999 sctp_sackhdr_t *sackh;
3000 __u32 ctsn;
3001
3002 if (!sctp_vtag_verify(chunk, asoc))
3003 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3004
3005
3006 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_sack_chunk_t)))
3007 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3008 commands);
3009
3010
3011 sackh = sctp_sm_pull_sack(chunk);
3012
3013 if (!sackh)
3014 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3015 chunk->subh.sack_hdr = sackh;
3016 ctsn = ntohl(sackh->cum_tsn_ack);
3017
3018
3019
3020
3021
3022
3023
3024 if (TSN_lt(ctsn, asoc->ctsn_ack_point)) {
3025 SCTP_DEBUG_PRINTK("ctsn %x\n", ctsn);
3026 SCTP_DEBUG_PRINTK("ctsn_ack_point %x\n", asoc->ctsn_ack_point);
3027 return SCTP_DISPOSITION_DISCARD;
3028 }
3029
3030
3031
3032
3033
3034 if (!TSN_lt(ctsn, asoc->next_tsn))
3035 return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands);
3036
3037
3038 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh));
3039
3040
3041
3042
3043 return SCTP_DISPOSITION_CONSUME;
3044}
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
3065 const struct sctp_association *asoc,
3066 const sctp_subtype_t type,
3067 void *arg,
3068 sctp_cmd_seq_t *commands)
3069{
3070 struct sctp_packet *packet = NULL;
3071 struct sctp_chunk *chunk = arg;
3072 struct sctp_chunk *abort;
3073
3074 packet = sctp_ootb_pkt_new(asoc, chunk);
3075
3076 if (packet) {
3077
3078
3079
3080 abort = sctp_make_abort(asoc, chunk, 0);
3081 if (!abort) {
3082 sctp_ootb_pkt_free(packet);
3083 return SCTP_DISPOSITION_NOMEM;
3084 }
3085
3086
3087 if (sctp_test_T_bit(abort))
3088 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
3089
3090
3091 abort->skb->sk = ep->base.sk;
3092
3093 sctp_packet_append_chunk(packet, abort);
3094
3095 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
3096 SCTP_PACKET(packet));
3097
3098 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
3099
3100 sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3101 return SCTP_DISPOSITION_CONSUME;
3102 }
3103
3104 return SCTP_DISPOSITION_NOMEM;
3105}
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
3116 const struct sctp_association *asoc,
3117 const sctp_subtype_t type,
3118 void *arg,
3119 sctp_cmd_seq_t *commands)
3120{
3121 struct sctp_chunk *chunk = arg;
3122 struct sctp_ulpevent *ev;
3123
3124 if (!sctp_vtag_verify(chunk, asoc))
3125 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3126
3127
3128 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
3129 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3130 commands);
3131
3132 while (chunk->chunk_end > chunk->skb->data) {
3133 ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0,
3134 GFP_ATOMIC);
3135 if (!ev)
3136 goto nomem;
3137
3138 if (!sctp_add_cmd(commands, SCTP_CMD_EVENT_ULP,
3139 SCTP_ULPEVENT(ev))) {
3140 sctp_ulpevent_free(ev);
3141 goto nomem;
3142 }
3143
3144 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR,
3145 SCTP_CHUNK(chunk));
3146 }
3147 return SCTP_DISPOSITION_CONSUME;
3148
3149nomem:
3150 return SCTP_DISPOSITION_NOMEM;
3151}
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
3164 const struct sctp_association *asoc,
3165 const sctp_subtype_t type,
3166 void *arg,
3167 sctp_cmd_seq_t *commands)
3168{
3169 struct sctp_chunk *chunk = arg;
3170 struct sctp_chunk *reply;
3171 struct sctp_ulpevent *ev;
3172
3173 if (!sctp_vtag_verify(chunk, asoc))
3174 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3175
3176
3177 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3178 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3179 commands);
3180
3181
3182
3183
3184
3185 ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP,
3186 0, 0, 0, NULL, GFP_ATOMIC);
3187 if (!ev)
3188 goto nomem;
3189
3190
3191 reply = sctp_make_shutdown_complete(asoc, chunk);
3192 if (!reply)
3193 goto nomem_chunk;
3194
3195
3196
3197
3198 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
3199
3200
3201
3202
3203 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
3204 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
3205
3206 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
3207 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
3208
3209 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
3210 SCTP_STATE(SCTP_STATE_CLOSED));
3211 SCTP_INC_STATS(SCTP_MIB_SHUTDOWNS);
3212 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
3213 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
3214
3215
3216 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
3217 return SCTP_DISPOSITION_DELETE_TCB;
3218
3219nomem_chunk:
3220 sctp_ulpevent_free(ev);
3221nomem:
3222 return SCTP_DISPOSITION_NOMEM;
3223}
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
3246 const struct sctp_association *asoc,
3247 const sctp_subtype_t type,
3248 void *arg,
3249 sctp_cmd_seq_t *commands)
3250{
3251 struct sctp_chunk *chunk = arg;
3252 struct sk_buff *skb = chunk->skb;
3253 sctp_chunkhdr_t *ch;
3254 __u8 *ch_end;
3255 int ootb_shut_ack = 0;
3256
3257 SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
3258
3259 ch = (sctp_chunkhdr_t *) chunk->chunk_hdr;
3260 do {
3261
3262 if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
3263 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3264 commands);
3265
3266
3267
3268
3269 if (SCTP_CID_SHUTDOWN_ACK == ch->type)
3270 ootb_shut_ack = 1;
3271
3272
3273
3274
3275
3276
3277 if (SCTP_CID_ABORT == ch->type)
3278 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3279
3280
3281 ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
3282 if (ch_end > skb_tail_pointer(skb))
3283 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3284 commands);
3285
3286 ch = (sctp_chunkhdr_t *) ch_end;
3287 } while (ch_end < skb_tail_pointer(skb));
3288
3289 if (ootb_shut_ack)
3290 return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
3291 else
3292 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
3293}
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
3317 const struct sctp_association *asoc,
3318 const sctp_subtype_t type,
3319 void *arg,
3320 sctp_cmd_seq_t *commands)
3321{
3322 struct sctp_packet *packet = NULL;
3323 struct sctp_chunk *chunk = arg;
3324 struct sctp_chunk *shut;
3325
3326 packet = sctp_ootb_pkt_new(asoc, chunk);
3327
3328 if (packet) {
3329
3330
3331
3332 shut = sctp_make_shutdown_complete(asoc, chunk);
3333 if (!shut) {
3334 sctp_ootb_pkt_free(packet);
3335 return SCTP_DISPOSITION_NOMEM;
3336 }
3337
3338
3339 if (sctp_test_T_bit(shut))
3340 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
3341
3342
3343 shut->skb->sk = ep->base.sk;
3344
3345 sctp_packet_append_chunk(packet, shut);
3346
3347 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
3348 SCTP_PACKET(packet));
3349
3350 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
3351
3352
3353
3354
3355 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3356 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3357
3358
3359
3360
3361
3362 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3363 }
3364
3365 return SCTP_DISPOSITION_NOMEM;
3366}
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
3380 const struct sctp_association *asoc,
3381 const sctp_subtype_t type,
3382 void *arg,
3383 sctp_cmd_seq_t *commands)
3384{
3385 struct sctp_chunk *chunk = arg;
3386
3387
3388 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3389 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3390 commands);
3391
3392
3393
3394
3395
3396
3397 return sctp_sf_shut_8_4_5(ep, NULL, type, arg, commands);
3398}
3399
3400
3401sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
3402 const struct sctp_association *asoc,
3403 const sctp_subtype_t type, void *arg,
3404 sctp_cmd_seq_t *commands)
3405{
3406 struct sctp_chunk *chunk = arg;
3407 struct sctp_chunk *asconf_ack = NULL;
3408 struct sctp_paramhdr *err_param = NULL;
3409 sctp_addiphdr_t *hdr;
3410 union sctp_addr_param *addr_param;
3411 __u32 serial;
3412 int length;
3413
3414 if (!sctp_vtag_verify(chunk, asoc)) {
3415 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
3416 SCTP_NULL());
3417 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3418 }
3419
3420
3421
3422
3423
3424
3425
3426 if (!sctp_addip_noauth && !chunk->auth)
3427 return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
3428
3429
3430 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_addip_chunk_t)))
3431 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3432 commands);
3433
3434 hdr = (sctp_addiphdr_t *)chunk->skb->data;
3435 serial = ntohl(hdr->serial);
3436
3437 addr_param = (union sctp_addr_param *)hdr->params;
3438 length = ntohs(addr_param->p.length);
3439 if (length < sizeof(sctp_paramhdr_t))
3440 return sctp_sf_violation_paramlen(ep, asoc, type,
3441 (void *)addr_param, commands);
3442
3443
3444 if (!sctp_verify_asconf(asoc,
3445 (sctp_paramhdr_t *)((void *)addr_param + length),
3446 (void *)chunk->chunk_end,
3447 &err_param))
3448 return sctp_sf_violation_paramlen(ep, asoc, type,
3449 (void *)&err_param, commands);
3450
3451
3452
3453
3454
3455 if (serial == asoc->peer.addip_serial + 1) {
3456
3457
3458
3459 if (!chunk->has_asconf)
3460 sctp_assoc_clean_asconf_ack_cache(asoc);
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470 asconf_ack = sctp_process_asconf((struct sctp_association *)
3471 asoc, chunk);
3472 if (!asconf_ack)
3473 return SCTP_DISPOSITION_NOMEM;
3474 } else if (serial < asoc->peer.addip_serial + 1) {
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487 asconf_ack = sctp_assoc_lookup_asconf_ack(asoc, hdr->serial);
3488 if (!asconf_ack)
3489 return SCTP_DISPOSITION_DISCARD;
3490 } else {
3491
3492
3493
3494 return SCTP_DISPOSITION_DISCARD;
3495 }
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506 asconf_ack->dest = chunk->source;
3507 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack));
3508
3509 return SCTP_DISPOSITION_CONSUME;
3510}
3511
3512
3513
3514
3515
3516
3517sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3518 const struct sctp_association *asoc,
3519 const sctp_subtype_t type, void *arg,
3520 sctp_cmd_seq_t *commands)
3521{
3522 struct sctp_chunk *asconf_ack = arg;
3523 struct sctp_chunk *last_asconf = asoc->addip_last_asconf;
3524 struct sctp_chunk *abort;
3525 struct sctp_paramhdr *err_param = NULL;
3526 sctp_addiphdr_t *addip_hdr;
3527 __u32 sent_serial, rcvd_serial;
3528
3529 if (!sctp_vtag_verify(asconf_ack, asoc)) {
3530 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
3531 SCTP_NULL());
3532 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3533 }
3534
3535
3536
3537
3538
3539
3540
3541 if (!sctp_addip_noauth && !asconf_ack->auth)
3542 return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
3543
3544
3545 if (!sctp_chunk_length_valid(asconf_ack, sizeof(sctp_addip_chunk_t)))
3546 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3547 commands);
3548
3549 addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data;
3550 rcvd_serial = ntohl(addip_hdr->serial);
3551
3552
3553 if (!sctp_verify_asconf(asoc,
3554 (sctp_paramhdr_t *)addip_hdr->params,
3555 (void *)asconf_ack->chunk_end,
3556 &err_param))
3557 return sctp_sf_violation_paramlen(ep, asoc, type,
3558 (void *)&err_param, commands);
3559
3560 if (last_asconf) {
3561 addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr;
3562 sent_serial = ntohl(addip_hdr->serial);
3563 } else {
3564 sent_serial = asoc->addip_serial - 1;
3565 }
3566
3567
3568
3569
3570
3571
3572
3573 if (ADDIP_SERIAL_gte(rcvd_serial, sent_serial + 1) &&
3574 !(asoc->addip_last_asconf)) {
3575 abort = sctp_make_abort(asoc, asconf_ack,
3576 sizeof(sctp_errhdr_t));
3577 if (abort) {
3578 sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, 0);
3579 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
3580 SCTP_CHUNK(abort));
3581 }
3582
3583
3584
3585 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
3586 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
3587 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
3588 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3589 SCTP_ERROR(ECONNABORTED));
3590 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3591 SCTP_PERR(SCTP_ERROR_ASCONF_ACK));
3592 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
3593 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
3594 return SCTP_DISPOSITION_ABORT;
3595 }
3596
3597 if ((rcvd_serial == sent_serial) && asoc->addip_last_asconf) {
3598 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
3599 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
3600
3601 if (!sctp_process_asconf_ack((struct sctp_association *)asoc,
3602 asconf_ack))
3603 return SCTP_DISPOSITION_CONSUME;
3604
3605 abort = sctp_make_abort(asoc, asconf_ack,
3606 sizeof(sctp_errhdr_t));
3607 if (abort) {
3608 sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
3609 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
3610 SCTP_CHUNK(abort));
3611 }
3612
3613
3614
3615 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
3616 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3617 SCTP_ERROR(ECONNABORTED));
3618 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3619 SCTP_PERR(SCTP_ERROR_ASCONF_ACK));
3620 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
3621 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
3622 return SCTP_DISPOSITION_ABORT;
3623 }
3624
3625 return SCTP_DISPOSITION_DISCARD;
3626}
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
3643 const struct sctp_association *asoc,
3644 const sctp_subtype_t type,
3645 void *arg,
3646 sctp_cmd_seq_t *commands)
3647{
3648 struct sctp_chunk *chunk = arg;
3649 struct sctp_fwdtsn_hdr *fwdtsn_hdr;
3650 __u16 len;
3651 __u32 tsn;
3652
3653 if (!sctp_vtag_verify(chunk, asoc)) {
3654 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
3655 SCTP_NULL());
3656 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3657 }
3658
3659
3660 if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
3661 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3662 commands);
3663
3664 fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
3665 chunk->subh.fwdtsn_hdr = fwdtsn_hdr;
3666 len = ntohs(chunk->chunk_hdr->length);
3667 len -= sizeof(struct sctp_chunkhdr);
3668 skb_pull(chunk->skb, len);
3669
3670 tsn = ntohl(fwdtsn_hdr->new_cum_tsn);
3671 SCTP_DEBUG_PRINTK("%s: TSN 0x%x.\n", __FUNCTION__, tsn);
3672
3673
3674
3675
3676 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
3677 goto discard_noforce;
3678
3679 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
3680 if (len > sizeof(struct sctp_fwdtsn_hdr))
3681 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
3682 SCTP_CHUNK(chunk));
3683
3684
3685 if (asoc->autoclose) {
3686 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
3687 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
3688 }
3689
3690
3691
3692
3693 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
3694
3695 return SCTP_DISPOSITION_CONSUME;
3696
3697discard_noforce:
3698 return SCTP_DISPOSITION_DISCARD;
3699}
3700
3701sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
3702 const struct sctp_endpoint *ep,
3703 const struct sctp_association *asoc,
3704 const sctp_subtype_t type,
3705 void *arg,
3706 sctp_cmd_seq_t *commands)
3707{
3708 struct sctp_chunk *chunk = arg;
3709 struct sctp_fwdtsn_hdr *fwdtsn_hdr;
3710 __u16 len;
3711 __u32 tsn;
3712
3713 if (!sctp_vtag_verify(chunk, asoc)) {
3714 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
3715 SCTP_NULL());
3716 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3717 }
3718
3719
3720 if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
3721 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3722 commands);
3723
3724 fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
3725 chunk->subh.fwdtsn_hdr = fwdtsn_hdr;
3726 len = ntohs(chunk->chunk_hdr->length);
3727 len -= sizeof(struct sctp_chunkhdr);
3728 skb_pull(chunk->skb, len);
3729
3730 tsn = ntohl(fwdtsn_hdr->new_cum_tsn);
3731 SCTP_DEBUG_PRINTK("%s: TSN 0x%x.\n", __FUNCTION__, tsn);
3732
3733
3734
3735
3736 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
3737 goto gen_shutdown;
3738
3739 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
3740 if (len > sizeof(struct sctp_fwdtsn_hdr))
3741 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
3742 SCTP_CHUNK(chunk));
3743
3744
3745gen_shutdown:
3746
3747
3748
3749
3750
3751
3752 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SHUTDOWN, SCTP_NULL());
3753 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
3754 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
3755 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
3756
3757 return SCTP_DISPOSITION_CONSUME;
3758}
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep,
3783 const struct sctp_association *asoc,
3784 const sctp_subtype_t type,
3785 struct sctp_chunk *chunk)
3786{
3787 struct sctp_authhdr *auth_hdr;
3788 struct sctp_hmac *hmac;
3789 unsigned int sig_len;
3790 __u16 key_id;
3791 __u8 *save_digest;
3792 __u8 *digest;
3793
3794
3795 auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
3796 chunk->subh.auth_hdr = auth_hdr;
3797 skb_pull(chunk->skb, sizeof(struct sctp_authhdr));
3798
3799
3800
3801
3802 if (!sctp_auth_asoc_verify_hmac_id(asoc, auth_hdr->hmac_id))
3803 return SCTP_IERROR_AUTH_BAD_HMAC;
3804
3805
3806
3807
3808 key_id = ntohs(auth_hdr->shkey_id);
3809 if (key_id != asoc->active_key_id && !sctp_auth_get_shkey(asoc, key_id))
3810 return SCTP_IERROR_AUTH_BAD_KEYID;
3811
3812
3813
3814
3815
3816 sig_len = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_auth_chunk_t);
3817 hmac = sctp_auth_get_hmac(ntohs(auth_hdr->hmac_id));
3818 if (sig_len != hmac->hmac_len)
3819 return SCTP_IERROR_PROTO_VIOLATION;
3820
3821
3822
3823
3824
3825
3826
3827
3828 digest = auth_hdr->hmac;
3829 skb_pull(chunk->skb, sig_len);
3830
3831 save_digest = kmemdup(digest, sig_len, GFP_ATOMIC);
3832 if (!save_digest)
3833 goto nomem;
3834
3835 memset(digest, 0, sig_len);
3836
3837 sctp_auth_calculate_hmac(asoc, chunk->skb,
3838 (struct sctp_auth_chunk *)chunk->chunk_hdr,
3839 GFP_ATOMIC);
3840
3841
3842 if (memcmp(save_digest, digest, sig_len)) {
3843 kfree(save_digest);
3844 return SCTP_IERROR_BAD_SIG;
3845 }
3846
3847 kfree(save_digest);
3848 chunk->auth = 1;
3849
3850 return SCTP_IERROR_NO_ERROR;
3851nomem:
3852 return SCTP_IERROR_NOMEM;
3853}
3854
3855sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
3856 const struct sctp_association *asoc,
3857 const sctp_subtype_t type,
3858 void *arg,
3859 sctp_cmd_seq_t *commands)
3860{
3861 struct sctp_authhdr *auth_hdr;
3862 struct sctp_chunk *chunk = arg;
3863 struct sctp_chunk *err_chunk;
3864 sctp_ierror_t error;
3865
3866
3867 if (!asoc->peer.auth_capable)
3868 return sctp_sf_unk_chunk(ep, asoc, type, arg, commands);
3869
3870 if (!sctp_vtag_verify(chunk, asoc)) {
3871 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
3872 SCTP_NULL());
3873 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3874 }
3875
3876
3877 if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_auth_chunk)))
3878 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3879 commands);
3880
3881 auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
3882 error = sctp_sf_authenticate(ep, asoc, type, chunk);
3883 switch (error) {
3884 case SCTP_IERROR_AUTH_BAD_HMAC:
3885
3886
3887
3888 err_chunk = sctp_make_op_error(asoc, chunk,
3889 SCTP_ERROR_UNSUP_HMAC,
3890 &auth_hdr->hmac_id,
3891 sizeof(__u16));
3892 if (err_chunk) {
3893 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
3894 SCTP_CHUNK(err_chunk));
3895 }
3896
3897 case SCTP_IERROR_AUTH_BAD_KEYID:
3898 case SCTP_IERROR_BAD_SIG:
3899 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3900 break;
3901 case SCTP_IERROR_PROTO_VIOLATION:
3902 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3903 commands);
3904 break;
3905 case SCTP_IERROR_NOMEM:
3906 return SCTP_DISPOSITION_NOMEM;
3907 default:
3908 break;
3909 }
3910
3911 if (asoc->active_key_id != ntohs(auth_hdr->shkey_id)) {
3912 struct sctp_ulpevent *ev;
3913
3914 ev = sctp_ulpevent_make_authkey(asoc, ntohs(auth_hdr->shkey_id),
3915 SCTP_AUTH_NEWKEY, GFP_ATOMIC);
3916
3917 if (!ev)
3918 return -ENOMEM;
3919
3920 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
3921 SCTP_ULPEVENT(ev));
3922 }
3923
3924 return SCTP_DISPOSITION_CONSUME;
3925}
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
3951 const struct sctp_association *asoc,
3952 const sctp_subtype_t type,
3953 void *arg,
3954 sctp_cmd_seq_t *commands)
3955{
3956 struct sctp_chunk *unk_chunk = arg;
3957 struct sctp_chunk *err_chunk;
3958 sctp_chunkhdr_t *hdr;
3959
3960 SCTP_DEBUG_PRINTK("Processing the unknown chunk id %d.\n", type.chunk);
3961
3962 if (!sctp_vtag_verify(unk_chunk, asoc))
3963 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3964
3965
3966
3967
3968
3969 if (!sctp_chunk_length_valid(unk_chunk, sizeof(sctp_chunkhdr_t)))
3970 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3971 commands);
3972
3973 switch (type.chunk & SCTP_CID_ACTION_MASK) {
3974 case SCTP_CID_ACTION_DISCARD:
3975
3976 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3977 break;
3978 case SCTP_CID_ACTION_DISCARD_ERR:
3979
3980 sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3981
3982
3983 hdr = unk_chunk->chunk_hdr;
3984 err_chunk = sctp_make_op_error(asoc, unk_chunk,
3985 SCTP_ERROR_UNKNOWN_CHUNK, hdr,
3986 WORD_ROUND(ntohs(hdr->length)));
3987 if (err_chunk) {
3988 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
3989 SCTP_CHUNK(err_chunk));
3990 }
3991 return SCTP_DISPOSITION_CONSUME;
3992 break;
3993 case SCTP_CID_ACTION_SKIP:
3994
3995 return SCTP_DISPOSITION_DISCARD;
3996 break;
3997 case SCTP_CID_ACTION_SKIP_ERR:
3998
3999 hdr = unk_chunk->chunk_hdr;
4000 err_chunk = sctp_make_op_error(asoc, unk_chunk,
4001 SCTP_ERROR_UNKNOWN_CHUNK, hdr,
4002 WORD_ROUND(ntohs(hdr->length)));
4003 if (err_chunk) {
4004 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
4005 SCTP_CHUNK(err_chunk));
4006 }
4007
4008 return SCTP_DISPOSITION_CONSUME;
4009 break;
4010 default:
4011 break;
4012 }
4013
4014 return SCTP_DISPOSITION_DISCARD;
4015}
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
4032 const struct sctp_association *asoc,
4033 const sctp_subtype_t type,
4034 void *arg,
4035 sctp_cmd_seq_t *commands)
4036{
4037 struct sctp_chunk *chunk = arg;
4038
4039
4040
4041
4042
4043 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
4044 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
4045 commands);
4046
4047 SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk);
4048 return SCTP_DISPOSITION_DISCARD;
4049}
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069sctp_disposition_t sctp_sf_pdiscard(const struct sctp_endpoint *ep,
4070 const struct sctp_association *asoc,
4071 const sctp_subtype_t type,
4072 void *arg,
4073 sctp_cmd_seq_t *commands)
4074{
4075 SCTP_INC_STATS(SCTP_MIB_IN_PKT_DISCARDS);
4076 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
4077
4078 return SCTP_DISPOSITION_CONSUME;
4079}
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
4097 const struct sctp_association *asoc,
4098 const sctp_subtype_t type,
4099 void *arg,
4100 sctp_cmd_seq_t *commands)
4101{
4102 struct sctp_chunk *chunk = arg;
4103
4104
4105 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
4106 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
4107 commands);
4108
4109 return SCTP_DISPOSITION_VIOLATION;
4110}
4111
4112
4113
4114
4115static sctp_disposition_t sctp_sf_abort_violation(
4116 const struct sctp_endpoint *ep,
4117 const struct sctp_association *asoc,
4118 void *arg,
4119 sctp_cmd_seq_t *commands,
4120 const __u8 *payload,
4121 const size_t paylen)
4122{
4123 struct sctp_packet *packet = NULL;
4124 struct sctp_chunk *chunk = arg;
4125 struct sctp_chunk *abort = NULL;
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138 if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
4139 goto discard;
4140
4141
4142 abort = sctp_make_abort_violation(asoc, chunk, payload, paylen);
4143 if (!abort)
4144 goto nomem;
4145
4146 if (asoc) {
4147
4148 if (chunk->chunk_hdr->type == SCTP_CID_INIT_ACK &&
4149 !asoc->peer.i.init_tag) {
4150 sctp_initack_chunk_t *initack;
4151
4152 initack = (sctp_initack_chunk_t *)chunk->chunk_hdr;
4153 if (!sctp_chunk_length_valid(chunk,
4154 sizeof(sctp_initack_chunk_t)))
4155 abort->chunk_hdr->flags |= SCTP_CHUNK_FLAG_T;
4156 else {
4157 unsigned int inittag;
4158
4159 inittag = ntohl(initack->init_hdr.init_tag);
4160 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_INITTAG,
4161 SCTP_U32(inittag));
4162 }
4163 }
4164
4165 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
4166 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
4167
4168 if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) {
4169 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
4170 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
4171 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4172 SCTP_ERROR(ECONNREFUSED));
4173 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
4174 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
4175 } else {
4176 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4177 SCTP_ERROR(ECONNABORTED));
4178 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4179 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
4180 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
4181 }
4182 } else {
4183 packet = sctp_ootb_pkt_new(asoc, chunk);
4184
4185 if (!packet)
4186 goto nomem_pkt;
4187
4188 if (sctp_test_T_bit(abort))
4189 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
4190
4191 abort->skb->sk = ep->base.sk;
4192
4193 sctp_packet_append_chunk(packet, abort);
4194
4195 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
4196 SCTP_PACKET(packet));
4197
4198 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
4199 }
4200
4201discard:
4202 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
4203
4204 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
4205
4206 return SCTP_DISPOSITION_ABORT;
4207
4208nomem_pkt:
4209 sctp_chunk_free(abort);
4210nomem:
4211 return SCTP_DISPOSITION_NOMEM;
4212}
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233static sctp_disposition_t sctp_sf_violation_chunklen(
4234 const struct sctp_endpoint *ep,
4235 const struct sctp_association *asoc,
4236 const sctp_subtype_t type,
4237 void *arg,
4238 sctp_cmd_seq_t *commands)
4239{
4240 char err_str[]="The following chunk had invalid length:";
4241
4242 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
4243 sizeof(err_str));
4244}
4245
4246
4247
4248
4249
4250
4251static sctp_disposition_t sctp_sf_violation_paramlen(
4252 const struct sctp_endpoint *ep,
4253 const struct sctp_association *asoc,
4254 const sctp_subtype_t type,
4255 void *arg,
4256 sctp_cmd_seq_t *commands) {
4257 char err_str[] = "The following parameter had invalid length:";
4258
4259 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
4260 sizeof(err_str));
4261}
4262
4263
4264
4265
4266
4267
4268
4269static sctp_disposition_t sctp_sf_violation_ctsn(
4270 const struct sctp_endpoint *ep,
4271 const struct sctp_association *asoc,
4272 const sctp_subtype_t type,
4273 void *arg,
4274 sctp_cmd_seq_t *commands)
4275{
4276 char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:";
4277
4278 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
4279 sizeof(err_str));
4280}
4281
4282
4283
4284
4285
4286
4287
4288static sctp_disposition_t sctp_sf_violation_chunk(
4289 const struct sctp_endpoint *ep,
4290 const struct sctp_association *asoc,
4291 const sctp_subtype_t type,
4292 void *arg,
4293 sctp_cmd_seq_t *commands)
4294{
4295 char err_str[]="The following chunk violates protocol:";
4296
4297 if (!asoc)
4298 return sctp_sf_violation(ep, asoc, type, arg, commands);
4299
4300 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
4301 sizeof(err_str));
4302}
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
4364 const struct sctp_association *asoc,
4365 const sctp_subtype_t type,
4366 void *arg,
4367 sctp_cmd_seq_t *commands)
4368{
4369 struct sctp_chunk *repl;
4370 struct sctp_association* my_asoc;
4371
4372
4373
4374
4375
4376 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
4377 SCTP_STATE(SCTP_STATE_COOKIE_WAIT));
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387 repl = sctp_make_init(asoc, &asoc->base.bind_addr, GFP_ATOMIC, 0);
4388 if (!repl)
4389 goto nomem;
4390
4391
4392
4393
4394 my_asoc = (struct sctp_association *)asoc;
4395 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(my_asoc));
4396
4397
4398 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
4399 SCTP_CHUNK(repl));
4400
4401
4402
4403
4404 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
4405 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
4406 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
4407 return SCTP_DISPOSITION_CONSUME;
4408
4409nomem:
4410 return SCTP_DISPOSITION_NOMEM;
4411}
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474sctp_disposition_t sctp_sf_do_prm_send(const struct sctp_endpoint *ep,
4475 const struct sctp_association *asoc,
4476 const sctp_subtype_t type,
4477 void *arg,
4478 sctp_cmd_seq_t *commands)
4479{
4480 struct sctp_chunk *chunk = arg;
4481
4482 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(chunk));
4483 return SCTP_DISPOSITION_CONSUME;
4484}
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(
4513 const struct sctp_endpoint *ep,
4514 const struct sctp_association *asoc,
4515 const sctp_subtype_t type,
4516 void *arg,
4517 sctp_cmd_seq_t *commands)
4518{
4519 int disposition;
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
4530 SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
4531
4532
4533
4534
4535
4536 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
4537 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
4538
4539 disposition = SCTP_DISPOSITION_CONSUME;
4540 if (sctp_outq_is_empty(&asoc->outqueue)) {
4541 disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
4542 arg, commands);
4543 }
4544 return disposition;
4545}
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574sctp_disposition_t sctp_sf_do_9_1_prm_abort(
4575 const struct sctp_endpoint *ep,
4576 const struct sctp_association *asoc,
4577 const sctp_subtype_t type,
4578 void *arg,
4579 sctp_cmd_seq_t *commands)
4580{
4581
4582
4583
4584
4585
4586
4587
4588
4589 struct sctp_chunk *abort = arg;
4590 sctp_disposition_t retval;
4591
4592 retval = SCTP_DISPOSITION_CONSUME;
4593
4594 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
4595
4596
4597
4598
4599
4600 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4601 SCTP_ERROR(ECONNABORTED));
4602
4603 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4604 SCTP_PERR(SCTP_ERROR_USER_ABORT));
4605
4606 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
4607 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
4608
4609 return retval;
4610}
4611
4612
4613sctp_disposition_t sctp_sf_error_closed(const struct sctp_endpoint *ep,
4614 const struct sctp_association *asoc,
4615 const sctp_subtype_t type,
4616 void *arg,
4617 sctp_cmd_seq_t *commands)
4618{
4619 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_ERROR, SCTP_ERROR(-EINVAL));
4620 return SCTP_DISPOSITION_CONSUME;
4621}
4622
4623
4624
4625
4626sctp_disposition_t sctp_sf_error_shutdown(const struct sctp_endpoint *ep,
4627 const struct sctp_association *asoc,
4628 const sctp_subtype_t type,
4629 void *arg,
4630 sctp_cmd_seq_t *commands)
4631{
4632 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_ERROR,
4633 SCTP_ERROR(-ESHUTDOWN));
4634 return SCTP_DISPOSITION_CONSUME;
4635}
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown(
4652 const struct sctp_endpoint *ep,
4653 const struct sctp_association *asoc,
4654 const sctp_subtype_t type,
4655 void *arg,
4656 sctp_cmd_seq_t *commands)
4657{
4658 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
4659 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
4660
4661 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
4662 SCTP_STATE(SCTP_STATE_CLOSED));
4663
4664 SCTP_INC_STATS(SCTP_MIB_SHUTDOWNS);
4665
4666 sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
4667
4668 return SCTP_DISPOSITION_DELETE_TCB;
4669}
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
4686 const struct sctp_endpoint *ep,
4687 const struct sctp_association *asoc,
4688 const sctp_subtype_t type,
4689 void *arg, sctp_cmd_seq_t *commands)
4690{
4691
4692
4693
4694 return sctp_sf_cookie_wait_prm_shutdown(ep, asoc, type, arg, commands);
4695}
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
4712 const struct sctp_endpoint *ep,
4713 const struct sctp_association *asoc,
4714 const sctp_subtype_t type,
4715 void *arg,
4716 sctp_cmd_seq_t *commands)
4717{
4718 struct sctp_chunk *abort = arg;
4719 sctp_disposition_t retval;
4720
4721
4722 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
4723 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
4724 retval = SCTP_DISPOSITION_CONSUME;
4725
4726 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
4727
4728 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
4729 SCTP_STATE(SCTP_STATE_CLOSED));
4730
4731 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
4732
4733
4734
4735
4736
4737 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4738 SCTP_ERROR(ECONNREFUSED));
4739
4740 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
4741 SCTP_PERR(SCTP_ERROR_USER_ABORT));
4742
4743 return retval;
4744}
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(
4761 const struct sctp_endpoint *ep,
4762 const struct sctp_association *asoc,
4763 const sctp_subtype_t type,
4764 void *arg,
4765 sctp_cmd_seq_t *commands)
4766{
4767
4768
4769
4770 return sctp_sf_cookie_wait_prm_abort(ep, asoc, type, arg, commands);
4771}
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785sctp_disposition_t sctp_sf_shutdown_pending_prm_abort(
4786 const struct sctp_endpoint *ep,
4787 const struct sctp_association *asoc,
4788 const sctp_subtype_t type,
4789 void *arg,
4790 sctp_cmd_seq_t *commands)
4791{
4792
4793 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
4794 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
4795
4796 return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands);
4797}
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811sctp_disposition_t sctp_sf_shutdown_sent_prm_abort(
4812 const struct sctp_endpoint *ep,
4813 const struct sctp_association *asoc,
4814 const sctp_subtype_t type,
4815 void *arg,
4816 sctp_cmd_seq_t *commands)
4817{
4818
4819 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
4820 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
4821
4822
4823 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
4824 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
4825
4826 return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands);
4827}
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841sctp_disposition_t sctp_sf_shutdown_ack_sent_prm_abort(
4842 const struct sctp_endpoint *ep,
4843 const struct sctp_association *asoc,
4844 const sctp_subtype_t type,
4845 void *arg,
4846 sctp_cmd_seq_t *commands)
4847{
4848
4849
4850
4851 return sctp_sf_shutdown_sent_prm_abort(ep, asoc, type, arg, commands);
4852}
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876sctp_disposition_t sctp_sf_do_prm_requestheartbeat(
4877 const struct sctp_endpoint *ep,
4878 const struct sctp_association *asoc,
4879 const sctp_subtype_t type,
4880 void *arg,
4881 sctp_cmd_seq_t *commands)
4882{
4883 if (SCTP_DISPOSITION_NOMEM == sctp_sf_heartbeat(ep, asoc, type,
4884 (struct sctp_transport *)arg, commands))
4885 return SCTP_DISPOSITION_NOMEM;
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET,
4899 SCTP_TRANSPORT(arg));
4900 return SCTP_DISPOSITION_CONSUME;
4901}
4902
4903
4904
4905
4906
4907
4908sctp_disposition_t sctp_sf_do_prm_asconf(const struct sctp_endpoint *ep,
4909 const struct sctp_association *asoc,
4910 const sctp_subtype_t type,
4911 void *arg,
4912 sctp_cmd_seq_t *commands)
4913{
4914 struct sctp_chunk *chunk = arg;
4915
4916 sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk));
4917 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
4918 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
4919 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(chunk));
4920 return SCTP_DISPOSITION_CONSUME;
4921}
4922
4923
4924
4925
4926
4927
4928sctp_disposition_t sctp_sf_ignore_primitive(
4929 const struct sctp_endpoint *ep,
4930 const struct sctp_association *asoc,
4931 const sctp_subtype_t type,
4932 void *arg,
4933 sctp_cmd_seq_t *commands)
4934{
4935 SCTP_DEBUG_PRINTK("Primitive type %d is ignored.\n", type.primitive);
4936 return SCTP_DISPOSITION_DISCARD;
4937}
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
4957 const struct sctp_endpoint *ep,
4958 const struct sctp_association *asoc,
4959 const sctp_subtype_t type,
4960 void *arg,
4961 sctp_cmd_seq_t *commands)
4962{
4963 struct sctp_chunk *reply;
4964
4965
4966
4967
4968
4969
4970 reply = sctp_make_shutdown(asoc, NULL);
4971 if (!reply)
4972 goto nomem;
4973
4974
4975
4976
4977 sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
4978
4979
4980 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
4981 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
4982
4983 if (asoc->autoclose)
4984 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
4985 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
4986
4987
4988 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
4989 SCTP_STATE(SCTP_STATE_SHUTDOWN_SENT));
4990
4991
4992
4993
4994
4995
4996 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
4997
4998 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
4999
5000 return SCTP_DISPOSITION_CONSUME;
5001
5002nomem:
5003 return SCTP_DISPOSITION_NOMEM;
5004}
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
5019 const struct sctp_endpoint *ep,
5020 const struct sctp_association *asoc,
5021 const sctp_subtype_t type,
5022 void *arg,
5023 sctp_cmd_seq_t *commands)
5024{
5025 struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
5026 struct sctp_chunk *reply;
5027
5028
5029
5030
5031
5032
5033
5034
5035 if (chunk) {
5036 if (!sctp_vtag_verify(chunk, asoc))
5037 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
5038
5039
5040 if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_shutdown_chunk_t)))
5041 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
5042 commands);
5043 }
5044
5045
5046
5047
5048 reply = sctp_make_shutdown_ack(asoc, chunk);
5049 if (!reply)
5050 goto nomem;
5051
5052
5053
5054
5055 sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
5056
5057
5058 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
5059 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
5060
5061 if (asoc->autoclose)
5062 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
5063 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
5064
5065
5066 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
5067 SCTP_STATE(SCTP_STATE_SHUTDOWN_ACK_SENT));
5068
5069
5070
5071
5072
5073
5074 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
5075
5076 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
5077
5078 return SCTP_DISPOSITION_CONSUME;
5079
5080nomem:
5081 return SCTP_DISPOSITION_NOMEM;
5082}
5083
5084
5085
5086
5087
5088
5089sctp_disposition_t sctp_sf_ignore_other(const struct sctp_endpoint *ep,
5090 const struct sctp_association *asoc,
5091 const sctp_subtype_t type,
5092 void *arg,
5093 sctp_cmd_seq_t *commands)
5094{
5095 SCTP_DEBUG_PRINTK("The event other type %d is ignored\n", type.other);
5096 return SCTP_DISPOSITION_DISCARD;
5097}
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
5115 const struct sctp_association *asoc,
5116 const sctp_subtype_t type,
5117 void *arg,
5118 sctp_cmd_seq_t *commands)
5119{
5120 struct sctp_transport *transport = arg;
5121
5122 SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS);
5123
5124 if (asoc->overall_error_count >= asoc->max_retrans) {
5125 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
5126 SCTP_ERROR(ETIMEDOUT));
5127
5128 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5129 SCTP_PERR(SCTP_ERROR_NO_ERROR));
5130 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
5131 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
5132 return SCTP_DISPOSITION_DELETE_TCB;
5133 }
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163 sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport));
5164
5165
5166 sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN, SCTP_TRANSPORT(transport));
5167
5168 return SCTP_DISPOSITION_CONSUME;
5169}
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
5187 const struct sctp_association *asoc,
5188 const sctp_subtype_t type,
5189 void *arg,
5190 sctp_cmd_seq_t *commands)
5191{
5192 SCTP_INC_STATS(SCTP_MIB_DELAY_SACK_EXPIREDS);
5193 sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
5194 return SCTP_DISPOSITION_CONSUME;
5195}
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
5217 const struct sctp_association *asoc,
5218 const sctp_subtype_t type,
5219 void *arg,
5220 sctp_cmd_seq_t *commands)
5221{
5222 struct sctp_chunk *repl = NULL;
5223 struct sctp_bind_addr *bp;
5224 int attempts = asoc->init_err_counter + 1;
5225
5226 SCTP_DEBUG_PRINTK("Timer T1 expired (INIT).\n");
5227 SCTP_INC_STATS(SCTP_MIB_T1_INIT_EXPIREDS);
5228
5229 if (attempts <= asoc->max_init_attempts) {
5230 bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
5231 repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
5232 if (!repl)
5233 return SCTP_DISPOSITION_NOMEM;
5234
5235
5236 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
5237 SCTP_CHUNK(repl));
5238
5239
5240 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
5241 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
5242
5243 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
5244 } else {
5245 SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d"
5246 " max_init_attempts: %d\n",
5247 attempts, asoc->max_init_attempts);
5248 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
5249 SCTP_ERROR(ETIMEDOUT));
5250 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
5251 SCTP_PERR(SCTP_ERROR_NO_ERROR));
5252 return SCTP_DISPOSITION_DELETE_TCB;
5253 }
5254
5255 return SCTP_DISPOSITION_CONSUME;
5256}
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep,
5278 const struct sctp_association *asoc,
5279 const sctp_subtype_t type,
5280 void *arg,
5281 sctp_cmd_seq_t *commands)
5282{
5283 struct sctp_chunk *repl = NULL;
5284 int attempts = asoc->init_err_counter + 1;
5285
5286 SCTP_DEBUG_PRINTK("Timer T1 expired (COOKIE-ECHO).\n");
5287 SCTP_INC_STATS(SCTP_MIB_T1_COOKIE_EXPIREDS);
5288
5289 if (attempts <= asoc->max_init_attempts) {
5290 repl = sctp_make_cookie_echo(asoc, NULL);
5291 if (!repl)
5292 return SCTP_DISPOSITION_NOMEM;
5293
5294
5295 sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART,
5296 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
5297
5298 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
5299 } else {
5300 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
5301 SCTP_ERROR(ETIMEDOUT));
5302 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
5303 SCTP_PERR(SCTP_ERROR_NO_ERROR));
5304 return SCTP_DISPOSITION_DELETE_TCB;
5305 }
5306
5307 return SCTP_DISPOSITION_CONSUME;
5308}
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
5324 const struct sctp_association *asoc,
5325 const sctp_subtype_t type,
5326 void *arg,
5327 sctp_cmd_seq_t *commands)
5328{
5329 struct sctp_chunk *reply = NULL;
5330
5331 SCTP_DEBUG_PRINTK("Timer T2 expired.\n");
5332 SCTP_INC_STATS(SCTP_MIB_T2_SHUTDOWN_EXPIREDS);
5333
5334 if (asoc->overall_error_count >= asoc->max_retrans) {
5335 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
5336 SCTP_ERROR(ETIMEDOUT));
5337
5338 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5339 SCTP_PERR(SCTP_ERROR_NO_ERROR));
5340 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
5341 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
5342 return SCTP_DISPOSITION_DELETE_TCB;
5343 }
5344
5345 switch (asoc->state) {
5346 case SCTP_STATE_SHUTDOWN_SENT:
5347 reply = sctp_make_shutdown(asoc, NULL);
5348 break;
5349
5350 case SCTP_STATE_SHUTDOWN_ACK_SENT:
5351 reply = sctp_make_shutdown_ack(asoc, NULL);
5352 break;
5353
5354 default:
5355 BUG();
5356 break;
5357 }
5358
5359 if (!reply)
5360 goto nomem;
5361
5362
5363 sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE,
5364 SCTP_TRANSPORT(asoc->shutdown_last_sent_to));
5365
5366
5367
5368
5369 sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
5370
5371
5372 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
5373 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
5374 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
5375 return SCTP_DISPOSITION_CONSUME;
5376
5377nomem:
5378 return SCTP_DISPOSITION_NOMEM;
5379}
5380
5381
5382
5383
5384
5385sctp_disposition_t sctp_sf_t4_timer_expire(
5386 const struct sctp_endpoint *ep,
5387 const struct sctp_association *asoc,
5388 const sctp_subtype_t type,
5389 void *arg,
5390 sctp_cmd_seq_t *commands)
5391{
5392 struct sctp_chunk *chunk = asoc->addip_last_asconf;
5393 struct sctp_transport *transport = chunk->transport;
5394
5395 SCTP_INC_STATS(SCTP_MIB_T4_RTO_EXPIREDS);
5396
5397
5398
5399
5400
5401 sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport));
5402
5403
5404 sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk));
5405
5406
5407
5408
5409
5410
5411 if (asoc->overall_error_count >= asoc->max_retrans) {
5412 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
5413 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
5414 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
5415 SCTP_ERROR(ETIMEDOUT));
5416 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5417 SCTP_PERR(SCTP_ERROR_NO_ERROR));
5418 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);