Commit 644807e3 authored by Florian Westphal's avatar Florian Westphal Committed by Jakub Kicinski
Browse files

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: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 5cbd886c
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -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,