bpf: devmap: check XDP features in __xdp_enqueue routine
Check if the destination device implements ndo_xdp_xmit callback relying on NETDEV_XDP_ACT_NDO_XMIT flags. Moreover, check if the destination device supports XDP non-linear frame in __xdp_enqueue and is_valid_dst routines. This patch allows to perform XDP_REDIRECT on non-linear XDP buffers. Acked-by: Jesper Dangaard Brouer <brouer@redhat.com> Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://lore.kernel.org/r/26a94c33520c0bfba021b3fbb2cb8c1e69bf53b8.1675245258.git.lorenzo@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Родитель
04d58f1b26
Коммит
b9d460c924
|
@ -474,7 +474,11 @@ static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf,
|
|||
{
|
||||
int err;
|
||||
|
||||
if (!dev->netdev_ops->ndo_xdp_xmit)
|
||||
if (!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (unlikely(!(dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT_SG) &&
|
||||
xdp_frame_has_frags(xdpf)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
err = xdp_ok_fwd_dev(dev, xdp_get_frame_len(xdpf));
|
||||
|
@ -532,8 +536,14 @@ int dev_map_enqueue(struct bpf_dtab_netdev *dst, struct xdp_frame *xdpf,
|
|||
|
||||
static bool is_valid_dst(struct bpf_dtab_netdev *obj, struct xdp_frame *xdpf)
|
||||
{
|
||||
if (!obj ||
|
||||
!obj->dev->netdev_ops->ndo_xdp_xmit)
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
if (!(obj->dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT))
|
||||
return false;
|
||||
|
||||
if (unlikely(!(obj->dev->xdp_features & NETDEV_XDP_ACT_NDO_XMIT_SG) &&
|
||||
xdp_frame_has_frags(xdpf)))
|
||||
return false;
|
||||
|
||||
if (xdp_ok_fwd_dev(obj->dev, xdp_get_frame_len(xdpf)))
|
||||
|
|
|
@ -4318,16 +4318,13 @@ int xdp_do_redirect(struct net_device *dev, struct xdp_buff *xdp,
|
|||
struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
|
||||
enum bpf_map_type map_type = ri->map_type;
|
||||
|
||||
/* XDP_REDIRECT is not fully supported yet for xdp frags since
|
||||
* not all XDP capable drivers can map non-linear xdp_frame in
|
||||
* ndo_xdp_xmit.
|
||||
*/
|
||||
if (unlikely(xdp_buff_has_frags(xdp) &&
|
||||
map_type != BPF_MAP_TYPE_CPUMAP))
|
||||
return -EOPNOTSUPP;
|
||||
if (map_type == BPF_MAP_TYPE_XSKMAP) {
|
||||
/* XDP_REDIRECT is not supported AF_XDP yet. */
|
||||
if (unlikely(xdp_buff_has_frags(xdp)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (map_type == BPF_MAP_TYPE_XSKMAP)
|
||||
return __xdp_do_redirect_xsk(ri, dev, xdp, xdp_prog);
|
||||
}
|
||||
|
||||
return __xdp_do_redirect_frame(ri, dev, xdp_convert_buff_to_frame(xdp),
|
||||
xdp_prog);
|
||||
|
|
Загрузка…
Ссылка в новой задаче