]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mptcp: cleanup SOL_TCP handling
authorPaolo Abeni <pabeni@redhat.com>
Fri, 1 Mar 2024 17:43:47 +0000 (18:43 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 May 2024 07:49:28 +0000 (09:49 +0200)
[ 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

index f2fe28a3912a92d18bafa6790f0aea26e28b59ca..b0a61ec8c24481a9031a36ef1c0885183c3aa359 100644 (file)
@@ -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,