1#include <linux/kernel.h>
2#include <linux/ip.h>
3#include <linux/sctp.h>
4#include <net/ip.h>
5#include <net/ip6_checksum.h>
6#include <linux/netfilter.h>
7#include <linux/netfilter_ipv4.h>
8#include <net/sctp/checksum.h>
9#include <net/ip_vs.h>
10
11static int
12sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
13 int *verdict, struct ip_vs_conn **cpp)
14{
15 struct net *net;
16 struct ip_vs_service *svc;
17 sctp_chunkhdr_t _schunkh, *sch;
18 sctp_sctphdr_t *sh, _sctph;
19 struct ip_vs_iphdr iph;
20
21 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
22
23 sh = skb_header_pointer(skb, iph.len, sizeof(_sctph), &_sctph);
24 if (sh == NULL)
25 return 0;
26
27 sch = skb_header_pointer(skb, iph.len + sizeof(sctp_sctphdr_t),
28 sizeof(_schunkh), &_schunkh);
29 if (sch == NULL)
30 return 0;
31 net = skb_net(skb);
32 if ((sch->type == SCTP_CID_INIT) &&
33 (svc = ip_vs_service_get(net, af, skb->mark, iph.protocol,
34 &iph.daddr, sh->dest))) {
35 int ignored;
36
37 if (ip_vs_todrop(net_ipvs(net))) {
38
39
40
41
42 ip_vs_service_put(svc);
43 *verdict = NF_DROP;
44 return 0;
45 }
46
47
48
49
50 *cpp = ip_vs_schedule(svc, skb, pd, &ignored);
51 if (!*cpp && ignored <= 0) {
52 if (!ignored)
53 *verdict = ip_vs_leave(svc, skb, pd);
54 else {
55 ip_vs_service_put(svc);
56 *verdict = NF_DROP;
57 }
58 return 0;
59 }
60 ip_vs_service_put(svc);
61 }
62
63 return 1;
64}
65
66static int
67sctp_snat_handler(struct sk_buff *skb,
68 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
69{
70 sctp_sctphdr_t *sctph;
71 unsigned int sctphoff;
72 struct sk_buff *iter;
73 __be32 crc32;
74
75#ifdef CONFIG_IP_VS_IPV6
76 if (cp->af == AF_INET6)
77 sctphoff = sizeof(struct ipv6hdr);
78 else
79#endif
80 sctphoff = ip_hdrlen(skb);
81
82
83 if (!skb_make_writable(skb, sctphoff + sizeof(*sctph)))
84 return 0;
85
86 if (unlikely(cp->app != NULL)) {
87
88 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
89 return 0;
90
91
92 if (!ip_vs_app_pkt_out(cp, skb))
93 return 0;
94 }
95
96 sctph = (void *) skb_network_header(skb) + sctphoff;
97 sctph->source = cp->vport;
98
99
100 crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff);
101 skb_walk_frags(skb, iter)
102 crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter),
103 crc32);
104 crc32 = sctp_end_cksum(crc32);
105 sctph->checksum = crc32;
106
107 return 1;
108}
109
110static int
111sctp_dnat_handler(struct sk_buff *skb,
112 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
113{
114 sctp_sctphdr_t *sctph;
115 unsigned int sctphoff;
116 struct sk_buff *iter;
117 __be32 crc32;
118
119#ifdef CONFIG_IP_VS_IPV6
120 if (cp->af == AF_INET6)
121 sctphoff = sizeof(struct ipv6hdr);
122 else
123#endif
124 sctphoff = ip_hdrlen(skb);
125
126
127 if (!skb_make_writable(skb, sctphoff + sizeof(*sctph)))
128 return 0;
129
130 if (unlikely(cp->app != NULL)) {
131
132 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
133 return 0;
134
135
136 if (!ip_vs_app_pkt_in(cp, skb))
137 return 0;
138 }
139
140 sctph = (void *) skb_network_header(skb) + sctphoff;
141 sctph->dest = cp->dport;
142
143
144 crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff);
145 skb_walk_frags(skb, iter)
146 crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter),
147 crc32);
148 crc32 = sctp_end_cksum(crc32);
149 sctph->checksum = crc32;
150
151 return 1;
152}
153
154static int
155sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
156{
157 unsigned int sctphoff;
158 struct sctphdr *sh, _sctph;
159 struct sk_buff *iter;
160 __le32 cmp;
161 __le32 val;
162 __u32 tmp;
163
164#ifdef CONFIG_IP_VS_IPV6
165 if (af == AF_INET6)
166 sctphoff = sizeof(struct ipv6hdr);
167 else
168#endif
169 sctphoff = ip_hdrlen(skb);
170
171 sh = skb_header_pointer(skb, sctphoff, sizeof(_sctph), &_sctph);
172 if (sh == NULL)
173 return 0;
174
175 cmp = sh->checksum;
176
177 tmp = sctp_start_cksum((__u8 *) sh, skb_headlen(skb));
178 skb_walk_frags(skb, iter)
179 tmp = sctp_update_cksum((__u8 *) iter->data,
180 skb_headlen(iter), tmp);
181
182 val = sctp_end_cksum(tmp);
183
184 if (val != cmp) {
185
186 IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
187 "Failed checksum for");
188 return 0;
189 }
190 return 1;
191}
192
193struct ipvs_sctp_nextstate {
194 int next_state;
195};
196enum ipvs_sctp_event_t {
197 IP_VS_SCTP_EVE_DATA_CLI,
198 IP_VS_SCTP_EVE_DATA_SER,
199 IP_VS_SCTP_EVE_INIT_CLI,
200 IP_VS_SCTP_EVE_INIT_SER,
201 IP_VS_SCTP_EVE_INIT_ACK_CLI,
202 IP_VS_SCTP_EVE_INIT_ACK_SER,
203 IP_VS_SCTP_EVE_COOKIE_ECHO_CLI,
204 IP_VS_SCTP_EVE_COOKIE_ECHO_SER,
205 IP_VS_SCTP_EVE_COOKIE_ACK_CLI,
206 IP_VS_SCTP_EVE_COOKIE_ACK_SER,
207 IP_VS_SCTP_EVE_ABORT_CLI,
208 IP_VS_SCTP_EVE__ABORT_SER,
209 IP_VS_SCTP_EVE_SHUT_CLI,
210 IP_VS_SCTP_EVE_SHUT_SER,
211 IP_VS_SCTP_EVE_SHUT_ACK_CLI,
212 IP_VS_SCTP_EVE_SHUT_ACK_SER,
213 IP_VS_SCTP_EVE_SHUT_COM_CLI,
214 IP_VS_SCTP_EVE_SHUT_COM_SER,
215 IP_VS_SCTP_EVE_LAST
216};
217
218static enum ipvs_sctp_event_t sctp_events[255] = {
219 IP_VS_SCTP_EVE_DATA_CLI,
220 IP_VS_SCTP_EVE_INIT_CLI,
221 IP_VS_SCTP_EVE_INIT_ACK_CLI,
222 IP_VS_SCTP_EVE_DATA_CLI,
223 IP_VS_SCTP_EVE_DATA_CLI,
224 IP_VS_SCTP_EVE_DATA_CLI,
225 IP_VS_SCTP_EVE_ABORT_CLI,
226 IP_VS_SCTP_EVE_SHUT_CLI,
227 IP_VS_SCTP_EVE_SHUT_ACK_CLI,
228 IP_VS_SCTP_EVE_DATA_CLI,
229 IP_VS_SCTP_EVE_COOKIE_ECHO_CLI,
230 IP_VS_SCTP_EVE_COOKIE_ACK_CLI,
231 IP_VS_SCTP_EVE_DATA_CLI,
232 IP_VS_SCTP_EVE_DATA_CLI,
233 IP_VS_SCTP_EVE_SHUT_COM_CLI,
234};
235
236static struct ipvs_sctp_nextstate
237 sctp_states_table[IP_VS_SCTP_S_LAST][IP_VS_SCTP_EVE_LAST] = {
238
239
240
241
242 {{IP_VS_SCTP_S_CLOSED },
243 {IP_VS_SCTP_S_CLOSED },
244 {IP_VS_SCTP_S_INIT_CLI },
245 {IP_VS_SCTP_S_INIT_SER },
246 {IP_VS_SCTP_S_CLOSED },
247 {IP_VS_SCTP_S_CLOSED },
248 {IP_VS_SCTP_S_CLOSED },
249 {IP_VS_SCTP_S_CLOSED },
250 {IP_VS_SCTP_S_CLOSED },
251 {IP_VS_SCTP_S_CLOSED },
252 {IP_VS_SCTP_S_CLOSED },
253 {IP_VS_SCTP_S_CLOSED },
254 {IP_VS_SCTP_S_CLOSED },
255 {IP_VS_SCTP_S_CLOSED },
256 {IP_VS_SCTP_S_CLOSED },
257 {IP_VS_SCTP_S_CLOSED },
258 {IP_VS_SCTP_S_CLOSED },
259 {IP_VS_SCTP_S_CLOSED },
260 },
261
262
263
264
265 {{IP_VS_SCTP_S_CLOSED },
266 {IP_VS_SCTP_S_CLOSED },
267 {IP_VS_SCTP_S_INIT_CLI },
268 {IP_VS_SCTP_S_INIT_SER },
269 {IP_VS_SCTP_S_CLOSED },
270 {IP_VS_SCTP_S_INIT_ACK_SER },
271 {IP_VS_SCTP_S_CLOSED },
272 {IP_VS_SCTP_S_INIT_CLI },
273 {IP_VS_SCTP_S_CLOSED },
274 {IP_VS_SCTP_S_INIT_CLI },
275 {IP_VS_SCTP_S_CLOSED },
276 {IP_VS_SCTP_S_CLOSED },
277 {IP_VS_SCTP_S_CLOSED },
278 {IP_VS_SCTP_S_CLOSED },
279 {IP_VS_SCTP_S_CLOSED },
280 {IP_VS_SCTP_S_CLOSED },
281 {IP_VS_SCTP_S_CLOSED },
282 {IP_VS_SCTP_S_CLOSED }
283 },
284
285
286
287
288 {{IP_VS_SCTP_S_CLOSED },
289 {IP_VS_SCTP_S_CLOSED },
290 {IP_VS_SCTP_S_INIT_CLI },
291 {IP_VS_SCTP_S_INIT_SER },
292 {IP_VS_SCTP_S_INIT_ACK_CLI },
293 {IP_VS_SCTP_S_CLOSED },
294 {IP_VS_SCTP_S_INIT_SER },
295 {IP_VS_SCTP_S_CLOSED },
296 {IP_VS_SCTP_S_INIT_SER },
297 {IP_VS_SCTP_S_CLOSED },
298 {IP_VS_SCTP_S_CLOSED },
299 {IP_VS_SCTP_S_CLOSED },
300 {IP_VS_SCTP_S_CLOSED },
301 {IP_VS_SCTP_S_CLOSED },
302 {IP_VS_SCTP_S_CLOSED },
303 {IP_VS_SCTP_S_CLOSED },
304 {IP_VS_SCTP_S_CLOSED },
305 {IP_VS_SCTP_S_CLOSED }
306 },
307
308
309
310
311 {{IP_VS_SCTP_S_CLOSED },
312 {IP_VS_SCTP_S_CLOSED },
313
314
315
316
317
318
319 {IP_VS_SCTP_S_INIT_CLI },
320 {IP_VS_SCTP_S_INIT_SER },
321
322
323
324
325 {IP_VS_SCTP_S_INIT_ACK_CLI },
326
327
328
329 {IP_VS_SCTP_S_CLOSED },
330
331
332
333 {IP_VS_SCTP_S_CLOSED },
334
335
336
337 {IP_VS_SCTP_S_ECHO_SER },
338
339
340
341 {IP_VS_SCTP_S_CLOSED },
342
343
344
345 {IP_VS_SCTP_S_INIT_ACK_CLI },
346 {IP_VS_SCTP_S_CLOSED },
347 {IP_VS_SCTP_S_CLOSED },
348 {IP_VS_SCTP_S_CLOSED },
349 {IP_VS_SCTP_S_CLOSED },
350 {IP_VS_SCTP_S_CLOSED },
351 {IP_VS_SCTP_S_CLOSED },
352 {IP_VS_SCTP_S_CLOSED },
353 {IP_VS_SCTP_S_CLOSED }
354 },
355
356
357
358
359 {{IP_VS_SCTP_S_CLOSED },
360 {IP_VS_SCTP_S_CLOSED },
361
362
363
364
365
366
367 {IP_VS_SCTP_S_INIT_CLI },
368 {IP_VS_SCTP_S_INIT_SER },
369
370
371
372 {IP_VS_SCTP_S_CLOSED },
373
374
375
376 {IP_VS_SCTP_S_INIT_ACK_SER },
377
378
379
380
381 {IP_VS_SCTP_S_ECHO_CLI },
382
383
384
385
386 {IP_VS_SCTP_S_CLOSED },
387
388
389
390 {IP_VS_SCTP_S_INIT_ACK_SER },
391
392
393
394
395 {IP_VS_SCTP_S_CLOSED },
396 {IP_VS_SCTP_S_CLOSED },
397 {IP_VS_SCTP_S_CLOSED },
398 {IP_VS_SCTP_S_CLOSED },
399 {IP_VS_SCTP_S_CLOSED },
400 {IP_VS_SCTP_S_CLOSED },
401 {IP_VS_SCTP_S_CLOSED },
402 {IP_VS_SCTP_S_CLOSED },
403 {IP_VS_SCTP_S_CLOSED }
404 },
405
406
407
408
409 {{IP_VS_SCTP_S_CLOSED },
410 {IP_VS_SCTP_S_CLOSED },
411
412
413
414
415
416
417 {IP_VS_SCTP_S_INIT_CLI },
418 {IP_VS_SCTP_S_INIT_SER },
419
420
421
422 {IP_VS_SCTP_S_CLOSED },
423
424
425
426
427
428
429 {IP_VS_SCTP_S_ECHO_CLI },
430
431
432
433 {IP_VS_SCTP_S_ECHO_CLI },
434
435
436
437
438 {IP_VS_SCTP_S_CLOSED },
439
440
441
442
443 {IP_VS_SCTP_S_CLOSED },
444
445
446
447
448 {IP_VS_SCTP_S_ESTABLISHED },
449 {IP_VS_SCTP_S_CLOSED },
450 {IP_VS_SCTP_S_CLOSED },
451 {IP_VS_SCTP_S_CLOSED },
452 {IP_VS_SCTP_S_CLOSED },
453 {IP_VS_SCTP_S_CLOSED },
454 {IP_VS_SCTP_S_CLOSED },
455 {IP_VS_SCTP_S_CLOSED },
456 {IP_VS_SCTP_S_CLOSED }
457 },
458
459
460
461
462 {{IP_VS_SCTP_S_CLOSED },
463 {IP_VS_SCTP_S_CLOSED },
464
465
466
467
468
469
470 {IP_VS_SCTP_S_INIT_CLI },
471 {IP_VS_SCTP_S_INIT_SER },
472
473
474
475
476
477
478 {IP_VS_SCTP_S_ECHO_SER },
479
480
481
482 {IP_VS_SCTP_S_CLOSED },
483
484
485
486
487 {IP_VS_SCTP_S_CLOSED },
488
489
490
491 {IP_VS_SCTP_S_ECHO_SER },
492
493
494
495
496 {IP_VS_SCTP_S_ESTABLISHED },
497
498
499
500
501 {IP_VS_SCTP_S_CLOSED },
502 {IP_VS_SCTP_S_CLOSED },
503 {IP_VS_SCTP_S_CLOSED },
504 {IP_VS_SCTP_S_CLOSED },
505 {IP_VS_SCTP_S_CLOSED },
506 {IP_VS_SCTP_S_CLOSED },
507 {IP_VS_SCTP_S_CLOSED },
508 {IP_VS_SCTP_S_CLOSED },
509 {IP_VS_SCTP_S_CLOSED }
510 },
511
512
513
514
515 {{IP_VS_SCTP_S_ESTABLISHED },
516 {IP_VS_SCTP_S_ESTABLISHED },
517
518
519
520
521
522
523 {IP_VS_SCTP_S_INIT_CLI },
524 {IP_VS_SCTP_S_INIT_SER },
525
526
527
528
529
530
531 {IP_VS_SCTP_S_ESTABLISHED },
532 {IP_VS_SCTP_S_ESTABLISHED },
533
534
535
536
537
538 {IP_VS_SCTP_S_ESTABLISHED },
539 {IP_VS_SCTP_S_ESTABLISHED },
540
541
542
543 {IP_VS_SCTP_S_ESTABLISHED },
544 {IP_VS_SCTP_S_ESTABLISHED },
545 {IP_VS_SCTP_S_CLOSED },
546 {IP_VS_SCTP_S_CLOSED },
547
548
549
550 {IP_VS_SCTP_S_SHUT_CLI },
551
552
553
554 {IP_VS_SCTP_S_SHUT_SER },
555
556
557
558
559 {IP_VS_SCTP_S_CLOSED },
560 {IP_VS_SCTP_S_CLOSED },
561 {IP_VS_SCTP_S_CLOSED },
562 {IP_VS_SCTP_S_CLOSED }
563 },
564
565
566
567
568
569
570
571
572
573
574 {{IP_VS_SCTP_S_SHUT_CLI },
575 {IP_VS_SCTP_S_SHUT_CLI },
576
577
578
579
580
581
582 {IP_VS_SCTP_S_INIT_CLI },
583 {IP_VS_SCTP_S_INIT_SER },
584
585
586
587
588
589
590 {IP_VS_SCTP_S_SHUT_CLI },
591 {IP_VS_SCTP_S_SHUT_CLI },
592
593
594
595
596
597 {IP_VS_SCTP_S_ESTABLISHED },
598 {IP_VS_SCTP_S_ESTABLISHED },
599
600
601
602 {IP_VS_SCTP_S_SHUT_CLI },
603 {IP_VS_SCTP_S_SHUT_CLI },
604 {IP_VS_SCTP_S_CLOSED },
605 {IP_VS_SCTP_S_CLOSED },
606
607
608
609 {IP_VS_SCTP_S_SHUT_CLI },
610
611
612
613 {IP_VS_SCTP_S_SHUT_SER },
614
615
616
617
618 {IP_VS_SCTP_S_CLOSED },
619
620
621
622
623 {IP_VS_SCTP_S_SHUT_ACK_SER },
624
625
626
627
628 {IP_VS_SCTP_S_CLOSED },
629 {IP_VS_SCTP_S_CLOSED }
630 },
631
632
633
634
635
636
637
638
639
640
641 {{IP_VS_SCTP_S_SHUT_SER },
642 {IP_VS_SCTP_S_SHUT_SER },
643
644
645
646
647
648
649 {IP_VS_SCTP_S_INIT_CLI },
650 {IP_VS_SCTP_S_INIT_SER },
651
652
653
654
655
656
657 {IP_VS_SCTP_S_SHUT_SER },
658 {IP_VS_SCTP_S_SHUT_SER },
659
660
661
662
663
664 {IP_VS_SCTP_S_ESTABLISHED },
665 {IP_VS_SCTP_S_ESTABLISHED },
666
667
668
669 {IP_VS_SCTP_S_SHUT_SER },
670 {IP_VS_SCTP_S_SHUT_SER },
671 {IP_VS_SCTP_S_CLOSED },
672 {IP_VS_SCTP_S_CLOSED },
673
674
675
676 {IP_VS_SCTP_S_SHUT_CLI },
677
678
679
680 {IP_VS_SCTP_S_SHUT_SER },
681
682
683
684
685 {IP_VS_SCTP_S_SHUT_ACK_CLI },
686
687
688
689
690 {IP_VS_SCTP_S_CLOSED },
691
692
693
694
695 {IP_VS_SCTP_S_CLOSED },
696 {IP_VS_SCTP_S_CLOSED }
697 },
698
699
700
701
702
703
704
705
706
707
708
709 {{IP_VS_SCTP_S_SHUT_ACK_CLI },
710 {IP_VS_SCTP_S_SHUT_ACK_CLI },
711
712
713
714
715
716
717 {IP_VS_SCTP_S_INIT_CLI },
718 {IP_VS_SCTP_S_INIT_SER },
719
720
721
722
723
724
725 {IP_VS_SCTP_S_SHUT_ACK_CLI },
726 {IP_VS_SCTP_S_SHUT_ACK_CLI },
727
728
729
730
731
732 {IP_VS_SCTP_S_ESTABLISHED },
733 {IP_VS_SCTP_S_ESTABLISHED },
734
735
736
737 {IP_VS_SCTP_S_SHUT_ACK_CLI },
738 {IP_VS_SCTP_S_SHUT_ACK_CLI },
739 {IP_VS_SCTP_S_CLOSED },
740 {IP_VS_SCTP_S_CLOSED },
741
742
743
744 {IP_VS_SCTP_S_SHUT_CLI },
745
746
747
748 {IP_VS_SCTP_S_SHUT_SER },
749
750
751
752 {IP_VS_SCTP_S_SHUT_ACK_CLI },
753
754
755
756
757 {IP_VS_SCTP_S_CLOSED },
758
759
760
761
762 {IP_VS_SCTP_S_CLOSED },
763
764
765
766 {IP_VS_SCTP_S_CLOSED }
767 },
768
769
770
771
772
773
774
775
776
777
778
779 {{IP_VS_SCTP_S_SHUT_ACK_SER },
780 {IP_VS_SCTP_S_SHUT_ACK_SER },
781
782
783
784
785
786
787 {IP_VS_SCTP_S_INIT_CLI },
788 {IP_VS_SCTP_S_INIT_SER },
789
790
791
792
793
794
795 {IP_VS_SCTP_S_SHUT_ACK_SER },
796 {IP_VS_SCTP_S_SHUT_ACK_SER },
797
798
799
800
801
802 {IP_VS_SCTP_S_ESTABLISHED },
803 {IP_VS_SCTP_S_ESTABLISHED },
804
805
806
807 {IP_VS_SCTP_S_SHUT_ACK_SER },
808 {IP_VS_SCTP_S_SHUT_ACK_SER },
809 {IP_VS_SCTP_S_CLOSED },
810 {IP_VS_SCTP_S_CLOSED },
811
812
813
814 {IP_VS_SCTP_S_SHUT_CLI },
815
816
817
818 {IP_VS_SCTP_S_SHUT_SER },
819
820
821
822
823 {IP_VS_SCTP_S_CLOSED },
824
825
826
827 {IP_VS_SCTP_S_SHUT_ACK_SER },
828
829
830
831
832 {IP_VS_SCTP_S_CLOSED },
833
834
835
836 {IP_VS_SCTP_S_CLOSED }
837 },
838
839
840
841 {{IP_VS_SCTP_S_CLOSED },
842 {IP_VS_SCTP_S_CLOSED },
843 {IP_VS_SCTP_S_INIT_CLI },
844 {IP_VS_SCTP_S_INIT_SER },
845 {IP_VS_SCTP_S_CLOSED },
846 {IP_VS_SCTP_S_CLOSED },
847 {IP_VS_SCTP_S_CLOSED },
848 {IP_VS_SCTP_S_CLOSED },
849 {IP_VS_SCTP_S_CLOSED },
850 {IP_VS_SCTP_S_CLOSED },
851 {IP_VS_SCTP_S_CLOSED },
852 {IP_VS_SCTP_S_CLOSED },
853 {IP_VS_SCTP_S_CLOSED },
854 {IP_VS_SCTP_S_CLOSED },
855 {IP_VS_SCTP_S_CLOSED },
856 {IP_VS_SCTP_S_CLOSED },
857 {IP_VS_SCTP_S_CLOSED },
858 {IP_VS_SCTP_S_CLOSED }
859 }
860};
861
862
863
864
865static const int sctp_timeouts[IP_VS_SCTP_S_LAST + 1] = {
866 [IP_VS_SCTP_S_NONE] = 2 * HZ,
867 [IP_VS_SCTP_S_INIT_CLI] = 1 * 60 * HZ,
868 [IP_VS_SCTP_S_INIT_SER] = 1 * 60 * HZ,
869 [IP_VS_SCTP_S_INIT_ACK_CLI] = 1 * 60 * HZ,
870 [IP_VS_SCTP_S_INIT_ACK_SER] = 1 * 60 * HZ,
871 [IP_VS_SCTP_S_ECHO_CLI] = 1 * 60 * HZ,
872 [IP_VS_SCTP_S_ECHO_SER] = 1 * 60 * HZ,
873 [IP_VS_SCTP_S_ESTABLISHED] = 15 * 60 * HZ,
874 [IP_VS_SCTP_S_SHUT_CLI] = 1 * 60 * HZ,
875 [IP_VS_SCTP_S_SHUT_SER] = 1 * 60 * HZ,
876 [IP_VS_SCTP_S_SHUT_ACK_CLI] = 1 * 60 * HZ,
877 [IP_VS_SCTP_S_SHUT_ACK_SER] = 1 * 60 * HZ,
878 [IP_VS_SCTP_S_CLOSED] = 10 * HZ,
879 [IP_VS_SCTP_S_LAST] = 2 * HZ,
880};
881
882static const char *sctp_state_name_table[IP_VS_SCTP_S_LAST + 1] = {
883 [IP_VS_SCTP_S_NONE] = "NONE",
884 [IP_VS_SCTP_S_INIT_CLI] = "INIT_CLI",
885 [IP_VS_SCTP_S_INIT_SER] = "INIT_SER",
886 [IP_VS_SCTP_S_INIT_ACK_CLI] = "INIT_ACK_CLI",
887 [IP_VS_SCTP_S_INIT_ACK_SER] = "INIT_ACK_SER",
888 [IP_VS_SCTP_S_ECHO_CLI] = "COOKIE_ECHO_CLI",
889 [IP_VS_SCTP_S_ECHO_SER] = "COOKIE_ECHO_SER",
890 [IP_VS_SCTP_S_ESTABLISHED] = "ESTABISHED",
891 [IP_VS_SCTP_S_SHUT_CLI] = "SHUTDOWN_CLI",
892 [IP_VS_SCTP_S_SHUT_SER] = "SHUTDOWN_SER",
893 [IP_VS_SCTP_S_SHUT_ACK_CLI] = "SHUTDOWN_ACK_CLI",
894 [IP_VS_SCTP_S_SHUT_ACK_SER] = "SHUTDOWN_ACK_SER",
895 [IP_VS_SCTP_S_CLOSED] = "CLOSED",
896 [IP_VS_SCTP_S_LAST] = "BUG!"
897};
898
899
900static const char *sctp_state_name(int state)
901{
902 if (state >= IP_VS_SCTP_S_LAST)
903 return "ERR!";
904 if (sctp_state_name_table[state])
905 return sctp_state_name_table[state];
906 return "?";
907}
908
909static inline void
910set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
911 int direction, const struct sk_buff *skb)
912{
913 sctp_chunkhdr_t _sctpch, *sch;
914 unsigned char chunk_type;
915 int event, next_state;
916 int ihl;
917
918#ifdef CONFIG_IP_VS_IPV6
919 ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
920#else
921 ihl = ip_hdrlen(skb);
922#endif
923
924 sch = skb_header_pointer(skb, ihl + sizeof(sctp_sctphdr_t),
925 sizeof(_sctpch), &_sctpch);
926 if (sch == NULL)
927 return;
928
929 chunk_type = sch->type;
930
931
932
933
934
935
936
937
938
939
940
941 if ((sch->type == SCTP_CID_COOKIE_ECHO) ||
942 (sch->type == SCTP_CID_COOKIE_ACK)) {
943 sch = skb_header_pointer(skb, (ihl + sizeof(sctp_sctphdr_t) +
944 sch->length), sizeof(_sctpch), &_sctpch);
945 if (sch) {
946 if (sch->type == SCTP_CID_ABORT)
947 chunk_type = sch->type;
948 }
949 }
950
951 event = sctp_events[chunk_type];
952
953
954
955
956 if (direction == IP_VS_DIR_OUTPUT)
957 event++;
958
959
960
961 next_state = sctp_states_table[cp->state][event].next_state;
962
963 if (next_state != cp->state) {
964 struct ip_vs_dest *dest = cp->dest;
965
966 IP_VS_DBG_BUF(8, "%s %s %s:%d->"
967 "%s:%d state: %s->%s conn->refcnt:%d\n",
968 pd->pp->name,
969 ((direction == IP_VS_DIR_OUTPUT) ?
970 "output " : "input "),
971 IP_VS_DBG_ADDR(cp->af, &cp->daddr),
972 ntohs(cp->dport),
973 IP_VS_DBG_ADDR(cp->af, &cp->caddr),
974 ntohs(cp->cport),
975 sctp_state_name(cp->state),
976 sctp_state_name(next_state),
977 atomic_read(&cp->refcnt));
978 if (dest) {
979 if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
980 (next_state != IP_VS_SCTP_S_ESTABLISHED)) {
981 atomic_dec(&dest->activeconns);
982 atomic_inc(&dest->inactconns);
983 cp->flags |= IP_VS_CONN_F_INACTIVE;
984 } else if ((cp->flags & IP_VS_CONN_F_INACTIVE) &&
985 (next_state == IP_VS_SCTP_S_ESTABLISHED)) {
986 atomic_inc(&dest->activeconns);
987 atomic_dec(&dest->inactconns);
988 cp->flags &= ~IP_VS_CONN_F_INACTIVE;
989 }
990 }
991 }
992 if (likely(pd))
993 cp->timeout = pd->timeout_table[cp->state = next_state];
994 else
995 cp->timeout = sctp_timeouts[cp->state = next_state];
996}
997
998static void
999sctp_state_transition(struct ip_vs_conn *cp, int direction,
1000 const struct sk_buff *skb, struct ip_vs_proto_data *pd)
1001{
1002 spin_lock(&cp->lock);
1003 set_sctp_state(pd, cp, direction, skb);
1004 spin_unlock(&cp->lock);
1005}
1006
1007static inline __u16 sctp_app_hashkey(__be16 port)
1008{
1009 return (((__force u16)port >> SCTP_APP_TAB_BITS) ^ (__force u16)port)
1010 & SCTP_APP_TAB_MASK;
1011}
1012
1013static int sctp_register_app(struct net *net, struct ip_vs_app *inc)
1014{
1015 struct ip_vs_app *i;
1016 __u16 hash;
1017 __be16 port = inc->port;
1018 int ret = 0;
1019 struct netns_ipvs *ipvs = net_ipvs(net);
1020 struct ip_vs_proto_data *pd = ip_vs_proto_data_get(net, IPPROTO_SCTP);
1021
1022 hash = sctp_app_hashkey(port);
1023
1024 spin_lock_bh(&ipvs->sctp_app_lock);
1025 list_for_each_entry(i, &ipvs->sctp_apps[hash], p_list) {
1026 if (i->port == port) {
1027 ret = -EEXIST;
1028 goto out;
1029 }
1030 }
1031 list_add(&inc->p_list, &ipvs->sctp_apps[hash]);
1032 atomic_inc(&pd->appcnt);
1033out:
1034 spin_unlock_bh(&ipvs->sctp_app_lock);
1035
1036 return ret;
1037}
1038
1039static void sctp_unregister_app(struct net *net, struct ip_vs_app *inc)
1040{
1041 struct netns_ipvs *ipvs = net_ipvs(net);
1042 struct ip_vs_proto_data *pd = ip_vs_proto_data_get(net, IPPROTO_SCTP);
1043
1044 spin_lock_bh(&ipvs->sctp_app_lock);
1045 atomic_dec(&pd->appcnt);
1046 list_del(&inc->p_list);
1047 spin_unlock_bh(&ipvs->sctp_app_lock);
1048}
1049
1050static int sctp_app_conn_bind(struct ip_vs_conn *cp)
1051{
1052 struct netns_ipvs *ipvs = net_ipvs(ip_vs_conn_net(cp));
1053 int hash;
1054 struct ip_vs_app *inc;
1055 int result = 0;
1056
1057
1058 if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
1059 return 0;
1060
1061 hash = sctp_app_hashkey(cp->vport);
1062
1063 spin_lock(&ipvs->sctp_app_lock);
1064 list_for_each_entry(inc, &ipvs->sctp_apps[hash], p_list) {
1065 if (inc->port == cp->vport) {
1066 if (unlikely(!ip_vs_app_inc_get(inc)))
1067 break;
1068 spin_unlock(&ipvs->sctp_app_lock);
1069
1070 IP_VS_DBG_BUF(9, "%s: Binding conn %s:%u->"
1071 "%s:%u to app %s on port %u\n",
1072 __func__,
1073 IP_VS_DBG_ADDR(cp->af, &cp->caddr),
1074 ntohs(cp->cport),
1075 IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
1076 ntohs(cp->vport),
1077 inc->name, ntohs(inc->port));
1078 cp->app = inc;
1079 if (inc->init_conn)
1080 result = inc->init_conn(inc, cp);
1081 goto out;
1082 }
1083 }
1084 spin_unlock(&ipvs->sctp_app_lock);
1085out:
1086 return result;
1087}
1088
1089
1090
1091
1092
1093static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
1094{
1095 struct netns_ipvs *ipvs = net_ipvs(net);
1096
1097 ip_vs_init_hash_table(ipvs->sctp_apps, SCTP_APP_TAB_SIZE);
1098 spin_lock_init(&ipvs->sctp_app_lock);
1099 pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts,
1100 sizeof(sctp_timeouts));
1101}
1102
1103static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd)
1104{
1105 kfree(pd->timeout_table);
1106}
1107
1108struct ip_vs_protocol ip_vs_protocol_sctp = {
1109 .name = "SCTP",
1110 .protocol = IPPROTO_SCTP,
1111 .num_states = IP_VS_SCTP_S_LAST,
1112 .dont_defrag = 0,
1113 .init = NULL,
1114 .exit = NULL,
1115 .init_netns = __ip_vs_sctp_init,
1116 .exit_netns = __ip_vs_sctp_exit,
1117 .register_app = sctp_register_app,
1118 .unregister_app = sctp_unregister_app,
1119 .conn_schedule = sctp_conn_schedule,
1120 .conn_in_get = ip_vs_conn_in_get_proto,
1121 .conn_out_get = ip_vs_conn_out_get_proto,
1122 .snat_handler = sctp_snat_handler,
1123 .dnat_handler = sctp_dnat_handler,
1124 .csum_check = sctp_csum_check,
1125 .state_name = sctp_state_name,
1126 .state_transition = sctp_state_transition,
1127 .app_conn_bind = sctp_app_conn_bind,
1128 .debug_packet = ip_vs_tcpudp_debug_packet,
1129 .timeout_change = NULL,
1130};
1131