mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02: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
					
				
					 1 changed files with 58 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue