This source file includes following definitions.
- dccp_new
- dccp_ack_seq
- dccp_error
- nf_conntrack_dccp_packet
- dccp_can_early_drop
- dccp_print_conntrack
- dccp_to_nlattr
- nlattr_to_dccp
- dccp_timeout_nlattr_to_obj
- dccp_timeout_obj_to_nlattr
- nf_conntrack_dccp_init_net
1
2
3
4
5
6
7 #include <linux/kernel.h>
8 #include <linux/init.h>
9 #include <linux/sysctl.h>
10 #include <linux/spinlock.h>
11 #include <linux/skbuff.h>
12 #include <linux/dccp.h>
13 #include <linux/slab.h>
14
15 #include <net/net_namespace.h>
16 #include <net/netns/generic.h>
17
18 #include <linux/netfilter/nfnetlink_conntrack.h>
19 #include <net/netfilter/nf_conntrack.h>
20 #include <net/netfilter/nf_conntrack_l4proto.h>
21 #include <net/netfilter/nf_conntrack_ecache.h>
22 #include <net/netfilter/nf_conntrack_timeout.h>
23 #include <net/netfilter/nf_log.h>
24
25
26
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 #define DCCP_MSL (2 * 60 * HZ)
71
72 static const char * const dccp_state_names[] = {
73 [CT_DCCP_NONE] = "NONE",
74 [CT_DCCP_REQUEST] = "REQUEST",
75 [CT_DCCP_RESPOND] = "RESPOND",
76 [CT_DCCP_PARTOPEN] = "PARTOPEN",
77 [CT_DCCP_OPEN] = "OPEN",
78 [CT_DCCP_CLOSEREQ] = "CLOSEREQ",
79 [CT_DCCP_CLOSING] = "CLOSING",
80 [CT_DCCP_TIMEWAIT] = "TIMEWAIT",
81 [CT_DCCP_IGNORE] = "IGNORE",
82 [CT_DCCP_INVALID] = "INVALID",
83 };
84
85 #define sNO CT_DCCP_NONE
86 #define sRQ CT_DCCP_REQUEST
87 #define sRS CT_DCCP_RESPOND
88 #define sPO CT_DCCP_PARTOPEN
89 #define sOP CT_DCCP_OPEN
90 #define sCR CT_DCCP_CLOSEREQ
91 #define sCG CT_DCCP_CLOSING
92 #define sTW CT_DCCP_TIMEWAIT
93 #define sIG CT_DCCP_IGNORE
94 #define sIV CT_DCCP_INVALID
95
96
97
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 static const u_int8_t
129 dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = {
130 [CT_DCCP_ROLE_CLIENT] = {
131 [DCCP_PKT_REQUEST] = {
132
133
134
135
136
137
138
139
140
141
142
143
144 sRQ, sRQ, sRS, sIG, sIG, sIG, sIG, sRQ,
145 },
146 [DCCP_PKT_RESPONSE] = {
147
148
149
150
151
152
153
154
155
156
157
158
159 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIV,
160 },
161 [DCCP_PKT_ACK] = {
162
163
164
165
166
167
168
169
170
171
172
173 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
174 },
175 [DCCP_PKT_DATA] = {
176
177
178
179
180
181
182
183
184
185
186
187 sIV, sIV, sIV, sIV, sOP, sCR, sCG, sIV,
188 },
189 [DCCP_PKT_DATAACK] = {
190
191
192
193
194
195
196
197
198
199
200
201 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
202 },
203 [DCCP_PKT_CLOSEREQ] = {
204
205
206
207
208 sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV
209 },
210 [DCCP_PKT_CLOSE] = {
211
212
213
214
215
216
217
218
219
220
221
222 sIV, sIV, sIV, sCG, sCG, sCG, sIV, sIV
223 },
224 [DCCP_PKT_RESET] = {
225
226
227
228
229
230
231
232
233
234
235
236 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sIG
237 },
238 [DCCP_PKT_SYNC] = {
239
240
241
242
243 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
244 },
245 [DCCP_PKT_SYNCACK] = {
246
247
248
249
250 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
251 },
252 },
253 [CT_DCCP_ROLE_SERVER] = {
254 [DCCP_PKT_REQUEST] = {
255
256
257
258
259
260
261
262
263
264
265
266 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sRQ
267 },
268 [DCCP_PKT_RESPONSE] = {
269
270
271
272
273
274
275
276
277
278
279
280 sIV, sRS, sRS, sIG, sIG, sIG, sIG, sIV
281 },
282 [DCCP_PKT_ACK] = {
283
284
285
286
287
288
289
290
291
292
293
294 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
295 },
296 [DCCP_PKT_DATA] = {
297
298
299
300
301
302
303
304
305
306
307
308 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
309 },
310 [DCCP_PKT_DATAACK] = {
311
312
313
314
315
316
317
318
319
320
321
322 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
323 },
324 [DCCP_PKT_CLOSEREQ] = {
325
326
327
328
329
330
331
332
333
334
335
336 sIV, sIV, sIV, sCR, sCR, sCR, sCR, sIV
337 },
338 [DCCP_PKT_CLOSE] = {
339
340
341
342
343
344
345
346
347
348
349
350 sIV, sIV, sIV, sCG, sCG, sIV, sCG, sIV
351 },
352 [DCCP_PKT_RESET] = {
353
354
355
356
357
358
359
360
361
362
363
364 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sTW, sIG
365 },
366 [DCCP_PKT_SYNC] = {
367
368
369
370
371 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
372 },
373 [DCCP_PKT_SYNCACK] = {
374
375
376
377
378 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
379 },
380 },
381 };
382
383 static noinline bool
384 dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
385 const struct dccp_hdr *dh)
386 {
387 struct net *net = nf_ct_net(ct);
388 struct nf_dccp_net *dn;
389 const char *msg;
390 u_int8_t state;
391
392 state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
393 switch (state) {
394 default:
395 dn = nf_dccp_pernet(net);
396 if (dn->dccp_loose == 0) {
397 msg = "not picking up existing connection ";
398 goto out_invalid;
399 }
400 case CT_DCCP_REQUEST:
401 break;
402 case CT_DCCP_INVALID:
403 msg = "invalid state transition ";
404 goto out_invalid;
405 }
406
407 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
408 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
409 ct->proto.dccp.state = CT_DCCP_NONE;
410 ct->proto.dccp.last_pkt = DCCP_PKT_REQUEST;
411 ct->proto.dccp.last_dir = IP_CT_DIR_ORIGINAL;
412 ct->proto.dccp.handshake_seq = 0;
413 return true;
414
415 out_invalid:
416 nf_ct_l4proto_log_invalid(skb, ct, "%s", msg);
417 return false;
418 }
419
420 static u64 dccp_ack_seq(const struct dccp_hdr *dh)
421 {
422 const struct dccp_hdr_ack_bits *dhack;
423
424 dhack = (void *)dh + __dccp_basic_hdr_len(dh);
425 return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) +
426 ntohl(dhack->dccph_ack_nr_low);
427 }
428
429 static bool dccp_error(const struct dccp_hdr *dh,
430 struct sk_buff *skb, unsigned int dataoff,
431 const struct nf_hook_state *state)
432 {
433 unsigned int dccp_len = skb->len - dataoff;
434 unsigned int cscov;
435 const char *msg;
436
437 if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
438 dh->dccph_doff * 4 > dccp_len) {
439 msg = "nf_ct_dccp: truncated/malformed packet ";
440 goto out_invalid;
441 }
442
443 cscov = dccp_len;
444 if (dh->dccph_cscov) {
445 cscov = (dh->dccph_cscov - 1) * 4;
446 if (cscov > dccp_len) {
447 msg = "nf_ct_dccp: bad checksum coverage ";
448 goto out_invalid;
449 }
450 }
451
452 if (state->hook == NF_INET_PRE_ROUTING &&
453 state->net->ct.sysctl_checksum &&
454 nf_checksum_partial(skb, state->hook, dataoff, cscov,
455 IPPROTO_DCCP, state->pf)) {
456 msg = "nf_ct_dccp: bad checksum ";
457 goto out_invalid;
458 }
459
460 if (dh->dccph_type >= DCCP_PKT_INVALID) {
461 msg = "nf_ct_dccp: reserved packet type ";
462 goto out_invalid;
463 }
464 return false;
465 out_invalid:
466 nf_l4proto_log_invalid(skb, state->net, state->pf,
467 IPPROTO_DCCP, "%s", msg);
468 return true;
469 }
470
471 int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
472 unsigned int dataoff,
473 enum ip_conntrack_info ctinfo,
474 const struct nf_hook_state *state)
475 {
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 unsigned int *timeouts;
481
482 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
483 if (!dh)
484 return NF_DROP;
485
486 if (dccp_error(dh, skb, dataoff, state))
487 return -NF_ACCEPT;
488
489 type = dh->dccph_type;
490 if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh))
491 return -NF_ACCEPT;
492
493 if (type == DCCP_PKT_RESET &&
494 !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
495
496 nf_ct_kill_acct(ct, ctinfo, skb);
497 return NF_ACCEPT;
498 }
499
500 spin_lock_bh(&ct->lock);
501
502 role = ct->proto.dccp.role[dir];
503 old_state = ct->proto.dccp.state;
504 new_state = dccp_state_table[role][type][old_state];
505
506 switch (new_state) {
507 case CT_DCCP_REQUEST:
508 if (old_state == CT_DCCP_TIMEWAIT &&
509 role == CT_DCCP_ROLE_SERVER) {
510
511
512 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_CLIENT;
513 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_SERVER;
514 }
515 break;
516 case CT_DCCP_RESPOND:
517 if (old_state == CT_DCCP_REQUEST)
518 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
519 break;
520 case CT_DCCP_PARTOPEN:
521 if (old_state == CT_DCCP_RESPOND &&
522 type == DCCP_PKT_ACK &&
523 dccp_ack_seq(dh) == ct->proto.dccp.handshake_seq)
524 set_bit(IPS_ASSURED_BIT, &ct->status);
525 break;
526 case CT_DCCP_IGNORE:
527
528
529
530
531
532 if (ct->proto.dccp.last_dir == !dir &&
533 ct->proto.dccp.last_pkt == DCCP_PKT_REQUEST &&
534 type == DCCP_PKT_RESPONSE) {
535 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_CLIENT;
536 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_SERVER;
537 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
538 new_state = CT_DCCP_RESPOND;
539 break;
540 }
541 ct->proto.dccp.last_dir = dir;
542 ct->proto.dccp.last_pkt = type;
543
544 spin_unlock_bh(&ct->lock);
545 nf_ct_l4proto_log_invalid(skb, ct, "%s", "invalid packet");
546 return NF_ACCEPT;
547 case CT_DCCP_INVALID:
548 spin_unlock_bh(&ct->lock);
549 nf_ct_l4proto_log_invalid(skb, ct, "%s", "invalid state transition");
550 return -NF_ACCEPT;
551 }
552
553 ct->proto.dccp.last_dir = dir;
554 ct->proto.dccp.last_pkt = type;
555 ct->proto.dccp.state = new_state;
556 spin_unlock_bh(&ct->lock);
557
558 if (new_state != old_state)
559 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
560
561 timeouts = nf_ct_timeout_lookup(ct);
562 if (!timeouts)
563 timeouts = nf_dccp_pernet(nf_ct_net(ct))->dccp_timeout;
564 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
565
566 return NF_ACCEPT;
567 }
568
569 static bool dccp_can_early_drop(const struct nf_conn *ct)
570 {
571 switch (ct->proto.dccp.state) {
572 case CT_DCCP_CLOSEREQ:
573 case CT_DCCP_CLOSING:
574 case CT_DCCP_TIMEWAIT:
575 return true;
576 default:
577 break;
578 }
579
580 return false;
581 }
582
583 #ifdef CONFIG_NF_CONNTRACK_PROCFS
584 static void dccp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
585 {
586 seq_printf(s, "%s ", dccp_state_names[ct->proto.dccp.state]);
587 }
588 #endif
589
590 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
591 static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
592 struct nf_conn *ct)
593 {
594 struct nlattr *nest_parms;
595
596 spin_lock_bh(&ct->lock);
597 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_DCCP);
598 if (!nest_parms)
599 goto nla_put_failure;
600 if (nla_put_u8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state) ||
601 nla_put_u8(skb, CTA_PROTOINFO_DCCP_ROLE,
602 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]) ||
603 nla_put_be64(skb, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
604 cpu_to_be64(ct->proto.dccp.handshake_seq),
605 CTA_PROTOINFO_DCCP_PAD))
606 goto nla_put_failure;
607 nla_nest_end(skb, nest_parms);
608 spin_unlock_bh(&ct->lock);
609 return 0;
610
611 nla_put_failure:
612 spin_unlock_bh(&ct->lock);
613 return -1;
614 }
615
616 static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = {
617 [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 },
618 [CTA_PROTOINFO_DCCP_ROLE] = { .type = NLA_U8 },
619 [CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ] = { .type = NLA_U64 },
620 [CTA_PROTOINFO_DCCP_PAD] = { .type = NLA_UNSPEC },
621 };
622
623 #define DCCP_NLATTR_SIZE ( \
624 NLA_ALIGN(NLA_HDRLEN + 1) + \
625 NLA_ALIGN(NLA_HDRLEN + 1) + \
626 NLA_ALIGN(NLA_HDRLEN + sizeof(u64)) + \
627 NLA_ALIGN(NLA_HDRLEN + 0))
628
629 static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
630 {
631 struct nlattr *attr = cda[CTA_PROTOINFO_DCCP];
632 struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX + 1];
633 int err;
634
635 if (!attr)
636 return 0;
637
638 err = nla_parse_nested_deprecated(tb, CTA_PROTOINFO_DCCP_MAX, attr,
639 dccp_nla_policy, NULL);
640 if (err < 0)
641 return err;
642
643 if (!tb[CTA_PROTOINFO_DCCP_STATE] ||
644 !tb[CTA_PROTOINFO_DCCP_ROLE] ||
645 nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) > CT_DCCP_ROLE_MAX ||
646 nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE) {
647 return -EINVAL;
648 }
649
650 spin_lock_bh(&ct->lock);
651 ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
652 if (nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) == CT_DCCP_ROLE_CLIENT) {
653 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
654 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
655 } else {
656 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_SERVER;
657 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_CLIENT;
658 }
659 if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) {
660 ct->proto.dccp.handshake_seq =
661 be64_to_cpu(nla_get_be64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]));
662 }
663 spin_unlock_bh(&ct->lock);
664 return 0;
665 }
666 #endif
667
668 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
669
670 #include <linux/netfilter/nfnetlink.h>
671 #include <linux/netfilter/nfnetlink_cttimeout.h>
672
673 static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
674 struct net *net, void *data)
675 {
676 struct nf_dccp_net *dn = nf_dccp_pernet(net);
677 unsigned int *timeouts = data;
678 int i;
679
680 if (!timeouts)
681 timeouts = dn->dccp_timeout;
682
683
684 for (i=0; i<CT_DCCP_MAX; i++)
685 timeouts[i] = dn->dccp_timeout[i];
686
687
688 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) {
689 if (tb[i]) {
690 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
691 }
692 }
693
694 timeouts[CTA_TIMEOUT_DCCP_UNSPEC] = timeouts[CTA_TIMEOUT_DCCP_REQUEST];
695 return 0;
696 }
697
698 static int
699 dccp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
700 {
701 const unsigned int *timeouts = data;
702 int i;
703
704 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) {
705 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
706 goto nla_put_failure;
707 }
708 return 0;
709
710 nla_put_failure:
711 return -ENOSPC;
712 }
713
714 static const struct nla_policy
715 dccp_timeout_nla_policy[CTA_TIMEOUT_DCCP_MAX+1] = {
716 [CTA_TIMEOUT_DCCP_REQUEST] = { .type = NLA_U32 },
717 [CTA_TIMEOUT_DCCP_RESPOND] = { .type = NLA_U32 },
718 [CTA_TIMEOUT_DCCP_PARTOPEN] = { .type = NLA_U32 },
719 [CTA_TIMEOUT_DCCP_OPEN] = { .type = NLA_U32 },
720 [CTA_TIMEOUT_DCCP_CLOSEREQ] = { .type = NLA_U32 },
721 [CTA_TIMEOUT_DCCP_CLOSING] = { .type = NLA_U32 },
722 [CTA_TIMEOUT_DCCP_TIMEWAIT] = { .type = NLA_U32 },
723 };
724 #endif
725
726 void nf_conntrack_dccp_init_net(struct net *net)
727 {
728 struct nf_dccp_net *dn = nf_dccp_pernet(net);
729
730
731 dn->dccp_loose = 1;
732 dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL;
733 dn->dccp_timeout[CT_DCCP_RESPOND] = 4 * DCCP_MSL;
734 dn->dccp_timeout[CT_DCCP_PARTOPEN] = 4 * DCCP_MSL;
735 dn->dccp_timeout[CT_DCCP_OPEN] = 12 * 3600 * HZ;
736 dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ;
737 dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ;
738 dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL;
739
740
741
742
743 dn->dccp_timeout[CT_DCCP_NONE] = dn->dccp_timeout[CT_DCCP_REQUEST];
744 }
745
746 const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp = {
747 .l4proto = IPPROTO_DCCP,
748 .can_early_drop = dccp_can_early_drop,
749 #ifdef CONFIG_NF_CONNTRACK_PROCFS
750 .print_conntrack = dccp_print_conntrack,
751 #endif
752 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
753 .nlattr_size = DCCP_NLATTR_SIZE,
754 .to_nlattr = dccp_to_nlattr,
755 .from_nlattr = nlattr_to_dccp,
756 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
757 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
758 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
759 .nla_policy = nf_ct_port_nla_policy,
760 #endif
761 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
762 .ctnl_timeout = {
763 .nlattr_to_obj = dccp_timeout_nlattr_to_obj,
764 .obj_to_nlattr = dccp_timeout_obj_to_nlattr,
765 .nlattr_max = CTA_TIMEOUT_DCCP_MAX,
766 .obj_size = sizeof(unsigned int) * CT_DCCP_MAX,
767 .nla_policy = dccp_timeout_nla_policy,
768 },
769 #endif
770 };