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