xsk: Check if a queue exists during umem setup
In the xdp_umem_assign_dev() path, the xsk code does not
check if a queue for which umem is to be created exists.
It leads to a situation where umem is not assigned to any
Tx/Rx queue of a netdevice, without notifying the stack
about an error. This affects both XDP_SKB and XDP_DRV
modes - in case of XDP_DRV_ZC, queue index is checked by
the driver.
This patch fixes xsk code, so that in both XDP_SKB and
XDP_DRV mode of AF_XDP, an error is returned when requested
queue index exceedes an existing maximum.
Fixes: c9b47cc1fa
("xsk: fix bug when trying to use both copy and zero-copy on one queue id")
Reported-by: Jakub Spizewski <jakub.spizewski@intel.com>
Signed-off-by: Krzysztof Kazimierczak <krzysztof.kazimierczak@intel.com>
Acked-by: Björn Töpel <bjorn.topel@intel.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
parent
7939f8beec
commit
cc5b5d3565
@ -41,13 +41,20 @@ void xdp_del_sk_umem(struct xdp_umem *umem, struct xdp_sock *xs)
|
|||||||
* not know if the device has more tx queues than rx, or the opposite.
|
* not know if the device has more tx queues than rx, or the opposite.
|
||||||
* This might also change during run time.
|
* This might also change during run time.
|
||||||
*/
|
*/
|
||||||
static void xdp_reg_umem_at_qid(struct net_device *dev, struct xdp_umem *umem,
|
static int xdp_reg_umem_at_qid(struct net_device *dev, struct xdp_umem *umem,
|
||||||
u16 queue_id)
|
u16 queue_id)
|
||||||
{
|
{
|
||||||
|
if (queue_id >= max_t(unsigned int,
|
||||||
|
dev->real_num_rx_queues,
|
||||||
|
dev->real_num_tx_queues))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (queue_id < dev->real_num_rx_queues)
|
if (queue_id < dev->real_num_rx_queues)
|
||||||
dev->_rx[queue_id].umem = umem;
|
dev->_rx[queue_id].umem = umem;
|
||||||
if (queue_id < dev->real_num_tx_queues)
|
if (queue_id < dev->real_num_tx_queues)
|
||||||
dev->_tx[queue_id].umem = umem;
|
dev->_tx[queue_id].umem = umem;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev,
|
struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev,
|
||||||
@ -88,7 +95,10 @@ int xdp_umem_assign_dev(struct xdp_umem *umem, struct net_device *dev,
|
|||||||
goto out_rtnl_unlock;
|
goto out_rtnl_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
xdp_reg_umem_at_qid(dev, umem, queue_id);
|
err = xdp_reg_umem_at_qid(dev, umem, queue_id);
|
||||||
|
if (err)
|
||||||
|
goto out_rtnl_unlock;
|
||||||
|
|
||||||
umem->dev = dev;
|
umem->dev = dev;
|
||||||
umem->queue_id = queue_id;
|
umem->queue_id = queue_id;
|
||||||
if (force_copy)
|
if (force_copy)
|
||||||
|
Loading…
Reference in New Issue
Block a user