mptcp: move sockopt function into a new file
authorPaolo Abeni <pabeni@redhat.com>
Thu, 15 Apr 2021 23:44:51 +0000 (16:44 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 16 Apr 2021 22:23:09 +0000 (15:23 -0700)
The MPTCP sockopt implementation is going to be much
more big and complex soon. Let's move it to a different
source file.

No functional change intended.

Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/Makefile
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/sockopt.c [new file with mode: 0644]

index a611968..d2642c0 100644 (file)
@@ -2,7 +2,7 @@
 obj-$(CONFIG_MPTCP) += mptcp.o
 
 mptcp-y := protocol.o subflow.o options.o token.o crypto.o ctrl.o pm.o diag.o \
-          mib.o pm_netlink.o
+          mib.o pm_netlink.o sockopt.o
 
 obj-$(CONFIG_SYN_COOKIES) += syncookies.o
 obj-$(CONFIG_INET_MPTCP_DIAG) += mptcp_diag.o
index 2fcdc61..e0b381a 100644 (file)
@@ -90,16 +90,6 @@ static bool mptcp_is_tcpsk(struct sock *sk)
        return false;
 }
 
-static struct sock *__mptcp_tcp_fallback(struct mptcp_sock *msk)
-{
-       sock_owned_by_me((const struct sock *)msk);
-
-       if (likely(!__mptcp_check_fallback(msk)))
-               return NULL;
-
-       return msk->first;
-}
-
 static int __mptcp_socket_create(struct mptcp_sock *msk)
 {
        struct mptcp_subflow_context *subflow;
@@ -2811,116 +2801,6 @@ static void mptcp_destroy(struct sock *sk)
        sk_sockets_allocated_dec(sk);
 }
 
-static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
-                                      sockptr_t optval, unsigned int optlen)
-{
-       struct sock *sk = (struct sock *)msk;
-       struct socket *ssock;
-       int ret;
-
-       switch (optname) {
-       case SO_REUSEPORT:
-       case SO_REUSEADDR:
-               lock_sock(sk);
-               ssock = __mptcp_nmpc_socket(msk);
-               if (!ssock) {
-                       release_sock(sk);
-                       return -EINVAL;
-               }
-
-               ret = sock_setsockopt(ssock, SOL_SOCKET, optname, optval, optlen);
-               if (ret == 0) {
-                       if (optname == SO_REUSEPORT)
-                               sk->sk_reuseport = ssock->sk->sk_reuseport;
-                       else if (optname == SO_REUSEADDR)
-                               sk->sk_reuse = ssock->sk->sk_reuse;
-               }
-               release_sock(sk);
-               return ret;
-       }
-
-       return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen);
-}
-
-static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
-                              sockptr_t optval, unsigned int optlen)
-{
-       struct sock *sk = (struct sock *)msk;
-       int ret = -EOPNOTSUPP;
-       struct socket *ssock;
-
-       switch (optname) {
-       case IPV6_V6ONLY:
-               lock_sock(sk);
-               ssock = __mptcp_nmpc_socket(msk);
-               if (!ssock) {
-                       release_sock(sk);
-                       return -EINVAL;
-               }
-
-               ret = tcp_setsockopt(ssock->sk, SOL_IPV6, optname, optval, optlen);
-               if (ret == 0)
-                       sk->sk_ipv6only = ssock->sk->sk_ipv6only;
-
-               release_sock(sk);
-               break;
-       }
-
-       return ret;
-}
-
-static int mptcp_setsockopt(struct sock *sk, int level, int optname,
-                           sockptr_t optval, unsigned int optlen)
-{
-       struct mptcp_sock *msk = mptcp_sk(sk);
-       struct sock *ssk;
-
-       pr_debug("msk=%p", msk);
-
-       if (level == SOL_SOCKET)
-               return mptcp_setsockopt_sol_socket(msk, optname, optval, optlen);
-
-       /* @@ the meaning of setsockopt() when the socket is connected and
-        * there are multiple subflows is not yet defined. It is up to the
-        * MPTCP-level socket to configure the subflows until the subflow
-        * is in TCP fallback, when TCP socket options are passed through
-        * to the one remaining subflow.
-        */
-       lock_sock(sk);
-       ssk = __mptcp_tcp_fallback(msk);
-       release_sock(sk);
-       if (ssk)
-               return tcp_setsockopt(ssk, level, optname, optval, optlen);
-
-       if (level == SOL_IPV6)
-               return mptcp_setsockopt_v6(msk, optname, optval, optlen);
-
-       return -EOPNOTSUPP;
-}
-
-static int mptcp_getsockopt(struct sock *sk, int level, int optname,
-                           char __user *optval, int __user *option)
-{
-       struct mptcp_sock *msk = mptcp_sk(sk);
-       struct sock *ssk;
-
-       pr_debug("msk=%p", msk);
-
-       /* @@ the meaning of setsockopt() when the socket is connected and
-        * there are multiple subflows is not yet defined. It is up to the
-        * MPTCP-level socket to configure the subflows until the subflow
-        * is in TCP fallback, when socket options are passed through
-        * to the one remaining subflow.
-        */
-       lock_sock(sk);
-       ssk = __mptcp_tcp_fallback(msk);
-       release_sock(sk);
-       if (ssk)
-               return tcp_getsockopt(ssk, level, optname, optval, option);
-
-       return -EOPNOTSUPP;
-}
-
 void __mptcp_data_acked(struct sock *sk)
 {
        if (!sock_owned_by_user(sk))
index d8de1e9..14f0114 100644 (file)
@@ -571,6 +571,11 @@ void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk);
 void mptcp_data_ready(struct sock *sk, struct sock *ssk);
 bool mptcp_finish_join(struct sock *sk);
 bool mptcp_schedule_work(struct sock *sk);
+int mptcp_setsockopt(struct sock *sk, int level, int optname,
+                    sockptr_t optval, unsigned int optlen);
+int mptcp_getsockopt(struct sock *sk, int level, int optname,
+                    char __user *optval, int __user *option);
+
 void __mptcp_check_push(struct sock *sk, struct sock *ssk);
 void __mptcp_data_acked(struct sock *sk);
 void __mptcp_error_report(struct sock *sk);
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
new file mode 100644 (file)
index 0000000..479f756
--- /dev/null
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Multipath TCP
+ *
+ * Copyright (c) 2021, Red Hat.
+ */
+
+#define pr_fmt(fmt) "MPTCP: " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <net/sock.h>
+#include <net/protocol.h>
+#include <net/tcp.h>
+#include <net/mptcp.h>
+#include "protocol.h"
+
+static struct sock *__mptcp_tcp_fallback(struct mptcp_sock *msk)
+{
+       sock_owned_by_me((const struct sock *)msk);
+
+       if (likely(!__mptcp_check_fallback(msk)))
+               return NULL;
+
+       return msk->first;
+}
+
+static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
+                                      sockptr_t optval, unsigned int optlen)
+{
+       struct sock *sk = (struct sock *)msk;
+       struct socket *ssock;
+       int ret;
+
+       switch (optname) {
+       case SO_REUSEPORT:
+       case SO_REUSEADDR:
+               lock_sock(sk);
+               ssock = __mptcp_nmpc_socket(msk);
+               if (!ssock) {
+                       release_sock(sk);
+                       return -EINVAL;
+               }
+
+               ret = sock_setsockopt(ssock, SOL_SOCKET, optname, optval, optlen);
+               if (ret == 0) {
+                       if (optname == SO_REUSEPORT)
+                               sk->sk_reuseport = ssock->sk->sk_reuseport;
+                       else if (optname == SO_REUSEADDR)
+                               sk->sk_reuse = ssock->sk->sk_reuse;
+               }
+               release_sock(sk);
+               return ret;
+       }
+
+       return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen);
+}
+
+static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
+                              sockptr_t optval, unsigned int optlen)
+{
+       struct sock *sk = (struct sock *)msk;
+       int ret = -EOPNOTSUPP;
+       struct socket *ssock;
+
+       switch (optname) {
+       case IPV6_V6ONLY:
+               lock_sock(sk);
+               ssock = __mptcp_nmpc_socket(msk);
+               if (!ssock) {
+                       release_sock(sk);
+                       return -EINVAL;
+               }
+
+               ret = tcp_setsockopt(ssock->sk, SOL_IPV6, optname, optval, optlen);
+               if (ret == 0)
+                       sk->sk_ipv6only = ssock->sk->sk_ipv6only;
+
+               release_sock(sk);
+               break;
+       }
+
+       return ret;
+}
+
+int mptcp_setsockopt(struct sock *sk, int level, int optname,
+                    sockptr_t optval, unsigned int optlen)
+{
+       struct mptcp_sock *msk = mptcp_sk(sk);
+       struct sock *ssk;
+
+       pr_debug("msk=%p", msk);
+
+       if (level == SOL_SOCKET)
+               return mptcp_setsockopt_sol_socket(msk, optname, optval, optlen);
+
+       /* @@ the meaning of setsockopt() when the socket is connected and
+        * there are multiple subflows is not yet defined. It is up to the
+        * MPTCP-level socket to configure the subflows until the subflow
+        * is in TCP fallback, when TCP socket options are passed through
+        * to the one remaining subflow.
+        */
+       lock_sock(sk);
+       ssk = __mptcp_tcp_fallback(msk);
+       release_sock(sk);
+       if (ssk)
+               return tcp_setsockopt(ssk, level, optname, optval, optlen);
+
+       if (level == SOL_IPV6)
+               return mptcp_setsockopt_v6(msk, optname, optval, optlen);
+
+       return -EOPNOTSUPP;
+}
+
+int mptcp_getsockopt(struct sock *sk, int level, int optname,
+                    char __user *optval, int __user *option)
+{
+       struct mptcp_sock *msk = mptcp_sk(sk);
+       struct sock *ssk;
+
+       pr_debug("msk=%p", msk);
+
+       /* @@ the meaning of setsockopt() when the socket is connected and
+        * there are multiple subflows is not yet defined. It is up to the
+        * MPTCP-level socket to configure the subflows until the subflow
+        * is in TCP fallback, when socket options are passed through
+        * to the one remaining subflow.
+        */
+       lock_sock(sk);
+       ssk = __mptcp_tcp_fallback(msk);
+       release_sock(sk);
+       if (ssk)
+               return tcp_getsockopt(ssk, level, optname, optval, option);
+
+       return -EOPNOTSUPP;
+}
+