Commit d8ea07c7 authored by D. Wythe's avatar D. Wythe Committed by sanglipeng
Browse files

net/smc: fix fallback failed while sendmsg with fastopen

stable inclusion
from stable-v5.10.175
commit e1b8342a85289d0d3411744c4fc1e0fc46fc9d5c
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8711T

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e1b8342a85289d0d3411744c4fc1e0fc46fc9d5c



--------------------------------

[ Upstream commit ce7ca794 ]

Before determining whether the msg has unsupported options, it has been
prematurely terminated by the wrong status check.

For the application, the general usages of MSG_FASTOPEN likes

fd = socket(...)
/* rather than connect */
sendto(fd, data, len, MSG_FASTOPEN)

Hence, We need to check the flag before state check, because the sock
state here is always SMC_INIT when applications tries MSG_FASTOPEN.
Once we found unsupported options, fallback it to TCP.

Fixes: ee9dfbef ("net/smc: handle sockopts forcing fallback")
Signed-off-by: default avatarD. Wythe <alibuda@linux.alibaba.com>
Signed-off-by: default avatarSimon Horman <simon.horman@corigine.com>

v2 -> v1: Optimize code style
Reviewed-by: default avatarTony Lu <tonylu@linux.alibaba.com>

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarsanglipeng <sanglipeng1@jd.com>
parent 339d423a
Loading
Loading
Loading
Loading
+8 −5
Original line number Original line Diff line number Diff line
@@ -1988,16 +1988,14 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
{
{
	struct sock *sk = sock->sk;
	struct sock *sk = sock->sk;
	struct smc_sock *smc;
	struct smc_sock *smc;
	int rc = -EPIPE;
	int rc;


	smc = smc_sk(sk);
	smc = smc_sk(sk);
	lock_sock(sk);
	lock_sock(sk);
	if ((sk->sk_state != SMC_ACTIVE) &&
	    (sk->sk_state != SMC_APPCLOSEWAIT1) &&
	    (sk->sk_state != SMC_INIT))
		goto out;


	/* SMC does not support connect with fastopen */
	if (msg->msg_flags & MSG_FASTOPEN) {
	if (msg->msg_flags & MSG_FASTOPEN) {
		/* not connected yet, fallback */
		if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) {
		if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) {
			smc_switch_to_fallback(smc);
			smc_switch_to_fallback(smc);
			smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP;
			smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP;
@@ -2005,6 +2003,11 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
			rc = -EINVAL;
			rc = -EINVAL;
			goto out;
			goto out;
		}
		}
	} else if ((sk->sk_state != SMC_ACTIVE) &&
		   (sk->sk_state != SMC_APPCLOSEWAIT1) &&
		   (sk->sk_state != SMC_INIT)) {
		rc = -EPIPE;
		goto out;
	}
	}


	if (smc->use_fallback)
	if (smc->use_fallback)