| From 42d8a05907bb7cb4d2365c53a5e54164174712d8 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 1 Mar 2024 18:43:47 +0100 |
| Subject: mptcp: cleanup SOL_TCP handling |
| |
| From: Paolo Abeni <pabeni@redhat.com> |
| |
| [ Upstream commit 7f71a337b5152ea0e7bef408d1af53778a919316 ] |
| |
| 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: Paolo Abeni <pabeni@redhat.com> |
| Reviewed-by: Mat Martineau <martineau@kernel.org> |
| Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Stable-dep-of: bd11dc4fb969 ("mptcp: fix full TCP keep-alive support") |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/mptcp/sockopt.c | 75 ++++++++++++++++++--------------------------- |
| 1 file changed, 30 insertions(+), 45 deletions(-) |
| |
| diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c |
| index f2fe28a3912a9..b0a61ec8c2448 100644 |
| --- a/net/mptcp/sockopt.c |
| +++ b/net/mptcp/sockopt.c |
| @@ -622,18 +622,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) { |
| @@ -645,23 +638,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) { |
| @@ -673,8 +658,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; |
| } |
| |
| @@ -797,35 +780,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); |
| @@ -838,7 +796,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, |
| -- |
| 2.43.0 |
| |