diff mbox

[Precise,SRU] Fix for LP#1270237 v2

Message ID 53039B48.6060407@canonical.com
State New
Headers show

Commit Message

Chris J Arges Feb. 18, 2014, 5:41 p.m. UTC
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(+)

Comments

Brad Figg Feb. 18, 2014, 7:59 p.m. UTC | #1
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 mbox

Patch

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)