Commit 0d68e6fe authored by Maciej Fijalkowski's avatar Maciej Fijalkowski Committed by Daniel Borkmann

selftests/xsk: Query for native XDP support

Currently, xdpxceiver assumes that underlying device supports XDP in
native mode - it is fine by now since tests can run only on a veth pair.
Future commit is going to allow running test suite against physical
devices, so let us query the device if it is capable of running XDP
programs in native mode. This way xdpxceiver will not try to run
TEST_MODE_DRV if device being tested is not supporting it.
Signed-off-by: default avatarMaciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarMagnus Karlsson <magnus.karlsson@intel.com>
Link: https://lore.kernel.org/bpf/20220901114813.16275-2-maciej.fijalkowski@intel.com
parent 8cc61b7a
...@@ -99,6 +99,8 @@ ...@@ -99,6 +99,8 @@
#include <stdatomic.h> #include <stdatomic.h>
#include "xsk.h" #include "xsk.h"
#include "xskxceiver.h" #include "xskxceiver.h"
#include <bpf/bpf.h>
#include <linux/filter.h>
#include "../kselftest.h" #include "../kselftest.h"
/* AF_XDP APIs were moved into libxdp and marked as deprecated in libbpf. /* AF_XDP APIs were moved into libxdp and marked as deprecated in libbpf.
...@@ -1712,10 +1714,40 @@ static void ifobject_delete(struct ifobject *ifobj) ...@@ -1712,10 +1714,40 @@ static void ifobject_delete(struct ifobject *ifobj)
free(ifobj); free(ifobj);
} }
static bool is_xdp_supported(struct ifobject *ifobject)
{
int flags = XDP_FLAGS_DRV_MODE;
LIBBPF_OPTS(bpf_link_create_opts, opts, .flags = flags);
struct bpf_insn insns[2] = {
BPF_MOV64_IMM(BPF_REG_0, XDP_PASS),
BPF_EXIT_INSN()
};
int ifindex = if_nametoindex(ifobject->ifname);
int prog_fd, insn_cnt = ARRAY_SIZE(insns);
int err;
prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, NULL, "GPL", insns, insn_cnt, NULL);
if (prog_fd < 0)
return false;
err = bpf_xdp_attach(ifindex, prog_fd, flags, NULL);
if (err) {
close(prog_fd);
return false;
}
bpf_xdp_detach(ifindex, flags, NULL);
close(prog_fd);
return true;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct pkt_stream *pkt_stream_default; struct pkt_stream *pkt_stream_default;
struct ifobject *ifobj_tx, *ifobj_rx; struct ifobject *ifobj_tx, *ifobj_rx;
int modes = TEST_MODE_SKB + 1;
u32 i, j, failed_tests = 0; u32 i, j, failed_tests = 0;
struct test_spec test; struct test_spec test;
...@@ -1743,15 +1775,18 @@ int main(int argc, char **argv) ...@@ -1743,15 +1775,18 @@ int main(int argc, char **argv)
init_iface(ifobj_rx, MAC2, MAC1, IP2, IP1, UDP_PORT2, UDP_PORT1, init_iface(ifobj_rx, MAC2, MAC1, IP2, IP1, UDP_PORT2, UDP_PORT1,
worker_testapp_validate_rx); worker_testapp_validate_rx);
if (is_xdp_supported(ifobj_tx))
modes++;
test_spec_init(&test, ifobj_tx, ifobj_rx, 0); test_spec_init(&test, ifobj_tx, ifobj_rx, 0);
pkt_stream_default = pkt_stream_generate(ifobj_tx->umem, DEFAULT_PKT_CNT, PKT_SIZE); pkt_stream_default = pkt_stream_generate(ifobj_tx->umem, DEFAULT_PKT_CNT, PKT_SIZE);
if (!pkt_stream_default) if (!pkt_stream_default)
exit_with_error(ENOMEM); exit_with_error(ENOMEM);
test.pkt_stream_default = pkt_stream_default; test.pkt_stream_default = pkt_stream_default;
ksft_set_plan(TEST_MODE_MAX * TEST_TYPE_MAX); ksft_set_plan(modes * TEST_TYPE_MAX);
for (i = 0; i < TEST_MODE_MAX; i++) for (i = 0; i < modes; i++)
for (j = 0; j < TEST_TYPE_MAX; j++) { for (j = 0; j < TEST_TYPE_MAX; j++) {
test_spec_init(&test, ifobj_tx, ifobj_rx, i); test_spec_init(&test, ifobj_tx, ifobj_rx, i);
run_pkt_test(&test, i, j); run_pkt_test(&test, i, j);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment