Message ID | 53039B48.6060407@canonical.com |
---|---|
State | New |
Headers | show |
On 02/18/2014 09:41 AM, Chris J Arges wrote: > From de89d4f0143294944d88108dfa8b96a4dcd6d08f Mon Sep 17 00:00:00 2001 > From: Florian Westphal <fw@strlen.de> > Date: Fri, 7 Feb 2014 15:51:20 -0600 > Subject: [PATCH] netfilter: nf_conntrack: avoid large timeout for mid-stream > pickup > > When loose tracking is enabled (default), non-syn packets cause > creation of new conntracks in established state with default timeout for > established state (5 days). This causes the table to fill up with UNREPLIED > when the 'new ack' packet happened to be the last-ack of a previous, > already timed-out connection. > > Consider: > > A 192.168.x.52792 > 10.184.y.80: F, 426:426(0) ack 9237 win 255 > B 10.184.y.80 > 192.168.x.52792: ., ack 427 win 123 > <61 second pause> > C 10.184.y.80 > 192.168.x.52792: F, 9237:9237(0) ack 427 win 123 > D 192.168.x.52792 > 10.184.y.80: ., ack 9238 win 255 > > B moves conntrack to CLOSE_WAIT and will kill it after 60 second timeout, > C is ignored (FIN set), but last packet (D) causes new ct with 5-days > timeout. > > Use UNACK timeout (5 minutes) instead to get rid of these entries sooner > when in ESTABLISHED state without having seen traffic in both directions. > > Signed-off-by: Florian Westphal <fw@strlen.de> > Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> > > (cherry picked from commit 6547a221871f139cc56328a38105d47c14874cbe) > BugLink: http://bugs.launchpad.net/bugs/1270237 > Signed-off-by: Chris J Arges <chris.j.arges@canonical.com> > --- > net/netfilter/nf_conntrack_proto_tcp.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/net/netfilter/nf_conntrack_proto_tcp.c > b/net/netfilter/nf_conntrack_proto_tcp.c > index 57ad466..7bf48eb 100644 > --- a/net/netfilter/nf_conntrack_proto_tcp.c > +++ b/net/netfilter/nf_conntrack_proto_tcp.c > @@ -1028,6 +1028,12 @@ static int tcp_packet(struct nf_conn *ct, > nf_ct_kill_acct(ct, ctinfo, skb); > return NF_ACCEPT; > } > + /* ESTABLISHED without SEEN_REPLY, i.e. mid-connection > + * pickup with loose=1. Avoid large ESTABLISHED timeout. > + */ > + if (new_state == TCP_CONNTRACK_ESTABLISHED && > + timeout > nf_ct_tcp_timeout_unacknowledged) > + timeout = nf_ct_tcp_timeout_unacknowledged; > } else if (!test_bit(IPS_ASSURED_BIT, &ct->status) > && (old_state == TCP_CONNTRACK_SYN_RECV > || old_state == TCP_CONNTRACK_ESTABLISHED) >
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 57ad466..7bf48eb 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1028,6 +1028,12 @@ static int tcp_packet(struct nf_conn *ct, nf_ct_kill_acct(ct, ctinfo, skb); return NF_ACCEPT; } + /* ESTABLISHED without SEEN_REPLY, i.e. mid-connection + * pickup with loose=1. Avoid large ESTABLISHED timeout. + */ + if (new_state == TCP_CONNTRACK_ESTABLISHED && + timeout > nf_ct_tcp_timeout_unacknowledged) + timeout = nf_ct_tcp_timeout_unacknowledged; } else if (!test_bit(IPS_ASSURED_BIT, &ct->status) && (old_state == TCP_CONNTRACK_SYN_RECV || old_state == TCP_CONNTRACK_ESTABLISHED)