mptcp: cleanup SOL_TCP handling
authorPaolo Abeni <pabeni@redhat.com>
Fri, 1 Mar 2024 17:43:47 +0000 (18:43 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 4 Mar 2024 10:50:28 +0000 (10:50 +0000)
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>
net/mptcp/sockopt.c

index 1b38dac70719bb372c7aca867d3932787b9bcb28..dcd1c76d2a3ba1ccc31a3e9279f725cd6d433782 100644 (file)
@@ -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,