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