diff options
Diffstat (limited to 'net/mptcp/protocol.c')
| -rw-r--r-- | net/mptcp/protocol.c | 52 | 
1 files changed, 34 insertions, 18 deletions
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 6a817a13b154..9a287b75c1b3 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -11,6 +11,7 @@  #include <linux/netdevice.h>  #include <linux/sched/signal.h>  #include <linux/atomic.h> +#include <net/aligned_data.h>  #include <net/sock.h>  #include <net/inet_common.h>  #include <net/inet_hashtables.h> @@ -67,6 +68,26 @@ static const struct proto_ops *mptcp_fallback_tcp_ops(const struct sock *sk)  	return &inet_stream_ops;  } +bool __mptcp_try_fallback(struct mptcp_sock *msk, int fb_mib) +{ +	struct net *net = sock_net((struct sock *)msk); + +	if (__mptcp_check_fallback(msk)) +		return true; + +	spin_lock_bh(&msk->fallback_lock); +	if (!msk->allow_infinite_fallback) { +		spin_unlock_bh(&msk->fallback_lock); +		return false; +	} + +	msk->allow_subflows = false; +	set_bit(MPTCP_FALLBACK_DONE, &msk->flags); +	__MPTCP_INC_STATS(net, fb_mib); +	spin_unlock_bh(&msk->fallback_lock); +	return true; +} +  static int __mptcp_socket_create(struct mptcp_sock *msk)  {  	struct mptcp_subflow_context *subflow; @@ -560,10 +581,7 @@ static bool mptcp_check_data_fin(struct sock *sk)  static void mptcp_dss_corruption(struct mptcp_sock *msk, struct sock *ssk)  { -	if (mptcp_try_fallback(ssk)) { -		MPTCP_INC_STATS(sock_net(ssk), -				MPTCP_MIB_DSSCORRUPTIONFALLBACK); -	} else { +	if (!mptcp_try_fallback(ssk, MPTCP_MIB_DSSCORRUPTIONFALLBACK)) {  		MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCORRUPTIONRESET);  		mptcp_subflow_reset(ssk);  	} @@ -1142,14 +1160,13 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk,  	mpext->infinite_map = 1;  	mpext->data_len = 0; -	if (!mptcp_try_fallback(ssk)) { +	if (!mptcp_try_fallback(ssk, MPTCP_MIB_INFINITEMAPTX)) { +		MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_FALLBACKFAILED);  		mptcp_subflow_reset(ssk);  		return;  	} -	MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPTX);  	mptcp_subflow_ctx(ssk)->send_infinite_map = 0; -	pr_fallback(msk);  }  #define MPTCP_MAX_GSO_SIZE (GSO_LEGACY_MAX_SIZE - (MAX_TCP_HEADER + 1)) @@ -1386,7 +1403,7 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk)  	 * - estimate the faster flow linger time  	 * - use the above to estimate the amount of byte transferred  	 *   by the faster flow -	 * - check that the amount of queued data is greter than the above, +	 * - check that the amount of queued data is greater than the above,  	 *   otherwise do not use the picked, slower, subflow  	 * We select the subflow with the shorter estimated time to flush  	 * the queued mem, which basically ensure the above. We just need @@ -3537,7 +3554,7 @@ void mptcp_sock_graft(struct sock *sk, struct socket *parent)  	write_lock_bh(&sk->sk_callback_lock);  	rcu_assign_pointer(sk->sk_wq, &parent->wq);  	sk_set_socket(sk, parent); -	sk->sk_uid = SOCK_INODE(parent)->i_uid; +	WRITE_ONCE(sk->sk_uid, SOCK_INODE(parent)->i_uid);  	write_unlock_bh(&sk->sk_callback_lock);  } @@ -3688,16 +3705,15 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)  	 * TCP option space.  	 */  	if (rcu_access_pointer(tcp_sk(ssk)->md5sig_info)) -		mptcp_subflow_early_fallback(msk, subflow); +		mptcp_early_fallback(msk, subflow, MPTCP_MIB_MD5SIGFALLBACK);  #endif  	if (subflow->request_mptcp) { -		if (mptcp_active_should_disable(sk)) { -			MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_MPCAPABLEACTIVEDISABLED); -			mptcp_subflow_early_fallback(msk, subflow); -		} else if (mptcp_token_new_connect(ssk) < 0) { -			MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_TOKENFALLBACKINIT); -			mptcp_subflow_early_fallback(msk, subflow); -		} +		if (mptcp_active_should_disable(sk)) +			mptcp_early_fallback(msk, subflow, +					     MPTCP_MIB_MPCAPABLEACTIVEDISABLED); +		else if (mptcp_token_new_connect(ssk) < 0) +			mptcp_early_fallback(msk, subflow, +					     MPTCP_MIB_TOKENFALLBACKINIT);  	}  	WRITE_ONCE(msk->write_seq, subflow->idsn); @@ -3769,7 +3785,7 @@ static struct proto mptcp_prot = {  	.stream_memory_free	= mptcp_stream_memory_free,  	.sockets_allocated	= &mptcp_sockets_allocated, -	.memory_allocated	= &tcp_memory_allocated, +	.memory_allocated	= &net_aligned_data.tcp_memory_allocated,  	.per_cpu_fw_alloc	= &tcp_memory_per_cpu_fw_alloc,  	.memory_pressure	= &tcp_memory_pressure,  | 
