Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: add cttimeout infrastructure for fine timeout tuning

This patch adds the infrastructure to add fine timeout tuning
over nfnetlink. Now you can use the NFNL_SUBSYS_CTNETLINK_TIMEOUT
subsystem to create/delete/dump timeout objects that contain some
specific timeout policy for one flow.

The follow up patches will allow you attach timeout policy object
to conntrack via the CT target and the conntrack extension
infrastructure.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+1131 -1
+1
include/linux/netfilter/Kbuild
··· 10 10 header-y += nfnetlink_acct.h 11 11 header-y += nfnetlink_compat.h 12 12 header-y += nfnetlink_conntrack.h 13 + header-y += nfnetlink_cttimeout.h 13 14 header-y += nfnetlink_log.h 14 15 header-y += nfnetlink_queue.h 15 16 header-y += x_tables.h
+2 -1
include/linux/netfilter/nfnetlink.h
··· 49 49 #define NFNL_SUBSYS_OSF 5 50 50 #define NFNL_SUBSYS_IPSET 6 51 51 #define NFNL_SUBSYS_ACCT 7 52 - #define NFNL_SUBSYS_COUNT 8 52 + #define NFNL_SUBSYS_CTNETLINK_TIMEOUT 8 53 + #define NFNL_SUBSYS_COUNT 9 53 54 54 55 #ifdef __KERNEL__ 55 56
+11
include/net/netfilter/nf_conntrack_l4proto.h
··· 83 83 84 84 size_t nla_size; 85 85 86 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 87 + struct { 88 + size_t obj_size; 89 + int (*nlattr_to_obj)(struct nlattr *tb[], void *data); 90 + int (*obj_to_nlattr)(struct sk_buff *skb, const void *data); 91 + 92 + unsigned int nlattr_max; 93 + const struct nla_policy *nla_policy; 94 + } ctnl_timeout; 95 + #endif 96 + 86 97 #ifdef CONFIG_SYSCTL 87 98 struct ctl_table_header **ctl_table_header; 88 99 struct ctl_table *ctl_table;
+47
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
··· 269 269 } 270 270 #endif 271 271 272 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 273 + 274 + #include <linux/netfilter/nfnetlink.h> 275 + #include <linux/netfilter/nfnetlink_cttimeout.h> 276 + 277 + static int icmp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 278 + { 279 + unsigned int *timeout = data; 280 + 281 + if (tb[CTA_TIMEOUT_ICMP_TIMEOUT]) { 282 + *timeout = 283 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMP_TIMEOUT])) * HZ; 284 + } else { 285 + /* Set default ICMP timeout. */ 286 + *timeout = nf_ct_icmp_timeout; 287 + } 288 + return 0; 289 + } 290 + 291 + static int 292 + icmp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 293 + { 294 + const unsigned int *timeout = data; 295 + 296 + NLA_PUT_BE32(skb, CTA_TIMEOUT_ICMP_TIMEOUT, htonl(*timeout / HZ)); 297 + 298 + return 0; 299 + 300 + nla_put_failure: 301 + return -ENOSPC; 302 + } 303 + 304 + static const struct nla_policy 305 + icmp_timeout_nla_policy[CTA_TIMEOUT_ICMP_MAX+1] = { 306 + [CTA_TIMEOUT_ICMP_TIMEOUT] = { .type = NLA_U32 }, 307 + }; 308 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 309 + 272 310 #ifdef CONFIG_SYSCTL 273 311 static struct ctl_table_header *icmp_sysctl_header; 274 312 static struct ctl_table icmp_sysctl_table[] = { ··· 353 315 .nlattr_to_tuple = icmp_nlattr_to_tuple, 354 316 .nla_policy = icmp_nla_policy, 355 317 #endif 318 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 319 + .ctnl_timeout = { 320 + .nlattr_to_obj = icmp_timeout_nlattr_to_obj, 321 + .obj_to_nlattr = icmp_timeout_obj_to_nlattr, 322 + .nlattr_max = CTA_TIMEOUT_ICMP_MAX, 323 + .obj_size = sizeof(unsigned int), 324 + .nla_policy = icmp_timeout_nla_policy, 325 + }, 326 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 356 327 #ifdef CONFIG_SYSCTL 357 328 .ctl_table_header = &icmp_sysctl_header, 358 329 .ctl_table = icmp_sysctl_table,
+47
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
··· 276 276 } 277 277 #endif 278 278 279 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 280 + 281 + #include <linux/netfilter/nfnetlink.h> 282 + #include <linux/netfilter/nfnetlink_cttimeout.h> 283 + 284 + static int icmpv6_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 285 + { 286 + unsigned int *timeout = data; 287 + 288 + if (tb[CTA_TIMEOUT_ICMPV6_TIMEOUT]) { 289 + *timeout = 290 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMPV6_TIMEOUT])) * HZ; 291 + } else { 292 + /* Set default ICMPv6 timeout. */ 293 + *timeout = nf_ct_icmpv6_timeout; 294 + } 295 + return 0; 296 + } 297 + 298 + static int 299 + icmpv6_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 300 + { 301 + const unsigned int *timeout = data; 302 + 303 + NLA_PUT_BE32(skb, CTA_TIMEOUT_ICMPV6_TIMEOUT, htonl(*timeout / HZ)); 304 + 305 + return 0; 306 + 307 + nla_put_failure: 308 + return -ENOSPC; 309 + } 310 + 311 + static const struct nla_policy 312 + icmpv6_timeout_nla_policy[CTA_TIMEOUT_ICMPV6_MAX+1] = { 313 + [CTA_TIMEOUT_ICMPV6_TIMEOUT] = { .type = NLA_U32 }, 314 + }; 315 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 316 + 279 317 #ifdef CONFIG_SYSCTL 280 318 static struct ctl_table_header *icmpv6_sysctl_header; 281 319 static struct ctl_table icmpv6_sysctl_table[] = { ··· 346 308 .nlattr_to_tuple = icmpv6_nlattr_to_tuple, 347 309 .nla_policy = icmpv6_nla_policy, 348 310 #endif 311 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 312 + .ctnl_timeout = { 313 + .nlattr_to_obj = icmpv6_timeout_nlattr_to_obj, 314 + .obj_to_nlattr = icmpv6_timeout_obj_to_nlattr, 315 + .nlattr_max = CTA_TIMEOUT_ICMP_MAX, 316 + .obj_size = sizeof(unsigned int), 317 + .nla_policy = icmpv6_timeout_nla_policy, 318 + }, 319 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 349 320 #ifdef CONFIG_SYSCTL 350 321 .ctl_table_header = &icmpv6_sysctl_header, 351 322 .ctl_table = icmpv6_sysctl_table,
+11
net/netfilter/Kconfig
··· 314 314 help 315 315 This option enables support for a netlink-based userspace interface 316 316 317 + config NF_CT_NETLINK_TIMEOUT 318 + tristate 'Connection tracking timeout tuning via Netlink' 319 + select NETFILTER_NETLINK 320 + depends on NETFILTER_ADVANCED 321 + help 322 + This option enables support for connection tracking timeout 323 + fine-grain tuning. This allows you to attach specific timeout 324 + policies to flows, instead of using the global timeout policy. 325 + 326 + If unsure, say `N'. 327 + 317 328 endif # NF_CONNTRACK 318 329 319 330 # transparent proxy support
+1
net/netfilter/Makefile
··· 22 22 23 23 # netlink interface for nf_conntrack 24 24 obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o 25 + obj-$(CONFIG_NF_CT_NETLINK_TIMEOUT) += nfnetlink_cttimeout.o 25 26 26 27 # connection tracking helpers 27 28 nf_conntrack_h323-objs := nf_conntrack_h323_main.o nf_conntrack_h323_asn1.o
+70
net/netfilter/nf_conntrack_proto_dccp.c
··· 706 706 return nla_total_size(0) /* CTA_PROTOINFO_DCCP */ 707 707 + nla_policy_len(dccp_nla_policy, CTA_PROTOINFO_DCCP_MAX + 1); 708 708 } 709 + 709 710 #endif 711 + 712 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 713 + 714 + #include <linux/netfilter/nfnetlink.h> 715 + #include <linux/netfilter/nfnetlink_cttimeout.h> 716 + 717 + static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 718 + { 719 + struct dccp_net *dn = dccp_pernet(&init_net); 720 + unsigned int *timeouts = data; 721 + int i; 722 + 723 + /* set default DCCP timeouts. */ 724 + for (i=0; i<CT_DCCP_MAX; i++) 725 + timeouts[i] = dn->dccp_timeout[i]; 726 + 727 + /* there's a 1:1 mapping between attributes and protocol states. */ 728 + for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) { 729 + if (tb[i]) { 730 + timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ; 731 + } 732 + } 733 + return 0; 734 + } 735 + 736 + static int 737 + dccp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 738 + { 739 + const unsigned int *timeouts = data; 740 + int i; 741 + 742 + for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) 743 + NLA_PUT_BE32(skb, i, htonl(timeouts[i] / HZ)); 744 + 745 + return 0; 746 + 747 + nla_put_failure: 748 + return -ENOSPC; 749 + } 750 + 751 + static const struct nla_policy 752 + dccp_timeout_nla_policy[CTA_TIMEOUT_DCCP_MAX+1] = { 753 + [CTA_TIMEOUT_DCCP_REQUEST] = { .type = NLA_U32 }, 754 + [CTA_TIMEOUT_DCCP_RESPOND] = { .type = NLA_U32 }, 755 + [CTA_TIMEOUT_DCCP_PARTOPEN] = { .type = NLA_U32 }, 756 + [CTA_TIMEOUT_DCCP_OPEN] = { .type = NLA_U32 }, 757 + [CTA_TIMEOUT_DCCP_CLOSEREQ] = { .type = NLA_U32 }, 758 + [CTA_TIMEOUT_DCCP_CLOSING] = { .type = NLA_U32 }, 759 + [CTA_TIMEOUT_DCCP_TIMEWAIT] = { .type = NLA_U32 }, 760 + }; 761 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 710 762 711 763 #ifdef CONFIG_SYSCTL 712 764 /* template, data assigned later */ ··· 836 784 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 837 785 .nla_policy = nf_ct_port_nla_policy, 838 786 #endif 787 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 788 + .ctnl_timeout = { 789 + .nlattr_to_obj = dccp_timeout_nlattr_to_obj, 790 + .obj_to_nlattr = dccp_timeout_obj_to_nlattr, 791 + .nlattr_max = CTA_TIMEOUT_DCCP_MAX, 792 + .obj_size = sizeof(unsigned int) * CT_DCCP_MAX, 793 + .nla_policy = dccp_timeout_nla_policy, 794 + }, 795 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 839 796 }; 840 797 841 798 static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = { ··· 868 807 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 869 808 .nla_policy = nf_ct_port_nla_policy, 870 809 #endif 810 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 811 + .ctnl_timeout = { 812 + .nlattr_to_obj = dccp_timeout_nlattr_to_obj, 813 + .obj_to_nlattr = dccp_timeout_obj_to_nlattr, 814 + .nlattr_max = CTA_TIMEOUT_DCCP_MAX, 815 + .obj_size = sizeof(unsigned int) * CT_DCCP_MAX, 816 + .nla_policy = dccp_timeout_nla_policy, 817 + }, 818 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 871 819 }; 872 820 873 821 static __net_init int dccp_net_init(struct net *net)
+48
net/netfilter/nf_conntrack_proto_generic.c
··· 65 65 return true; 66 66 } 67 67 68 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 69 + 70 + #include <linux/netfilter/nfnetlink.h> 71 + #include <linux/netfilter/nfnetlink_cttimeout.h> 72 + 73 + static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 74 + { 75 + unsigned int *timeout = data; 76 + 77 + if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT]) 78 + *timeout = 79 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ; 80 + else { 81 + /* Set default generic timeout. */ 82 + *timeout = nf_ct_generic_timeout; 83 + } 84 + 85 + return 0; 86 + } 87 + 88 + static int 89 + generic_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 90 + { 91 + const unsigned int *timeout = data; 92 + 93 + NLA_PUT_BE32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ)); 94 + 95 + return 0; 96 + 97 + nla_put_failure: 98 + return -ENOSPC; 99 + } 100 + 101 + static const struct nla_policy 102 + generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = { 103 + [CTA_TIMEOUT_GENERIC_TIMEOUT] = { .type = NLA_U32 }, 104 + }; 105 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 106 + 68 107 #ifdef CONFIG_SYSCTL 69 108 static struct ctl_table_header *generic_sysctl_header; 70 109 static struct ctl_table generic_sysctl_table[] = { ··· 141 102 .packet = generic_packet, 142 103 .get_timeouts = generic_get_timeouts, 143 104 .new = generic_new, 105 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 106 + .ctnl_timeout = { 107 + .nlattr_to_obj = generic_timeout_nlattr_to_obj, 108 + .obj_to_nlattr = generic_timeout_obj_to_nlattr, 109 + .nlattr_max = CTA_TIMEOUT_GENERIC_MAX, 110 + .obj_size = sizeof(unsigned int), 111 + .nla_policy = generic_timeout_nla_policy, 112 + }, 113 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 144 114 #ifdef CONFIG_SYSCTL 145 115 .ctl_table_header = &generic_sysctl_header, 146 116 .ctl_table = generic_sysctl_table,
+55
net/netfilter/nf_conntrack_proto_gre.c
··· 292 292 nf_ct_gre_keymap_destroy(master); 293 293 } 294 294 295 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 296 + 297 + #include <linux/netfilter/nfnetlink.h> 298 + #include <linux/netfilter/nfnetlink_cttimeout.h> 299 + 300 + static int gre_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 301 + { 302 + unsigned int *timeouts = data; 303 + 304 + /* set default timeouts for GRE. */ 305 + timeouts[GRE_CT_UNREPLIED] = gre_timeouts[GRE_CT_UNREPLIED]; 306 + timeouts[GRE_CT_REPLIED] = gre_timeouts[GRE_CT_REPLIED]; 307 + 308 + if (tb[CTA_TIMEOUT_GRE_UNREPLIED]) { 309 + timeouts[GRE_CT_UNREPLIED] = 310 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_GRE_UNREPLIED])) * HZ; 311 + } 312 + if (tb[CTA_TIMEOUT_GRE_REPLIED]) { 313 + timeouts[GRE_CT_REPLIED] = 314 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_GRE_REPLIED])) * HZ; 315 + } 316 + return 0; 317 + } 318 + 319 + static int 320 + gre_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 321 + { 322 + const unsigned int *timeouts = data; 323 + 324 + NLA_PUT_BE32(skb, CTA_TIMEOUT_GRE_UNREPLIED, 325 + htonl(timeouts[GRE_CT_UNREPLIED] / HZ)); 326 + NLA_PUT_BE32(skb, CTA_TIMEOUT_GRE_REPLIED, 327 + htonl(timeouts[GRE_CT_REPLIED] / HZ)); 328 + return 0; 329 + 330 + nla_put_failure: 331 + return -ENOSPC; 332 + } 333 + 334 + static const struct nla_policy 335 + gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = { 336 + [CTA_TIMEOUT_GRE_UNREPLIED] = { .type = NLA_U32 }, 337 + [CTA_TIMEOUT_GRE_REPLIED] = { .type = NLA_U32 }, 338 + }; 339 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 340 + 295 341 /* protocol helper struct */ 296 342 static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = { 297 343 .l3proto = AF_INET, ··· 358 312 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 359 313 .nla_policy = nf_ct_port_nla_policy, 360 314 #endif 315 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 316 + .ctnl_timeout = { 317 + .nlattr_to_obj = gre_timeout_nlattr_to_obj, 318 + .obj_to_nlattr = gre_timeout_obj_to_nlattr, 319 + .nlattr_max = CTA_TIMEOUT_GRE_MAX, 320 + .obj_size = sizeof(unsigned int) * GRE_CT_MAX, 321 + .nla_policy = gre_timeout_nla_policy, 322 + }, 323 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 361 324 }; 362 325 363 326 static int proto_gre_net_init(struct net *net)
+69
net/netfilter/nf_conntrack_proto_sctp.c
··· 549 549 } 550 550 #endif 551 551 552 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 553 + 554 + #include <linux/netfilter/nfnetlink.h> 555 + #include <linux/netfilter/nfnetlink_cttimeout.h> 556 + 557 + static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 558 + { 559 + unsigned int *timeouts = data; 560 + int i; 561 + 562 + /* set default SCTP timeouts. */ 563 + for (i=0; i<SCTP_CONNTRACK_MAX; i++) 564 + timeouts[i] = sctp_timeouts[i]; 565 + 566 + /* there's a 1:1 mapping between attributes and protocol states. */ 567 + for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) { 568 + if (tb[i]) { 569 + timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ; 570 + } 571 + } 572 + return 0; 573 + } 574 + 575 + static int 576 + sctp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 577 + { 578 + const unsigned int *timeouts = data; 579 + int i; 580 + 581 + for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) 582 + NLA_PUT_BE32(skb, i, htonl(timeouts[i] / HZ)); 583 + 584 + return 0; 585 + 586 + nla_put_failure: 587 + return -ENOSPC; 588 + } 589 + 590 + static const struct nla_policy 591 + sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = { 592 + [CTA_TIMEOUT_SCTP_CLOSED] = { .type = NLA_U32 }, 593 + [CTA_TIMEOUT_SCTP_COOKIE_WAIT] = { .type = NLA_U32 }, 594 + [CTA_TIMEOUT_SCTP_COOKIE_ECHOED] = { .type = NLA_U32 }, 595 + [CTA_TIMEOUT_SCTP_ESTABLISHED] = { .type = NLA_U32 }, 596 + [CTA_TIMEOUT_SCTP_SHUTDOWN_SENT] = { .type = NLA_U32 }, 597 + [CTA_TIMEOUT_SCTP_SHUTDOWN_RECD] = { .type = NLA_U32 }, 598 + [CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT] = { .type = NLA_U32 }, 599 + }; 600 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 601 + 602 + 552 603 #ifdef CONFIG_SYSCTL 553 604 static unsigned int sctp_sysctl_table_users; 554 605 static struct ctl_table_header *sctp_sysctl_header; ··· 733 682 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 734 683 .nla_policy = nf_ct_port_nla_policy, 735 684 #endif 685 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 686 + .ctnl_timeout = { 687 + .nlattr_to_obj = sctp_timeout_nlattr_to_obj, 688 + .obj_to_nlattr = sctp_timeout_obj_to_nlattr, 689 + .nlattr_max = CTA_TIMEOUT_SCTP_MAX, 690 + .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX, 691 + .nla_policy = sctp_timeout_nla_policy, 692 + }, 693 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 736 694 #ifdef CONFIG_SYSCTL 737 695 .ctl_table_users = &sctp_sysctl_table_users, 738 696 .ctl_table_header = &sctp_sysctl_header, ··· 772 712 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 773 713 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 774 714 .nla_policy = nf_ct_port_nla_policy, 715 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 716 + .ctnl_timeout = { 717 + .nlattr_to_obj = sctp_timeout_nlattr_to_obj, 718 + .obj_to_nlattr = sctp_timeout_obj_to_nlattr, 719 + .nlattr_max = CTA_TIMEOUT_SCTP_MAX, 720 + .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX, 721 + .nla_policy = sctp_timeout_nla_policy, 722 + }, 723 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 775 724 #endif 776 725 #ifdef CONFIG_SYSCTL 777 726 .ctl_table_users = &sctp_sysctl_table_users,
+127
net/netfilter/nf_conntrack_proto_tcp.c
··· 1244 1244 } 1245 1245 #endif 1246 1246 1247 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 1248 + 1249 + #include <linux/netfilter/nfnetlink.h> 1250 + #include <linux/netfilter/nfnetlink_cttimeout.h> 1251 + 1252 + static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 1253 + { 1254 + unsigned int *timeouts = data; 1255 + int i; 1256 + 1257 + /* set default TCP timeouts. */ 1258 + for (i=0; i<TCP_CONNTRACK_TIMEOUT_MAX; i++) 1259 + timeouts[i] = tcp_timeouts[i]; 1260 + 1261 + if (tb[CTA_TIMEOUT_TCP_SYN_SENT]) { 1262 + timeouts[TCP_CONNTRACK_SYN_SENT] = 1263 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_SENT]))*HZ; 1264 + } 1265 + if (tb[CTA_TIMEOUT_TCP_SYN_RECV]) { 1266 + timeouts[TCP_CONNTRACK_SYN_RECV] = 1267 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_RECV]))*HZ; 1268 + } 1269 + if (tb[CTA_TIMEOUT_TCP_ESTABLISHED]) { 1270 + timeouts[TCP_CONNTRACK_ESTABLISHED] = 1271 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_ESTABLISHED]))*HZ; 1272 + } 1273 + if (tb[CTA_TIMEOUT_TCP_FIN_WAIT]) { 1274 + timeouts[TCP_CONNTRACK_FIN_WAIT] = 1275 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_FIN_WAIT]))*HZ; 1276 + } 1277 + if (tb[CTA_TIMEOUT_TCP_CLOSE_WAIT]) { 1278 + timeouts[TCP_CONNTRACK_CLOSE_WAIT] = 1279 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_CLOSE_WAIT]))*HZ; 1280 + } 1281 + if (tb[CTA_TIMEOUT_TCP_LAST_ACK]) { 1282 + timeouts[TCP_CONNTRACK_LAST_ACK] = 1283 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_LAST_ACK]))*HZ; 1284 + } 1285 + if (tb[CTA_TIMEOUT_TCP_TIME_WAIT]) { 1286 + timeouts[TCP_CONNTRACK_TIME_WAIT] = 1287 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_TIME_WAIT]))*HZ; 1288 + } 1289 + if (tb[CTA_TIMEOUT_TCP_CLOSE]) { 1290 + timeouts[TCP_CONNTRACK_CLOSE] = 1291 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_CLOSE]))*HZ; 1292 + } 1293 + if (tb[CTA_TIMEOUT_TCP_SYN_SENT2]) { 1294 + timeouts[TCP_CONNTRACK_SYN_SENT2] = 1295 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_SYN_SENT2]))*HZ; 1296 + } 1297 + if (tb[CTA_TIMEOUT_TCP_RETRANS]) { 1298 + timeouts[TCP_CONNTRACK_RETRANS] = 1299 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_RETRANS]))*HZ; 1300 + } 1301 + if (tb[CTA_TIMEOUT_TCP_UNACK]) { 1302 + timeouts[TCP_CONNTRACK_UNACK] = 1303 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_TCP_UNACK]))*HZ; 1304 + } 1305 + return 0; 1306 + } 1307 + 1308 + static int 1309 + tcp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 1310 + { 1311 + const unsigned int *timeouts = data; 1312 + 1313 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_SYN_SENT, 1314 + htonl(timeouts[TCP_CONNTRACK_SYN_SENT] / HZ)); 1315 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_SYN_RECV, 1316 + htonl(timeouts[TCP_CONNTRACK_SYN_RECV] / HZ)); 1317 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_ESTABLISHED, 1318 + htonl(timeouts[TCP_CONNTRACK_ESTABLISHED] / HZ)); 1319 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_FIN_WAIT, 1320 + htonl(timeouts[TCP_CONNTRACK_FIN_WAIT] / HZ)); 1321 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_CLOSE_WAIT, 1322 + htonl(timeouts[TCP_CONNTRACK_CLOSE_WAIT] / HZ)); 1323 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_LAST_ACK, 1324 + htonl(timeouts[TCP_CONNTRACK_LAST_ACK] / HZ)); 1325 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_TIME_WAIT, 1326 + htonl(timeouts[TCP_CONNTRACK_TIME_WAIT] / HZ)); 1327 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_CLOSE, 1328 + htonl(timeouts[TCP_CONNTRACK_CLOSE] / HZ)); 1329 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_SYN_SENT2, 1330 + htonl(timeouts[TCP_CONNTRACK_SYN_SENT2] / HZ)); 1331 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_RETRANS, 1332 + htonl(timeouts[TCP_CONNTRACK_RETRANS] / HZ)); 1333 + NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_UNACK, 1334 + htonl(timeouts[TCP_CONNTRACK_UNACK] / HZ)); 1335 + return 0; 1336 + 1337 + nla_put_failure: 1338 + return -ENOSPC; 1339 + } 1340 + 1341 + static const struct nla_policy tcp_timeout_nla_policy[CTA_TIMEOUT_TCP_MAX+1] = { 1342 + [CTA_TIMEOUT_TCP_SYN_SENT] = { .type = NLA_U32 }, 1343 + [CTA_TIMEOUT_TCP_SYN_RECV] = { .type = NLA_U32 }, 1344 + [CTA_TIMEOUT_TCP_ESTABLISHED] = { .type = NLA_U32 }, 1345 + [CTA_TIMEOUT_TCP_FIN_WAIT] = { .type = NLA_U32 }, 1346 + [CTA_TIMEOUT_TCP_CLOSE_WAIT] = { .type = NLA_U32 }, 1347 + [CTA_TIMEOUT_TCP_LAST_ACK] = { .type = NLA_U32 }, 1348 + [CTA_TIMEOUT_TCP_TIME_WAIT] = { .type = NLA_U32 }, 1349 + [CTA_TIMEOUT_TCP_CLOSE] = { .type = NLA_U32 }, 1350 + [CTA_TIMEOUT_TCP_SYN_SENT2] = { .type = NLA_U32 }, 1351 + }; 1352 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 1353 + 1247 1354 #ifdef CONFIG_SYSCTL 1248 1355 static unsigned int tcp_sysctl_table_users; 1249 1356 static struct ctl_table_header *tcp_sysctl_header; ··· 1569 1462 .nlattr_tuple_size = tcp_nlattr_tuple_size, 1570 1463 .nla_policy = nf_ct_port_nla_policy, 1571 1464 #endif 1465 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 1466 + .ctnl_timeout = { 1467 + .nlattr_to_obj = tcp_timeout_nlattr_to_obj, 1468 + .obj_to_nlattr = tcp_timeout_obj_to_nlattr, 1469 + .nlattr_max = CTA_TIMEOUT_TCP_MAX, 1470 + .obj_size = sizeof(unsigned int) * 1471 + TCP_CONNTRACK_TIMEOUT_MAX, 1472 + .nla_policy = tcp_timeout_nla_policy, 1473 + }, 1474 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 1572 1475 #ifdef CONFIG_SYSCTL 1573 1476 .ctl_table_users = &tcp_sysctl_table_users, 1574 1477 .ctl_table_header = &tcp_sysctl_header, ··· 1612 1495 .nlattr_tuple_size = tcp_nlattr_tuple_size, 1613 1496 .nla_policy = nf_ct_port_nla_policy, 1614 1497 #endif 1498 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 1499 + .ctnl_timeout = { 1500 + .nlattr_to_obj = tcp_timeout_nlattr_to_obj, 1501 + .obj_to_nlattr = tcp_timeout_obj_to_nlattr, 1502 + .nlattr_max = CTA_TIMEOUT_TCP_MAX, 1503 + .obj_size = sizeof(unsigned int) * 1504 + TCP_CONNTRACK_TIMEOUT_MAX, 1505 + .nla_policy = tcp_timeout_nla_policy, 1506 + }, 1507 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 1615 1508 #ifdef CONFIG_SYSCTL 1616 1509 .ctl_table_users = &tcp_sysctl_table_users, 1617 1510 .ctl_table_header = &tcp_sysctl_header,
+64
net/netfilter/nf_conntrack_proto_udp.c
··· 152 152 return NF_ACCEPT; 153 153 } 154 154 155 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 156 + 157 + #include <linux/netfilter/nfnetlink.h> 158 + #include <linux/netfilter/nfnetlink_cttimeout.h> 159 + 160 + static int udp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 161 + { 162 + unsigned int *timeouts = data; 163 + 164 + /* set default timeouts for UDP. */ 165 + timeouts[UDP_CT_UNREPLIED] = udp_timeouts[UDP_CT_UNREPLIED]; 166 + timeouts[UDP_CT_REPLIED] = udp_timeouts[UDP_CT_REPLIED]; 167 + 168 + if (tb[CTA_TIMEOUT_UDP_UNREPLIED]) { 169 + timeouts[UDP_CT_UNREPLIED] = 170 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDP_UNREPLIED])) * HZ; 171 + } 172 + if (tb[CTA_TIMEOUT_UDP_REPLIED]) { 173 + timeouts[UDP_CT_REPLIED] = 174 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDP_REPLIED])) * HZ; 175 + } 176 + return 0; 177 + } 178 + 179 + static int 180 + udp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 181 + { 182 + const unsigned int *timeouts = data; 183 + 184 + NLA_PUT_BE32(skb, CTA_TIMEOUT_UDP_UNREPLIED, 185 + htonl(timeouts[UDP_CT_UNREPLIED] / HZ)); 186 + NLA_PUT_BE32(skb, CTA_TIMEOUT_UDP_REPLIED, 187 + htonl(timeouts[UDP_CT_REPLIED] / HZ)); 188 + return 0; 189 + 190 + nla_put_failure: 191 + return -ENOSPC; 192 + } 193 + 194 + static const struct nla_policy 195 + udp_timeout_nla_policy[CTA_TIMEOUT_UDP_MAX+1] = { 196 + [CTA_TIMEOUT_UDP_UNREPLIED] = { .type = NLA_U32 }, 197 + [CTA_TIMEOUT_UDP_REPLIED] = { .type = NLA_U32 }, 198 + }; 199 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 200 + 155 201 #ifdef CONFIG_SYSCTL 156 202 static unsigned int udp_sysctl_table_users; 157 203 static struct ctl_table_header *udp_sysctl_header; ··· 257 211 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 258 212 .nla_policy = nf_ct_port_nla_policy, 259 213 #endif 214 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 215 + .ctnl_timeout = { 216 + .nlattr_to_obj = udp_timeout_nlattr_to_obj, 217 + .obj_to_nlattr = udp_timeout_obj_to_nlattr, 218 + .nlattr_max = CTA_TIMEOUT_UDP_MAX, 219 + .obj_size = sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX, 220 + .nla_policy = udp_timeout_nla_policy, 221 + }, 222 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 260 223 #ifdef CONFIG_SYSCTL 261 224 .ctl_table_users = &udp_sysctl_table_users, 262 225 .ctl_table_header = &udp_sysctl_header, ··· 295 240 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 296 241 .nla_policy = nf_ct_port_nla_policy, 297 242 #endif 243 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 244 + .ctnl_timeout = { 245 + .nlattr_to_obj = udp_timeout_nlattr_to_obj, 246 + .obj_to_nlattr = udp_timeout_obj_to_nlattr, 247 + .nlattr_max = CTA_TIMEOUT_UDP_MAX, 248 + .obj_size = sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX, 249 + .nla_policy = udp_timeout_nla_policy, 250 + }, 251 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 298 252 #ifdef CONFIG_SYSCTL 299 253 .ctl_table_users = &udp_sysctl_table_users, 300 254 .ctl_table_header = &udp_sysctl_header,
+66
net/netfilter/nf_conntrack_proto_udplite.c
··· 156 156 return NF_ACCEPT; 157 157 } 158 158 159 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 160 + 161 + #include <linux/netfilter/nfnetlink.h> 162 + #include <linux/netfilter/nfnetlink_cttimeout.h> 163 + 164 + static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 165 + { 166 + unsigned int *timeouts = data; 167 + 168 + /* set default timeouts for UDPlite. */ 169 + timeouts[UDPLITE_CT_UNREPLIED] = udplite_timeouts[UDPLITE_CT_UNREPLIED]; 170 + timeouts[UDPLITE_CT_REPLIED] = udplite_timeouts[UDPLITE_CT_REPLIED]; 171 + 172 + if (tb[CTA_TIMEOUT_UDPLITE_UNREPLIED]) { 173 + timeouts[UDPLITE_CT_UNREPLIED] = 174 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDPLITE_UNREPLIED])) * HZ; 175 + } 176 + if (tb[CTA_TIMEOUT_UDPLITE_REPLIED]) { 177 + timeouts[UDPLITE_CT_REPLIED] = 178 + ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDPLITE_REPLIED])) * HZ; 179 + } 180 + return 0; 181 + } 182 + 183 + static int 184 + udplite_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 185 + { 186 + const unsigned int *timeouts = data; 187 + 188 + NLA_PUT_BE32(skb, CTA_TIMEOUT_UDPLITE_UNREPLIED, 189 + htonl(timeouts[UDPLITE_CT_UNREPLIED] / HZ)); 190 + NLA_PUT_BE32(skb, CTA_TIMEOUT_UDPLITE_REPLIED, 191 + htonl(timeouts[UDPLITE_CT_REPLIED] / HZ)); 192 + return 0; 193 + 194 + nla_put_failure: 195 + return -ENOSPC; 196 + } 197 + 198 + static const struct nla_policy 199 + udplite_timeout_nla_policy[CTA_TIMEOUT_UDPLITE_MAX+1] = { 200 + [CTA_TIMEOUT_UDPLITE_UNREPLIED] = { .type = NLA_U32 }, 201 + [CTA_TIMEOUT_UDPLITE_REPLIED] = { .type = NLA_U32 }, 202 + }; 203 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 204 + 159 205 #ifdef CONFIG_SYSCTL 160 206 static unsigned int udplite_sysctl_table_users; 161 207 static struct ctl_table_header *udplite_sysctl_header; ··· 242 196 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 243 197 .nla_policy = nf_ct_port_nla_policy, 244 198 #endif 199 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 200 + .ctnl_timeout = { 201 + .nlattr_to_obj = udplite_timeout_nlattr_to_obj, 202 + .obj_to_nlattr = udplite_timeout_obj_to_nlattr, 203 + .nlattr_max = CTA_TIMEOUT_UDPLITE_MAX, 204 + .obj_size = sizeof(unsigned int) * 205 + CTA_TIMEOUT_UDPLITE_MAX, 206 + .nla_policy = udplite_timeout_nla_policy, 207 + }, 208 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 245 209 #ifdef CONFIG_SYSCTL 246 210 .ctl_table_users = &udplite_sysctl_table_users, 247 211 .ctl_table_header = &udplite_sysctl_header, ··· 277 221 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 278 222 .nla_policy = nf_ct_port_nla_policy, 279 223 #endif 224 + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 225 + .ctnl_timeout = { 226 + .nlattr_to_obj = udplite_timeout_nlattr_to_obj, 227 + .obj_to_nlattr = udplite_timeout_obj_to_nlattr, 228 + .nlattr_max = CTA_TIMEOUT_UDPLITE_MAX, 229 + .obj_size = sizeof(unsigned int) * 230 + CTA_TIMEOUT_UDPLITE_MAX, 231 + .nla_policy = udplite_timeout_nla_policy, 232 + }, 233 + #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 280 234 #ifdef CONFIG_SYSCTL 281 235 .ctl_table_users = &udplite_sysctl_table_users, 282 236 .ctl_table_header = &udplite_sysctl_header,