1
2
3
4
5
6
7
8
9
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/sysctl.h>
14#include <linux/spinlock.h>
15#include <linux/skbuff.h>
16#include <linux/dccp.h>
17#include <linux/slab.h>
18
19#include <net/net_namespace.h>
20#include <net/netns/generic.h>
21
22#include <linux/netfilter/nfnetlink_conntrack.h>
23#include <net/netfilter/nf_conntrack.h>
24#include <net/netfilter/nf_conntrack_l4proto.h>
25#include <net/netfilter/nf_conntrack_ecache.h>
26#include <net/netfilter/nf_log.h>
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73#define DCCP_MSL (2 * 60 * HZ)
74
75static const char * const dccp_state_names[] = {
76 [CT_DCCP_NONE] = "NONE",
77 [CT_DCCP_REQUEST] = "REQUEST",
78 [CT_DCCP_RESPOND] = "RESPOND",
79 [CT_DCCP_PARTOPEN] = "PARTOPEN",
80 [CT_DCCP_OPEN] = "OPEN",
81 [CT_DCCP_CLOSEREQ] = "CLOSEREQ",
82 [CT_DCCP_CLOSING] = "CLOSING",
83 [CT_DCCP_TIMEWAIT] = "TIMEWAIT",
84 [CT_DCCP_IGNORE] = "IGNORE",
85 [CT_DCCP_INVALID] = "INVALID",
86};
87
88#define sNO CT_DCCP_NONE
89#define sRQ CT_DCCP_REQUEST
90#define sRS CT_DCCP_RESPOND
91#define sPO CT_DCCP_PARTOPEN
92#define sOP CT_DCCP_OPEN
93#define sCR CT_DCCP_CLOSEREQ
94#define sCG CT_DCCP_CLOSING
95#define sTW CT_DCCP_TIMEWAIT
96#define sIG CT_DCCP_IGNORE
97#define sIV CT_DCCP_INVALID
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131static const u_int8_t
132dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = {
133 [CT_DCCP_ROLE_CLIENT] = {
134 [DCCP_PKT_REQUEST] = {
135
136
137
138
139
140
141
142
143
144
145
146
147 sRQ, sRQ, sRS, sIG, sIG, sIG, sIG, sRQ,
148 },
149 [DCCP_PKT_RESPONSE] = {
150
151
152
153
154
155
156
157
158
159
160
161
162 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIV,
163 },
164 [DCCP_PKT_ACK] = {
165
166
167
168
169
170
171
172
173
174
175
176 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
177 },
178 [DCCP_PKT_DATA] = {
179
180
181
182
183
184
185
186
187
188
189
190 sIV, sIV, sIV, sIV, sOP, sCR, sCG, sIV,
191 },
192 [DCCP_PKT_DATAACK] = {
193
194
195
196
197
198
199
200
201
202
203
204 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
205 },
206 [DCCP_PKT_CLOSEREQ] = {
207
208
209
210
211 sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV
212 },
213 [DCCP_PKT_CLOSE] = {
214
215
216
217
218
219
220
221
222
223
224
225 sIV, sIV, sIV, sCG, sCG, sCG, sIV, sIV
226 },
227 [DCCP_PKT_RESET] = {
228
229
230
231
232
233
234
235
236
237
238
239 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sIG
240 },
241 [DCCP_PKT_SYNC] = {
242
243
244
245
246 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
247 },
248 [DCCP_PKT_SYNCACK] = {
249
250
251
252
253 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
254 },
255 },
256 [CT_DCCP_ROLE_SERVER] = {
257 [DCCP_PKT_REQUEST] = {
258
259
260
261
262
263
264
265
266
267
268
269 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sRQ
270 },
271 [DCCP_PKT_RESPONSE] = {
272
273
274
275
276
277
278
279
280
281
282
283 sIV, sRS, sRS, sIG, sIG, sIG, sIG, sIV
284 },
285 [DCCP_PKT_ACK] = {
286
287
288
289
290
291
292
293
294
295
296
297 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
298 },
299 [DCCP_PKT_DATA] = {
300
301
302
303
304
305
306
307
308
309
310
311 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
312 },
313 [DCCP_PKT_DATAACK] = {
314
315
316
317
318
319
320
321
322
323
324
325 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
326 },
327 [DCCP_PKT_CLOSEREQ] = {
328
329
330
331
332
333
334
335
336
337
338
339 sIV, sIV, sIV, sCR, sCR, sCR, sCR, sIV
340 },
341 [DCCP_PKT_CLOSE] = {
342
343
344
345
346
347
348
349
350
351
352
353 sIV, sIV, sIV, sCG, sCG, sIV, sCG, sIV
354 },
355 [DCCP_PKT_RESET] = {
356
357
358
359
360
361
362
363
364
365
366
367 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sTW, sIG
368 },
369 [DCCP_PKT_SYNC] = {
370
371
372
373
374 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
375 },
376 [DCCP_PKT_SYNCACK] = {
377
378
379
380
381 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
382 },
383 },
384};
385
386static inline struct nf_dccp_net *dccp_pernet(struct net *net)
387{
388 return &net->ct.nf_ct_proto.dccp;
389}
390
391static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
392 struct net *net, struct nf_conntrack_tuple *tuple)
393{
394 struct dccp_hdr _hdr, *dh;
395
396
397 dh = skb_header_pointer(skb, dataoff, 4, &_hdr);
398 if (dh == NULL)
399 return false;
400
401 tuple->src.u.dccp.port = dh->dccph_sport;
402 tuple->dst.u.dccp.port = dh->dccph_dport;
403 return true;
404}
405
406static bool dccp_invert_tuple(struct nf_conntrack_tuple *inv,
407 const struct nf_conntrack_tuple *tuple)
408{
409 inv->src.u.dccp.port = tuple->dst.u.dccp.port;
410 inv->dst.u.dccp.port = tuple->src.u.dccp.port;
411 return true;
412}
413
414static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
415 unsigned int dataoff, unsigned int *timeouts)
416{
417 struct net *net = nf_ct_net(ct);
418 struct nf_dccp_net *dn;
419 struct dccp_hdr _dh, *dh;
420 const char *msg;
421 u_int8_t state;
422
423 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
424 BUG_ON(dh == NULL);
425
426 state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
427 switch (state) {
428 default:
429 dn = dccp_pernet(net);
430 if (dn->dccp_loose == 0) {
431 msg = "not picking up existing connection ";
432 goto out_invalid;
433 }
434 case CT_DCCP_REQUEST:
435 break;
436 case CT_DCCP_INVALID:
437 msg = "invalid state transition ";
438 goto out_invalid;
439 }
440
441 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
442 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
443 ct->proto.dccp.state = CT_DCCP_NONE;
444 ct->proto.dccp.last_pkt = DCCP_PKT_REQUEST;
445 ct->proto.dccp.last_dir = IP_CT_DIR_ORIGINAL;
446 ct->proto.dccp.handshake_seq = 0;
447 return true;
448
449out_invalid:
450 nf_ct_l4proto_log_invalid(skb, ct, "%s", msg);
451 return false;
452}
453
454static u64 dccp_ack_seq(const struct dccp_hdr *dh)
455{
456 const struct dccp_hdr_ack_bits *dhack;
457
458 dhack = (void *)dh + __dccp_basic_hdr_len(dh);
459 return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) +
460 ntohl(dhack->dccph_ack_nr_low);
461}
462
463static unsigned int *dccp_get_timeouts(struct net *net)
464{
465 return dccp_pernet(net)->dccp_timeout;
466}
467
468static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
469 unsigned int dataoff, enum ip_conntrack_info ctinfo,
470 unsigned int *timeouts)
471{
472 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
473 struct dccp_hdr _dh, *dh;
474 u_int8_t type, old_state, new_state;
475 enum ct_dccp_roles role;
476
477 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
478 BUG_ON(dh == NULL);
479 type = dh->dccph_type;
480
481 if (type == DCCP_PKT_RESET &&
482 !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
483
484 nf_ct_kill_acct(ct, ctinfo, skb);
485 return NF_ACCEPT;
486 }
487
488 spin_lock_bh(&ct->lock);
489
490 role = ct->proto.dccp.role[dir];
491 old_state = ct->proto.dccp.state;
492 new_state = dccp_state_table[role][type][old_state];
493
494 switch (new_state) {
495 case CT_DCCP_REQUEST:
496 if (old_state == CT_DCCP_TIMEWAIT &&
497 role == CT_DCCP_ROLE_SERVER) {
498
499
500 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_CLIENT;
501 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_SERVER;
502 }
503 break;
504 case CT_DCCP_RESPOND:
505 if (old_state == CT_DCCP_REQUEST)
506 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
507 break;
508 case CT_DCCP_PARTOPEN:
509 if (old_state == CT_DCCP_RESPOND &&
510 type == DCCP_PKT_ACK &&
511 dccp_ack_seq(dh) == ct->proto.dccp.handshake_seq)
512 set_bit(IPS_ASSURED_BIT, &ct->status);
513 break;
514 case CT_DCCP_IGNORE:
515
516
517
518
519
520 if (ct->proto.dccp.last_dir == !dir &&
521 ct->proto.dccp.last_pkt == DCCP_PKT_REQUEST &&
522 type == DCCP_PKT_RESPONSE) {
523 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_CLIENT;
524 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_SERVER;
525 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
526 new_state = CT_DCCP_RESPOND;
527 break;
528 }
529 ct->proto.dccp.last_dir = dir;
530 ct->proto.dccp.last_pkt = type;
531
532 spin_unlock_bh(&ct->lock);
533 nf_ct_l4proto_log_invalid(skb, ct, "%s", "invalid packet");
534 return NF_ACCEPT;
535 case CT_DCCP_INVALID:
536 spin_unlock_bh(&ct->lock);
537 nf_ct_l4proto_log_invalid(skb, ct, "%s", "invalid state transition");
538 return -NF_ACCEPT;
539 }
540
541 ct->proto.dccp.last_dir = dir;
542 ct->proto.dccp.last_pkt = type;
543 ct->proto.dccp.state = new_state;
544 spin_unlock_bh(&ct->lock);
545
546 if (new_state != old_state)
547 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
548
549 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
550
551 return NF_ACCEPT;
552}
553
554static int dccp_error(struct net *net, struct nf_conn *tmpl,
555 struct sk_buff *skb, unsigned int dataoff,
556 u_int8_t pf, unsigned int hooknum)
557{
558 struct dccp_hdr _dh, *dh;
559 unsigned int dccp_len = skb->len - dataoff;
560 unsigned int cscov;
561 const char *msg;
562
563 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
564 if (dh == NULL) {
565 msg = "nf_ct_dccp: short packet ";
566 goto out_invalid;
567 }
568
569 if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
570 dh->dccph_doff * 4 > dccp_len) {
571 msg = "nf_ct_dccp: truncated/malformed packet ";
572 goto out_invalid;
573 }
574
575 cscov = dccp_len;
576 if (dh->dccph_cscov) {
577 cscov = (dh->dccph_cscov - 1) * 4;
578 if (cscov > dccp_len) {
579 msg = "nf_ct_dccp: bad checksum coverage ";
580 goto out_invalid;
581 }
582 }
583
584 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
585 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP,
586 pf)) {
587 msg = "nf_ct_dccp: bad checksum ";
588 goto out_invalid;
589 }
590
591 if (dh->dccph_type >= DCCP_PKT_INVALID) {
592 msg = "nf_ct_dccp: reserved packet type ";
593 goto out_invalid;
594 }
595
596 return NF_ACCEPT;
597
598out_invalid:
599 nf_l4proto_log_invalid(skb, net, pf, IPPROTO_DCCP, "%s", msg);
600 return -NF_ACCEPT;
601}
602
603static bool dccp_can_early_drop(const struct nf_conn *ct)
604{
605 switch (ct->proto.dccp.state) {
606 case CT_DCCP_CLOSEREQ:
607 case CT_DCCP_CLOSING:
608 case CT_DCCP_TIMEWAIT:
609 return true;
610 default:
611 break;
612 }
613
614 return false;
615}
616
617#ifdef CONFIG_NF_CONNTRACK_PROCFS
618static void dccp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
619{
620 seq_printf(s, "%s ", dccp_state_names[ct->proto.dccp.state]);
621}
622#endif
623
624#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
625static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
626 struct nf_conn *ct)
627{
628 struct nlattr *nest_parms;
629
630 spin_lock_bh(&ct->lock);
631 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_DCCP | NLA_F_NESTED);
632 if (!nest_parms)
633 goto nla_put_failure;
634 if (nla_put_u8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state) ||
635 nla_put_u8(skb, CTA_PROTOINFO_DCCP_ROLE,
636 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]) ||
637 nla_put_be64(skb, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
638 cpu_to_be64(ct->proto.dccp.handshake_seq),
639 CTA_PROTOINFO_DCCP_PAD))
640 goto nla_put_failure;
641 nla_nest_end(skb, nest_parms);
642 spin_unlock_bh(&ct->lock);
643 return 0;
644
645nla_put_failure:
646 spin_unlock_bh(&ct->lock);
647 return -1;
648}
649
650static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = {
651 [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 },
652 [CTA_PROTOINFO_DCCP_ROLE] = { .type = NLA_U8 },
653 [CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ] = { .type = NLA_U64 },
654 [CTA_PROTOINFO_DCCP_PAD] = { .type = NLA_UNSPEC },
655};
656
657#define DCCP_NLATTR_SIZE ( \
658 NLA_ALIGN(NLA_HDRLEN + 1) + \
659 NLA_ALIGN(NLA_HDRLEN + 1) + \
660 NLA_ALIGN(NLA_HDRLEN + sizeof(u64)) + \
661 NLA_ALIGN(NLA_HDRLEN + 0))
662
663static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
664{
665 struct nlattr *attr = cda[CTA_PROTOINFO_DCCP];
666 struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX + 1];
667 int err;
668
669 if (!attr)
670 return 0;
671
672 err = nla_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr,
673 dccp_nla_policy, NULL);
674 if (err < 0)
675 return err;
676
677 if (!tb[CTA_PROTOINFO_DCCP_STATE] ||
678 !tb[CTA_PROTOINFO_DCCP_ROLE] ||
679 nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) > CT_DCCP_ROLE_MAX ||
680 nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE) {
681 return -EINVAL;
682 }
683
684 spin_lock_bh(&ct->lock);
685 ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
686 if (nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) == CT_DCCP_ROLE_CLIENT) {
687 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
688 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
689 } else {
690 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_SERVER;
691 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_CLIENT;
692 }
693 if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) {
694 ct->proto.dccp.handshake_seq =
695 be64_to_cpu(nla_get_be64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]));
696 }
697 spin_unlock_bh(&ct->lock);
698 return 0;
699}
700#endif
701
702#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
703
704#include <linux/netfilter/nfnetlink.h>
705#include <linux/netfilter/nfnetlink_cttimeout.h>
706
707static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
708 struct net *net, void *data)
709{
710 struct nf_dccp_net *dn = dccp_pernet(net);
711 unsigned int *timeouts = data;
712 int i;
713
714
715 for (i=0; i<CT_DCCP_MAX; i++)
716 timeouts[i] = dn->dccp_timeout[i];
717
718
719 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) {
720 if (tb[i]) {
721 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
722 }
723 }
724 return 0;
725}
726
727static int
728dccp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
729{
730 const unsigned int *timeouts = data;
731 int i;
732
733 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) {
734 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
735 goto nla_put_failure;
736 }
737 return 0;
738
739nla_put_failure:
740 return -ENOSPC;
741}
742
743static const struct nla_policy
744dccp_timeout_nla_policy[CTA_TIMEOUT_DCCP_MAX+1] = {
745 [CTA_TIMEOUT_DCCP_REQUEST] = { .type = NLA_U32 },
746 [CTA_TIMEOUT_DCCP_RESPOND] = { .type = NLA_U32 },
747 [CTA_TIMEOUT_DCCP_PARTOPEN] = { .type = NLA_U32 },
748 [CTA_TIMEOUT_DCCP_OPEN] = { .type = NLA_U32 },
749 [CTA_TIMEOUT_DCCP_CLOSEREQ] = { .type = NLA_U32 },
750 [CTA_TIMEOUT_DCCP_CLOSING] = { .type = NLA_U32 },
751 [CTA_TIMEOUT_DCCP_TIMEWAIT] = { .type = NLA_U32 },
752};
753#endif
754
755#ifdef CONFIG_SYSCTL
756
757static struct ctl_table dccp_sysctl_table[] = {
758 {
759 .procname = "nf_conntrack_dccp_timeout_request",
760 .maxlen = sizeof(unsigned int),
761 .mode = 0644,
762 .proc_handler = proc_dointvec_jiffies,
763 },
764 {
765 .procname = "nf_conntrack_dccp_timeout_respond",
766 .maxlen = sizeof(unsigned int),
767 .mode = 0644,
768 .proc_handler = proc_dointvec_jiffies,
769 },
770 {
771 .procname = "nf_conntrack_dccp_timeout_partopen",
772 .maxlen = sizeof(unsigned int),
773 .mode = 0644,
774 .proc_handler = proc_dointvec_jiffies,
775 },
776 {
777 .procname = "nf_conntrack_dccp_timeout_open",
778 .maxlen = sizeof(unsigned int),
779 .mode = 0644,
780 .proc_handler = proc_dointvec_jiffies,
781 },
782 {
783 .procname = "nf_conntrack_dccp_timeout_closereq",
784 .maxlen = sizeof(unsigned int),
785 .mode = 0644,
786 .proc_handler = proc_dointvec_jiffies,
787 },
788 {
789 .procname = "nf_conntrack_dccp_timeout_closing",
790 .maxlen = sizeof(unsigned int),
791 .mode = 0644,
792 .proc_handler = proc_dointvec_jiffies,
793 },
794 {
795 .procname = "nf_conntrack_dccp_timeout_timewait",
796 .maxlen = sizeof(unsigned int),
797 .mode = 0644,
798 .proc_handler = proc_dointvec_jiffies,
799 },
800 {
801 .procname = "nf_conntrack_dccp_loose",
802 .maxlen = sizeof(int),
803 .mode = 0644,
804 .proc_handler = proc_dointvec,
805 },
806 { }
807};
808#endif
809
810static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn,
811 struct nf_dccp_net *dn)
812{
813#ifdef CONFIG_SYSCTL
814 if (pn->ctl_table)
815 return 0;
816
817 pn->ctl_table = kmemdup(dccp_sysctl_table,
818 sizeof(dccp_sysctl_table),
819 GFP_KERNEL);
820 if (!pn->ctl_table)
821 return -ENOMEM;
822
823 pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST];
824 pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND];
825 pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN];
826 pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN];
827 pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ];
828 pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING];
829 pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT];
830 pn->ctl_table[7].data = &dn->dccp_loose;
831
832
833 if (net->user_ns != &init_user_ns)
834 pn->ctl_table[0].procname = NULL;
835#endif
836 return 0;
837}
838
839static int dccp_init_net(struct net *net, u_int16_t proto)
840{
841 struct nf_dccp_net *dn = dccp_pernet(net);
842 struct nf_proto_net *pn = &dn->pn;
843
844 if (!pn->users) {
845
846 dn->dccp_loose = 1;
847 dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL;
848 dn->dccp_timeout[CT_DCCP_RESPOND] = 4 * DCCP_MSL;
849 dn->dccp_timeout[CT_DCCP_PARTOPEN] = 4 * DCCP_MSL;
850 dn->dccp_timeout[CT_DCCP_OPEN] = 12 * 3600 * HZ;
851 dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ;
852 dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ;
853 dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL;
854 }
855
856 return dccp_kmemdup_sysctl_table(net, pn, dn);
857}
858
859static struct nf_proto_net *dccp_get_net_proto(struct net *net)
860{
861 return &net->ct.nf_ct_proto.dccp.pn;
862}
863
864const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 = {
865 .l3proto = AF_INET,
866 .l4proto = IPPROTO_DCCP,
867 .pkt_to_tuple = dccp_pkt_to_tuple,
868 .invert_tuple = dccp_invert_tuple,
869 .new = dccp_new,
870 .packet = dccp_packet,
871 .get_timeouts = dccp_get_timeouts,
872 .error = dccp_error,
873 .can_early_drop = dccp_can_early_drop,
874#ifdef CONFIG_NF_CONNTRACK_PROCFS
875 .print_conntrack = dccp_print_conntrack,
876#endif
877#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
878 .nlattr_size = DCCP_NLATTR_SIZE,
879 .to_nlattr = dccp_to_nlattr,
880 .from_nlattr = nlattr_to_dccp,
881 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
882 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
883 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
884 .nla_policy = nf_ct_port_nla_policy,
885#endif
886#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
887 .ctnl_timeout = {
888 .nlattr_to_obj = dccp_timeout_nlattr_to_obj,
889 .obj_to_nlattr = dccp_timeout_obj_to_nlattr,
890 .nlattr_max = CTA_TIMEOUT_DCCP_MAX,
891 .obj_size = sizeof(unsigned int) * CT_DCCP_MAX,
892 .nla_policy = dccp_timeout_nla_policy,
893 },
894#endif
895 .init_net = dccp_init_net,
896 .get_net_proto = dccp_get_net_proto,
897};
898EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4);
899
900const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 = {
901 .l3proto = AF_INET6,
902 .l4proto = IPPROTO_DCCP,
903 .pkt_to_tuple = dccp_pkt_to_tuple,
904 .invert_tuple = dccp_invert_tuple,
905 .new = dccp_new,
906 .packet = dccp_packet,
907 .get_timeouts = dccp_get_timeouts,
908 .error = dccp_error,
909 .can_early_drop = dccp_can_early_drop,
910#ifdef CONFIG_NF_CONNTRACK_PROCFS
911 .print_conntrack = dccp_print_conntrack,
912#endif
913#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
914 .nlattr_size = DCCP_NLATTR_SIZE,
915 .to_nlattr = dccp_to_nlattr,
916 .from_nlattr = nlattr_to_dccp,
917 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
918 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
919 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
920 .nla_policy = nf_ct_port_nla_policy,
921#endif
922#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
923 .ctnl_timeout = {
924 .nlattr_to_obj = dccp_timeout_nlattr_to_obj,
925 .obj_to_nlattr = dccp_timeout_obj_to_nlattr,
926 .nlattr_max = CTA_TIMEOUT_DCCP_MAX,
927 .obj_size = sizeof(unsigned int) * CT_DCCP_MAX,
928 .nla_policy = dccp_timeout_nla_policy,
929 },
930#endif
931 .init_net = dccp_init_net,
932 .get_net_proto = dccp_get_net_proto,
933};
934EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp6);
935