1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/types.h>
16#include <linux/timer.h>
17#include <linux/netfilter.h>
18#include <linux/module.h>
19#include <linux/in.h>
20#include <linux/ip.h>
21#include <linux/sctp.h>
22#include <linux/string.h>
23#include <linux/seq_file.h>
24#include <linux/spinlock.h>
25#include <linux/interrupt.h>
26
27#include <net/netfilter/nf_conntrack.h>
28#include <net/netfilter/nf_conntrack_l4proto.h>
29#include <net/netfilter/nf_conntrack_ecache.h>
30
31
32
33
34
35
36static const char *const sctp_conntrack_names[] = {
37 "NONE",
38 "CLOSED",
39 "COOKIE_WAIT",
40 "COOKIE_ECHOED",
41 "ESTABLISHED",
42 "SHUTDOWN_SENT",
43 "SHUTDOWN_RECD",
44 "SHUTDOWN_ACK_SENT",
45};
46
47#define SECS * HZ
48#define MINS * 60 SECS
49#define HOURS * 60 MINS
50#define DAYS * 24 HOURS
51
52static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
53 [SCTP_CONNTRACK_CLOSED] = 10 SECS,
54 [SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS,
55 [SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS,
56 [SCTP_CONNTRACK_ESTABLISHED] = 5 DAYS,
57 [SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000,
58 [SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000,
59 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS,
60};
61
62#define sNO SCTP_CONNTRACK_NONE
63#define sCL SCTP_CONNTRACK_CLOSED
64#define sCW SCTP_CONNTRACK_COOKIE_WAIT
65#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
66#define sES SCTP_CONNTRACK_ESTABLISHED
67#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
68#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
69#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
70#define sIV SCTP_CONNTRACK_MAX
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
101
102
103
104static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
105 {
106
107
108 {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
109 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
110 {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
111 {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
112 {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
113 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
114 {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},
115 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
116 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
117 },
118 {
119
120
121 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
122 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
123 {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
124 {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
125 {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
126 {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
127 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
128 {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
129 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
130 }
131};
132
133static int sctp_net_id __read_mostly;
134struct sctp_net {
135 struct nf_proto_net pn;
136 unsigned int timeouts[SCTP_CONNTRACK_MAX];
137};
138
139static inline struct sctp_net *sctp_pernet(struct net *net)
140{
141 return net_generic(net, sctp_net_id);
142}
143
144static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
145 struct nf_conntrack_tuple *tuple)
146{
147 const struct sctphdr *hp;
148 struct sctphdr _hdr;
149
150
151 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
152 if (hp == NULL)
153 return false;
154
155 tuple->src.u.sctp.port = hp->source;
156 tuple->dst.u.sctp.port = hp->dest;
157 return true;
158}
159
160static bool sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
161 const struct nf_conntrack_tuple *orig)
162{
163 tuple->src.u.sctp.port = orig->dst.u.sctp.port;
164 tuple->dst.u.sctp.port = orig->src.u.sctp.port;
165 return true;
166}
167
168
169static int sctp_print_tuple(struct seq_file *s,
170 const struct nf_conntrack_tuple *tuple)
171{
172 return seq_printf(s, "sport=%hu dport=%hu ",
173 ntohs(tuple->src.u.sctp.port),
174 ntohs(tuple->dst.u.sctp.port));
175}
176
177
178static int sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
179{
180 enum sctp_conntrack state;
181
182 spin_lock_bh(&ct->lock);
183 state = ct->proto.sctp.state;
184 spin_unlock_bh(&ct->lock);
185
186 return seq_printf(s, "%s ", sctp_conntrack_names[state]);
187}
188
189#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
190for ((offset) = (dataoff) + sizeof(sctp_sctphdr_t), (count) = 0; \
191 (offset) < (skb)->len && \
192 ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \
193 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
194
195
196static int do_basic_checks(struct nf_conn *ct,
197 const struct sk_buff *skb,
198 unsigned int dataoff,
199 unsigned long *map)
200{
201 u_int32_t offset, count;
202 sctp_chunkhdr_t _sch, *sch;
203 int flag;
204
205 flag = 0;
206
207 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
208 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type);
209
210 if (sch->type == SCTP_CID_INIT ||
211 sch->type == SCTP_CID_INIT_ACK ||
212 sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
213 flag = 1;
214
215
216
217
218
219
220 if (((sch->type == SCTP_CID_COOKIE_ACK ||
221 sch->type == SCTP_CID_COOKIE_ECHO ||
222 flag) &&
223 count != 0) || !sch->length) {
224 pr_debug("Basic checks failed\n");
225 return 1;
226 }
227
228 if (map)
229 set_bit(sch->type, map);
230 }
231
232 pr_debug("Basic checks passed\n");
233 return count == 0;
234}
235
236static int sctp_new_state(enum ip_conntrack_dir dir,
237 enum sctp_conntrack cur_state,
238 int chunk_type)
239{
240 int i;
241
242 pr_debug("Chunk type: %d\n", chunk_type);
243
244 switch (chunk_type) {
245 case SCTP_CID_INIT:
246 pr_debug("SCTP_CID_INIT\n");
247 i = 0;
248 break;
249 case SCTP_CID_INIT_ACK:
250 pr_debug("SCTP_CID_INIT_ACK\n");
251 i = 1;
252 break;
253 case SCTP_CID_ABORT:
254 pr_debug("SCTP_CID_ABORT\n");
255 i = 2;
256 break;
257 case SCTP_CID_SHUTDOWN:
258 pr_debug("SCTP_CID_SHUTDOWN\n");
259 i = 3;
260 break;
261 case SCTP_CID_SHUTDOWN_ACK:
262 pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
263 i = 4;
264 break;
265 case SCTP_CID_ERROR:
266 pr_debug("SCTP_CID_ERROR\n");
267 i = 5;
268 break;
269 case SCTP_CID_COOKIE_ECHO:
270 pr_debug("SCTP_CID_COOKIE_ECHO\n");
271 i = 6;
272 break;
273 case SCTP_CID_COOKIE_ACK:
274 pr_debug("SCTP_CID_COOKIE_ACK\n");
275 i = 7;
276 break;
277 case SCTP_CID_SHUTDOWN_COMPLETE:
278 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
279 i = 8;
280 break;
281 default:
282
283
284 pr_debug("Unknown chunk type, Will stay in %s\n",
285 sctp_conntrack_names[cur_state]);
286 return cur_state;
287 }
288
289 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
290 dir, sctp_conntrack_names[cur_state], chunk_type,
291 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
292
293 return sctp_conntracks[dir][i][cur_state];
294}
295
296static unsigned int *sctp_get_timeouts(struct net *net)
297{
298 return sctp_pernet(net)->timeouts;
299}
300
301
302static int sctp_packet(struct nf_conn *ct,
303 const struct sk_buff *skb,
304 unsigned int dataoff,
305 enum ip_conntrack_info ctinfo,
306 u_int8_t pf,
307 unsigned int hooknum,
308 unsigned int *timeouts)
309{
310 enum sctp_conntrack new_state, old_state;
311 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
312 const struct sctphdr *sh;
313 struct sctphdr _sctph;
314 const struct sctp_chunkhdr *sch;
315 struct sctp_chunkhdr _sch;
316 u_int32_t offset, count;
317 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
318
319 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
320 if (sh == NULL)
321 goto out;
322
323 if (do_basic_checks(ct, skb, dataoff, map) != 0)
324 goto out;
325
326
327 if (!test_bit(SCTP_CID_INIT, map) &&
328 !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) &&
329 !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
330 !test_bit(SCTP_CID_ABORT, map) &&
331 !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
332 sh->vtag != ct->proto.sctp.vtag[dir]) {
333 pr_debug("Verification tag check failed\n");
334 goto out;
335 }
336
337 old_state = new_state = SCTP_CONNTRACK_NONE;
338 spin_lock_bh(&ct->lock);
339 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
340
341 if (sch->type == SCTP_CID_INIT) {
342
343 if (sh->vtag != 0)
344 goto out_unlock;
345 } else if (sch->type == SCTP_CID_ABORT) {
346
347 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
348 sh->vtag != ct->proto.sctp.vtag[!dir])
349 goto out_unlock;
350 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
351
352 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
353 sh->vtag != ct->proto.sctp.vtag[!dir] &&
354 sch->flags & SCTP_CHUNK_FLAG_T)
355 goto out_unlock;
356 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
357
358 if (sh->vtag != ct->proto.sctp.vtag[dir])
359 goto out_unlock;
360 }
361
362 old_state = ct->proto.sctp.state;
363 new_state = sctp_new_state(dir, old_state, sch->type);
364
365
366 if (new_state == SCTP_CONNTRACK_MAX) {
367 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
368 "conntrack=%u\n",
369 dir, sch->type, old_state);
370 goto out_unlock;
371 }
372
373
374 if (sch->type == SCTP_CID_INIT ||
375 sch->type == SCTP_CID_INIT_ACK) {
376 sctp_inithdr_t _inithdr, *ih;
377
378 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
379 sizeof(_inithdr), &_inithdr);
380 if (ih == NULL)
381 goto out_unlock;
382 pr_debug("Setting vtag %x for dir %d\n",
383 ih->init_tag, !dir);
384 ct->proto.sctp.vtag[!dir] = ih->init_tag;
385 }
386
387 ct->proto.sctp.state = new_state;
388 if (old_state != new_state)
389 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
390 }
391 spin_unlock_bh(&ct->lock);
392
393 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
394
395 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
396 dir == IP_CT_DIR_REPLY &&
397 new_state == SCTP_CONNTRACK_ESTABLISHED) {
398 pr_debug("Setting assured bit\n");
399 set_bit(IPS_ASSURED_BIT, &ct->status);
400 nf_conntrack_event_cache(IPCT_ASSURED, ct);
401 }
402
403 return NF_ACCEPT;
404
405out_unlock:
406 spin_unlock_bh(&ct->lock);
407out:
408 return -NF_ACCEPT;
409}
410
411
412static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
413 unsigned int dataoff, unsigned int *timeouts)
414{
415 enum sctp_conntrack new_state;
416 const struct sctphdr *sh;
417 struct sctphdr _sctph;
418 const struct sctp_chunkhdr *sch;
419 struct sctp_chunkhdr _sch;
420 u_int32_t offset, count;
421 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
422
423 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
424 if (sh == NULL)
425 return false;
426
427 if (do_basic_checks(ct, skb, dataoff, map) != 0)
428 return false;
429
430
431 if (test_bit(SCTP_CID_ABORT, map) ||
432 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
433 test_bit(SCTP_CID_COOKIE_ACK, map))
434 return false;
435
436 memset(&ct->proto.sctp, 0, sizeof(ct->proto.sctp));
437 new_state = SCTP_CONNTRACK_MAX;
438 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
439
440 new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
441 SCTP_CONNTRACK_NONE, sch->type);
442
443
444 if (new_state == SCTP_CONNTRACK_NONE ||
445 new_state == SCTP_CONNTRACK_MAX) {
446 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
447 return false;
448 }
449
450
451 if (sch->type == SCTP_CID_INIT) {
452 if (sh->vtag == 0) {
453 sctp_inithdr_t _inithdr, *ih;
454
455 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
456 sizeof(_inithdr), &_inithdr);
457 if (ih == NULL)
458 return false;
459
460 pr_debug("Setting vtag %x for new conn\n",
461 ih->init_tag);
462
463 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
464 ih->init_tag;
465 } else {
466
467 return false;
468 }
469 }
470
471
472 else {
473 pr_debug("Setting vtag %x for new conn OOTB\n",
474 sh->vtag);
475 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
476 }
477
478 ct->proto.sctp.state = new_state;
479 }
480
481 return true;
482}
483
484#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
485
486#include <linux/netfilter/nfnetlink.h>
487#include <linux/netfilter/nfnetlink_conntrack.h>
488
489static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
490 struct nf_conn *ct)
491{
492 struct nlattr *nest_parms;
493
494 spin_lock_bh(&ct->lock);
495 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP | NLA_F_NESTED);
496 if (!nest_parms)
497 goto nla_put_failure;
498
499 if (nla_put_u8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state) ||
500 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
501 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]) ||
502 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_REPLY,
503 ct->proto.sctp.vtag[IP_CT_DIR_REPLY]))
504 goto nla_put_failure;
505
506 spin_unlock_bh(&ct->lock);
507
508 nla_nest_end(skb, nest_parms);
509
510 return 0;
511
512nla_put_failure:
513 spin_unlock_bh(&ct->lock);
514 return -1;
515}
516
517static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = {
518 [CTA_PROTOINFO_SCTP_STATE] = { .type = NLA_U8 },
519 [CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] = { .type = NLA_U32 },
520 [CTA_PROTOINFO_SCTP_VTAG_REPLY] = { .type = NLA_U32 },
521};
522
523static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
524{
525 struct nlattr *attr = cda[CTA_PROTOINFO_SCTP];
526 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1];
527 int err;
528
529
530 if (!attr)
531 return 0;
532
533 err = nla_parse_nested(tb,
534 CTA_PROTOINFO_SCTP_MAX,
535 attr,
536 sctp_nla_policy);
537 if (err < 0)
538 return err;
539
540 if (!tb[CTA_PROTOINFO_SCTP_STATE] ||
541 !tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] ||
542 !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])
543 return -EINVAL;
544
545 spin_lock_bh(&ct->lock);
546 ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
547 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
548 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
549 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
550 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
551 spin_unlock_bh(&ct->lock);
552
553 return 0;
554}
555
556static int sctp_nlattr_size(void)
557{
558 return nla_total_size(0)
559 + nla_policy_len(sctp_nla_policy, CTA_PROTOINFO_SCTP_MAX + 1);
560}
561#endif
562
563#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
564
565#include <linux/netfilter/nfnetlink.h>
566#include <linux/netfilter/nfnetlink_cttimeout.h>
567
568static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[],
569 struct net *net, void *data)
570{
571 unsigned int *timeouts = data;
572 struct sctp_net *sn = sctp_pernet(net);
573 int i;
574
575
576 for (i=0; i<SCTP_CONNTRACK_MAX; i++)
577 timeouts[i] = sn->timeouts[i];
578
579
580 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
581 if (tb[i]) {
582 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
583 }
584 }
585 return 0;
586}
587
588static int
589sctp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
590{
591 const unsigned int *timeouts = data;
592 int i;
593
594 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
595 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
596 goto nla_put_failure;
597 }
598 return 0;
599
600nla_put_failure:
601 return -ENOSPC;
602}
603
604static const struct nla_policy
605sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
606 [CTA_TIMEOUT_SCTP_CLOSED] = { .type = NLA_U32 },
607 [CTA_TIMEOUT_SCTP_COOKIE_WAIT] = { .type = NLA_U32 },
608 [CTA_TIMEOUT_SCTP_COOKIE_ECHOED] = { .type = NLA_U32 },
609 [CTA_TIMEOUT_SCTP_ESTABLISHED] = { .type = NLA_U32 },
610 [CTA_TIMEOUT_SCTP_SHUTDOWN_SENT] = { .type = NLA_U32 },
611 [CTA_TIMEOUT_SCTP_SHUTDOWN_RECD] = { .type = NLA_U32 },
612 [CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT] = { .type = NLA_U32 },
613};
614#endif
615
616
617#ifdef CONFIG_SYSCTL
618static struct ctl_table sctp_sysctl_table[] = {
619 {
620 .procname = "nf_conntrack_sctp_timeout_closed",
621 .maxlen = sizeof(unsigned int),
622 .mode = 0644,
623 .proc_handler = proc_dointvec_jiffies,
624 },
625 {
626 .procname = "nf_conntrack_sctp_timeout_cookie_wait",
627 .maxlen = sizeof(unsigned int),
628 .mode = 0644,
629 .proc_handler = proc_dointvec_jiffies,
630 },
631 {
632 .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
633 .maxlen = sizeof(unsigned int),
634 .mode = 0644,
635 .proc_handler = proc_dointvec_jiffies,
636 },
637 {
638 .procname = "nf_conntrack_sctp_timeout_established",
639 .maxlen = sizeof(unsigned int),
640 .mode = 0644,
641 .proc_handler = proc_dointvec_jiffies,
642 },
643 {
644 .procname = "nf_conntrack_sctp_timeout_shutdown_sent",
645 .maxlen = sizeof(unsigned int),
646 .mode = 0644,
647 .proc_handler = proc_dointvec_jiffies,
648 },
649 {
650 .procname = "nf_conntrack_sctp_timeout_shutdown_recd",
651 .maxlen = sizeof(unsigned int),
652 .mode = 0644,
653 .proc_handler = proc_dointvec_jiffies,
654 },
655 {
656 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
657 .maxlen = sizeof(unsigned int),
658 .mode = 0644,
659 .proc_handler = proc_dointvec_jiffies,
660 },
661 { }
662};
663
664#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
665static struct ctl_table sctp_compat_sysctl_table[] = {
666 {
667 .procname = "ip_conntrack_sctp_timeout_closed",
668 .maxlen = sizeof(unsigned int),
669 .mode = 0644,
670 .proc_handler = proc_dointvec_jiffies,
671 },
672 {
673 .procname = "ip_conntrack_sctp_timeout_cookie_wait",
674 .maxlen = sizeof(unsigned int),
675 .mode = 0644,
676 .proc_handler = proc_dointvec_jiffies,
677 },
678 {
679 .procname = "ip_conntrack_sctp_timeout_cookie_echoed",
680 .maxlen = sizeof(unsigned int),
681 .mode = 0644,
682 .proc_handler = proc_dointvec_jiffies,
683 },
684 {
685 .procname = "ip_conntrack_sctp_timeout_established",
686 .maxlen = sizeof(unsigned int),
687 .mode = 0644,
688 .proc_handler = proc_dointvec_jiffies,
689 },
690 {
691 .procname = "ip_conntrack_sctp_timeout_shutdown_sent",
692 .maxlen = sizeof(unsigned int),
693 .mode = 0644,
694 .proc_handler = proc_dointvec_jiffies,
695 },
696 {
697 .procname = "ip_conntrack_sctp_timeout_shutdown_recd",
698 .maxlen = sizeof(unsigned int),
699 .mode = 0644,
700 .proc_handler = proc_dointvec_jiffies,
701 },
702 {
703 .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
704 .maxlen = sizeof(unsigned int),
705 .mode = 0644,
706 .proc_handler = proc_dointvec_jiffies,
707 },
708 { }
709};
710#endif
711#endif
712
713static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn,
714 struct sctp_net *sn)
715{
716#ifdef CONFIG_SYSCTL
717 if (pn->ctl_table)
718 return 0;
719
720 pn->ctl_table = kmemdup(sctp_sysctl_table,
721 sizeof(sctp_sysctl_table),
722 GFP_KERNEL);
723 if (!pn->ctl_table)
724 return -ENOMEM;
725
726 pn->ctl_table[0].data = &sn->timeouts[SCTP_CONNTRACK_CLOSED];
727 pn->ctl_table[1].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_WAIT];
728 pn->ctl_table[2].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_ECHOED];
729 pn->ctl_table[3].data = &sn->timeouts[SCTP_CONNTRACK_ESTABLISHED];
730 pn->ctl_table[4].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT];
731 pn->ctl_table[5].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD];
732 pn->ctl_table[6].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT];
733#endif
734 return 0;
735}
736
737static int sctp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
738 struct sctp_net *sn)
739{
740#ifdef CONFIG_SYSCTL
741#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
742 pn->ctl_compat_table = kmemdup(sctp_compat_sysctl_table,
743 sizeof(sctp_compat_sysctl_table),
744 GFP_KERNEL);
745 if (!pn->ctl_compat_table)
746 return -ENOMEM;
747
748 pn->ctl_compat_table[0].data = &sn->timeouts[SCTP_CONNTRACK_CLOSED];
749 pn->ctl_compat_table[1].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_WAIT];
750 pn->ctl_compat_table[2].data = &sn->timeouts[SCTP_CONNTRACK_COOKIE_ECHOED];
751 pn->ctl_compat_table[3].data = &sn->timeouts[SCTP_CONNTRACK_ESTABLISHED];
752 pn->ctl_compat_table[4].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT];
753 pn->ctl_compat_table[5].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD];
754 pn->ctl_compat_table[6].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT];
755#endif
756#endif
757 return 0;
758}
759
760static int sctp_init_net(struct net *net, u_int16_t proto)
761{
762 int ret;
763 struct sctp_net *sn = sctp_pernet(net);
764 struct nf_proto_net *pn = &sn->pn;
765
766 if (!pn->users) {
767 int i;
768
769 for (i = 0; i < SCTP_CONNTRACK_MAX; i++)
770 sn->timeouts[i] = sctp_timeouts[i];
771 }
772
773 if (proto == AF_INET) {
774 ret = sctp_kmemdup_compat_sysctl_table(pn, sn);
775 if (ret < 0)
776 return ret;
777
778 ret = sctp_kmemdup_sysctl_table(pn, sn);
779 if (ret < 0)
780 nf_ct_kfree_compat_sysctl_table(pn);
781 } else
782 ret = sctp_kmemdup_sysctl_table(pn, sn);
783
784 return ret;
785}
786
787static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
788 .l3proto = PF_INET,
789 .l4proto = IPPROTO_SCTP,
790 .name = "sctp",
791 .pkt_to_tuple = sctp_pkt_to_tuple,
792 .invert_tuple = sctp_invert_tuple,
793 .print_tuple = sctp_print_tuple,
794 .print_conntrack = sctp_print_conntrack,
795 .packet = sctp_packet,
796 .get_timeouts = sctp_get_timeouts,
797 .new = sctp_new,
798 .me = THIS_MODULE,
799#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
800 .to_nlattr = sctp_to_nlattr,
801 .nlattr_size = sctp_nlattr_size,
802 .from_nlattr = nlattr_to_sctp,
803 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
804 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
805 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
806 .nla_policy = nf_ct_port_nla_policy,
807#endif
808#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
809 .ctnl_timeout = {
810 .nlattr_to_obj = sctp_timeout_nlattr_to_obj,
811 .obj_to_nlattr = sctp_timeout_obj_to_nlattr,
812 .nlattr_max = CTA_TIMEOUT_SCTP_MAX,
813 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
814 .nla_policy = sctp_timeout_nla_policy,
815 },
816#endif
817 .net_id = &sctp_net_id,
818 .init_net = sctp_init_net,
819};
820
821static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
822 .l3proto = PF_INET6,
823 .l4proto = IPPROTO_SCTP,
824 .name = "sctp",
825 .pkt_to_tuple = sctp_pkt_to_tuple,
826 .invert_tuple = sctp_invert_tuple,
827 .print_tuple = sctp_print_tuple,
828 .print_conntrack = sctp_print_conntrack,
829 .packet = sctp_packet,
830 .get_timeouts = sctp_get_timeouts,
831 .new = sctp_new,
832 .me = THIS_MODULE,
833#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
834 .to_nlattr = sctp_to_nlattr,
835 .nlattr_size = sctp_nlattr_size,
836 .from_nlattr = nlattr_to_sctp,
837 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
838 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
839 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
840 .nla_policy = nf_ct_port_nla_policy,
841#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
842 .ctnl_timeout = {
843 .nlattr_to_obj = sctp_timeout_nlattr_to_obj,
844 .obj_to_nlattr = sctp_timeout_obj_to_nlattr,
845 .nlattr_max = CTA_TIMEOUT_SCTP_MAX,
846 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
847 .nla_policy = sctp_timeout_nla_policy,
848 },
849#endif
850#endif
851 .net_id = &sctp_net_id,
852 .init_net = sctp_init_net,
853};
854
855static int sctp_net_init(struct net *net)
856{
857 int ret = 0;
858
859 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_sctp4);
860 if (ret < 0) {
861 pr_err("nf_conntrack_sctp4: pernet registration failed.\n");
862 goto out;
863 }
864 ret = nf_ct_l4proto_pernet_register(net, &nf_conntrack_l4proto_sctp6);
865 if (ret < 0) {
866 pr_err("nf_conntrack_sctp6: pernet registration failed.\n");
867 goto cleanup_sctp4;
868 }
869 return 0;
870
871cleanup_sctp4:
872 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_sctp4);
873out:
874 return ret;
875}
876
877static void sctp_net_exit(struct net *net)
878{
879 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_sctp6);
880 nf_ct_l4proto_pernet_unregister(net, &nf_conntrack_l4proto_sctp4);
881}
882
883static struct pernet_operations sctp_net_ops = {
884 .init = sctp_net_init,
885 .exit = sctp_net_exit,
886 .id = &sctp_net_id,
887 .size = sizeof(struct sctp_net),
888};
889
890static int __init nf_conntrack_proto_sctp_init(void)
891{
892 int ret;
893
894 ret = register_pernet_subsys(&sctp_net_ops);
895 if (ret < 0)
896 goto out_pernet;
897
898 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp4);
899 if (ret < 0)
900 goto out_sctp4;
901
902 ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp6);
903 if (ret < 0)
904 goto out_sctp6;
905
906 return 0;
907out_sctp6:
908 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
909out_sctp4:
910 unregister_pernet_subsys(&sctp_net_ops);
911out_pernet:
912 return ret;
913}
914
915static void __exit nf_conntrack_proto_sctp_fini(void)
916{
917 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
918 nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
919 unregister_pernet_subsys(&sctp_net_ops);
920}
921
922module_init(nf_conntrack_proto_sctp_init);
923module_exit(nf_conntrack_proto_sctp_fini);
924
925MODULE_LICENSE("GPL");
926MODULE_AUTHOR("Kiran Kumar Immidi");
927MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
928MODULE_ALIAS("ip_conntrack_proto_sctp");
929