diff mbox series

[nf] netfilter: conntrack: connection timeout after re-register

Message ID 20201006003430.DFDEE95C02DC@us180.sjc.aristanetworks.com
State Changes Requested
Delegated to: Pablo Neira
Headers show
Series [nf] netfilter: conntrack: connection timeout after re-register | expand

Commit Message

Francesco Ruggeri Oct. 6, 2020, 12:34 a.m. UTC
I am sending out this patch mainly to clarify the source of a problem
I am seeing.
An idle tcp connection is timing out on a 4.19 kernel after
conntrack unregister/re-register. By playing with SO_KEEPALIVE
setsockopts on the client I can make it timeout in a few seconds.
I could not find any relevant commits in code after 4.19.
The problem seems to come from commit f94e63801ab2 ("netfilter:
conntrack: reset tcp maxwin on re-register").
Clearing maxwin of existing tcp connections on register, causes
tcp_in_window to set td_end to 1 less than it should if the first
packet it sees after the re-register is an outgoing keepalive packet,
causing it to later return false when getting packets from the peer
ack-ing the correct octet.
My iptables configuration on the client is:

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p icmp -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 4445 -j ACCEPT
COMMIT

I unregister conntrack by using:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

and then I restore the original one.
I do not see the issue with this patch, but I am not sure it is the
correct

Thanks,
Francesco Ruggeri

Fixes: f94e63801ab2 ("netfilter: conntrack: reset tcp maxwin on re-register")
Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
---
 net/netfilter/nf_conntrack_proto_tcp.c | 6 ++++++
 1 file changed, 6 insertions(+)
diff mbox series

Patch

diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index e8c86ee4c1c4..1ae1b7c78393 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -538,6 +538,12 @@  static bool tcp_in_window(const struct nf_conn *ct,
 			 * Let's try to use the data from the packet.
 			 */
 			sender->td_end = end;
+			if (seq == end) {
+				/* This could be a keepalive packet with
+				 * SEG.SEQ = SND.NXT-1.
+				 */
+				sender->td_end++;
+			}
 			swin = win << sender->td_scale;
 			sender->td_maxwin = (swin == 0 ? 1 : swin);
 			sender->td_maxend = end + sender->td_maxwin;