mptcp: Add setsockopt()/getsockopt() socket operations

set/getsockopt behaviour with multiple subflows is undefined.
Therefore, for now, we return -EOPNOTSUPP unless we're in fallback mode.

Co-developed-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Peter Krystad <peter.krystad@linux.intel.com>
Signed-off-by: Christoph Paasch <cpaasch@apple.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Peter Krystad 2020-01-21 16:56:22 -08:00 committed by David S. Miller
parent 214984901a
commit 717e79c867

View file

@ -330,6 +330,62 @@ static void mptcp_destroy(struct sock *sk)
{
}
static int mptcp_setsockopt(struct sock *sk, int level, int optname,
char __user *uoptval, unsigned int optlen)
{
struct mptcp_sock *msk = mptcp_sk(sk);
char __kernel *optval;
int ret = -EOPNOTSUPP;
struct socket *ssock;
/* will be treated as __user in tcp_setsockopt */
optval = (char __kernel __force *)uoptval;
pr_debug("msk=%p", msk);
/* @@ the meaning of setsockopt() when the socket is connected and
* there are multiple subflows is not defined.
*/
lock_sock(sk);
ssock = __mptcp_socket_create(msk, MPTCP_SAME_STATE);
if (!IS_ERR(ssock)) {
pr_debug("subflow=%p", ssock->sk);
ret = kernel_setsockopt(ssock, level, optname, optval, optlen);
}
release_sock(sk);
return ret;
}
static int mptcp_getsockopt(struct sock *sk, int level, int optname,
char __user *uoptval, int __user *uoption)
{
struct mptcp_sock *msk = mptcp_sk(sk);
char __kernel *optval;
int ret = -EOPNOTSUPP;
int __kernel *option;
struct socket *ssock;
/* will be treated as __user in tcp_getsockopt */
optval = (char __kernel __force *)uoptval;
option = (int __kernel __force *)uoption;
pr_debug("msk=%p", msk);
/* @@ the meaning of getsockopt() when the socket is connected and
* there are multiple subflows is not defined.
*/
lock_sock(sk);
ssock = __mptcp_socket_create(msk, MPTCP_SAME_STATE);
if (!IS_ERR(ssock)) {
pr_debug("subflow=%p", ssock->sk);
ret = kernel_getsockopt(ssock, level, optname, optval, option);
}
release_sock(sk);
return ret;
}
static int mptcp_get_port(struct sock *sk, unsigned short snum)
{
struct mptcp_sock *msk = mptcp_sk(sk);
@ -380,6 +436,8 @@ static struct proto mptcp_prot = {
.init = mptcp_init_sock,
.close = mptcp_close,
.accept = mptcp_accept,
.setsockopt = mptcp_setsockopt,
.getsockopt = mptcp_getsockopt,
.shutdown = tcp_shutdown,
.destroy = mptcp_destroy,
.sendmsg = mptcp_sendmsg,