Skip to content

Commit 717e79c

Browse files
Peter Krystaddavem330
authored andcommitted
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 <[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]>
1 parent 2149849 commit 717e79c

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

net/mptcp/protocol.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,62 @@ static void mptcp_destroy(struct sock *sk)
330330
{
331331
}
332332

333+
static int mptcp_setsockopt(struct sock *sk, int level, int optname,
334+
char __user *uoptval, unsigned int optlen)
335+
{
336+
struct mptcp_sock *msk = mptcp_sk(sk);
337+
char __kernel *optval;
338+
int ret = -EOPNOTSUPP;
339+
struct socket *ssock;
340+
341+
/* will be treated as __user in tcp_setsockopt */
342+
optval = (char __kernel __force *)uoptval;
343+
344+
pr_debug("msk=%p", msk);
345+
346+
/* @@ the meaning of setsockopt() when the socket is connected and
347+
* there are multiple subflows is not defined.
348+
*/
349+
lock_sock(sk);
350+
ssock = __mptcp_socket_create(msk, MPTCP_SAME_STATE);
351+
if (!IS_ERR(ssock)) {
352+
pr_debug("subflow=%p", ssock->sk);
353+
ret = kernel_setsockopt(ssock, level, optname, optval, optlen);
354+
}
355+
release_sock(sk);
356+
357+
return ret;
358+
}
359+
360+
static int mptcp_getsockopt(struct sock *sk, int level, int optname,
361+
char __user *uoptval, int __user *uoption)
362+
{
363+
struct mptcp_sock *msk = mptcp_sk(sk);
364+
char __kernel *optval;
365+
int ret = -EOPNOTSUPP;
366+
int __kernel *option;
367+
struct socket *ssock;
368+
369+
/* will be treated as __user in tcp_getsockopt */
370+
optval = (char __kernel __force *)uoptval;
371+
option = (int __kernel __force *)uoption;
372+
373+
pr_debug("msk=%p", msk);
374+
375+
/* @@ the meaning of getsockopt() when the socket is connected and
376+
* there are multiple subflows is not defined.
377+
*/
378+
lock_sock(sk);
379+
ssock = __mptcp_socket_create(msk, MPTCP_SAME_STATE);
380+
if (!IS_ERR(ssock)) {
381+
pr_debug("subflow=%p", ssock->sk);
382+
ret = kernel_getsockopt(ssock, level, optname, optval, option);
383+
}
384+
release_sock(sk);
385+
386+
return ret;
387+
}
388+
333389
static int mptcp_get_port(struct sock *sk, unsigned short snum)
334390
{
335391
struct mptcp_sock *msk = mptcp_sk(sk);
@@ -380,6 +436,8 @@ static struct proto mptcp_prot = {
380436
.init = mptcp_init_sock,
381437
.close = mptcp_close,
382438
.accept = mptcp_accept,
439+
.setsockopt = mptcp_setsockopt,
440+
.getsockopt = mptcp_getsockopt,
383441
.shutdown = tcp_shutdown,
384442
.destroy = mptcp_destroy,
385443
.sendmsg = mptcp_sendmsg,

0 commit comments

Comments
 (0)