On 6/4/21 3:02 PM, Zvi Effron wrote:
Support specifying the ingress_ifindex and rx_queue_index of xdp_md
contexts for BPF_PROG_TEST_RUN.
The intended use case is to allow testing XDP programs that make decisions
based on the ingress interface or RX queue.
If ingress_ifindex is specified, look up the device by the provided index
in the current namespace and use its xdp_rxq for the xdp_buff. If the
rx_queue_index is out of range, or is non-zero when the ingress_ifindex is
0, return EINVAL.
Co-developed-by: Cody Haas <chaas@xxxxxxxxxxxxx>
Signed-off-by: Cody Haas <chaas@xxxxxxxxxxxxx>
Co-developed-by: Lisa Watanabe <lwatanabe@xxxxxxxxxxxxx>
Signed-off-by: Lisa Watanabe <lwatanabe@xxxxxxxxxxxxx>
Signed-off-by: Zvi Effron <zeffron@xxxxxxxxxxxxx>
---
net/bpf/test_run.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 698618f2b27e..3916205fc3d4 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -690,6 +690,8 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
static int xdp_convert_md_to_buff(struct xdp_buff *xdp, struct xdp_md *xdp_md)
{
void *data;
+ struct net_device *device;
+ struct netdev_rx_queue *rxqueue;
reverse christmas tree?
if (!xdp_md)
return 0;
@@ -702,9 +704,21 @@ static int xdp_convert_md_to_buff(struct xdp_buff *xdp, struct xdp_md *xdp_md)
xdp->data = xdp->data_meta + xdp_md->data;
- if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0)
+ if (!xdp_md->ingress_ifindex && xdp_md->rx_queue_index)
return -EINVAL;
xdp_md->ingress_ifindex and xdp_md->rx_queue_index are used three times
each in this function here. Maybe worthwhile to assign them to
temporary variables?
+ if (xdp_md->ingress_ifindex) {
+ device = dev_get_by_index(current->nsproxy->net_ns, xdp_md->ingress_ifindex);
+ if (!device)
+ return -EINVAL;
+
+ if (xdp_md->rx_queue_index >= device->real_num_rx_queues)
+ return -EINVAL;
+
+ rxqueue = __netif_get_rx_queue(device, xdp_md->rx_queue_index);
+ xdp->rxq = &rxqueue->xdp_rxq;
+ }
+
return 0;
}