aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-02-28 12:23:31 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2012-03-07 11:41:19 -0500
commit2c8503f55fbdfbeff4164f133df804cf4d316290 (patch)
treefe491bc79fd59aa4b8b99ea63d13e62b6a2ef1cb /net
parentb888341c7f33035694f70428d7001d73f0b2a3b1 (diff)
netfilter: nf_conntrack: pass timeout array to l4->new and l4->packet
This patch defines a new interface for l4 protocol trackers: unsigned int *(*get_timeouts)(struct net *net); that is used to return the array of unsigned int that contains the timeouts that will be applied for this flow. This is passed to the l4proto->new(...) and l4proto->packet(...) functions to specify the timeout policy. This interface allows per-net global timeout configuration (although only DCCP supports this by now) and it will allow custom custom timeout configuration by means of follow-up patches. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c13
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c13
-rw-r--r--net/netfilter/nf_conntrack_core.c18
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c16
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c29
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c15
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c14
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c22
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c16
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c16
10 files changed, 122 insertions, 50 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index ab5b27a2916f..6b801124b31f 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -75,25 +75,31 @@ static int icmp_print_tuple(struct seq_file *s,
75 ntohs(tuple->src.u.icmp.id)); 75 ntohs(tuple->src.u.icmp.id));
76} 76}
77 77
78static unsigned int *icmp_get_timeouts(struct net *net)
79{
80 return &nf_ct_icmp_timeout;
81}
82
78/* Returns verdict for packet, or -1 for invalid. */ 83/* Returns verdict for packet, or -1 for invalid. */
79static int icmp_packet(struct nf_conn *ct, 84static int icmp_packet(struct nf_conn *ct,
80 const struct sk_buff *skb, 85 const struct sk_buff *skb,
81 unsigned int dataoff, 86 unsigned int dataoff,
82 enum ip_conntrack_info ctinfo, 87 enum ip_conntrack_info ctinfo,
83 u_int8_t pf, 88 u_int8_t pf,
84 unsigned int hooknum) 89 unsigned int hooknum,
90 unsigned int *timeout)
85{ 91{
86 /* Do not immediately delete the connection after the first 92 /* Do not immediately delete the connection after the first
87 successful reply to avoid excessive conntrackd traffic 93 successful reply to avoid excessive conntrackd traffic
88 and also to handle correctly ICMP echo reply duplicates. */ 94 and also to handle correctly ICMP echo reply duplicates. */
89 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); 95 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
90 96
91 return NF_ACCEPT; 97 return NF_ACCEPT;
92} 98}
93 99
94/* Called when a new connection for this protocol found. */ 100/* Called when a new connection for this protocol found. */
95static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb, 101static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
96 unsigned int dataoff) 102 unsigned int dataoff, unsigned int *timeouts)
97{ 103{
98 static const u_int8_t valid_new[] = { 104 static const u_int8_t valid_new[] = {
99 [ICMP_ECHO] = 1, 105 [ICMP_ECHO] = 1,
@@ -298,6 +304,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
298 .invert_tuple = icmp_invert_tuple, 304 .invert_tuple = icmp_invert_tuple,
299 .print_tuple = icmp_print_tuple, 305 .print_tuple = icmp_print_tuple,
300 .packet = icmp_packet, 306 .packet = icmp_packet,
307 .get_timeouts = icmp_get_timeouts,
301 .new = icmp_new, 308 .new = icmp_new,
302 .error = icmp_error, 309 .error = icmp_error,
303 .destroy = NULL, 310 .destroy = NULL,
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 7c05e7eacbc6..2eb9751eb7a8 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -88,25 +88,31 @@ static int icmpv6_print_tuple(struct seq_file *s,
88 ntohs(tuple->src.u.icmp.id)); 88 ntohs(tuple->src.u.icmp.id));
89} 89}
90 90
91static unsigned int *icmpv6_get_timeouts(struct net *net)
92{
93 return &nf_ct_icmpv6_timeout;
94}
95
91/* Returns verdict for packet, or -1 for invalid. */ 96/* Returns verdict for packet, or -1 for invalid. */
92static int icmpv6_packet(struct nf_conn *ct, 97static int icmpv6_packet(struct nf_conn *ct,
93 const struct sk_buff *skb, 98 const struct sk_buff *skb,
94 unsigned int dataoff, 99 unsigned int dataoff,
95 enum ip_conntrack_info ctinfo, 100 enum ip_conntrack_info ctinfo,
96 u_int8_t pf, 101 u_int8_t pf,
97 unsigned int hooknum) 102 unsigned int hooknum,
103 unsigned int *timeout)
98{ 104{
99 /* Do not immediately delete the connection after the first 105 /* Do not immediately delete the connection after the first
100 successful reply to avoid excessive conntrackd traffic 106 successful reply to avoid excessive conntrackd traffic
101 and also to handle correctly ICMP echo reply duplicates. */ 107 and also to handle correctly ICMP echo reply duplicates. */
102 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout); 108 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
103 109
104 return NF_ACCEPT; 110 return NF_ACCEPT;
105} 111}
106 112
107/* Called when a new connection for this protocol found. */ 113/* Called when a new connection for this protocol found. */
108static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, 114static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
109 unsigned int dataoff) 115 unsigned int dataoff, unsigned int *timeouts)
110{ 116{
111 static const u_int8_t valid_new[] = { 117 static const u_int8_t valid_new[] = {
112 [ICMPV6_ECHO_REQUEST - 128] = 1, 118 [ICMPV6_ECHO_REQUEST - 128] = 1,
@@ -293,6 +299,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
293 .invert_tuple = icmpv6_invert_tuple, 299 .invert_tuple = icmpv6_invert_tuple,
294 .print_tuple = icmpv6_print_tuple, 300 .print_tuple = icmpv6_print_tuple,
295 .packet = icmpv6_packet, 301 .packet = icmpv6_packet,
302 .get_timeouts = icmpv6_get_timeouts,
296 .new = icmpv6_new, 303 .new = icmpv6_new,
297 .error = icmpv6_error, 304 .error = icmpv6_error,
298#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 305#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ed86a3be678e..d18995eea1c6 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -763,7 +763,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
763 struct nf_conntrack_l3proto *l3proto, 763 struct nf_conntrack_l3proto *l3proto,
764 struct nf_conntrack_l4proto *l4proto, 764 struct nf_conntrack_l4proto *l4proto,
765 struct sk_buff *skb, 765 struct sk_buff *skb,
766 unsigned int dataoff, u32 hash) 766 unsigned int dataoff, u32 hash,
767 unsigned int *timeouts)
767{ 768{
768 struct nf_conn *ct; 769 struct nf_conn *ct;
769 struct nf_conn_help *help; 770 struct nf_conn_help *help;
@@ -782,7 +783,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
782 if (IS_ERR(ct)) 783 if (IS_ERR(ct))
783 return (struct nf_conntrack_tuple_hash *)ct; 784 return (struct nf_conntrack_tuple_hash *)ct;
784 785
785 if (!l4proto->new(ct, skb, dataoff)) { 786 if (!l4proto->new(ct, skb, dataoff, timeouts)) {
786 nf_conntrack_free(ct); 787 nf_conntrack_free(ct);
787 pr_debug("init conntrack: can't track with proto module\n"); 788 pr_debug("init conntrack: can't track with proto module\n");
788 return NULL; 789 return NULL;
@@ -848,7 +849,8 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
848 struct nf_conntrack_l3proto *l3proto, 849 struct nf_conntrack_l3proto *l3proto,
849 struct nf_conntrack_l4proto *l4proto, 850 struct nf_conntrack_l4proto *l4proto,
850 int *set_reply, 851 int *set_reply,
851 enum ip_conntrack_info *ctinfo) 852 enum ip_conntrack_info *ctinfo,
853 unsigned int *timeouts)
852{ 854{
853 struct nf_conntrack_tuple tuple; 855 struct nf_conntrack_tuple tuple;
854 struct nf_conntrack_tuple_hash *h; 856 struct nf_conntrack_tuple_hash *h;
@@ -868,7 +870,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
868 h = __nf_conntrack_find_get(net, zone, &tuple, hash); 870 h = __nf_conntrack_find_get(net, zone, &tuple, hash);
869 if (!h) { 871 if (!h) {
870 h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto, 872 h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto,
871 skb, dataoff, hash); 873 skb, dataoff, hash, timeouts);
872 if (!h) 874 if (!h)
873 return NULL; 875 return NULL;
874 if (IS_ERR(h)) 876 if (IS_ERR(h))
@@ -909,6 +911,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
909 enum ip_conntrack_info ctinfo; 911 enum ip_conntrack_info ctinfo;
910 struct nf_conntrack_l3proto *l3proto; 912 struct nf_conntrack_l3proto *l3proto;
911 struct nf_conntrack_l4proto *l4proto; 913 struct nf_conntrack_l4proto *l4proto;
914 unsigned int *timeouts;
912 unsigned int dataoff; 915 unsigned int dataoff;
913 u_int8_t protonum; 916 u_int8_t protonum;
914 int set_reply = 0; 917 int set_reply = 0;
@@ -955,8 +958,11 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
955 goto out; 958 goto out;
956 } 959 }
957 960
961 timeouts = l4proto->get_timeouts(net);
962
958 ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum, 963 ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
959 l3proto, l4proto, &set_reply, &ctinfo); 964 l3proto, l4proto, &set_reply, &ctinfo,
965 timeouts);
960 if (!ct) { 966 if (!ct) {
961 /* Not valid part of a connection */ 967 /* Not valid part of a connection */
962 NF_CT_STAT_INC_ATOMIC(net, invalid); 968 NF_CT_STAT_INC_ATOMIC(net, invalid);
@@ -973,7 +979,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
973 979
974 NF_CT_ASSERT(skb->nfct); 980 NF_CT_ASSERT(skb->nfct);
975 981
976 ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum); 982 ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum, timeouts);
977 if (ret <= 0) { 983 if (ret <= 0) {
978 /* Invalid: inverse of the return code tells 984 /* Invalid: inverse of the return code tells
979 * the netfilter core what to do */ 985 * the netfilter core what to do */
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index d6dde6dc09e6..8ea33598a0a7 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -423,7 +423,7 @@ static bool dccp_invert_tuple(struct nf_conntrack_tuple *inv,
423} 423}
424 424
425static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, 425static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
426 unsigned int dataoff) 426 unsigned int dataoff, unsigned int *timeouts)
427{ 427{
428 struct net *net = nf_ct_net(ct); 428 struct net *net = nf_ct_net(ct);
429 struct dccp_net *dn; 429 struct dccp_net *dn;
@@ -472,12 +472,17 @@ static u64 dccp_ack_seq(const struct dccp_hdr *dh)
472 ntohl(dhack->dccph_ack_nr_low); 472 ntohl(dhack->dccph_ack_nr_low);
473} 473}
474 474
475static unsigned int *dccp_get_timeouts(struct net *net)
476{
477 return dccp_pernet(net)->dccp_timeout;
478}
479
475static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, 480static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
476 unsigned int dataoff, enum ip_conntrack_info ctinfo, 481 unsigned int dataoff, enum ip_conntrack_info ctinfo,
477 u_int8_t pf, unsigned int hooknum) 482 u_int8_t pf, unsigned int hooknum,
483 unsigned int *timeouts)
478{ 484{
479 struct net *net = nf_ct_net(ct); 485 struct net *net = nf_ct_net(ct);
480 struct dccp_net *dn;
481 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 486 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
482 struct dccp_hdr _dh, *dh; 487 struct dccp_hdr _dh, *dh;
483 u_int8_t type, old_state, new_state; 488 u_int8_t type, old_state, new_state;
@@ -559,8 +564,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
559 if (new_state != old_state) 564 if (new_state != old_state)
560 nf_conntrack_event_cache(IPCT_PROTOINFO, ct); 565 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
561 566
562 dn = dccp_pernet(net); 567 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
563 nf_ct_refresh_acct(ct, ctinfo, skb, dn->dccp_timeout[new_state]);
564 568
565 return NF_ACCEPT; 569 return NF_ACCEPT;
566} 570}
@@ -767,6 +771,7 @@ static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
767 .invert_tuple = dccp_invert_tuple, 771 .invert_tuple = dccp_invert_tuple,
768 .new = dccp_new, 772 .new = dccp_new,
769 .packet = dccp_packet, 773 .packet = dccp_packet,
774 .get_timeouts = dccp_get_timeouts,
770 .error = dccp_error, 775 .error = dccp_error,
771 .print_tuple = dccp_print_tuple, 776 .print_tuple = dccp_print_tuple,
772 .print_conntrack = dccp_print_conntrack, 777 .print_conntrack = dccp_print_conntrack,
@@ -789,6 +794,7 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
789 .invert_tuple = dccp_invert_tuple, 794 .invert_tuple = dccp_invert_tuple,
790 .new = dccp_new, 795 .new = dccp_new,
791 .packet = dccp_packet, 796 .packet = dccp_packet,
797 .get_timeouts = dccp_get_timeouts,
792 .error = dccp_error, 798 .error = dccp_error,
793 .print_tuple = dccp_print_tuple, 799 .print_tuple = dccp_print_tuple,
794 .print_conntrack = dccp_print_conntrack, 800 .print_conntrack = dccp_print_conntrack,
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index e2091d0c7a2f..0e6c5451db80 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -40,21 +40,27 @@ static int generic_print_tuple(struct seq_file *s,
40 return 0; 40 return 0;
41} 41}
42 42
43static unsigned int *generic_get_timeouts(struct net *net)
44{
45 return &nf_ct_generic_timeout;
46}
47
43/* Returns verdict for packet, or -1 for invalid. */ 48/* Returns verdict for packet, or -1 for invalid. */
44static int packet(struct nf_conn *ct, 49static int generic_packet(struct nf_conn *ct,
45 const struct sk_buff *skb, 50 const struct sk_buff *skb,
46 unsigned int dataoff, 51 unsigned int dataoff,
47 enum ip_conntrack_info ctinfo, 52 enum ip_conntrack_info ctinfo,
48 u_int8_t pf, 53 u_int8_t pf,
49 unsigned int hooknum) 54 unsigned int hooknum,
55 unsigned int *timeout)
50{ 56{
51 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_generic_timeout); 57 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
52 return NF_ACCEPT; 58 return NF_ACCEPT;
53} 59}
54 60
55/* Called when a new connection for this protocol found. */ 61/* Called when a new connection for this protocol found. */
56static bool new(struct nf_conn *ct, const struct sk_buff *skb, 62static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
57 unsigned int dataoff) 63 unsigned int dataoff, unsigned int *timeouts)
58{ 64{
59 return true; 65 return true;
60} 66}
@@ -93,8 +99,9 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
93 .pkt_to_tuple = generic_pkt_to_tuple, 99 .pkt_to_tuple = generic_pkt_to_tuple,
94 .invert_tuple = generic_invert_tuple, 100 .invert_tuple = generic_invert_tuple,
95 .print_tuple = generic_print_tuple, 101 .print_tuple = generic_print_tuple,
96 .packet = packet, 102 .packet = generic_packet,
97 .new = new, 103 .get_timeouts = generic_get_timeouts,
104 .new = generic_new,
98#ifdef CONFIG_SYSCTL 105#ifdef CONFIG_SYSCTL
99 .ctl_table_header = &generic_sysctl_header, 106 .ctl_table_header = &generic_sysctl_header,
100 .ctl_table = generic_sysctl_table, 107 .ctl_table = generic_sysctl_table,
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 8144f22d159a..1bf01c95658b 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -235,13 +235,19 @@ static int gre_print_conntrack(struct seq_file *s, struct nf_conn *ct)
235 (ct->proto.gre.stream_timeout / HZ)); 235 (ct->proto.gre.stream_timeout / HZ));
236} 236}
237 237
238static unsigned int *gre_get_timeouts(struct net *net)
239{
240 return gre_timeouts;
241}
242
238/* Returns verdict for packet, and may modify conntrack */ 243/* Returns verdict for packet, and may modify conntrack */
239static int gre_packet(struct nf_conn *ct, 244static int gre_packet(struct nf_conn *ct,
240 const struct sk_buff *skb, 245 const struct sk_buff *skb,
241 unsigned int dataoff, 246 unsigned int dataoff,
242 enum ip_conntrack_info ctinfo, 247 enum ip_conntrack_info ctinfo,
243 u_int8_t pf, 248 u_int8_t pf,
244 unsigned int hooknum) 249 unsigned int hooknum,
250 unsigned int *timeouts)
245{ 251{
246 /* If we've seen traffic both ways, this is a GRE connection. 252 /* If we've seen traffic both ways, this is a GRE connection.
247 * Extend timeout. */ 253 * Extend timeout. */
@@ -260,15 +266,15 @@ static int gre_packet(struct nf_conn *ct,
260 266
261/* Called when a new connection for this protocol found. */ 267/* Called when a new connection for this protocol found. */
262static bool gre_new(struct nf_conn *ct, const struct sk_buff *skb, 268static bool gre_new(struct nf_conn *ct, const struct sk_buff *skb,
263 unsigned int dataoff) 269 unsigned int dataoff, unsigned int *timeouts)
264{ 270{
265 pr_debug(": "); 271 pr_debug(": ");
266 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 272 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
267 273
268 /* initialize to sane value. Ideally a conntrack helper 274 /* initialize to sane value. Ideally a conntrack helper
269 * (e.g. in case of pptp) is increasing them */ 275 * (e.g. in case of pptp) is increasing them */
270 ct->proto.gre.stream_timeout = gre_timeouts[GRE_CT_REPLIED]; 276 ct->proto.gre.stream_timeout = timeouts[GRE_CT_REPLIED];
271 ct->proto.gre.timeout = gre_timeouts[GRE_CT_UNREPLIED]; 277 ct->proto.gre.timeout = timeouts[GRE_CT_UNREPLIED];
272 278
273 return true; 279 return true;
274} 280}
@@ -295,6 +301,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
295 .invert_tuple = gre_invert_tuple, 301 .invert_tuple = gre_invert_tuple,
296 .print_tuple = gre_print_tuple, 302 .print_tuple = gre_print_tuple,
297 .print_conntrack = gre_print_conntrack, 303 .print_conntrack = gre_print_conntrack,
304 .get_timeouts = gre_get_timeouts,
298 .packet = gre_packet, 305 .packet = gre_packet,
299 .new = gre_new, 306 .new = gre_new,
300 .destroy = gre_destroy, 307 .destroy = gre_destroy,
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index afa69136061a..2a0703371e24 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -279,13 +279,19 @@ static int sctp_new_state(enum ip_conntrack_dir dir,
279 return sctp_conntracks[dir][i][cur_state]; 279 return sctp_conntracks[dir][i][cur_state];
280} 280}
281 281
282static unsigned int *sctp_get_timeouts(struct net *net)
283{
284 return sctp_timeouts;
285}
286
282/* Returns verdict for packet, or -NF_ACCEPT for invalid. */ 287/* Returns verdict for packet, or -NF_ACCEPT for invalid. */
283static int sctp_packet(struct nf_conn *ct, 288static int sctp_packet(struct nf_conn *ct,
284 const struct sk_buff *skb, 289 const struct sk_buff *skb,
285 unsigned int dataoff, 290 unsigned int dataoff,
286 enum ip_conntrack_info ctinfo, 291 enum ip_conntrack_info ctinfo,
287 u_int8_t pf, 292 u_int8_t pf,
288 unsigned int hooknum) 293 unsigned int hooknum,
294 unsigned int *timeouts)
289{ 295{
290 enum sctp_conntrack new_state, old_state; 296 enum sctp_conntrack new_state, old_state;
291 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 297 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
@@ -370,7 +376,7 @@ static int sctp_packet(struct nf_conn *ct,
370 } 376 }
371 spin_unlock_bh(&ct->lock); 377 spin_unlock_bh(&ct->lock);
372 378
373 nf_ct_refresh_acct(ct, ctinfo, skb, sctp_timeouts[new_state]); 379 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
374 380
375 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED && 381 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
376 dir == IP_CT_DIR_REPLY && 382 dir == IP_CT_DIR_REPLY &&
@@ -390,7 +396,7 @@ out:
390 396
391/* Called when a new connection for this protocol found. */ 397/* Called when a new connection for this protocol found. */
392static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb, 398static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
393 unsigned int dataoff) 399 unsigned int dataoff, unsigned int *timeouts)
394{ 400{
395 enum sctp_conntrack new_state; 401 enum sctp_conntrack new_state;
396 const struct sctphdr *sh; 402 const struct sctphdr *sh;
@@ -664,6 +670,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
664 .print_tuple = sctp_print_tuple, 670 .print_tuple = sctp_print_tuple,
665 .print_conntrack = sctp_print_conntrack, 671 .print_conntrack = sctp_print_conntrack,
666 .packet = sctp_packet, 672 .packet = sctp_packet,
673 .get_timeouts = sctp_get_timeouts,
667 .new = sctp_new, 674 .new = sctp_new,
668 .me = THIS_MODULE, 675 .me = THIS_MODULE,
669#if IS_ENABLED(CONFIG_NF_CT_NETLINK) 676#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
@@ -694,6 +701,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
694 .print_tuple = sctp_print_tuple, 701 .print_tuple = sctp_print_tuple,
695 .print_conntrack = sctp_print_conntrack, 702 .print_conntrack = sctp_print_conntrack,
696 .packet = sctp_packet, 703 .packet = sctp_packet,
704 .get_timeouts = sctp_get_timeouts,
697 .new = sctp_new, 705 .new = sctp_new,
698 .me = THIS_MODULE, 706 .me = THIS_MODULE,
699#if IS_ENABLED(CONFIG_NF_CT_NETLINK) 707#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 57c778546094..8372bb43feb0 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -813,13 +813,19 @@ static int tcp_error(struct net *net, struct nf_conn *tmpl,
813 return NF_ACCEPT; 813 return NF_ACCEPT;
814} 814}
815 815
816static unsigned int *tcp_get_timeouts(struct net *net)
817{
818 return tcp_timeouts;
819}
820
816/* Returns verdict for packet, or -1 for invalid. */ 821/* Returns verdict for packet, or -1 for invalid. */
817static int tcp_packet(struct nf_conn *ct, 822static int tcp_packet(struct nf_conn *ct,
818 const struct sk_buff *skb, 823 const struct sk_buff *skb,
819 unsigned int dataoff, 824 unsigned int dataoff,
820 enum ip_conntrack_info ctinfo, 825 enum ip_conntrack_info ctinfo,
821 u_int8_t pf, 826 u_int8_t pf,
822 unsigned int hooknum) 827 unsigned int hooknum,
828 unsigned int *timeouts)
823{ 829{
824 struct net *net = nf_ct_net(ct); 830 struct net *net = nf_ct_net(ct);
825 struct nf_conntrack_tuple *tuple; 831 struct nf_conntrack_tuple *tuple;
@@ -1014,14 +1020,14 @@ static int tcp_packet(struct nf_conn *ct,
1014 ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; 1020 ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
1015 1021
1016 if (ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans && 1022 if (ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans &&
1017 tcp_timeouts[new_state] > tcp_timeouts[TCP_CONNTRACK_RETRANS]) 1023 timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
1018 timeout = tcp_timeouts[TCP_CONNTRACK_RETRANS]; 1024 timeout = timeouts[TCP_CONNTRACK_RETRANS];
1019 else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) & 1025 else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
1020 IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && 1026 IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
1021 tcp_timeouts[new_state] > tcp_timeouts[TCP_CONNTRACK_UNACK]) 1027 timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK])
1022 timeout = tcp_timeouts[TCP_CONNTRACK_UNACK]; 1028 timeout = timeouts[TCP_CONNTRACK_UNACK];
1023 else 1029 else
1024 timeout = tcp_timeouts[new_state]; 1030 timeout = timeouts[new_state];
1025 spin_unlock_bh(&ct->lock); 1031 spin_unlock_bh(&ct->lock);
1026 1032
1027 if (new_state != old_state) 1033 if (new_state != old_state)
@@ -1053,7 +1059,7 @@ static int tcp_packet(struct nf_conn *ct,
1053 1059
1054/* Called when a new connection for this protocol found. */ 1060/* Called when a new connection for this protocol found. */
1055static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb, 1061static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
1056 unsigned int dataoff) 1062 unsigned int dataoff, unsigned int *timeouts)
1057{ 1063{
1058 enum tcp_conntrack new_state; 1064 enum tcp_conntrack new_state;
1059 const struct tcphdr *th; 1065 const struct tcphdr *th;
@@ -1444,6 +1450,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
1444 .print_tuple = tcp_print_tuple, 1450 .print_tuple = tcp_print_tuple,
1445 .print_conntrack = tcp_print_conntrack, 1451 .print_conntrack = tcp_print_conntrack,
1446 .packet = tcp_packet, 1452 .packet = tcp_packet,
1453 .get_timeouts = tcp_get_timeouts,
1447 .new = tcp_new, 1454 .new = tcp_new,
1448 .error = tcp_error, 1455 .error = tcp_error,
1449#if IS_ENABLED(CONFIG_NF_CT_NETLINK) 1456#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
@@ -1476,6 +1483,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
1476 .print_tuple = tcp_print_tuple, 1483 .print_tuple = tcp_print_tuple,
1477 .print_conntrack = tcp_print_conntrack, 1484 .print_conntrack = tcp_print_conntrack,
1478 .packet = tcp_packet, 1485 .packet = tcp_packet,
1486 .get_timeouts = tcp_get_timeouts,
1479 .new = tcp_new, 1487 .new = tcp_new,
1480 .error = tcp_error, 1488 .error = tcp_error,
1481#if IS_ENABLED(CONFIG_NF_CT_NETLINK) 1489#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 5b24ff882f95..70e005992d5b 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -71,32 +71,38 @@ static int udp_print_tuple(struct seq_file *s,
71 ntohs(tuple->dst.u.udp.port)); 71 ntohs(tuple->dst.u.udp.port));
72} 72}
73 73
74static unsigned int *udp_get_timeouts(struct net *net)
75{
76 return udp_timeouts;
77}
78
74/* Returns verdict for packet, and may modify conntracktype */ 79/* Returns verdict for packet, and may modify conntracktype */
75static int udp_packet(struct nf_conn *ct, 80static int udp_packet(struct nf_conn *ct,
76 const struct sk_buff *skb, 81 const struct sk_buff *skb,
77 unsigned int dataoff, 82 unsigned int dataoff,
78 enum ip_conntrack_info ctinfo, 83 enum ip_conntrack_info ctinfo,
79 u_int8_t pf, 84 u_int8_t pf,
80 unsigned int hooknum) 85 unsigned int hooknum,
86 unsigned int *timeouts)
81{ 87{
82 /* If we've seen traffic both ways, this is some kind of UDP 88 /* If we've seen traffic both ways, this is some kind of UDP
83 stream. Extend timeout. */ 89 stream. Extend timeout. */
84 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 90 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
85 nf_ct_refresh_acct(ct, ctinfo, skb, 91 nf_ct_refresh_acct(ct, ctinfo, skb,
86 udp_timeouts[UDP_CT_REPLIED]); 92 timeouts[UDP_CT_REPLIED]);
87 /* Also, more likely to be important, and not a probe */ 93 /* Also, more likely to be important, and not a probe */
88 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) 94 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
89 nf_conntrack_event_cache(IPCT_ASSURED, ct); 95 nf_conntrack_event_cache(IPCT_ASSURED, ct);
90 } else { 96 } else {
91 nf_ct_refresh_acct(ct, ctinfo, skb, 97 nf_ct_refresh_acct(ct, ctinfo, skb,
92 udp_timeouts[UDP_CT_UNREPLIED]); 98 timeouts[UDP_CT_UNREPLIED]);
93 } 99 }
94 return NF_ACCEPT; 100 return NF_ACCEPT;
95} 101}
96 102
97/* Called when a new connection for this protocol found. */ 103/* Called when a new connection for this protocol found. */
98static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb, 104static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb,
99 unsigned int dataoff) 105 unsigned int dataoff, unsigned int *timeouts)
100{ 106{
101 return true; 107 return true;
102} 108}
@@ -196,6 +202,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
196 .invert_tuple = udp_invert_tuple, 202 .invert_tuple = udp_invert_tuple,
197 .print_tuple = udp_print_tuple, 203 .print_tuple = udp_print_tuple,
198 .packet = udp_packet, 204 .packet = udp_packet,
205 .get_timeouts = udp_get_timeouts,
199 .new = udp_new, 206 .new = udp_new,
200 .error = udp_error, 207 .error = udp_error,
201#if IS_ENABLED(CONFIG_NF_CT_NETLINK) 208#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
@@ -224,6 +231,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
224 .invert_tuple = udp_invert_tuple, 231 .invert_tuple = udp_invert_tuple,
225 .print_tuple = udp_print_tuple, 232 .print_tuple = udp_print_tuple,
226 .packet = udp_packet, 233 .packet = udp_packet,
234 .get_timeouts = udp_get_timeouts,
227 .new = udp_new, 235 .new = udp_new,
228 .error = udp_error, 236 .error = udp_error,
229#if IS_ENABLED(CONFIG_NF_CT_NETLINK) 237#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index e73071743e01..0b32ccb1d515 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -68,32 +68,38 @@ static int udplite_print_tuple(struct seq_file *s,
68 ntohs(tuple->dst.u.udp.port)); 68 ntohs(tuple->dst.u.udp.port));
69} 69}
70 70
71static unsigned int *udplite_get_timeouts(struct net *net)
72{
73 return udplite_timeouts;
74}
75
71/* Returns verdict for packet, and may modify conntracktype */ 76/* Returns verdict for packet, and may modify conntracktype */
72static int udplite_packet(struct nf_conn *ct, 77static int udplite_packet(struct nf_conn *ct,
73 const struct sk_buff *skb, 78 const struct sk_buff *skb,
74 unsigned int dataoff, 79 unsigned int dataoff,
75 enum ip_conntrack_info ctinfo, 80 enum ip_conntrack_info ctinfo,
76 u_int8_t pf, 81 u_int8_t pf,
77 unsigned int hooknum) 82 unsigned int hooknum,
83 unsigned int *timeouts)
78{ 84{
79 /* If we've seen traffic both ways, this is some kind of UDP 85 /* If we've seen traffic both ways, this is some kind of UDP
80 stream. Extend timeout. */ 86 stream. Extend timeout. */
81 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 87 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
82 nf_ct_refresh_acct(ct, ctinfo, skb, 88 nf_ct_refresh_acct(ct, ctinfo, skb,
83 udplite_timeouts[UDPLITE_CT_REPLIED]); 89 timeouts[UDPLITE_CT_REPLIED]);
84 /* Also, more likely to be important, and not a probe */ 90 /* Also, more likely to be important, and not a probe */
85 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) 91 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
86 nf_conntrack_event_cache(IPCT_ASSURED, ct); 92 nf_conntrack_event_cache(IPCT_ASSURED, ct);
87 } else { 93 } else {
88 nf_ct_refresh_acct(ct, ctinfo, skb, 94 nf_ct_refresh_acct(ct, ctinfo, skb,
89 udplite_timeouts[UDPLITE_CT_UNREPLIED]); 95 timeouts[UDPLITE_CT_UNREPLIED]);
90 } 96 }
91 return NF_ACCEPT; 97 return NF_ACCEPT;
92} 98}
93 99
94/* Called when a new connection for this protocol found. */ 100/* Called when a new connection for this protocol found. */
95static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb, 101static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
96 unsigned int dataoff) 102 unsigned int dataoff, unsigned int *timeouts)
97{ 103{
98 return true; 104 return true;
99} 105}
@@ -181,6 +187,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
181 .invert_tuple = udplite_invert_tuple, 187 .invert_tuple = udplite_invert_tuple,
182 .print_tuple = udplite_print_tuple, 188 .print_tuple = udplite_print_tuple,
183 .packet = udplite_packet, 189 .packet = udplite_packet,
190 .get_timeouts = udplite_get_timeouts,
184 .new = udplite_new, 191 .new = udplite_new,
185 .error = udplite_error, 192 .error = udplite_error,
186#if IS_ENABLED(CONFIG_NF_CT_NETLINK) 193#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
@@ -205,6 +212,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
205 .invert_tuple = udplite_invert_tuple, 212 .invert_tuple = udplite_invert_tuple,
206 .print_tuple = udplite_print_tuple, 213 .print_tuple = udplite_print_tuple,
207 .packet = udplite_packet, 214 .packet = udplite_packet,
215 .get_timeouts = udplite_get_timeouts,
208 .new = udplite_new, 216 .new = udplite_new,
209 .error = udplite_error, 217 .error = udplite_error,
210#if IS_ENABLED(CONFIG_NF_CT_NETLINK) 218#if IS_ENABLED(CONFIG_NF_CT_NETLINK)