Commit 45a86681 authored by Björn Töpel's avatar Björn Töpel Committed by Daniel Borkmann
Browse files

xsk: Add support for recvmsg()



Add support for non-blocking recvmsg() to XDP sockets. Previously,
only sendmsg() was supported by XDP socket. Now, for symmetry and the
upcoming busy-polling support, recvmsg() is added.

Signed-off-by: default avatarBjörn Töpel <bjorn.topel@intel.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarMagnus Karlsson <magnus.karlsson@intel.com>
Link: https://lore.kernel.org/bpf/20201130185205.196029-4-bjorn.topel@gmail.com
parent 7c951caf
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -531,6 +531,26 @@ static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
	return __xsk_sendmsg(sk);
}

static int xsk_recvmsg(struct socket *sock, struct msghdr *m, size_t len, int flags)
{
	bool need_wait = !(flags & MSG_DONTWAIT);
	struct sock *sk = sock->sk;
	struct xdp_sock *xs = xdp_sk(sk);

	if (unlikely(!(xs->dev->flags & IFF_UP)))
		return -ENETDOWN;
	if (unlikely(!xs->rx))
		return -ENOBUFS;
	if (unlikely(!xsk_is_bound(xs)))
		return -ENXIO;
	if (unlikely(need_wait))
		return -EOPNOTSUPP;

	if (xs->pool->cached_need_wakeup & XDP_WAKEUP_RX && xs->zc)
		return xsk_wakeup(xs, XDP_WAKEUP_RX);
	return 0;
}

static __poll_t xsk_poll(struct file *file, struct socket *sock,
			     struct poll_table_struct *wait)
{
@@ -1191,7 +1211,7 @@ static const struct proto_ops xsk_proto_ops = {
	.setsockopt	= xsk_setsockopt,
	.getsockopt	= xsk_getsockopt,
	.sendmsg	= xsk_sendmsg,
	.recvmsg	= sock_no_recvmsg,
	.recvmsg	= xsk_recvmsg,
	.mmap		= xsk_mmap,
	.sendpage	= sock_no_sendpage,
};