Commit f87fb666 authored by Jan Kasprzak's avatar Jan Kasprzak Committed by Patrick McHardy

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: default avatarJan "Yenya" Kasprzak <kas@fi.muni.cz>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 17f2f52b
#ifndef _NF_CONNTRACK_ICMP_H
#define _NF_CONNTRACK_ICMP_H
/* ICMP tracking. */
#include <asm/atomic.h>
struct ip_ct_icmp
{
/* Optimization: when number in == number out, forget immediately. */
atomic_t count;
};
#endif /* _NF_CONNTRACK_ICMP_H */
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#ifndef _NF_CONNTRACK_ICMPV6_H #ifndef _NF_CONNTRACK_ICMPV6_H
#define _NF_CONNTRACK_ICMPV6_H #define _NF_CONNTRACK_ICMPV6_H
#include <asm/atomic.h>
#ifndef ICMPV6_NI_QUERY #ifndef ICMPV6_NI_QUERY
#define ICMPV6_NI_QUERY 139 #define ICMPV6_NI_QUERY 139
...@@ -18,10 +17,4 @@ ...@@ -18,10 +17,4 @@
#define ICMPV6_NI_REPLY 140 #define ICMPV6_NI_REPLY 140
#endif #endif
struct nf_ct_icmpv6
{
/* Optimization: when number in == number out, forget immediately. */
atomic_t count;
};
#endif /* _NF_CONNTRACK_ICMPV6_H */ #endif /* _NF_CONNTRACK_ICMPV6_H */
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/netfilter/nf_conntrack_dccp.h> #include <linux/netfilter/nf_conntrack_dccp.h>
#include <linux/netfilter/nf_conntrack_sctp.h> #include <linux/netfilter/nf_conntrack_sctp.h>
#include <linux/netfilter/nf_conntrack_proto_gre.h> #include <linux/netfilter/nf_conntrack_proto_gre.h>
#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
#include <net/netfilter/nf_conntrack_tuple.h> #include <net/netfilter/nf_conntrack_tuple.h>
...@@ -34,8 +33,6 @@ union nf_conntrack_proto { ...@@ -34,8 +33,6 @@ union nf_conntrack_proto {
struct nf_ct_dccp dccp; struct nf_ct_dccp dccp;
struct ip_ct_sctp sctp; struct ip_ct_sctp sctp;
struct ip_ct_tcp tcp; struct ip_ct_tcp tcp;
struct ip_ct_icmp icmp;
struct nf_ct_icmpv6 icmpv6;
struct nf_ct_gre gre; struct nf_ct_gre gre;
}; };
......
...@@ -82,17 +82,10 @@ static int icmp_packet(struct nf_conn *ct, ...@@ -82,17 +82,10 @@ static int icmp_packet(struct nf_conn *ct,
u_int8_t pf, u_int8_t pf,
unsigned int hooknum) unsigned int hooknum)
{ {
/* Try to delete connection immediately after all replies: /* Do not immediately delete the connection after the first
won't actually vanish as we still have skb, and del_timer successful reply to avoid excessive conntrackd traffic
means this will only run once even if count hits zero twice and also to handle correctly ICMP echo reply duplicates. */
(theoretically possible with SMP) */
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
if (atomic_dec_and_test(&ct->proto.icmp.count))
nf_ct_kill_acct(ct, ctinfo, skb);
} else {
atomic_inc(&ct->proto.icmp.count);
nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
}
return NF_ACCEPT; return NF_ACCEPT;
} }
...@@ -116,7 +109,6 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb, ...@@ -116,7 +109,6 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple); nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple);
return false; return false;
} }
atomic_set(&ct->proto.icmp.count, 0);
return true; return true;
} }
......
...@@ -95,17 +95,10 @@ static int icmpv6_packet(struct nf_conn *ct, ...@@ -95,17 +95,10 @@ static int icmpv6_packet(struct nf_conn *ct,
u_int8_t pf, u_int8_t pf,
unsigned int hooknum) unsigned int hooknum)
{ {
/* Try to delete connection immediately after all replies: /* Do not immediately delete the connection after the first
won't actually vanish as we still have skb, and del_timer successful reply to avoid excessive conntrackd traffic
means this will only run once even if count hits zero twice and also to handle correctly ICMP echo reply duplicates. */
(theoretically possible with SMP) */
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
if (atomic_dec_and_test(&ct->proto.icmp.count))
nf_ct_kill_acct(ct, ctinfo, skb);
} else {
atomic_inc(&ct->proto.icmp.count);
nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout); nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
}
return NF_ACCEPT; return NF_ACCEPT;
} }
...@@ -131,7 +124,6 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, ...@@ -131,7 +124,6 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
type + 128); type + 128);
return false; return false;
} }
atomic_set(&ct->proto.icmp.count, 0);
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment