Message ID | 20220610150923.583202-5-maciej.fijalkowski@intel.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | BPF |
Headers | show |
Series | AF_XDP ZC selftests | expand |
On Fri, Jun 10, 2022 at 5:15 PM Maciej Fijalkowski <maciej.fijalkowski@intel.com> wrote: > > 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: Maciej Fijalkowski <maciej.fijalkowski@intel.com> > --- > tools/testing/selftests/bpf/xdpxceiver.c | 38 ++++++++++++++++++++++-- > 1 file changed, 36 insertions(+), 2 deletions(-) > > diff --git a/tools/testing/selftests/bpf/xdpxceiver.c b/tools/testing/selftests/bpf/xdpxceiver.c > index e5992a6b5e09..da8098f1b655 100644 > --- a/tools/testing/selftests/bpf/xdpxceiver.c > +++ b/tools/testing/selftests/bpf/xdpxceiver.c > @@ -98,6 +98,8 @@ > #include <unistd.h> > #include <stdatomic.h> > #include <bpf/xsk.h> > +#include <bpf/bpf.h> > +#include <linux/filter.h> > #include "xdpxceiver.h" > #include "../kselftest.h" > > @@ -1605,10 +1607,39 @@ static void ifobject_delete(struct ifobject *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); > + bool ret = false; > + int err; > + > + prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, NULL, "GPL", insns, insn_cnt, NULL); > + if (prog_fd < 0) > + return ret; > + > + err = bpf_xdp_attach(ifindex, prog_fd, flags, NULL); > + > + if (!err) { > + ret = true; > + bpf_xdp_detach(ifindex, flags, NULL); > + } > + > + return ret; Think it would be clearer if you got rid of the bool ret and just wrote "return false" and "return true" where applicable. > +} > + > int main(int argc, char **argv) > { > struct pkt_stream *pkt_stream_default; > struct ifobject *ifobj_tx, *ifobj_rx; > + int modes = TEST_MODE_SKB + 1; Why not keep it a u32? A nit in any way. > u32 i, j, failed_tests = 0; > struct test_spec test; > > @@ -1636,15 +1667,18 @@ int main(int argc, char **argv) > init_iface(ifobj_rx, MAC2, MAC1, IP2, IP1, UDP_PORT2, UDP_PORT1, > worker_testapp_validate_rx); > > + if (is_xdp_supported(ifobj_tx)) > + modes++; > + > test_spec_init(&test, ifobj_tx, ifobj_rx, 0); > pkt_stream_default = pkt_stream_generate(ifobj_tx->umem, DEFAULT_PKT_CNT, PKT_SIZE); > if (!pkt_stream_default) > exit_with_error(ENOMEM); > 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++) { > test_spec_init(&test, ifobj_tx, ifobj_rx, i); > run_pkt_test(&test, i, j); > -- > 2.27.0 >
diff --git a/tools/testing/selftests/bpf/xdpxceiver.c b/tools/testing/selftests/bpf/xdpxceiver.c index e5992a6b5e09..da8098f1b655 100644 --- a/tools/testing/selftests/bpf/xdpxceiver.c +++ b/tools/testing/selftests/bpf/xdpxceiver.c @@ -98,6 +98,8 @@ #include <unistd.h> #include <stdatomic.h> #include <bpf/xsk.h> +#include <bpf/bpf.h> +#include <linux/filter.h> #include "xdpxceiver.h" #include "../kselftest.h" @@ -1605,10 +1607,39 @@ static void ifobject_delete(struct ifobject *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); + bool ret = false; + int err; + + prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, NULL, "GPL", insns, insn_cnt, NULL); + if (prog_fd < 0) + return ret; + + err = bpf_xdp_attach(ifindex, prog_fd, flags, NULL); + + if (!err) { + ret = true; + bpf_xdp_detach(ifindex, flags, NULL); + } + + return ret; +} + int main(int argc, char **argv) { struct pkt_stream *pkt_stream_default; struct ifobject *ifobj_tx, *ifobj_rx; + int modes = TEST_MODE_SKB + 1; u32 i, j, failed_tests = 0; struct test_spec test; @@ -1636,15 +1667,18 @@ int main(int argc, char **argv) init_iface(ifobj_rx, MAC2, MAC1, IP2, IP1, UDP_PORT2, UDP_PORT1, worker_testapp_validate_rx); + if (is_xdp_supported(ifobj_tx)) + modes++; + test_spec_init(&test, ifobj_tx, ifobj_rx, 0); pkt_stream_default = pkt_stream_generate(ifobj_tx->umem, DEFAULT_PKT_CNT, PKT_SIZE); if (!pkt_stream_default) exit_with_error(ENOMEM); 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++) { test_spec_init(&test, ifobj_tx, ifobj_rx, i); run_pkt_test(&test, i, j);
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: Maciej Fijalkowski <maciej.fijalkowski@intel.com> --- tools/testing/selftests/bpf/xdpxceiver.c | 38 ++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-)