When tcp_options is called all flags are cleared. When the IP_CT_TCP_FLAG_BE_LIBERAL is set it should be preserved otherwise such connections will fail in the window check. Signed-off-by: Sven Auhagen <sven.auhagen@xxxxxxxxxxxx> Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- Supersedes: https://patchwork.ozlabs.org/project/netfilter-devel/patch/20220318144939.69465-1-pablo@xxxxxxxxxxxxx/ which is not correct, it breaks TCP FIN handling. net/netfilter/nf_conntrack_proto_tcp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index d1582b888c0d..d8599ab5f767 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -342,7 +342,7 @@ static void tcp_options(const struct sk_buff *skb, return; state->td_scale = - state->flags = 0; + state->flags &= IP_CT_TCP_FLAG_BE_LIBERAL; while (length > 0) { int opcode=*ptr++; @@ -873,7 +873,7 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, struct nf_tcp_net *tn = nf_tcp_pernet(net); struct nf_conntrack_tuple *tuple; enum tcp_conntrack new_state, old_state; - unsigned int index, *timeouts; + unsigned int index, flags, *timeouts; enum ip_conntrack_dir dir; const struct tcphdr *th; struct tcphdr _tcph; @@ -968,8 +968,10 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK; ct->proto.tcp.seen[ct->proto.tcp.last_dir].flags = ct->proto.tcp.last_flags; + flags = ct->proto.tcp.seen[dir].flags; memset(&ct->proto.tcp.seen[dir], 0, sizeof(struct ip_ct_tcp_state)); + ct->proto.tcp.seen[dir].flags = flags & IP_CT_TCP_FLAG_BE_LIBERAL; break; } ct->proto.tcp.last_index = index; -- 2.30.2