mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	mptcp: add SIOCINQ, OUTQ and OUTQNSD ioctls
Allows to query in-sequence data ready for read(), total bytes in write queue and total bytes in write queue that have not yet been sent. v2: remove unneeded READ_ONCE() (Paolo Abeni) v3: check for new data unconditionally in SIOCINQ ioctl (Mat Martineau) Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									5cbd886ce2
								
							
						
					
					
						commit
						644807e3e4
					
				
					 1 changed files with 53 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -22,6 +22,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
#include <net/mptcp.h>
 | 
			
		||||
#include <net/xfrm.h>
 | 
			
		||||
#include <asm/ioctls.h>
 | 
			
		||||
#include "protocol.h"
 | 
			
		||||
#include "mib.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3211,6 +3212,57 @@ static int mptcp_forward_alloc_get(const struct sock *sk)
 | 
			
		|||
	return sk->sk_forward_alloc + mptcp_sk(sk)->rmem_fwd_alloc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int mptcp_ioctl_outq(const struct mptcp_sock *msk, u64 v)
 | 
			
		||||
{
 | 
			
		||||
	const struct sock *sk = (void *)msk;
 | 
			
		||||
	u64 delta;
 | 
			
		||||
 | 
			
		||||
	if (sk->sk_state == TCP_LISTEN)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	delta = msk->write_seq - v;
 | 
			
		||||
	if (delta > INT_MAX)
 | 
			
		||||
		delta = INT_MAX;
 | 
			
		||||
 | 
			
		||||
	return (int)delta;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int mptcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 | 
			
		||||
{
 | 
			
		||||
	struct mptcp_sock *msk = mptcp_sk(sk);
 | 
			
		||||
	bool slow;
 | 
			
		||||
	int answ;
 | 
			
		||||
 | 
			
		||||
	switch (cmd) {
 | 
			
		||||
	case SIOCINQ:
 | 
			
		||||
		if (sk->sk_state == TCP_LISTEN)
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
 | 
			
		||||
		lock_sock(sk);
 | 
			
		||||
		__mptcp_move_skbs(msk);
 | 
			
		||||
		answ = mptcp_inq_hint(sk);
 | 
			
		||||
		release_sock(sk);
 | 
			
		||||
		break;
 | 
			
		||||
	case SIOCOUTQ:
 | 
			
		||||
		slow = lock_sock_fast(sk);
 | 
			
		||||
		answ = mptcp_ioctl_outq(msk, READ_ONCE(msk->snd_una));
 | 
			
		||||
		unlock_sock_fast(sk, slow);
 | 
			
		||||
		break;
 | 
			
		||||
	case SIOCOUTQNSD:
 | 
			
		||||
		slow = lock_sock_fast(sk);
 | 
			
		||||
		answ = mptcp_ioctl_outq(msk, msk->snd_nxt);
 | 
			
		||||
		unlock_sock_fast(sk, slow);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return -ENOIOCTLCMD;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return put_user(answ, (int __user *)arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct proto mptcp_prot = {
 | 
			
		||||
	.name		= "MPTCP",
 | 
			
		||||
	.owner		= THIS_MODULE,
 | 
			
		||||
| 
						 | 
				
			
			@ -3223,6 +3275,7 @@ static struct proto mptcp_prot = {
 | 
			
		|||
	.shutdown	= mptcp_shutdown,
 | 
			
		||||
	.destroy	= mptcp_destroy,
 | 
			
		||||
	.sendmsg	= mptcp_sendmsg,
 | 
			
		||||
	.ioctl		= mptcp_ioctl,
 | 
			
		||||
	.recvmsg	= mptcp_recvmsg,
 | 
			
		||||
	.release_cb	= mptcp_release_cb,
 | 
			
		||||
	.hash		= mptcp_hash,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue