On 6/16/21 3:47 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.
Let us match actual implementation.
EINVAL => -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 | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index f3054f25409c..0183fefd165c 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -690,15 +690,36 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
static int xdp_convert_md_to_buff(struct xdp_md *xdp_md, struct xdp_buff *xdp)
{
+ unsigned int ingress_ifindex;
+ unsigned int rx_queue_index;
nit: the above two definitions have the same type, let us merge them
into one line.
+ struct netdev_rx_queue *rxqueue;
+ struct net_device *device;
+
if (!xdp_md)
return 0;
if (xdp_md->egress_ifindex != 0)
return -EINVAL;
- if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0)
+ ingress_ifindex = xdp_md->ingress_ifindex;
+ rx_queue_index = xdp_md->rx_queue_index;
+
+ if (!ingress_ifindex && rx_queue_index)
return -EINVAL;
+ if (ingress_ifindex) {
+ device = dev_get_by_index(current->nsproxy->net_ns,
+ ingress_ifindex);
+ if (!device)
+ return -EINVAL;
+
+ if (rx_queue_index >= device->real_num_rx_queues)
+ return -EINVAL;
Does rx_queue_index = 0 is valid? I don't know whether it is valid
or not, just asking.
+
+ rxqueue = __netif_get_rx_queue(device, rx_queue_index);
+ xdp->rxq = &rxqueue->xdp_rxq;
+ }
+
xdp->data = xdp->data_meta + xdp_md->data;
return 0;