aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kasprzak <kas@fi.muni.cz>2009-06-08 09:53:43 -0400
committerPatrick McHardy <kaber@trash.net>2009-06-08 09:53:43 -0400
commitf87fb666bb00a7afcbd7992d236e42ac544996f9 (patch)
tree0ec53ee8c373e6b4224b2fda40ed4fc49c1ed822
parent17f2f52be0edb6d1ff5a3675f2bc545aea2dbf76 (diff)
netfilter: nf_ct_icmp: keep the ICMP ct entries longer
Current conntrack code kills the ICMP conntrack entry as soon as the first reply is received. This is incorrect, as we then see only the first ICMP echo reply out of several possible duplicates as ESTABLISHED, while the rest will be INVALID. Also this unnecessarily increases the conntrackd traffic on H-A firewalls. Make all the ICMP conntrack entries (including the replied ones) last for the default of nf_conntrack_icmp{,v6}_timeout seconds. Signed-off-by: Jan "Yenya" Kasprzak <kas@fi.muni.cz> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_icmp.h11
-rw-r--r--include/net/netfilter/ipv6/nf_conntrack_icmpv6.h7
-rw-r--r--include/net/netfilter/nf_conntrack.h3
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c16
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c16
5 files changed, 8 insertions, 45 deletions
diff --git a/include/net/netfilter/ipv4/nf_conntrack_icmp.h b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
deleted file mode 100644
index 3dd22cff23ec..000000000000
--- a/include/net/netfilter/ipv4/nf_conntrack_icmp.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifndef _NF_CONNTRACK_ICMP_H
2#define _NF_CONNTRACK_ICMP_H
3/* ICMP tracking. */
4#include <asm/atomic.h>
5
6struct ip_ct_icmp
7{
8 /* Optimization: when number in == number out, forget immediately. */
9 atomic_t count;
10};
11#endif /* _NF_CONNTRACK_ICMP_H */
diff --git a/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
index 86591afda29c..67edd50a398a 100644
--- a/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
+++ b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
@@ -9,7 +9,6 @@
9 9
10#ifndef _NF_CONNTRACK_ICMPV6_H 10#ifndef _NF_CONNTRACK_ICMPV6_H
11#define _NF_CONNTRACK_ICMPV6_H 11#define _NF_CONNTRACK_ICMPV6_H
12#include <asm/atomic.h>
13 12
14#ifndef ICMPV6_NI_QUERY 13#ifndef ICMPV6_NI_QUERY
15#define ICMPV6_NI_QUERY 139 14#define ICMPV6_NI_QUERY 139
@@ -18,10 +17,4 @@
18#define ICMPV6_NI_REPLY 140 17#define ICMPV6_NI_REPLY 140
19#endif 18#endif
20 19
21struct nf_ct_icmpv6
22{
23 /* Optimization: when number in == number out, forget immediately. */
24 atomic_t count;
25};
26
27#endif /* _NF_CONNTRACK_ICMPV6_H */ 20#endif /* _NF_CONNTRACK_ICMPV6_H */
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 2ba36dd33aeb..2b877374242d 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -23,7 +23,6 @@
23#include <linux/netfilter/nf_conntrack_dccp.h> 23#include <linux/netfilter/nf_conntrack_dccp.h>
24#include <linux/netfilter/nf_conntrack_sctp.h> 24#include <linux/netfilter/nf_conntrack_sctp.h>
25#include <linux/netfilter/nf_conntrack_proto_gre.h> 25#include <linux/netfilter/nf_conntrack_proto_gre.h>
26#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
27#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> 26#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
28 27
29#include <net/netfilter/nf_conntrack_tuple.h> 28#include <net/netfilter/nf_conntrack_tuple.h>
@@ -34,8 +33,6 @@ union nf_conntrack_proto {
34 struct nf_ct_dccp dccp; 33 struct nf_ct_dccp dccp;
35 struct ip_ct_sctp sctp; 34 struct ip_ct_sctp sctp;
36 struct ip_ct_tcp tcp; 35 struct ip_ct_tcp tcp;
37 struct ip_ct_icmp icmp;
38 struct nf_ct_icmpv6 icmpv6;
39 struct nf_ct_gre gre; 36 struct nf_ct_gre gre;
40}; 37};
41 38
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index c6ab3d99e792..d71ba7677344 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -82,17 +82,10 @@ static int icmp_packet(struct nf_conn *ct,
82 u_int8_t pf, 82 u_int8_t pf,
83 unsigned int hooknum) 83 unsigned int hooknum)
84{ 84{
85 /* Try to delete connection immediately after all replies: 85 /* Do not immediately delete the connection after the first
86 won't actually vanish as we still have skb, and del_timer 86 successful reply to avoid excessive conntrackd traffic
87 means this will only run once even if count hits zero twice 87 and also to handle correctly ICMP echo reply duplicates. */
88 (theoretically possible with SMP) */ 88 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
89 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
90 if (atomic_dec_and_test(&ct->proto.icmp.count))
91 nf_ct_kill_acct(ct, ctinfo, skb);
92 } else {
93 atomic_inc(&ct->proto.icmp.count);
94 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
95 }
96 89
97 return NF_ACCEPT; 90 return NF_ACCEPT;
98} 91}
@@ -116,7 +109,6 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
116 nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple); 109 nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple);
117 return false; 110 return false;
118 } 111 }
119 atomic_set(&ct->proto.icmp.count, 0);
120 return true; 112 return true;
121} 113}
122 114
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index a0acd9655fef..642dcb127bab 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -95,17 +95,10 @@ static int icmpv6_packet(struct nf_conn *ct,
95 u_int8_t pf, 95 u_int8_t pf,
96 unsigned int hooknum) 96 unsigned int hooknum)
97{ 97{
98 /* Try to delete connection immediately after all replies: 98 /* Do not immediately delete the connection after the first
99 won't actually vanish as we still have skb, and del_timer 99 successful reply to avoid excessive conntrackd traffic
100 means this will only run once even if count hits zero twice 100 and also to handle correctly ICMP echo reply duplicates. */
101 (theoretically possible with SMP) */ 101 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
102 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
103 if (atomic_dec_and_test(&ct->proto.icmp.count))
104 nf_ct_kill_acct(ct, ctinfo, skb);
105 } else {
106 atomic_inc(&ct->proto.icmp.count);
107 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
108 }
109 102
110 return NF_ACCEPT; 103 return NF_ACCEPT;
111} 104}
@@ -131,7 +124,6 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
131 type + 128); 124 type + 128);
132 return false; 125 return false;
133 } 126 }
134 atomic_set(&ct->proto.icmp.count, 0);
135 return true; 127 return true;
136} 128}
137 129