mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-06 11:58:09 +07:00
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:
parent
214984901a
commit
717e79c867
@ -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)
|
static int mptcp_get_port(struct sock *sk, unsigned short snum)
|
||||||
{
|
{
|
||||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||||
@ -380,6 +436,8 @@ static struct proto mptcp_prot = {
|
|||||||
.init = mptcp_init_sock,
|
.init = mptcp_init_sock,
|
||||||
.close = mptcp_close,
|
.close = mptcp_close,
|
||||||
.accept = mptcp_accept,
|
.accept = mptcp_accept,
|
||||||
|
.setsockopt = mptcp_setsockopt,
|
||||||
|
.getsockopt = mptcp_getsockopt,
|
||||||
.shutdown = tcp_shutdown,
|
.shutdown = tcp_shutdown,
|
||||||
.destroy = mptcp_destroy,
|
.destroy = mptcp_destroy,
|
||||||
.sendmsg = mptcp_sendmsg,
|
.sendmsg = mptcp_sendmsg,
|
||||||
|
Loading…
Reference in New Issue
Block a user