1
2
3
4
5
6
7
8
9
10
11
12#include <linux/types.h>
13#include <linux/timer.h>
14#include <linux/netfilter.h>
15#include <linux/module.h>
16#include <linux/in.h>
17#include <linux/ip.h>
18#include <linux/sctp.h>
19#include <linux/string.h>
20#include <linux/seq_file.h>
21#include <linux/spinlock.h>
22#include <linux/interrupt.h>
23
24#include <net/netfilter/nf_conntrack.h>
25#include <net/netfilter/nf_conntrack_l4proto.h>
26#include <net/netfilter/nf_conntrack_ecache.h>
27
28
29
30
31
32
33static const char *const sctp_conntrack_names[] = {
34 "NONE",
35 "CLOSED",
36 "COOKIE_WAIT",
37 "COOKIE_ECHOED",
38 "ESTABLISHED",
39 "SHUTDOWN_SENT",
40 "SHUTDOWN_RECD",
41 "SHUTDOWN_ACK_SENT",
42};
43
44#define SECS * HZ
45#define MINS * 60 SECS
46#define HOURS * 60 MINS
47#define DAYS * 24 HOURS
48
49static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
50 [SCTP_CONNTRACK_CLOSED] = 10 SECS,
51 [SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS,
52 [SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS,
53 [SCTP_CONNTRACK_ESTABLISHED] = 5 DAYS,
54 [SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000,
55 [SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000,
56 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS,
57};
58
59#define sNO SCTP_CONNTRACK_NONE
60#define sCL SCTP_CONNTRACK_CLOSED
61#define sCW SCTP_CONNTRACK_COOKIE_WAIT
62#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
63#define sES SCTP_CONNTRACK_ESTABLISHED
64#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
65#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
66#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
67#define sIV SCTP_CONNTRACK_MAX
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
102 {
103
104
105 {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
106 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
107 {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
108 {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
109 {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
110 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
111 {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},
112 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
113 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
114 },
115 {
116
117
118 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
119 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
120 {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
121 {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
122 {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
123 {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
124 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
125 {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
126 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
127 }
128};
129
130static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
131 struct nf_conntrack_tuple *tuple)
132{
133 const struct sctphdr *hp;
134 struct sctphdr _hdr;
135
136
137 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
138 if (hp == NULL)
139 return false;
140
141 tuple->src.u.sctp.port = hp->source;
142 tuple->dst.u.sctp.port = hp->dest;
143 return true;
144}
145
146static bool sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
147 const struct nf_conntrack_tuple *orig)
148{
149 tuple->src.u.sctp.port = orig->dst.u.sctp.port;
150 tuple->dst.u.sctp.port = orig->src.u.sctp.port;
151 return true;
152}
153
154
155static int sctp_print_tuple(struct seq_file *s,
156 const struct nf_conntrack_tuple *tuple)
157{
158 return seq_printf(s, "sport=%hu dport=%hu ",
159 ntohs(tuple->src.u.sctp.port),
160 ntohs(tuple->dst.u.sctp.port));
161}
162
163
164static int sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
165{
166 enum sctp_conntrack state;
167
168 spin_lock_bh(&ct->lock);
169 state = ct->proto.sctp.state;
170 spin_unlock_bh(&ct->lock);
171
172 return seq_printf(s, "%s ", sctp_conntrack_names[state]);
173}
174
175#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
176for ((offset) = (dataoff) + sizeof(sctp_sctphdr_t), (count) = 0; \
177 (offset) < (skb)->len && \
178 ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \
179 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
180
181
182static int do_basic_checks(struct nf_conn *ct,
183 const struct sk_buff *skb,
184 unsigned int dataoff,
185 unsigned long *map)
186{
187 u_int32_t offset, count;
188 sctp_chunkhdr_t _sch, *sch;
189 int flag;
190
191 flag = 0;
192
193 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
194 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type);
195
196 if (sch->type == SCTP_CID_INIT ||
197 sch->type == SCTP_CID_INIT_ACK ||
198 sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
199 flag = 1;
200
201
202
203
204
205
206 if (((sch->type == SCTP_CID_COOKIE_ACK ||
207 sch->type == SCTP_CID_COOKIE_ECHO ||
208 flag) &&
209 count != 0) || !sch->length) {
210 pr_debug("Basic checks failed\n");
211 return 1;
212 }
213
214 if (map)
215 set_bit(sch->type, map);
216 }
217
218 pr_debug("Basic checks passed\n");
219 return count == 0;
220}
221
222static int sctp_new_state(enum ip_conntrack_dir dir,
223 enum sctp_conntrack cur_state,
224 int chunk_type)
225{
226 int i;
227
228 pr_debug("Chunk type: %d\n", chunk_type);
229
230 switch (chunk_type) {
231 case SCTP_CID_INIT:
232 pr_debug("SCTP_CID_INIT\n");
233 i = 0;
234 break;
235 case SCTP_CID_INIT_ACK:
236 pr_debug("SCTP_CID_INIT_ACK\n");
237 i = 1;
238 break;
239 case SCTP_CID_ABORT:
240 pr_debug("SCTP_CID_ABORT\n");
241 i = 2;
242 break;
243 case SCTP_CID_SHUTDOWN:
244 pr_debug("SCTP_CID_SHUTDOWN\n");
245 i = 3;
246 break;
247 case SCTP_CID_SHUTDOWN_ACK:
248 pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
249 i = 4;
250 break;
251 case SCTP_CID_ERROR:
252 pr_debug("SCTP_CID_ERROR\n");
253 i = 5;
254 break;
255 case SCTP_CID_COOKIE_ECHO:
256 pr_debug("SCTP_CID_COOKIE_ECHO\n");
257 i = 6;
258 break;
259 case SCTP_CID_COOKIE_ACK:
260 pr_debug("SCTP_CID_COOKIE_ACK\n");
261 i = 7;
262 break;
263 case SCTP_CID_SHUTDOWN_COMPLETE:
264 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
265 i = 8;
266 break;
267 default:
268
269
270 pr_debug("Unknown chunk type, Will stay in %s\n",
271 sctp_conntrack_names[cur_state]);
272 return cur_state;
273 }
274
275 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
276 dir, sctp_conntrack_names[cur_state], chunk_type,
277 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
278
279 return sctp_conntracks[dir][i][cur_state];
280}
281
282
283static int sctp_packet(struct nf_conn *ct,
284 const struct sk_buff *skb,
285 unsigned int dataoff,
286 enum ip_conntrack_info ctinfo,
287 u_int8_t pf,
288 unsigned int hooknum)
289{
290 enum sctp_conntrack new_state, old_state;
291 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
292 const struct sctphdr *sh;
293 struct sctphdr _sctph;
294 const struct sctp_chunkhdr *sch;
295 struct sctp_chunkhdr _sch;
296 u_int32_t offset, count;
297 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
298
299 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
300 if (sh == NULL)
301 goto out;
302
303 if (do_basic_checks(ct, skb, dataoff, map) != 0)
304 goto out;
305
306
307 if (!test_bit(SCTP_CID_INIT, map) &&
308 !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) &&
309 !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
310 !test_bit(SCTP_CID_ABORT, map) &&
311 !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
312 sh->vtag != ct->proto.sctp.vtag[dir]) {
313 pr_debug("Verification tag check failed\n");
314 goto out;
315 }
316
317 old_state = new_state = SCTP_CONNTRACK_NONE;
318 spin_lock_bh(&ct->lock);
319 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
320
321 if (sch->type == SCTP_CID_INIT) {
322
323 if (sh->vtag != 0)
324 goto out_unlock;
325 } else if (sch->type == SCTP_CID_ABORT) {
326
327 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
328 sh->vtag != ct->proto.sctp.vtag[!dir])
329 goto out_unlock;
330 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
331
332 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
333 sh->vtag != ct->proto.sctp.vtag[!dir] &&
334 sch->flags & SCTP_CHUNK_FLAG_T)
335 goto out_unlock;
336 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
337
338 if (sh->vtag != ct->proto.sctp.vtag[dir])
339 goto out_unlock;
340 }
341
342 old_state = ct->proto.sctp.state;
343 new_state = sctp_new_state(dir, old_state, sch->type);
344
345
346 if (new_state == SCTP_CONNTRACK_MAX) {
347 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
348 "conntrack=%u\n",
349 dir, sch->type, old_state);
350 goto out_unlock;
351 }
352
353
354 if (sch->type == SCTP_CID_INIT ||
355 sch->type == SCTP_CID_INIT_ACK) {
356 sctp_inithdr_t _inithdr, *ih;
357
358 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
359 sizeof(_inithdr), &_inithdr);
360 if (ih == NULL)
361 goto out_unlock;
362 pr_debug("Setting vtag %x for dir %d\n",
363 ih->init_tag, !dir);
364 ct->proto.sctp.vtag[!dir] = ih->init_tag;
365 }
366
367 ct->proto.sctp.state = new_state;
368 if (old_state != new_state)
369 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
370 }
371 spin_unlock_bh(&ct->lock);
372
373 nf_ct_refresh_acct(ct, ctinfo, skb, sctp_timeouts[new_state]);
374
375 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
376 dir == IP_CT_DIR_REPLY &&
377 new_state == SCTP_CONNTRACK_ESTABLISHED) {
378 pr_debug("Setting assured bit\n");
379 set_bit(IPS_ASSURED_BIT, &ct->status);
380 nf_conntrack_event_cache(IPCT_ASSURED, ct);
381 }
382
383 return NF_ACCEPT;
384
385out_unlock:
386 spin_unlock_bh(&ct->lock);
387out:
388 return -NF_ACCEPT;
389}
390
391
392static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
393 unsigned int dataoff)
394{
395 enum sctp_conntrack new_state;
396 const struct sctphdr *sh;
397 struct sctphdr _sctph;
398 const struct sctp_chunkhdr *sch;
399 struct sctp_chunkhdr _sch;
400 u_int32_t offset, count;
401 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
402
403 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
404 if (sh == NULL)
405 return false;
406
407 if (do_basic_checks(ct, skb, dataoff, map) != 0)
408 return false;
409
410
411 if (test_bit(SCTP_CID_ABORT, map) ||
412 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
413 test_bit(SCTP_CID_COOKIE_ACK, map))
414 return false;
415
416 memset(&ct->proto.sctp, 0, sizeof(ct->proto.sctp));
417 new_state = SCTP_CONNTRACK_MAX;
418 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
419
420 new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
421 SCTP_CONNTRACK_NONE, sch->type);
422
423
424 if (new_state == SCTP_CONNTRACK_NONE ||
425 new_state == SCTP_CONNTRACK_MAX) {
426 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
427 return false;
428 }
429
430
431 if (sch->type == SCTP_CID_INIT) {
432 if (sh->vtag == 0) {
433 sctp_inithdr_t _inithdr, *ih;
434
435 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
436 sizeof(_inithdr), &_inithdr);
437 if (ih == NULL)
438 return false;
439
440 pr_debug("Setting vtag %x for new conn\n",
441 ih->init_tag);
442
443 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
444 ih->init_tag;
445 } else {
446
447 return false;
448 }
449 }
450
451
452 else {
453 pr_debug("Setting vtag %x for new conn OOTB\n",
454 sh->vtag);
455 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
456 }
457
458 ct->proto.sctp.state = new_state;
459 }
460
461 return true;
462}
463
464#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
465
466#include <linux/netfilter/nfnetlink.h>
467#include <linux/netfilter/nfnetlink_conntrack.h>
468
469static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
470 struct nf_conn *ct)
471{
472 struct nlattr *nest_parms;
473
474 spin_lock_bh(&ct->lock);
475 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP | NLA_F_NESTED);
476 if (!nest_parms)
477 goto nla_put_failure;
478
479 NLA_PUT_U8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state);
480
481 NLA_PUT_BE32(skb,
482 CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
483 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]);
484
485 NLA_PUT_BE32(skb,
486 CTA_PROTOINFO_SCTP_VTAG_REPLY,
487 ct->proto.sctp.vtag[IP_CT_DIR_REPLY]);
488
489 spin_unlock_bh(&ct->lock);
490
491 nla_nest_end(skb, nest_parms);
492
493 return 0;
494
495nla_put_failure:
496 spin_unlock_bh(&ct->lock);
497 return -1;
498}
499
500static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = {
501 [CTA_PROTOINFO_SCTP_STATE] = { .type = NLA_U8 },
502 [CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] = { .type = NLA_U32 },
503 [CTA_PROTOINFO_SCTP_VTAG_REPLY] = { .type = NLA_U32 },
504};
505
506static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
507{
508 struct nlattr *attr = cda[CTA_PROTOINFO_SCTP];
509 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1];
510 int err;
511
512
513 if (!attr)
514 return 0;
515
516 err = nla_parse_nested(tb,
517 CTA_PROTOINFO_SCTP_MAX,
518 attr,
519 sctp_nla_policy);
520 if (err < 0)
521 return err;
522
523 if (!tb[CTA_PROTOINFO_SCTP_STATE] ||
524 !tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] ||
525 !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])
526 return -EINVAL;
527
528 spin_lock_bh(&ct->lock);
529 ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
530 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
531 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
532 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
533 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
534 spin_unlock_bh(&ct->lock);
535
536 return 0;
537}
538
539static int sctp_nlattr_size(void)
540{
541 return nla_total_size(0)
542 + nla_policy_len(sctp_nla_policy, CTA_PROTOINFO_SCTP_MAX + 1);
543}
544#endif
545
546#ifdef CONFIG_SYSCTL
547static unsigned int sctp_sysctl_table_users;
548static struct ctl_table_header *sctp_sysctl_header;
549static struct ctl_table sctp_sysctl_table[] = {
550 {
551 .procname = "nf_conntrack_sctp_timeout_closed",
552 .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
553 .maxlen = sizeof(unsigned int),
554 .mode = 0644,
555 .proc_handler = proc_dointvec_jiffies,
556 },
557 {
558 .procname = "nf_conntrack_sctp_timeout_cookie_wait",
559 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
560 .maxlen = sizeof(unsigned int),
561 .mode = 0644,
562 .proc_handler = proc_dointvec_jiffies,
563 },
564 {
565 .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
566 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
567 .maxlen = sizeof(unsigned int),
568 .mode = 0644,
569 .proc_handler = proc_dointvec_jiffies,
570 },
571 {
572 .procname = "nf_conntrack_sctp_timeout_established",
573 .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
574 .maxlen = sizeof(unsigned int),
575 .mode = 0644,
576 .proc_handler = proc_dointvec_jiffies,
577 },
578 {
579 .procname = "nf_conntrack_sctp_timeout_shutdown_sent",
580 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
581 .maxlen = sizeof(unsigned int),
582 .mode = 0644,
583 .proc_handler = proc_dointvec_jiffies,
584 },
585 {
586 .procname = "nf_conntrack_sctp_timeout_shutdown_recd",
587 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
588 .maxlen = sizeof(unsigned int),
589 .mode = 0644,
590 .proc_handler = proc_dointvec_jiffies,
591 },
592 {
593 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
594 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
595 .maxlen = sizeof(unsigned int),
596 .mode = 0644,
597 .proc_handler = proc_dointvec_jiffies,
598 },
599 { }
600};
601
602#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
603static struct ctl_table sctp_compat_sysctl_table[] = {
604 {
605 .procname = "ip_conntrack_sctp_timeout_closed",
606 .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
607 .maxlen = sizeof(unsigned int),
608 .mode = 0644,
609 .proc_handler = proc_dointvec_jiffies,
610 },
611 {
612 .procname = "ip_conntrack_sctp_timeout_cookie_wait",
613 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
614 .maxlen = sizeof(unsigned int),
615 .mode = 0644,
616 .proc_handler = proc_dointvec_jiffies,
617 },
618 {
619 .procname = "ip_conntrack_sctp_timeout_cookie_echoed",
620 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
621 .maxlen = sizeof(unsigned int),
622 .mode = 0644,
623 .proc_handler = proc_dointvec_jiffies,
624 },
625 {
626 .procname = "ip_conntrack_sctp_timeout_established",
627 .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
628 .maxlen = sizeof(unsigned int),
629 .mode = 0644,
630 .proc_handler = proc_dointvec_jiffies,
631 },
632 {
633 .procname = "ip_conntrack_sctp_timeout_shutdown_sent",
634 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
635 .maxlen = sizeof(unsigned int),
636 .mode = 0644,
637 .proc_handler = proc_dointvec_jiffies,
638 },
639 {
640 .procname = "ip_conntrack_sctp_timeout_shutdown_recd",
641 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
642 .maxlen = sizeof(unsigned int),
643 .mode = 0644,
644 .proc_handler = proc_dointvec_jiffies,
645 },
646 {
647 .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
648 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
649 .maxlen = sizeof(unsigned int),
650 .mode = 0644,
651 .proc_handler = proc_dointvec_jiffies,
652 },
653 { }
654};
655#endif
656#endif
657
658static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
659 .l3proto = PF_INET,
660 .l4proto = IPPROTO_SCTP,
661 .name = "sctp",
662 .pkt_to_tuple = sctp_pkt_to_tuple,
663 .invert_tuple = sctp_invert_tuple,
664 .print_tuple = sctp_print_tuple,
665 .print_conntrack = sctp_print_conntrack,
666 .packet = sctp_packet,
667 .new = sctp_new,
668 .me = THIS_MODULE,
669#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
670 .to_nlattr = sctp_to_nlattr,
671 .nlattr_size = sctp_nlattr_size,
672 .from_nlattr = nlattr_to_sctp,
673 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
674 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
675 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
676 .nla_policy = nf_ct_port_nla_policy,
677#endif
678#ifdef CONFIG_SYSCTL
679 .ctl_table_users = &sctp_sysctl_table_users,
680 .ctl_table_header = &sctp_sysctl_header,
681 .ctl_table = sctp_sysctl_table,
682#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
683 .ctl_compat_table = sctp_compat_sysctl_table,
684#endif
685#endif
686};
687
688static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
689 .l3proto = PF_INET6,
690 .l4proto = IPPROTO_SCTP,
691 .name = "sctp",
692 .pkt_to_tuple = sctp_pkt_to_tuple,
693 .invert_tuple = sctp_invert_tuple,
694 .print_tuple = sctp_print_tuple,
695 .print_conntrack = sctp_print_conntrack,
696 .packet = sctp_packet,
697 .new = sctp_new,
698 .me = THIS_MODULE,
699#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
700 .to_nlattr = sctp_to_nlattr,
701 .nlattr_size = sctp_nlattr_size,
702 .from_nlattr = nlattr_to_sctp,
703 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
704 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
705 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
706 .nla_policy = nf_ct_port_nla_policy,
707#endif
708#ifdef CONFIG_SYSCTL
709 .ctl_table_users = &sctp_sysctl_table_users,
710 .ctl_table_header = &sctp_sysctl_header,
711 .ctl_table = sctp_sysctl_table,
712#endif
713};
714
715static int __init nf_conntrack_proto_sctp_init(void)
716{
717 int ret;
718
719 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
720 if (ret) {
721 pr_err("nf_conntrack_l4proto_sctp4: protocol register failed\n");
722 goto out;
723 }
724 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
725 if (ret) {
726 pr_err("nf_conntrack_l4proto_sctp6: protocol register failed\n");
727 goto cleanup_sctp4;
728 }
729
730 return ret;
731
732 cleanup_sctp4:
733 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
734 out:
735 return ret;
736}
737
738static void __exit nf_conntrack_proto_sctp_fini(void)
739{
740 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
741 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
742}
743
744module_init(nf_conntrack_proto_sctp_init);
745module_exit(nf_conntrack_proto_sctp_fini);
746
747MODULE_LICENSE("GPL");
748MODULE_AUTHOR("Kiran Kumar Immidi");
749MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
750MODULE_ALIAS("ip_conntrack_proto_sctp");
751