* [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support
@ 2020-07-04 23:30 Florian Westphal
2020-07-04 23:30 ` [PATCH net-next 1/3] net: use mptcp setsockopt function for SOL_SOCKET on mptcp sockets Florian Westphal
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Florian Westphal @ 2020-07-04 23:30 UTC (permalink / raw)
To: netdev; +Cc: mptcp
restarting an mptcp-patched sshd yields following error:
sshd: error: Bind to port 22 on 0.0.0.0 failed: Address already in use.
sshd: error: setsockopt IPV6_V6ONLY: Operation not supported
sshd: error: Bind to port 22 on :: failed: Address already in use.
sshd: fatal: Cannot bind any address.
This series adds support for the needed setsockopts:
First patch skips the generic SOL_SOCKET handler for MPTCP:
in mptcp case, the setsockopt needs to alter the tcp socket, not the mptcp
parent socket.
Second patch adds minimal SOL_SOCKET support: REUSEPORT and REUSEADDR.
Rest is still handled by the generic SOL_SOCKET code.
Last patch adds IPV6ONLY support. This makes ipv6 work for openssh:
It creates two listening sockets, before this patch, binding the ipv6
socket will fail because the port is already bound by the ipv4 one.
Florian Westphal (3):
net: use mptcp setsockopt function for SOL_SOCKET on mptcp sockets
mptcp: add REUSEADDR/REUSEPORT support
mptcp: support IPV6_V6ONLY setsockopt
net/mptcp/protocol.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
net/socket.c | 13 ++++++++++-
2 files changed, 76 insertions(+), 1 deletion(-)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net-next 1/3] net: use mptcp setsockopt function for SOL_SOCKET on mptcp sockets
2020-07-04 23:30 [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support Florian Westphal
@ 2020-07-04 23:30 ` Florian Westphal
2020-07-04 23:30 ` [PATCH net-next 2/3] mptcp: add REUSEADDR/REUSEPORT support Florian Westphal
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Florian Westphal @ 2020-07-04 23:30 UTC (permalink / raw)
To: netdev; +Cc: mptcp, Florian Westphal
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>
---
net/mptcp/protocol.c | 3 +++
net/socket.c | 13 ++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index fa137a9c42d1..320f306ea85c 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1609,6 +1609,9 @@ static int mptcp_setsockopt(struct sock *sk, int level, int optname,
pr_debug("msk=%p", msk);
+ if (level == SOL_SOCKET)
+ return sock_setsockopt(sk->sk_socket, level, 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
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);
--
2.26.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next 2/3] mptcp: add REUSEADDR/REUSEPORT support
2020-07-04 23:30 [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support Florian Westphal
2020-07-04 23:30 ` [PATCH net-next 1/3] net: use mptcp setsockopt function for SOL_SOCKET on mptcp sockets Florian Westphal
@ 2020-07-04 23:30 ` Florian Westphal
2020-07-04 23:30 ` [PATCH net-next 3/3] mptcp: support IPV6_V6ONLY setsockopt Florian Westphal
2020-07-05 0:57 ` [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Florian Westphal @ 2020-07-04 23:30 UTC (permalink / raw)
To: netdev; +Cc: mptcp, Florian Westphal, Christoph Paasch, Paolo Abeni
This will e.g. make 'sshd restart' work when MPTCP is used, as we will
now set this option on the listener socket instead of only the mptcp
socket (where it has no effect).
We still need to copy the setting to the master socket so that a
subsequent getsockopt() returns the expected value.
Reported-by: Christoph Paasch <cpaasch@apple.com>
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/mptcp/protocol.c | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 320f306ea85c..612f6d49f1bb 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1601,6 +1601,37 @@ static void mptcp_destroy(struct sock *sk)
sk_sockets_allocated_dec(sk);
}
+static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
+ char __user *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(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen)
{
@@ -1610,7 +1641,7 @@ static int mptcp_setsockopt(struct sock *sk, int level, int optname,
pr_debug("msk=%p", msk);
if (level == SOL_SOCKET)
- return sock_setsockopt(sk->sk_socket, level, optname, optval, optlen);
+ 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
--
2.26.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next 3/3] mptcp: support IPV6_V6ONLY setsockopt
2020-07-04 23:30 [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support Florian Westphal
2020-07-04 23:30 ` [PATCH net-next 1/3] net: use mptcp setsockopt function for SOL_SOCKET on mptcp sockets Florian Westphal
2020-07-04 23:30 ` [PATCH net-next 2/3] mptcp: add REUSEADDR/REUSEPORT support Florian Westphal
@ 2020-07-04 23:30 ` Florian Westphal
2020-07-05 0:57 ` [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Florian Westphal @ 2020-07-04 23:30 UTC (permalink / raw)
To: netdev; +Cc: mptcp, Florian Westphal
Without this, Opensshd fails to open an ipv6 socket listening
socket:
error: setsockopt IPV6_V6ONLY: Operation not supported
error: Bind to port 22 on :: failed: Address already in use.
Opensshd opens an ipv4 and and ipv6 listening socket, but because
IPV6_V6ONLY setsockopt fails, the port number is already in use.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/mptcp/protocol.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 612f6d49f1bb..3ab060e30038 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1632,6 +1632,33 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen);
}
+static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
+ char __user *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,
char __user *optval, unsigned int optlen)
{
@@ -1655,6 +1682,9 @@ static int mptcp_setsockopt(struct sock *sk, int level, int optname,
if (ssk)
return tcp_setsockopt(ssk, level, optname, optval, optlen);
+ if (level == SOL_IPV6)
+ return mptcp_setsockopt_v6(msk, optname, optval, optlen);
+
return -EOPNOTSUPP;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support
2020-07-04 23:30 [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support Florian Westphal
` (2 preceding siblings ...)
2020-07-04 23:30 ` [PATCH net-next 3/3] mptcp: support IPV6_V6ONLY setsockopt Florian Westphal
@ 2020-07-05 0:57 ` David Miller
3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2020-07-05 0:57 UTC (permalink / raw)
To: fw; +Cc: netdev, mptcp
From: Florian Westphal <fw@strlen.de>
Date: Sun, 5 Jul 2020 01:30:14 +0200
> restarting an mptcp-patched sshd yields following error:
>
> sshd: error: Bind to port 22 on 0.0.0.0 failed: Address already in use.
> sshd: error: setsockopt IPV6_V6ONLY: Operation not supported
> sshd: error: Bind to port 22 on :: failed: Address already in use.
> sshd: fatal: Cannot bind any address.
>
> This series adds support for the needed setsockopts:
>
> First patch skips the generic SOL_SOCKET handler for MPTCP:
> in mptcp case, the setsockopt needs to alter the tcp socket, not the mptcp
> parent socket.
>
> Second patch adds minimal SOL_SOCKET support: REUSEPORT and REUSEADDR.
> Rest is still handled by the generic SOL_SOCKET code.
>
> Last patch adds IPV6ONLY support. This makes ipv6 work for openssh:
> It creates two listening sockets, before this patch, binding the ipv6
> socket will fail because the port is already bound by the ipv4 one.
Series applied, thanks Florian.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-07-05 0:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-07-04 23:30 [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support Florian Westphal
2020-07-04 23:30 ` [PATCH net-next 1/3] net: use mptcp setsockopt function for SOL_SOCKET on mptcp sockets Florian Westphal
2020-07-04 23:30 ` [PATCH net-next 2/3] mptcp: add REUSEADDR/REUSEPORT support Florian Westphal
2020-07-04 23:30 ` [PATCH net-next 3/3] mptcp: support IPV6_V6ONLY setsockopt Florian Westphal
2020-07-05 0:57 ` [PATCH net-next 0/3] mptcp: add REUSEADDR/REUSEPORT/V6ONLY setsockopt support David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).