Re: [PATCH] Avoid potentially erroneos RST drop.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 05.05.2021 21:53, Florian Westphal wrote:
> Ali, sorry for coming back to this again and again.
> 
> What do you think of this change?

Hi Florian, I tested your patch and it solved the issue, no more NFS
hangs due to dropped RSTs. Please include it, together with the
following two patches I previously sent:

https://patchwork.ozlabs.org/project/netfilter-devel/patch/20210428130911.cteglt52r5if7ynp@Fryzen495/
https://patchwork.ozlabs.org/project/netfilter-devel/patch/20210430093601.zibczc4cjnwx3qwn@Fryzen495/

Thanks a lot!

> Its an incremental change on top of your patch.
> 
> The only real change is that this will skip window check if
> conntrack thinks connection is closing already.
> 
> In addition, tcp window check is skipped in that case.
> 
> This is supposed to expedite conntrack eviction in case of tuple reuse
> by some nat/pat middlebox, or a peer that has lower timeouts than
> conntrack before a port is re-used.
> 
> diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
> --- a/net/netfilter/nf_conntrack_proto_tcp.c
> +++ b/net/netfilter/nf_conntrack_proto_tcp.c
> @@ -834,6 +834,22 @@ static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
>  	return true;
>  }
>  
> +static bool tcp_can_early_drop(const struct nf_conn *ct)
> +{
> +	switch (ct->proto.tcp.state) {
> +	case TCP_CONNTRACK_FIN_WAIT:
> +	case TCP_CONNTRACK_LAST_ACK:
> +	case TCP_CONNTRACK_TIME_WAIT:
> +	case TCP_CONNTRACK_CLOSE:
> +	case TCP_CONNTRACK_CLOSE_WAIT:
> +		return true;
> +	default:
> +		break;
> +	}
> +
> +	return false;
> +}
> +
>  /* Returns verdict for packet, or -1 for invalid. */
>  int nf_conntrack_tcp_packet(struct nf_conn *ct,
>  			    struct sk_buff *skb,
> @@ -1053,8 +1069,16 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
>  			/* If we are not in established state, and an RST is
>  			 * observed with SEQ=0, this is most likely an answer
>  			 * to a SYN we had let go through above.
> +			 *
> +			 * Also expedite conntrack destruction: If we were already
> +			 * closing, peer or NAT/PAT might already have reused tuple.
>  			 */
> -			if (seq == 0 && !nf_conntrack_tcp_established(ct))
> +			if (!nf_conntrack_tcp_established(ct)) {
> +				if (seq == 0 || tcp_can_early_drop(ct))
> +					goto in_window;
> +			}
> +
> +			if (seq == ct->proto.tcp.seen[!dir].td_maxack)
>  				break;
>  
>  			if (before(seq, ct->proto.tcp.seen[!dir].td_maxack)) {
> @@ -1066,10 +1090,6 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
>  				return -NF_ACCEPT;
>  			}
>  
> -			if (!nf_conntrack_tcp_established(ct) ||
> -			    seq == ct->proto.tcp.seen[!dir].td_maxack)
> -				break;
> -
>  			/* Check if rst is part of train, such as
>  			 *   foo:80 > bar:4379: P, 235946583:235946602(19) ack 42
>  			 *   foo:80 > bar:4379: R, 235946602:235946602(0)  ack 42
> @@ -1181,22 +1201,6 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
>  	return NF_ACCEPT;
>  }
>  
> -static bool tcp_can_early_drop(const struct nf_conn *ct)
> -{
> -	switch (ct->proto.tcp.state) {
> -	case TCP_CONNTRACK_FIN_WAIT:
> -	case TCP_CONNTRACK_LAST_ACK:
> -	case TCP_CONNTRACK_TIME_WAIT:
> -	case TCP_CONNTRACK_CLOSE:
> -	case TCP_CONNTRACK_CLOSE_WAIT:
> -		return true;
> -	default:
> -		break;
> -	}
> -
> -	return false;
> -}
> -
>  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
>  
>  #include <linux/netfilter/nfnetlink.h>
> 

-- 
Ali Abdallah | SUSE Linux L3 Engineer
GPG fingerprint: 51A0 F4A0 C8CF C98F 842E  A9A8 B945 56F8 1C85 D0D5




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux