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