Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a517302 authored by D. Wythe's avatar D. Wythe Committed by Greg Kroah-Hartman
Browse files

net/smc: fix fallback failed while sendmsg with fastopen



[ Upstream commit ce7ca794712f186da99719e8b4e97bd5ddbb04c3 ]

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>
parent 3a747490
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -1542,16 +1542,14 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
{
	struct sock *sk = sock->sk;
	struct smc_sock *smc;
	int rc = -EPIPE;
	int rc;

	smc = smc_sk(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) {
		/* not connected yet, fallback */
		if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) {
			smc_switch_to_fallback(smc);
			smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP;
@@ -1559,6 +1557,11 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
			rc = -EINVAL;
			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)