Commit 9368397f authored by Daniel Borkmann's avatar Daniel Borkmann Committed by Jakub Kicinski
Browse files

xsk: Extend xsk_rcv_check validation



xsk_rcv_check tests for inbound packets to see whether they match
the bound AF_XDP socket. Refactor the test into a small helper
xsk_dev_queue_valid and move the validation against xs->dev and
xs->queue_id there.

The fast-path case stays in place and allows for quick return in
xsk_dev_queue_valid. If it fails, the validation is extended to
check whether the AF_XDP socket is bound against a leased queue,
and if so, the test is redone.

Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Co-developed-by: default avatarDavid Wei <dw@davidwei.uk>
Signed-off-by: default avatarDavid Wei <dw@davidwei.uk>
Acked-by: default avatarStanislav Fomichev <sdf@fomichev.me>
Reviewed-by: default avatarNikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260402231031.447597-9-daniel@iogearbox.net


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 222b5566
Loading
Loading
Loading
Loading
+26 −3
Original line number Diff line number Diff line
@@ -330,14 +330,37 @@ static bool xsk_is_bound(struct xdp_sock *xs)
	return false;
}

static bool xsk_dev_queue_valid(const struct xdp_sock *xs,
				const struct xdp_rxq_info *info)
{
	struct net_device *dev = xs->dev;
	u32 queue_index = xs->queue_id;
	struct netdev_rx_queue *rxq;

	if (info->dev == dev &&
	    info->queue_index == queue_index)
		return true;

	if (queue_index < dev->real_num_rx_queues) {
		rxq = READ_ONCE(__netif_get_rx_queue(dev, queue_index)->lease);
		if (!rxq)
			return false;

		dev = rxq->dev;
		queue_index = get_netdev_rx_queue_index(rxq);

		return info->dev == dev &&
		       info->queue_index == queue_index;
	}
	return false;
}

static int xsk_rcv_check(struct xdp_sock *xs, struct xdp_buff *xdp, u32 len)
{
	if (!xsk_is_bound(xs))
		return -ENXIO;

	if (xs->dev != xdp->rxq->dev || xs->queue_id != xdp->rxq->queue_index)
	if (!xsk_dev_queue_valid(xs, xdp->rxq))
		return -EINVAL;

	if (len > xsk_pool_get_rx_frame_size(xs->pool) && !xs->sg) {
		xs->rx_dropped++;
		return -ENOSPC;