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 = "nf_ct_dccp: not picking up existing connection ";
432 goto out_invalid;
433 }
434 case CT_DCCP_REQUEST:
435 break;
436 case CT_DCCP_INVALID:
437 msg = "nf_ct_dccp: 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 if (LOG_INVALID(net, IPPROTO_DCCP))
451 nf_log_packet(net, nf_ct_l3num(ct), 0, skb, NULL, NULL,
452 NULL, "%s", msg);
453 return false;
454}
455
456static u64 dccp_ack_seq(const struct dccp_hdr *dh)
457{
458 const struct dccp_hdr_ack_bits *dhack;
459
460 dhack = (void *)dh + __dccp_basic_hdr_len(dh);
461 return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) +
462 ntohl(dhack->dccph_ack_nr_low);
463}
464
465static unsigned int *dccp_get_timeouts(struct net *net)
466{
467 return dccp_pernet(net)->dccp_timeout;
468}
469
470static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
471 unsigned int dataoff, enum ip_conntrack_info ctinfo,
472 u_int8_t pf, unsigned int hooknum,
473 unsigned int *timeouts)
474{
475 struct net *net = nf_ct_net(ct);
476 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
477 struct dccp_hdr _dh, *dh;
478 u_int8_t type, old_state, new_state;
479 enum ct_dccp_roles role;
480
481 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
482 BUG_ON(dh == NULL);
483 type = dh->dccph_type;
484
485 if (type == DCCP_PKT_RESET &&
486 !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
487
488 nf_ct_kill_acct(ct, ctinfo, skb);
489 return NF_ACCEPT;
490 }
491
492 spin_lock_bh(&ct->lock);
493
494 role = ct->proto.dccp.role[dir];
495 old_state = ct->proto.dccp.state;
496 new_state = dccp_state_table[role][type][old_state];
497
498 switch (new_state) {
499 case CT_DCCP_REQUEST:
500 if (old_state == CT_DCCP_TIMEWAIT &&
501 role == CT_DCCP_ROLE_SERVER) {
502
503
504 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_CLIENT;
505 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_SERVER;
506 }
507 break;
508 case CT_DCCP_RESPOND:
509 if (old_state == CT_DCCP_REQUEST)
510 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
511 break;
512 case CT_DCCP_PARTOPEN:
513 if (old_state == CT_DCCP_RESPOND &&
514 type == DCCP_PKT_ACK &&
515 dccp_ack_seq(dh) == ct->proto.dccp.handshake_seq)
516 set_bit(IPS_ASSURED_BIT, &ct->status);
517 break;
518 case CT_DCCP_IGNORE:
519
520
521
522
523
524 if (ct->proto.dccp.last_dir == !dir &&
525 ct->proto.dccp.last_pkt == DCCP_PKT_REQUEST &&
526 type == DCCP_PKT_RESPONSE) {
527 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_CLIENT;
528 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_SERVER;
529 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
530 new_state = CT_DCCP_RESPOND;
531 break;
532 }
533 ct->proto.dccp.last_dir = dir;
534 ct->proto.dccp.last_pkt = type;
535
536 spin_unlock_bh(&ct->lock);
537 if (LOG_INVALID(net, IPPROTO_DCCP))
538 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
539 "nf_ct_dccp: invalid packet ignored ");
540 return NF_ACCEPT;
541 case CT_DCCP_INVALID:
542 spin_unlock_bh(&ct->lock);
543 if (LOG_INVALID(net, IPPROTO_DCCP))
544 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
545 "nf_ct_dccp: invalid state transition ");
546 return -NF_ACCEPT;
547 }
548
549 ct->proto.dccp.last_dir = dir;
550 ct->proto.dccp.last_pkt = type;
551 ct->proto.dccp.state = new_state;
552 spin_unlock_bh(&ct->lock);
553
554 if (new_state != old_state)
555 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
556
557 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
558
559 return NF_ACCEPT;
560}
561
562static int dccp_error(struct net *net, struct nf_conn *tmpl,
563 struct sk_buff *skb, unsigned int dataoff,
564 enum ip_conntrack_info *ctinfo,
565 u_int8_t pf, unsigned int hooknum)
566{
567 struct dccp_hdr _dh, *dh;
568 unsigned int dccp_len = skb->len - dataoff;
569 unsigned int cscov;
570 const char *msg;
571
572 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
573 if (dh == NULL) {
574 msg = "nf_ct_dccp: short packet ";
575 goto out_invalid;
576 }
577
578 if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
579 dh->dccph_doff * 4 > dccp_len) {
580 msg = "nf_ct_dccp: truncated/malformed packet ";
581 goto out_invalid;
582 }
583
584 cscov = dccp_len;
585 if (dh->dccph_cscov) {
586 cscov = (dh->dccph_cscov - 1) * 4;
587 if (cscov > dccp_len) {
588 msg = "nf_ct_dccp: bad checksum coverage ";
589 goto out_invalid;
590 }
591 }
592
593 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
594 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP,
595 pf)) {
596 msg = "nf_ct_dccp: bad checksum ";
597 goto out_invalid;
598 }
599
600 if (dh->dccph_type >= DCCP_PKT_INVALID) {
601 msg = "nf_ct_dccp: reserved packet type ";
602 goto out_invalid;
603 }
604
605 return NF_ACCEPT;
606
607out_invalid:
608 if (LOG_INVALID(net, IPPROTO_DCCP))
609 nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL, "%s", msg);
610 return -NF_ACCEPT;
611}
612
613static void dccp_print_tuple(struct seq_file *s,
614 const struct nf_conntrack_tuple *tuple)
615{
616 seq_printf(s, "sport=%hu dport=%hu ",
617 ntohs(tuple->src.u.dccp.port),
618 ntohs(tuple->dst.u.dccp.port));
619}
620
621static void dccp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
622{
623 seq_printf(s, "%s ", dccp_state_names[ct->proto.dccp.state]);
624}
625
626#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
627static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
628 struct nf_conn *ct)
629{
630 struct nlattr *nest_parms;
631
632 spin_lock_bh(&ct->lock);
633 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_DCCP | NLA_F_NESTED);
634 if (!nest_parms)
635 goto nla_put_failure;
636 if (nla_put_u8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state) ||
637 nla_put_u8(skb, CTA_PROTOINFO_DCCP_ROLE,
638 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]) ||
639 nla_put_be64(skb, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
640 cpu_to_be64(ct->proto.dccp.handshake_seq),
641 CTA_PROTOINFO_DCCP_PAD))
642 goto nla_put_failure;
643 nla_nest_end(skb, nest_parms);
644 spin_unlock_bh(&ct->lock);
645 return 0;
646
647nla_put_failure:
648 spin_unlock_bh(&ct->lock);
649 return -1;
650}
651
652static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = {
653 [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 },
654 [CTA_PROTOINFO_DCCP_ROLE] = { .type = NLA_U8 },
655 [CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ] = { .type = NLA_U64 },
656 [CTA_PROTOINFO_DCCP_PAD] = { .type = NLA_UNSPEC },
657};
658
659static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
660{
661 struct nlattr *attr = cda[CTA_PROTOINFO_DCCP];
662 struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX + 1];
663 int err;
664
665 if (!attr)
666 return 0;
667
668 err = nla_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr,
669 dccp_nla_policy);
670 if (err < 0)
671 return err;
672
673 if (!tb[CTA_PROTOINFO_DCCP_STATE] ||
674 !tb[CTA_PROTOINFO_DCCP_ROLE] ||
675 nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) > CT_DCCP_ROLE_MAX ||
676 nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE) {
677 return -EINVAL;
678 }
679
680 spin_lock_bh(&ct->lock);
681 ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
682 if (nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) == CT_DCCP_ROLE_CLIENT) {
683 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
684 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
685 } else {
686 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_SERVER;
687 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_CLIENT;
688 }
689 if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) {
690 ct->proto.dccp.handshake_seq =
691 be64_to_cpu(nla_get_be64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]));
692 }
693 spin_unlock_bh(&ct->lock);
694 return 0;
695}
696
697static int dccp_nlattr_size(void)
698{
699 return nla_total_size(0)
700 + nla_policy_len(dccp_nla_policy, CTA_PROTOINFO_DCCP_MAX + 1);
701}
702
703#endif
704
705#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
706
707#include <linux/netfilter/nfnetlink.h>
708#include <linux/netfilter/nfnetlink_cttimeout.h>
709
710static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
711 struct net *net, void *data)
712{
713 struct nf_dccp_net *dn = dccp_pernet(net);
714 unsigned int *timeouts = data;
715 int i;
716
717
718 for (i=0; i<CT_DCCP_MAX; i++)
719 timeouts[i] = dn->dccp_timeout[i];
720
721
722 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) {
723 if (tb[i]) {
724 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
725 }
726 }
727 return 0;
728}
729
730static int
731dccp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
732{
733 const unsigned int *timeouts = data;
734 int i;
735
736 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) {
737 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
738 goto nla_put_failure;
739 }
740 return 0;
741
742nla_put_failure:
743 return -ENOSPC;
744}
745
746static const struct nla_policy
747dccp_timeout_nla_policy[CTA_TIMEOUT_DCCP_MAX+1] = {
748 [CTA_TIMEOUT_DCCP_REQUEST] = { .type = NLA_U32 },
749 [CTA_TIMEOUT_DCCP_RESPOND] = { .type = NLA_U32 },
750 [CTA_TIMEOUT_DCCP_PARTOPEN] = { .type = NLA_U32 },
751 [CTA_TIMEOUT_DCCP_OPEN] = { .type = NLA_U32 },
752 [CTA_TIMEOUT_DCCP_CLOSEREQ] = { .type = NLA_U32 },
753 [CTA_TIMEOUT_DCCP_CLOSING] = { .type = NLA_U32 },
754 [CTA_TIMEOUT_DCCP_TIMEWAIT] = { .type = NLA_U32 },
755};
756#endif
757
758#ifdef CONFIG_SYSCTL
759
760static struct ctl_table dccp_sysctl_table[] = {
761 {
762 .procname = "nf_conntrack_dccp_timeout_request",
763 .maxlen = sizeof(unsigned int),
764 .mode = 0644,
765 .proc_handler = proc_dointvec_jiffies,
766 },
767 {
768 .procname = "nf_conntrack_dccp_timeout_respond",
769 .maxlen = sizeof(unsigned int),
770 .mode = 0644,
771 .proc_handler = proc_dointvec_jiffies,
772 },
773 {
774 .procname = "nf_conntrack_dccp_timeout_partopen",
775 .maxlen = sizeof(unsigned int),
776 .mode = 0644,
777 .proc_handler = proc_dointvec_jiffies,
778 },
779 {
780 .procname = "nf_conntrack_dccp_timeout_open",
781 .maxlen = sizeof(unsigned int),
782 .mode = 0644,
783 .proc_handler = proc_dointvec_jiffies,
784 },
785 {
786 .procname = "nf_conntrack_dccp_timeout_closereq",
787 .maxlen = sizeof(unsigned int),
788 .mode = 0644,
789 .proc_handler = proc_dointvec_jiffies,
790 },
791 {
792 .procname = "nf_conntrack_dccp_timeout_closing",
793 .maxlen = sizeof(unsigned int),
794 .mode = 0644,
795 .proc_handler = proc_dointvec_jiffies,
796 },
797 {
798 .procname = "nf_conntrack_dccp_timeout_timewait",
799 .maxlen = sizeof(unsigned int),
800 .mode = 0644,
801 .proc_handler = proc_dointvec_jiffies,
802 },
803 {
804 .procname = "nf_conntrack_dccp_loose",
805 .maxlen = sizeof(int),
806 .mode = 0644,
807 .proc_handler = proc_dointvec,
808 },
809 { }
810};
811#endif
812
813static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn,
814 struct nf_dccp_net *dn)
815{
816#ifdef CONFIG_SYSCTL
817 if (pn->ctl_table)
818 return 0;
819
820 pn->ctl_table = kmemdup(dccp_sysctl_table,
821 sizeof(dccp_sysctl_table),
822 GFP_KERNEL);
823 if (!pn->ctl_table)
824 return -ENOMEM;
825
826 pn->ctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST];
827 pn->ctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND];
828 pn->ctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN];
829 pn->ctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN];
830 pn->ctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ];
831 pn->ctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING];
832 pn->ctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT];
833 pn->ctl_table[7].data = &dn->dccp_loose;
834
835
836 if (net->user_ns != &init_user_ns)
837 pn->ctl_table[0].procname = NULL;
838#endif
839 return 0;
840}
841
842static int dccp_init_net(struct net *net, u_int16_t proto)
843{
844 struct nf_dccp_net *dn = dccp_pernet(net);
845 struct nf_proto_net *pn = &dn->pn;
846
847 if (!pn->users) {
848
849 dn->dccp_loose = 1;
850 dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL;
851 dn->dccp_timeout[CT_DCCP_RESPOND] = 4 * DCCP_MSL;
852 dn->dccp_timeout[CT_DCCP_PARTOPEN] = 4 * DCCP_MSL;
853 dn->dccp_timeout[CT_DCCP_OPEN] = 12 * 3600 * HZ;
854 dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ;
855 dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ;
856 dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL;
857 }
858
859 return dccp_kmemdup_sysctl_table(net, pn, dn);
860}
861
862struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = {
863 .l3proto = AF_INET,
864 .l4proto = IPPROTO_DCCP,
865 .name = "dccp",
866 .pkt_to_tuple = dccp_pkt_to_tuple,
867 .invert_tuple = dccp_invert_tuple,
868 .new = dccp_new,
869 .packet = dccp_packet,
870 .get_timeouts = dccp_get_timeouts,
871 .error = dccp_error,
872 .print_tuple = dccp_print_tuple,
873 .print_conntrack = dccp_print_conntrack,
874#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
875 .to_nlattr = dccp_to_nlattr,
876 .nlattr_size = dccp_nlattr_size,
877 .from_nlattr = nlattr_to_dccp,
878 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
879 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
880 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
881 .nla_policy = nf_ct_port_nla_policy,
882#endif
883#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
884 .ctnl_timeout = {
885 .nlattr_to_obj = dccp_timeout_nlattr_to_obj,
886 .obj_to_nlattr = dccp_timeout_obj_to_nlattr,
887 .nlattr_max = CTA_TIMEOUT_DCCP_MAX,
888 .obj_size = sizeof(unsigned int) * CT_DCCP_MAX,
889 .nla_policy = dccp_timeout_nla_policy,
890 },
891#endif
892 .init_net = dccp_init_net,
893};
894EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4);
895
896struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 __read_mostly = {
897 .l3proto = AF_INET6,
898 .l4proto = IPPROTO_DCCP,
899 .name = "dccp",
900 .pkt_to_tuple = dccp_pkt_to_tuple,
901 .invert_tuple = dccp_invert_tuple,
902 .new = dccp_new,
903 .packet = dccp_packet,
904 .get_timeouts = dccp_get_timeouts,
905 .error = dccp_error,
906 .print_tuple = dccp_print_tuple,
907 .print_conntrack = dccp_print_conntrack,
908#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
909 .to_nlattr = dccp_to_nlattr,
910 .nlattr_size = dccp_nlattr_size,
911 .from_nlattr = nlattr_to_dccp,
912 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
913 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
914 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
915 .nla_policy = nf_ct_port_nla_policy,
916#endif
917#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
918 .ctnl_timeout = {
919 .nlattr_to_obj = dccp_timeout_nlattr_to_obj,
920 .obj_to_nlattr = dccp_timeout_obj_to_nlattr,
921 .nlattr_max = CTA_TIMEOUT_DCCP_MAX,
922 .obj_size = sizeof(unsigned int) * CT_DCCP_MAX,
923 .nla_policy = dccp_timeout_nla_policy,
924 },
925#endif
926 .init_net = dccp_init_net,
927};
928EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp6);
929