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/in.h>
16#include <linux/ip.h>
17#include <linux/sctp.h>
18#include <linux/string.h>
19#include <linux/seq_file.h>
20#include <linux/spinlock.h>
21#include <linux/interrupt.h>
22#include <net/sctp/checksum.h>
23
24#include <net/netfilter/nf_log.h>
25#include <net/netfilter/nf_conntrack.h>
26#include <net/netfilter/nf_conntrack_l4proto.h>
27#include <net/netfilter/nf_conntrack_ecache.h>
28#include <net/netfilter/nf_conntrack_timeout.h>
29
30
31
32
33
34
35static const char *const sctp_conntrack_names[] = {
36 "NONE",
37 "CLOSED",
38 "COOKIE_WAIT",
39 "COOKIE_ECHOED",
40 "ESTABLISHED",
41 "SHUTDOWN_SENT",
42 "SHUTDOWN_RECD",
43 "SHUTDOWN_ACK_SENT",
44 "HEARTBEAT_SENT",
45 "HEARTBEAT_ACKED",
46};
47
48#define SECS * HZ
49#define MINS * 60 SECS
50#define HOURS * 60 MINS
51#define DAYS * 24 HOURS
52
53static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = {
54 [SCTP_CONNTRACK_CLOSED] = 10 SECS,
55 [SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS,
56 [SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS,
57 [SCTP_CONNTRACK_ESTABLISHED] = 5 DAYS,
58 [SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000,
59 [SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000,
60 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS,
61 [SCTP_CONNTRACK_HEARTBEAT_SENT] = 30 SECS,
62 [SCTP_CONNTRACK_HEARTBEAT_ACKED] = 210 SECS,
63};
64
65#define SCTP_FLAG_HEARTBEAT_VTAG_FAILED 1
66
67#define sNO SCTP_CONNTRACK_NONE
68#define sCL SCTP_CONNTRACK_CLOSED
69#define sCW SCTP_CONNTRACK_COOKIE_WAIT
70#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
71#define sES SCTP_CONNTRACK_ESTABLISHED
72#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
73#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
74#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
75#define sHS SCTP_CONNTRACK_HEARTBEAT_SENT
76#define sHA SCTP_CONNTRACK_HEARTBEAT_ACKED
77#define sIV SCTP_CONNTRACK_MAX
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
104
105
106
107
108
109
110
111
112
113
114
115static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
116 {
117
118
119 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCW, sHA},
120 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},
121 {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
122 {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL, sSS},
123 {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA, sHA},
124 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},
125 {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL, sHA},
126 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},
127 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL, sHA},
128 {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
129 {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA}
130 },
131 {
132
133
134 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},
135 {sIV, sCW, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},
136 {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV, sCL},
137 {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV, sSR},
138 {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV, sHA},
139 {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV, sHA},
140 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},
141 {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV, sHA},
142 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV, sHA},
143 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
144 {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHA, sHA}
145 }
146};
147
148#ifdef CONFIG_NF_CONNTRACK_PROCFS
149
150static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
151{
152 seq_printf(s, "%s ", sctp_conntrack_names[ct->proto.sctp.state]);
153}
154#endif
155
156#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
157for ((offset) = (dataoff) + sizeof(struct sctphdr), (count) = 0; \
158 (offset) < (skb)->len && \
159 ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \
160 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
161
162
163static int do_basic_checks(struct nf_conn *ct,
164 const struct sk_buff *skb,
165 unsigned int dataoff,
166 unsigned long *map)
167{
168 u_int32_t offset, count;
169 struct sctp_chunkhdr _sch, *sch;
170 int flag;
171
172 flag = 0;
173
174 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
175 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type);
176
177 if (sch->type == SCTP_CID_INIT ||
178 sch->type == SCTP_CID_INIT_ACK ||
179 sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
180 flag = 1;
181
182
183
184
185
186
187 if (((sch->type == SCTP_CID_COOKIE_ACK ||
188 sch->type == SCTP_CID_COOKIE_ECHO ||
189 flag) &&
190 count != 0) || !sch->length) {
191 pr_debug("Basic checks failed\n");
192 return 1;
193 }
194
195 if (map)
196 set_bit(sch->type, map);
197 }
198
199 pr_debug("Basic checks passed\n");
200 return count == 0;
201}
202
203static int sctp_new_state(enum ip_conntrack_dir dir,
204 enum sctp_conntrack cur_state,
205 int chunk_type)
206{
207 int i;
208
209 pr_debug("Chunk type: %d\n", chunk_type);
210
211 switch (chunk_type) {
212 case SCTP_CID_INIT:
213 pr_debug("SCTP_CID_INIT\n");
214 i = 0;
215 break;
216 case SCTP_CID_INIT_ACK:
217 pr_debug("SCTP_CID_INIT_ACK\n");
218 i = 1;
219 break;
220 case SCTP_CID_ABORT:
221 pr_debug("SCTP_CID_ABORT\n");
222 i = 2;
223 break;
224 case SCTP_CID_SHUTDOWN:
225 pr_debug("SCTP_CID_SHUTDOWN\n");
226 i = 3;
227 break;
228 case SCTP_CID_SHUTDOWN_ACK:
229 pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
230 i = 4;
231 break;
232 case SCTP_CID_ERROR:
233 pr_debug("SCTP_CID_ERROR\n");
234 i = 5;
235 break;
236 case SCTP_CID_COOKIE_ECHO:
237 pr_debug("SCTP_CID_COOKIE_ECHO\n");
238 i = 6;
239 break;
240 case SCTP_CID_COOKIE_ACK:
241 pr_debug("SCTP_CID_COOKIE_ACK\n");
242 i = 7;
243 break;
244 case SCTP_CID_SHUTDOWN_COMPLETE:
245 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
246 i = 8;
247 break;
248 case SCTP_CID_HEARTBEAT:
249 pr_debug("SCTP_CID_HEARTBEAT");
250 i = 9;
251 break;
252 case SCTP_CID_HEARTBEAT_ACK:
253 pr_debug("SCTP_CID_HEARTBEAT_ACK");
254 i = 10;
255 break;
256 default:
257
258 pr_debug("Unknown chunk type, Will stay in %s\n",
259 sctp_conntrack_names[cur_state]);
260 return cur_state;
261 }
262
263 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
264 dir, sctp_conntrack_names[cur_state], chunk_type,
265 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
266
267 return sctp_conntracks[dir][i][cur_state];
268}
269
270
271static noinline bool
272sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
273 const struct sctphdr *sh, unsigned int dataoff)
274{
275 enum sctp_conntrack new_state;
276 const struct sctp_chunkhdr *sch;
277 struct sctp_chunkhdr _sch;
278 u32 offset, count;
279
280 memset(&ct->proto.sctp, 0, sizeof(ct->proto.sctp));
281 new_state = SCTP_CONNTRACK_MAX;
282 for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) {
283 new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
284 SCTP_CONNTRACK_NONE, sch->type);
285
286
287 if (new_state == SCTP_CONNTRACK_NONE ||
288 new_state == SCTP_CONNTRACK_MAX) {
289 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
290 return false;
291 }
292
293
294 if (sch->type == SCTP_CID_INIT) {
295 struct sctp_inithdr _inithdr, *ih;
296
297 if (sh->vtag)
298 return false;
299
300 ih = skb_header_pointer(skb, offset + sizeof(_sch),
301 sizeof(_inithdr), &_inithdr);
302 if (!ih)
303 return false;
304
305 pr_debug("Setting vtag %x for new conn\n",
306 ih->init_tag);
307
308 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = ih->init_tag;
309 } else if (sch->type == SCTP_CID_HEARTBEAT) {
310 pr_debug("Setting vtag %x for secondary conntrack\n",
311 sh->vtag);
312 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = sh->vtag;
313 } else {
314
315
316 pr_debug("Setting vtag %x for new conn OOTB\n",
317 sh->vtag);
318 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
319 }
320
321 ct->proto.sctp.state = SCTP_CONNTRACK_NONE;
322 }
323
324 return true;
325}
326
327static bool sctp_error(struct sk_buff *skb,
328 unsigned int dataoff,
329 const struct nf_hook_state *state)
330{
331 const struct sctphdr *sh;
332 const char *logmsg;
333
334 if (skb->len < dataoff + sizeof(struct sctphdr)) {
335 logmsg = "nf_ct_sctp: short packet ";
336 goto out_invalid;
337 }
338 if (state->hook == NF_INET_PRE_ROUTING &&
339 state->net->ct.sysctl_checksum &&
340 skb->ip_summed == CHECKSUM_NONE) {
341 if (skb_ensure_writable(skb, dataoff + sizeof(*sh))) {
342 logmsg = "nf_ct_sctp: failed to read header ";
343 goto out_invalid;
344 }
345 sh = (const struct sctphdr *)(skb->data + dataoff);
346 if (sh->checksum != sctp_compute_cksum(skb, dataoff)) {
347 logmsg = "nf_ct_sctp: bad CRC ";
348 goto out_invalid;
349 }
350 skb->ip_summed = CHECKSUM_UNNECESSARY;
351 }
352 return false;
353out_invalid:
354 nf_l4proto_log_invalid(skb, state->net, state->pf, IPPROTO_SCTP, "%s", logmsg);
355 return true;
356}
357
358
359int nf_conntrack_sctp_packet(struct nf_conn *ct,
360 struct sk_buff *skb,
361 unsigned int dataoff,
362 enum ip_conntrack_info ctinfo,
363 const struct nf_hook_state *state)
364{
365 enum sctp_conntrack new_state, old_state;
366 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
367 const struct sctphdr *sh;
368 struct sctphdr _sctph;
369 const struct sctp_chunkhdr *sch;
370 struct sctp_chunkhdr _sch;
371 u_int32_t offset, count;
372 unsigned int *timeouts;
373 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
374 bool ignore = false;
375
376 if (sctp_error(skb, dataoff, state))
377 return -NF_ACCEPT;
378
379 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
380 if (sh == NULL)
381 goto out;
382
383 if (do_basic_checks(ct, skb, dataoff, map) != 0)
384 goto out;
385
386 if (!nf_ct_is_confirmed(ct)) {
387
388 if (test_bit(SCTP_CID_ABORT, map) ||
389 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
390 test_bit(SCTP_CID_COOKIE_ACK, map))
391 return -NF_ACCEPT;
392
393 if (!sctp_new(ct, skb, sh, dataoff))
394 return -NF_ACCEPT;
395 }
396
397
398 if (!test_bit(SCTP_CID_INIT, map) &&
399 !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) &&
400 !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
401 !test_bit(SCTP_CID_ABORT, map) &&
402 !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
403 !test_bit(SCTP_CID_HEARTBEAT, map) &&
404 !test_bit(SCTP_CID_HEARTBEAT_ACK, map) &&
405 sh->vtag != ct->proto.sctp.vtag[dir]) {
406 pr_debug("Verification tag check failed\n");
407 goto out;
408 }
409
410 old_state = new_state = SCTP_CONNTRACK_NONE;
411 spin_lock_bh(&ct->lock);
412 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
413
414 if (sch->type == SCTP_CID_INIT) {
415
416 if (sh->vtag != 0)
417 goto out_unlock;
418 } else if (sch->type == SCTP_CID_ABORT) {
419
420 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
421 sh->vtag != ct->proto.sctp.vtag[!dir])
422 goto out_unlock;
423 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
424
425 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
426 sh->vtag != ct->proto.sctp.vtag[!dir] &&
427 sch->flags & SCTP_CHUNK_FLAG_T)
428 goto out_unlock;
429 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
430
431 if (sh->vtag != ct->proto.sctp.vtag[dir])
432 goto out_unlock;
433 } else if (sch->type == SCTP_CID_HEARTBEAT) {
434 if (ct->proto.sctp.vtag[dir] == 0) {
435 pr_debug("Setting %d vtag %x for dir %d\n", sch->type, sh->vtag, dir);
436 ct->proto.sctp.vtag[dir] = sh->vtag;
437 } else if (sh->vtag != ct->proto.sctp.vtag[dir]) {
438 if (test_bit(SCTP_CID_DATA, map) || ignore)
439 goto out_unlock;
440
441 ct->proto.sctp.flags |= SCTP_FLAG_HEARTBEAT_VTAG_FAILED;
442 ct->proto.sctp.last_dir = dir;
443 ignore = true;
444 continue;
445 } else if (ct->proto.sctp.flags & SCTP_FLAG_HEARTBEAT_VTAG_FAILED) {
446 ct->proto.sctp.flags &= ~SCTP_FLAG_HEARTBEAT_VTAG_FAILED;
447 }
448 } else if (sch->type == SCTP_CID_HEARTBEAT_ACK) {
449 if (ct->proto.sctp.vtag[dir] == 0) {
450 pr_debug("Setting vtag %x for dir %d\n",
451 sh->vtag, dir);
452 ct->proto.sctp.vtag[dir] = sh->vtag;
453 } else if (sh->vtag != ct->proto.sctp.vtag[dir]) {
454 if (test_bit(SCTP_CID_DATA, map) || ignore)
455 goto out_unlock;
456
457 if ((ct->proto.sctp.flags & SCTP_FLAG_HEARTBEAT_VTAG_FAILED) == 0 ||
458 ct->proto.sctp.last_dir == dir)
459 goto out_unlock;
460
461 ct->proto.sctp.flags &= ~SCTP_FLAG_HEARTBEAT_VTAG_FAILED;
462 ct->proto.sctp.vtag[dir] = sh->vtag;
463 ct->proto.sctp.vtag[!dir] = 0;
464 } else if (ct->proto.sctp.flags & SCTP_FLAG_HEARTBEAT_VTAG_FAILED) {
465 ct->proto.sctp.flags &= ~SCTP_FLAG_HEARTBEAT_VTAG_FAILED;
466 }
467 }
468
469 old_state = ct->proto.sctp.state;
470 new_state = sctp_new_state(dir, old_state, sch->type);
471
472
473 if (new_state == SCTP_CONNTRACK_MAX) {
474 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
475 "conntrack=%u\n",
476 dir, sch->type, old_state);
477 goto out_unlock;
478 }
479
480
481 if (sch->type == SCTP_CID_INIT ||
482 sch->type == SCTP_CID_INIT_ACK) {
483 struct sctp_inithdr _inithdr, *ih;
484
485 ih = skb_header_pointer(skb, offset + sizeof(_sch),
486 sizeof(_inithdr), &_inithdr);
487 if (ih == NULL)
488 goto out_unlock;
489 pr_debug("Setting vtag %x for dir %d\n",
490 ih->init_tag, !dir);
491 ct->proto.sctp.vtag[!dir] = ih->init_tag;
492 }
493
494 ct->proto.sctp.state = new_state;
495 if (old_state != new_state)
496 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
497 }
498 spin_unlock_bh(&ct->lock);
499
500
501 if (ignore)
502 return NF_ACCEPT;
503
504 timeouts = nf_ct_timeout_lookup(ct);
505 if (!timeouts)
506 timeouts = nf_sctp_pernet(nf_ct_net(ct))->timeouts;
507
508 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
509
510 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
511 dir == IP_CT_DIR_REPLY &&
512 new_state == SCTP_CONNTRACK_ESTABLISHED) {
513 pr_debug("Setting assured bit\n");
514 set_bit(IPS_ASSURED_BIT, &ct->status);
515 nf_conntrack_event_cache(IPCT_ASSURED, ct);
516 }
517
518 return NF_ACCEPT;
519
520out_unlock:
521 spin_unlock_bh(&ct->lock);
522out:
523 return -NF_ACCEPT;
524}
525
526static bool sctp_can_early_drop(const struct nf_conn *ct)
527{
528 switch (ct->proto.sctp.state) {
529 case SCTP_CONNTRACK_SHUTDOWN_SENT:
530 case SCTP_CONNTRACK_SHUTDOWN_RECD:
531 case SCTP_CONNTRACK_SHUTDOWN_ACK_SENT:
532 return true;
533 default:
534 break;
535 }
536
537 return false;
538}
539
540#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
541
542#include <linux/netfilter/nfnetlink.h>
543#include <linux/netfilter/nfnetlink_conntrack.h>
544
545static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
546 struct nf_conn *ct, bool destroy)
547{
548 struct nlattr *nest_parms;
549
550 spin_lock_bh(&ct->lock);
551 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP);
552 if (!nest_parms)
553 goto nla_put_failure;
554
555 if (nla_put_u8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state))
556 goto nla_put_failure;
557
558 if (destroy)
559 goto skip_state;
560
561 if (nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
562 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]) ||
563 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_REPLY,
564 ct->proto.sctp.vtag[IP_CT_DIR_REPLY]))
565 goto nla_put_failure;
566
567skip_state:
568 spin_unlock_bh(&ct->lock);
569 nla_nest_end(skb, nest_parms);
570
571 return 0;
572
573nla_put_failure:
574 spin_unlock_bh(&ct->lock);
575 return -1;
576}
577
578static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = {
579 [CTA_PROTOINFO_SCTP_STATE] = { .type = NLA_U8 },
580 [CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] = { .type = NLA_U32 },
581 [CTA_PROTOINFO_SCTP_VTAG_REPLY] = { .type = NLA_U32 },
582};
583
584#define SCTP_NLATTR_SIZE ( \
585 NLA_ALIGN(NLA_HDRLEN + 1) + \
586 NLA_ALIGN(NLA_HDRLEN + 4) + \
587 NLA_ALIGN(NLA_HDRLEN + 4))
588
589static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
590{
591 struct nlattr *attr = cda[CTA_PROTOINFO_SCTP];
592 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1];
593 int err;
594
595
596 if (!attr)
597 return 0;
598
599 err = nla_parse_nested_deprecated(tb, CTA_PROTOINFO_SCTP_MAX, attr,
600 sctp_nla_policy, NULL);
601 if (err < 0)
602 return err;
603
604 if (!tb[CTA_PROTOINFO_SCTP_STATE] ||
605 !tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] ||
606 !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])
607 return -EINVAL;
608
609 spin_lock_bh(&ct->lock);
610 ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
611 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
612 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
613 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
614 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
615 spin_unlock_bh(&ct->lock);
616
617 return 0;
618}
619#endif
620
621#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
622
623#include <linux/netfilter/nfnetlink.h>
624#include <linux/netfilter/nfnetlink_cttimeout.h>
625
626static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[],
627 struct net *net, void *data)
628{
629 unsigned int *timeouts = data;
630 struct nf_sctp_net *sn = nf_sctp_pernet(net);
631 int i;
632
633 if (!timeouts)
634 timeouts = sn->timeouts;
635
636
637 for (i=0; i<SCTP_CONNTRACK_MAX; i++)
638 timeouts[i] = sn->timeouts[i];
639
640
641 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
642 if (tb[i]) {
643 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
644 }
645 }
646
647 timeouts[CTA_TIMEOUT_SCTP_UNSPEC] = timeouts[CTA_TIMEOUT_SCTP_CLOSED];
648 return 0;
649}
650
651static int
652sctp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
653{
654 const unsigned int *timeouts = data;
655 int i;
656
657 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
658 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
659 goto nla_put_failure;
660 }
661 return 0;
662
663nla_put_failure:
664 return -ENOSPC;
665}
666
667static const struct nla_policy
668sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
669 [CTA_TIMEOUT_SCTP_CLOSED] = { .type = NLA_U32 },
670 [CTA_TIMEOUT_SCTP_COOKIE_WAIT] = { .type = NLA_U32 },
671 [CTA_TIMEOUT_SCTP_COOKIE_ECHOED] = { .type = NLA_U32 },
672 [CTA_TIMEOUT_SCTP_ESTABLISHED] = { .type = NLA_U32 },
673 [CTA_TIMEOUT_SCTP_SHUTDOWN_SENT] = { .type = NLA_U32 },
674 [CTA_TIMEOUT_SCTP_SHUTDOWN_RECD] = { .type = NLA_U32 },
675 [CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT] = { .type = NLA_U32 },
676 [CTA_TIMEOUT_SCTP_HEARTBEAT_SENT] = { .type = NLA_U32 },
677 [CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED] = { .type = NLA_U32 },
678};
679#endif
680
681void nf_conntrack_sctp_init_net(struct net *net)
682{
683 struct nf_sctp_net *sn = nf_sctp_pernet(net);
684 int i;
685
686 for (i = 0; i < SCTP_CONNTRACK_MAX; i++)
687 sn->timeouts[i] = sctp_timeouts[i];
688
689
690
691
692 sn->timeouts[0] = sctp_timeouts[SCTP_CONNTRACK_CLOSED];
693}
694
695const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp = {
696 .l4proto = IPPROTO_SCTP,
697#ifdef CONFIG_NF_CONNTRACK_PROCFS
698 .print_conntrack = sctp_print_conntrack,
699#endif
700 .can_early_drop = sctp_can_early_drop,
701#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
702 .nlattr_size = SCTP_NLATTR_SIZE,
703 .to_nlattr = sctp_to_nlattr,
704 .from_nlattr = nlattr_to_sctp,
705 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
706 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
707 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
708 .nla_policy = nf_ct_port_nla_policy,
709#endif
710#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
711 .ctnl_timeout = {
712 .nlattr_to_obj = sctp_timeout_nlattr_to_obj,
713 .obj_to_nlattr = sctp_timeout_obj_to_nlattr,
714 .nlattr_max = CTA_TIMEOUT_SCTP_MAX,
715 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
716 .nla_policy = sctp_timeout_nla_policy,
717 },
718#endif
719};
720