summaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2020-07-05 01:30:15 +0200
committerDavid S. Miller <davem@davemloft.net>2020-07-04 17:56:22 -0700
commit83f0c10bc36f956102ce4a33c5fe596ae9891297 (patch)
tree748a717768cd39a766c5988cb13f19c7a0dab440 /net/socket.c
parentf551e2fdaf81b7b561bb5dc590da13f21c4c1295 (diff)
downloadlinux-stable-83f0c10bc36f956102ce4a33c5fe596ae9891297.tar.gz
linux-stable-83f0c10bc36f956102ce4a33c5fe596ae9891297.tar.bz2
linux-stable-83f0c10bc36f956102ce4a33c5fe596ae9891297.zip
net: use mptcp setsockopt function for SOL_SOCKET on mptcp sockets
setsockopt(mptcp_fd, SOL_SOCKET, ...)... appears to work (returns 0), but it has no effect -- this is because the MPTCP layer never has a chance to copy the settings to the subflow socket. Skip the generic handling for the mptcp case and instead call the mptcp specific handler instead for SOL_SOCKET too. Next patch adds more specific handling for SOL_SOCKET to mptcp. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/net/socket.c b/net/socket.c
index 976426d03f09..d87812a9ed4b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2080,6 +2080,17 @@ SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
}
+static bool sock_use_custom_sol_socket(const struct socket *sock)
+{
+ const struct sock *sk = sock->sk;
+
+ /* Use sock->ops->setsockopt() for MPTCP */
+ return IS_ENABLED(CONFIG_MPTCP) &&
+ sk->sk_protocol == IPPROTO_MPTCP &&
+ sk->sk_type == SOCK_STREAM &&
+ (sk->sk_family == AF_INET || sk->sk_family == AF_INET6);
+}
+
/*
* Set a socket option. Because we don't know the option lengths we have
* to pass the user mode parameter for the protocols to sort out.
@@ -2118,7 +2129,7 @@ static int __sys_setsockopt(int fd, int level, int optname,
optval = (char __user __force *)kernel_optval;
}
- if (level == SOL_SOCKET)
+ if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
err =
sock_setsockopt(sock, level, optname, optval,
optlen);