Commit fd1452d8 authored by Florian Westphal's avatar Florian Westphal Committed by David S. Miller

mptcp: add REUSEADDR/REUSEPORT support

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: default avatarChristoph Paasch <cpaasch@apple.com>
Suggested-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 83f0c10b
...@@ -1601,6 +1601,37 @@ static void mptcp_destroy(struct sock *sk) ...@@ -1601,6 +1601,37 @@ static void mptcp_destroy(struct sock *sk)
sk_sockets_allocated_dec(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, static int mptcp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen) char __user *optval, unsigned int optlen)
{ {
...@@ -1610,7 +1641,7 @@ static int mptcp_setsockopt(struct sock *sk, int level, int optname, ...@@ -1610,7 +1641,7 @@ static int mptcp_setsockopt(struct sock *sk, int level, int optname,
pr_debug("msk=%p", msk); pr_debug("msk=%p", msk);
if (level == SOL_SOCKET) 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 /* @@ the meaning of setsockopt() when the socket is connected and
* there are multiple subflows is not yet defined. It is up to the * there are multiple subflows is not yet defined. It is up to the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment