Commit 7f71a337 authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller
Browse files

mptcp: cleanup SOL_TCP handling



Most TCP-level socket options get an integer from user space, and
set the corresponding field under the msk-level socket lock.

Reduce the code duplication moving such operations in the common code.

Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarMat Martineau <martineau@kernel.org>
Signed-off-by: default avatarMatthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 29b5e5ef
Loading
Loading
Loading
Loading
+30 −45
Original line number Diff line number Diff line
@@ -624,18 +624,11 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t
	return ret;
}

static int mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, sockptr_t optval,
					 unsigned int optlen)
static int __mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, int val)
{
	struct mptcp_subflow_context *subflow;
	struct sock *sk = (struct sock *)msk;
	int val, ret;

	ret = mptcp_get_int_option(msk, optval, optlen, &val);
	if (ret)
		return ret;

	lock_sock(sk);
	sockopt_seq_inc(msk);
	msk->cork = !!val;
	mptcp_for_each_subflow(msk, subflow) {
@@ -647,23 +640,15 @@ static int mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, sockptr_t optva
	}
	if (!val)
		mptcp_check_and_set_pending(sk);
	release_sock(sk);

	return 0;
}

static int mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, sockptr_t optval,
					    unsigned int optlen)
static int __mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, int val)
{
	struct mptcp_subflow_context *subflow;
	struct sock *sk = (struct sock *)msk;
	int val, ret;

	ret = mptcp_get_int_option(msk, optval, optlen, &val);
	if (ret)
		return ret;

	lock_sock(sk);
	sockopt_seq_inc(msk);
	msk->nodelay = !!val;
	mptcp_for_each_subflow(msk, subflow) {
@@ -675,8 +660,6 @@ static int mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, sockptr_t op
	}
	if (val)
		mptcp_check_and_set_pending(sk);
	release_sock(sk);

	return 0;
}

@@ -799,35 +782,10 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
	int ret, val;

	switch (optname) {
	case TCP_INQ:
		ret = mptcp_get_int_option(msk, optval, optlen, &val);
		if (ret)
			return ret;
		if (val < 0 || val > 1)
			return -EINVAL;

		lock_sock(sk);
		msk->recvmsg_inq = !!val;
		release_sock(sk);
		return 0;
	case TCP_ULP:
		return -EOPNOTSUPP;
	case TCP_NOTSENT_LOWAT:
		ret = mptcp_get_int_option(msk, optval, optlen, &val);
		if (ret)
			return ret;

		lock_sock(sk);
		WRITE_ONCE(msk->notsent_lowat, val);
		mptcp_write_space(sk);
		release_sock(sk);
		return 0;
	case TCP_CONGESTION:
		return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen);
	case TCP_CORK:
		return mptcp_setsockopt_sol_tcp_cork(msk, optval, optlen);
	case TCP_NODELAY:
		return mptcp_setsockopt_sol_tcp_nodelay(msk, optval, optlen);
	case TCP_DEFER_ACCEPT:
		/* See tcp.c: TCP_DEFER_ACCEPT does not fail */
		mptcp_setsockopt_first_sf_only(msk, SOL_TCP, optname, optval, optlen);
@@ -840,7 +798,34 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
						      optval, optlen);
	}

	return -EOPNOTSUPP;
	ret = mptcp_get_int_option(msk, optval, optlen, &val);
	if (ret)
		return ret;

	lock_sock(sk);
	switch (optname) {
	case TCP_INQ:
		if (val < 0 || val > 1)
			ret = -EINVAL;
		else
			msk->recvmsg_inq = !!val;
		break;
	case TCP_NOTSENT_LOWAT:
		WRITE_ONCE(msk->notsent_lowat, val);
		mptcp_write_space(sk);
		break;
	case TCP_CORK:
		ret = __mptcp_setsockopt_sol_tcp_cork(msk, val);
		break;
	case TCP_NODELAY:
		ret = __mptcp_setsockopt_sol_tcp_nodelay(msk, val);
		break;
	default:
		ret = -ENOPROTOOPT;
	}

	release_sock(sk);
	return ret;
}

int mptcp_setsockopt(struct sock *sk, int level, int optname,