Skip to content

Commit

Permalink
mptcp: Add setsockopt()/getsockopt() socket operations
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Paolo Abeni <[email protected]>
Signed-off-by: Peter Krystad <[email protected]>
Signed-off-by: Christoph Paasch <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Peter Krystad authored and davem330 committed Jan 24, 2020
1 parent 2149849 commit 717e79c
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions net/mptcp/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 717e79c

Please sign in to comment.