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
@ -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 New Issue
Block a user