diff mbox series

[bpf-next,v2,5/5] selftests/bpf: xsk selftests - Bi-directional Sockets - SKB, DRV

Message ID 20201120130026.19029-6-weqaar.a.janjua@intel.com
State New
Headers show
Series selftests/bpf: xsk selftests | expand

Commit Message

Weqaar Janjua Nov. 20, 2020, 1 p.m. UTC
Adds following tests:

1. AF_XDP SKB mode
   d. Bi-directional Sockets
      Configure sockets as bi-directional tx/rx sockets, sets up fill
      and completion rings on each socket, tx/rx in both directions.
      Only nopoll mode is used

2. AF_XDP DRV/Native mode
   d. Bi-directional Sockets
   * Only copy mode is supported because veth does not currently support
     zero-copy mode

Signed-off-by: Weqaar Janjua <weqaar.a.janjua@intel.com>
---
 tools/testing/selftests/bpf/Makefile          |   4 +-
 .../bpf/test_xsk_drv_bidirectional.sh         |  23 ++++
 .../selftests/bpf/test_xsk_drv_teardown.sh    |   3 -
 .../bpf/test_xsk_skb_bidirectional.sh         |  20 ++++
 tools/testing/selftests/bpf/xdpxceiver.c      | 100 +++++++++++++-----
 tools/testing/selftests/bpf/xdpxceiver.h      |   4 +
 6 files changed, 126 insertions(+), 28 deletions(-)
 create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
 create mode 100755 tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh

Comments

Yonghong Song Nov. 20, 2020, 8:45 p.m. UTC | #1
On 11/20/20 5:00 AM, Weqaar Janjua wrote:
> Adds following tests:
> 
> 1. AF_XDP SKB mode
>     d. Bi-directional Sockets
>        Configure sockets as bi-directional tx/rx sockets, sets up fill
>        and completion rings on each socket, tx/rx in both directions.
>        Only nopoll mode is used
> 
> 2. AF_XDP DRV/Native mode
>     d. Bi-directional Sockets
>     * Only copy mode is supported because veth does not currently support
>       zero-copy mode
> 
> Signed-off-by: Weqaar Janjua <weqaar.a.janjua@intel.com>
> ---
>   tools/testing/selftests/bpf/Makefile          |   4 +-
>   .../bpf/test_xsk_drv_bidirectional.sh         |  23 ++++
>   .../selftests/bpf/test_xsk_drv_teardown.sh    |   3 -
>   .../bpf/test_xsk_skb_bidirectional.sh         |  20 ++++
>   tools/testing/selftests/bpf/xdpxceiver.c      | 100 +++++++++++++-----
>   tools/testing/selftests/bpf/xdpxceiver.h      |   4 +
>   6 files changed, 126 insertions(+), 28 deletions(-)
>   create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
>   create mode 100755 tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh
> 
> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> index 515b29d321d7..258bd72812e0 100644
> --- a/tools/testing/selftests/bpf/Makefile
> +++ b/tools/testing/selftests/bpf/Makefile
> @@ -78,7 +78,9 @@ TEST_PROGS := test_kmod.sh \
>   	test_xsk_drv_nopoll.sh \
>   	test_xsk_drv_poll.sh \
>   	test_xsk_skb_teardown.sh \
> -	test_xsk_drv_teardown.sh
> +	test_xsk_drv_teardown.sh \
> +	test_xsk_skb_bidirectional.sh \
> +	test_xsk_drv_bidirectional.sh
>   
>   TEST_PROGS_EXTENDED := with_addr.sh \
>   	with_tunnels.sh \
> diff --git a/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
> new file mode 100755
> index 000000000000..d3a7e2934d83
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
> @@ -0,0 +1,23 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright(c) 2020 Intel Corporation.
> +
> +# See test_xsk_prerequisites.sh for detailed information on tests
> +
> +. xsk_prereqs.sh
> +. xsk_env.sh
> +
> +TEST_NAME="DRV BIDIRECTIONAL SOCKETS"
> +
> +vethXDPnative ${VETH0} ${VETH1} ${NS1}
> +
> +params=("-N" "-B")
> +execxdpxceiver params
> +
> +retval=$?
> +test_status $retval "${TEST_NAME}"
> +
> +# Must be called in the last test to execute
> +cleanup_exit ${VETH0} ${VETH1} ${NS1}

This also makes hard to run tests as users will not know this unless 
they are familiar with the details of the tests.

How about you have another scripts test_xsk.sh which includes all these 
individual tests and pull the above cleanup_exit into test_xsk.sh?
User just need to run test_xsk.sh will be able to run all tests you
implemented here.

> +
> +test_exit $retval 0
> diff --git a/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh
[...]
Weqaar Janjua Nov. 21, 2020, 8:14 p.m. UTC | #2
On Fri, 20 Nov 2020 at 20:45, Yonghong Song <yhs@fb.com> wrote:
>
>
>
> On 11/20/20 5:00 AM, Weqaar Janjua wrote:
> > Adds following tests:
> >
> > 1. AF_XDP SKB mode
> >     d. Bi-directional Sockets
> >        Configure sockets as bi-directional tx/rx sockets, sets up fill
> >        and completion rings on each socket, tx/rx in both directions.
> >        Only nopoll mode is used
> >
> > 2. AF_XDP DRV/Native mode
> >     d. Bi-directional Sockets
> >     * Only copy mode is supported because veth does not currently support
> >       zero-copy mode
> >
> > Signed-off-by: Weqaar Janjua <weqaar.a.janjua@intel.com>
> > ---
> >   tools/testing/selftests/bpf/Makefile          |   4 +-
> >   .../bpf/test_xsk_drv_bidirectional.sh         |  23 ++++
> >   .../selftests/bpf/test_xsk_drv_teardown.sh    |   3 -
> >   .../bpf/test_xsk_skb_bidirectional.sh         |  20 ++++
> >   tools/testing/selftests/bpf/xdpxceiver.c      | 100 +++++++++++++-----
> >   tools/testing/selftests/bpf/xdpxceiver.h      |   4 +
> >   6 files changed, 126 insertions(+), 28 deletions(-)
> >   create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
> >   create mode 100755 tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh
> >
> > diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> > index 515b29d321d7..258bd72812e0 100644
> > --- a/tools/testing/selftests/bpf/Makefile
> > +++ b/tools/testing/selftests/bpf/Makefile
> > @@ -78,7 +78,9 @@ TEST_PROGS := test_kmod.sh \
> >       test_xsk_drv_nopoll.sh \
> >       test_xsk_drv_poll.sh \
> >       test_xsk_skb_teardown.sh \
> > -     test_xsk_drv_teardown.sh
> > +     test_xsk_drv_teardown.sh \
> > +     test_xsk_skb_bidirectional.sh \
> > +     test_xsk_drv_bidirectional.sh
> >
> >   TEST_PROGS_EXTENDED := with_addr.sh \
> >       with_tunnels.sh \
> > diff --git a/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
> > new file mode 100755
> > index 000000000000..d3a7e2934d83
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
> > @@ -0,0 +1,23 @@
> > +#!/bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright(c) 2020 Intel Corporation.
> > +
> > +# See test_xsk_prerequisites.sh for detailed information on tests
> > +
> > +. xsk_prereqs.sh
> > +. xsk_env.sh
> > +
> > +TEST_NAME="DRV BIDIRECTIONAL SOCKETS"
> > +
> > +vethXDPnative ${VETH0} ${VETH1} ${NS1}
> > +
> > +params=("-N" "-B")
> > +execxdpxceiver params
> > +
> > +retval=$?
> > +test_status $retval "${TEST_NAME}"
> > +
> > +# Must be called in the last test to execute
> > +cleanup_exit ${VETH0} ${VETH1} ${NS1}
>
> This also makes hard to run tests as users will not know this unless
> they are familiar with the details of the tests.
>
> How about you have another scripts test_xsk.sh which includes all these
> individual tests and pull the above cleanup_exit into test_xsk.sh?
> User just need to run test_xsk.sh will be able to run all tests you
> implemented here.
>
This works, test_xsk_* >> test_xsk.sh, will ship out as v3.

> > +
> > +test_exit $retval 0
> > diff --git a/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh
> [...]
Weqaar Janjua Nov. 24, 2020, 3:11 p.m. UTC | #3
On Sat, 21 Nov 2020 at 20:14, Weqaar Janjua <weqaar.janjua@gmail.com> wrote:
>

> On Fri, 20 Nov 2020 at 20:45, Yonghong Song <yhs@fb.com> wrote:

> >

> >

> >

> > On 11/20/20 5:00 AM, Weqaar Janjua wrote:

> > > Adds following tests:

> > >

> > > 1. AF_XDP SKB mode

> > >     d. Bi-directional Sockets

> > >        Configure sockets as bi-directional tx/rx sockets, sets up fill

> > >        and completion rings on each socket, tx/rx in both directions.

> > >        Only nopoll mode is used

> > >

> > > 2. AF_XDP DRV/Native mode

> > >     d. Bi-directional Sockets

> > >     * Only copy mode is supported because veth does not currently support

> > >       zero-copy mode

> > >

> > > Signed-off-by: Weqaar Janjua <weqaar.a.janjua@intel.com>

> > > ---

> > >   tools/testing/selftests/bpf/Makefile          |   4 +-

> > >   .../bpf/test_xsk_drv_bidirectional.sh         |  23 ++++

> > >   .../selftests/bpf/test_xsk_drv_teardown.sh    |   3 -

> > >   .../bpf/test_xsk_skb_bidirectional.sh         |  20 ++++

> > >   tools/testing/selftests/bpf/xdpxceiver.c      | 100 +++++++++++++-----

> > >   tools/testing/selftests/bpf/xdpxceiver.h      |   4 +

> > >   6 files changed, 126 insertions(+), 28 deletions(-)

> > >   create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh

> > >   create mode 100755 tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh

> > >

> > > diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile

> > > index 515b29d321d7..258bd72812e0 100644

> > > --- a/tools/testing/selftests/bpf/Makefile

> > > +++ b/tools/testing/selftests/bpf/Makefile

> > > @@ -78,7 +78,9 @@ TEST_PROGS := test_kmod.sh \

> > >       test_xsk_drv_nopoll.sh \

> > >       test_xsk_drv_poll.sh \

> > >       test_xsk_skb_teardown.sh \

> > > -     test_xsk_drv_teardown.sh

> > > +     test_xsk_drv_teardown.sh \

> > > +     test_xsk_skb_bidirectional.sh \

> > > +     test_xsk_drv_bidirectional.sh

> > >

> > >   TEST_PROGS_EXTENDED := with_addr.sh \

> > >       with_tunnels.sh \

> > > diff --git a/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh

> > > new file mode 100755

> > > index 000000000000..d3a7e2934d83

> > > --- /dev/null

> > > +++ b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh

> > > @@ -0,0 +1,23 @@

> > > +#!/bin/bash

> > > +# SPDX-License-Identifier: GPL-2.0

> > > +# Copyright(c) 2020 Intel Corporation.

> > > +

> > > +# See test_xsk_prerequisites.sh for detailed information on tests

> > > +

> > > +. xsk_prereqs.sh

> > > +. xsk_env.sh

> > > +

> > > +TEST_NAME="DRV BIDIRECTIONAL SOCKETS"

> > > +

> > > +vethXDPnative ${VETH0} ${VETH1} ${NS1}

> > > +

> > > +params=("-N" "-B")

> > > +execxdpxceiver params

> > > +

> > > +retval=$?

> > > +test_status $retval "${TEST_NAME}"

> > > +

> > > +# Must be called in the last test to execute

> > > +cleanup_exit ${VETH0} ${VETH1} ${NS1}

> >

> > This also makes hard to run tests as users will not know this unless

> > they are familiar with the details of the tests.

> >

> > How about you have another scripts test_xsk.sh which includes all these

> > individual tests and pull the above cleanup_exit into test_xsk.sh?

> > User just need to run test_xsk.sh will be able to run all tests you

> > implemented here.

> >

> This works, test_xsk_* >> test_xsk.sh, will ship out as v3.

>

An issue with merging all tests in a single test_xsk.sh is reporting
number of test failures, with this approach a single test status is
printed by kselftest:

# PREREQUISITES: [ PASS ]
# SKB NOPOLL: [ FAIL ]
# SKB POLL: [ PASS ]
ok 1 selftests: xsk-patch2: test_xsk.sh

This is due to the fact Makefile has one TEST_PROGS = test_xsk.sh
(thus kselftest considers it one test?), where in the original
approach all tests have separate TEST_PROGS .sh which makes reporting
match each test and status. This can be a problem for automation.

An alternative would be to exit each test with failure status but then
the tests will stop execution at the failed test without executing the
rest of xsk tests, which we probably wouldn't want.

Suggestions please?

> > > +

> > > +test_exit $retval 0

> > > diff --git a/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh

> > [...]
Weqaar Janjua Nov. 24, 2020, 10:28 p.m. UTC | #4
On Tue, 24 Nov 2020 at 17:10, Yonghong Song <yhs@fb.com> wrote:
>
>
>
> On 11/24/20 7:11 AM, Weqaar Janjua wrote:
> > On Sat, 21 Nov 2020 at 20:14, Weqaar Janjua <weqaar.janjua@gmail.com> wrote:
> >>
> >> On Fri, 20 Nov 2020 at 20:45, Yonghong Song <yhs@fb.com> wrote:
> >>>
> >>>
> >>>
> >>> On 11/20/20 5:00 AM, Weqaar Janjua wrote:
> >>>> Adds following tests:
> >>>>
> >>>> 1. AF_XDP SKB mode
> >>>>      d. Bi-directional Sockets
> >>>>         Configure sockets as bi-directional tx/rx sockets, sets up fill
> >>>>         and completion rings on each socket, tx/rx in both directions.
> >>>>         Only nopoll mode is used
> >>>>
> >>>> 2. AF_XDP DRV/Native mode
> >>>>      d. Bi-directional Sockets
> >>>>      * Only copy mode is supported because veth does not currently support
> >>>>        zero-copy mode
> >>>>
> >>>> Signed-off-by: Weqaar Janjua <weqaar.a.janjua@intel.com>
> >>>> ---
> >>>>    tools/testing/selftests/bpf/Makefile          |   4 +-
> >>>>    .../bpf/test_xsk_drv_bidirectional.sh         |  23 ++++
> >>>>    .../selftests/bpf/test_xsk_drv_teardown.sh    |   3 -
> >>>>    .../bpf/test_xsk_skb_bidirectional.sh         |  20 ++++
> >>>>    tools/testing/selftests/bpf/xdpxceiver.c      | 100 +++++++++++++-----
> >>>>    tools/testing/selftests/bpf/xdpxceiver.h      |   4 +
> >>>>    6 files changed, 126 insertions(+), 28 deletions(-)
> >>>>    create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
> >>>>    create mode 100755 tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh
> >>>>
> >>>> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> >>>> index 515b29d321d7..258bd72812e0 100644
> >>>> --- a/tools/testing/selftests/bpf/Makefile
> >>>> +++ b/tools/testing/selftests/bpf/Makefile
> >>>> @@ -78,7 +78,9 @@ TEST_PROGS := test_kmod.sh \
> >>>>        test_xsk_drv_nopoll.sh \
> >>>>        test_xsk_drv_poll.sh \
> >>>>        test_xsk_skb_teardown.sh \
> >>>> -     test_xsk_drv_teardown.sh
> >>>> +     test_xsk_drv_teardown.sh \
> >>>> +     test_xsk_skb_bidirectional.sh \
> >>>> +     test_xsk_drv_bidirectional.sh
> >>>>
> >>>>    TEST_PROGS_EXTENDED := with_addr.sh \
> >>>>        with_tunnels.sh \
> >>>> diff --git a/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
> >>>> new file mode 100755
> >>>> index 000000000000..d3a7e2934d83
> >>>> --- /dev/null
> >>>> +++ b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
> >>>> @@ -0,0 +1,23 @@
> >>>> +#!/bin/bash
> >>>> +# SPDX-License-Identifier: GPL-2.0
> >>>> +# Copyright(c) 2020 Intel Corporation.
> >>>> +
> >>>> +# See test_xsk_prerequisites.sh for detailed information on tests
> >>>> +
> >>>> +. xsk_prereqs.sh
> >>>> +. xsk_env.sh
> >>>> +
> >>>> +TEST_NAME="DRV BIDIRECTIONAL SOCKETS"
> >>>> +
> >>>> +vethXDPnative ${VETH0} ${VETH1} ${NS1}
> >>>> +
> >>>> +params=("-N" "-B")
> >>>> +execxdpxceiver params
> >>>> +
> >>>> +retval=$?
> >>>> +test_status $retval "${TEST_NAME}"
> >>>> +
> >>>> +# Must be called in the last test to execute
> >>>> +cleanup_exit ${VETH0} ${VETH1} ${NS1}
> >>>
> >>> This also makes hard to run tests as users will not know this unless
> >>> they are familiar with the details of the tests.
> >>>
> >>> How about you have another scripts test_xsk.sh which includes all these
> >>> individual tests and pull the above cleanup_exit into test_xsk.sh?
> >>> User just need to run test_xsk.sh will be able to run all tests you
> >>> implemented here.
> >>>
> >> This works, test_xsk_* >> test_xsk.sh, will ship out as v3.
> >>
> > An issue with merging all tests in a single test_xsk.sh is reporting
> > number of test failures, with this approach a single test status is
> > printed by kselftest:
> >
> > # PREREQUISITES: [ PASS ]
> > # SKB NOPOLL: [ FAIL ]
> > # SKB POLL: [ PASS ]
> > ok 1 selftests: xsk-patch2: test_xsk.sh
> >
> > This is due to the fact Makefile has one TEST_PROGS = test_xsk.sh
> > (thus kselftest considers it one test?), where in the original
> > approach all tests have separate TEST_PROGS .sh which makes reporting
> > match each test and status. This can be a problem for automation.
> >
> > An alternative would be to exit each test with failure status but then
> > the tests will stop execution at the failed test without executing the
> > rest of xsk tests, which we probably wouldn't want.
> >
> > Suggestions please?
>
> I think it is okay to put everything xsk related to one test.
> If later on the test becomes more complex, you can have
> test_xsk_<1>.sh test_xsk_<2>.sh etc. But each .sh should be able to
> run independently without any particular order.
>
> You can have subtests inside the .sh file. See test_offload.py as
> an example. You do not need to exit after one subtest fails, you can
> continue to run the next one. currently test_offload.py
> may exit when some subtest failed, but I think you don't have to.
>
ACK, I will go ahead and merge all test_xsk_*.sh into test_xsk.sh.

Just to clarify that all current xsk tests are independent, there is
no subtest at present, and do not need to run in any order.

Thanks,
/Weqaar

> >
> >>>> +
> >>>> +test_exit $retval 0
> >>>> diff --git a/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh
> >>> [...]
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 515b29d321d7..258bd72812e0 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -78,7 +78,9 @@  TEST_PROGS := test_kmod.sh \
 	test_xsk_drv_nopoll.sh \
 	test_xsk_drv_poll.sh \
 	test_xsk_skb_teardown.sh \
-	test_xsk_drv_teardown.sh
+	test_xsk_drv_teardown.sh \
+	test_xsk_skb_bidirectional.sh \
+	test_xsk_drv_bidirectional.sh
 
 TEST_PROGS_EXTENDED := with_addr.sh \
 	with_tunnels.sh \
diff --git a/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
new file mode 100755
index 000000000000..d3a7e2934d83
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh
@@ -0,0 +1,23 @@ 
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2020 Intel Corporation.
+
+# See test_xsk_prerequisites.sh for detailed information on tests
+
+. xsk_prereqs.sh
+. xsk_env.sh
+
+TEST_NAME="DRV BIDIRECTIONAL SOCKETS"
+
+vethXDPnative ${VETH0} ${VETH1} ${NS1}
+
+params=("-N" "-B")
+execxdpxceiver params
+
+retval=$?
+test_status $retval "${TEST_NAME}"
+
+# Must be called in the last test to execute
+cleanup_exit ${VETH0} ${VETH1} ${NS1}
+
+test_exit $retval 0
diff --git a/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh
index 28bf730b589e..7f11033747ac 100755
--- a/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh
+++ b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh
@@ -17,7 +17,4 @@  execxdpxceiver params
 retval=$?
 test_status $retval "${TEST_NAME}"
 
-# Must be called in the last test to execute
-cleanup_exit ${VETH0} ${VETH1} ${NS1}
-
 test_exit $retval 0
diff --git a/tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh b/tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh
new file mode 100755
index 000000000000..8ae1b6694f02
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh
@@ -0,0 +1,20 @@ 
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2020 Intel Corporation.
+
+# See test_xsk_prerequisites.sh for detailed information on tests
+
+. xsk_prereqs.sh
+. xsk_env.sh
+
+TEST_NAME="SKB BIDIRECTIONAL SOCKETS"
+
+vethXDPgeneric ${VETH0} ${VETH1} ${NS1}
+
+params=("-S" "-B")
+execxdpxceiver params
+
+retval=$?
+test_status $retval "${TEST_NAME}"
+
+test_exit $retval 0
diff --git a/tools/testing/selftests/bpf/xdpxceiver.c b/tools/testing/selftests/bpf/xdpxceiver.c
index ba5de1ef9f64..277d9344ce34 100644
--- a/tools/testing/selftests/bpf/xdpxceiver.c
+++ b/tools/testing/selftests/bpf/xdpxceiver.c
@@ -29,6 +29,10 @@ 
  *    c. Socket Teardown
  *       Create a Tx and a Rx socket, Tx from one socket, Rx on another. Destroy
  *       both sockets, then repeat multiple times. Only nopoll mode is used
+ *    d. Bi-directional sockets
+ *       Configure sockets as bi-directional tx/rx sockets, sets up fill and
+ *       completion rings on each socket, tx/rx in both directions. Only nopoll
+ *       mode is used
  *
  * 2. AF_XDP DRV/Native mode
  *    Works on any netdevice with XDP_REDIRECT support, driver dependent. Processes
@@ -37,10 +41,11 @@ 
  *    a. nopoll
  *    b. poll
  *    c. Socket Teardown
+ *    d. Bi-directional sockets
  *    - Only copy mode is supported because veth does not currently support
  *      zero-copy mode
  *
- * Total tests: 6
+ * Total tests: 8
  *
  * Flow:
  * -----
@@ -100,8 +105,9 @@  static void __exit_with_error(int error, const char *file, const char *func, int
 #define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, __LINE__)
 
 #define print_ksft_result(void)\
-	(ksft_test_result_pass("PASS: %s %s %s\n", uut ? "DRV" : "SKB", opt_poll ? "POLL" :\
-			       "NOPOLL", opt_teardown ? "Socket Teardown" : ""))
+	(ksft_test_result_pass("PASS: %s %s %s%s\n", uut ? "DRV" : "SKB", opt_poll ? "POLL" :\
+			       "NOPOLL", opt_teardown ? "Socket Teardown" : "",\
+			       opt_bidi ? "Bi-directional Sockets" : ""))
 
 static void pthread_init_mutex(void)
 {
@@ -307,8 +313,13 @@  static int xsk_configure_socket(struct ifobject *ifobject)
 	cfg.xdp_flags = opt_xdp_flags;
 	cfg.bind_flags = opt_xdp_bind_flags;
 
-	rxr = (ifobject->fv.vector == rx) ? &ifobject->xsk->rx : NULL;
-	txr = (ifobject->fv.vector == tx) ? &ifobject->xsk->tx : NULL;
+	if (!opt_bidi) {
+		rxr = (ifobject->fv.vector == rx) ? &ifobject->xsk->rx : NULL;
+		txr = (ifobject->fv.vector == tx) ? &ifobject->xsk->tx : NULL;
+	} else {
+		rxr = &ifobject->xsk->rx;
+		txr = &ifobject->xsk->tx;
+	}
 
 	ret = xsk_socket__create(&ifobject->xsk->xsk, ifobject->ifname,
 				 opt_queue, ifobject->umem->umem, rxr, txr, &cfg);
@@ -327,6 +338,7 @@  static struct option long_options[] = {
 	{"xdp-native", no_argument, 0, 'N'},
 	{"copy", no_argument, 0, 'c'},
 	{"tear-down", no_argument, 0, 'T'},
+	{"bidi", optional_argument, 0, 'B'},
 	{"debug", optional_argument, 0, 'D'},
 	{"tx-pkt-count", optional_argument, 0, 'C'},
 	{0, 0, 0, 0}
@@ -344,6 +356,7 @@  static void usage(const char *prog)
 	    "  -N, --xdp-native=n   Enforce XDP DRV (native) mode\n"
 	    "  -c, --copy           Force copy mode\n"
 	    "  -T, --tear-down      Tear down sockets by repeatedly recreating them\n"
+	    "  -B, --bidi           Bi-directional sockets test\n"
 	    "  -D, --debug          Debug mode - dump packets L2 - L5\n"
 	    "  -C, --tx-pkt-count=n Number of packets to send\n";
 	ksft_print_msg(str, prog);
@@ -434,7 +447,7 @@  static void parse_command_line(int argc, char **argv)
 	opterr = 0;
 
 	for (;;) {
-		c = getopt_long(argc, argv, "i:q:pSNcTDC:", long_options, &option_index);
+		c = getopt_long(argc, argv, "i:q:pSNcTBDC:", long_options, &option_index);
 
 		if (c == -1)
 			break;
@@ -475,6 +488,9 @@  static void parse_command_line(int argc, char **argv)
 		case 'T':
 			opt_teardown = 1;
 			break;
+		case 'B':
+			opt_bidi = 1;
+			break;
 		case 'D':
 			debug_pkt_dump = 1;
 			break;
@@ -784,22 +800,25 @@  static void *worker_testapp_validate(void *arg)
 	struct generic_data *data = (struct generic_data *)malloc(sizeof(struct generic_data));
 	struct iphdr *ip_hdr = (struct iphdr *)(pkt_data + sizeof(struct ethhdr));
 	struct ethhdr *eth_hdr = (struct ethhdr *)pkt_data;
-	void *bufs;
+	void *bufs = NULL;
 
 	pthread_attr_setstacksize(&attr, THREAD_STACK);
 
-	bufs = mmap(NULL, num_frames * XSK_UMEM__DEFAULT_FRAME_SIZE,
-		    PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-	if (bufs == MAP_FAILED)
-		exit_with_error(errno);
+	if (!bidi_pass) {
+		bufs = mmap(NULL, num_frames * XSK_UMEM__DEFAULT_FRAME_SIZE,
+			    PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+		if (bufs == MAP_FAILED)
+			exit_with_error(errno);
 
-	if (strcmp(((struct ifobject *)arg)->nsname, ""))
-		switch_namespace(((struct ifobject *)arg)->ifdict_index);
+		if (strcmp(((struct ifobject *)arg)->nsname, ""))
+			switch_namespace(((struct ifobject *)arg)->ifdict_index);
+	}
 
 	if (((struct ifobject *)arg)->fv.vector == tx) {
 		int spinningrxctr = 0;
 
-		thread_common_ops(arg, bufs, &sync_mutex_tx, &spinning_tx);
+		if (!bidi_pass)
+			thread_common_ops(arg, bufs, &sync_mutex_tx, &spinning_tx);
 
 		while (atomic_load(&spinning_rx) && spinningrxctr < SOCK_RECONF_CTR) {
 			spinningrxctr++;
@@ -829,7 +848,8 @@  static void *worker_testapp_validate(void *arg)
 		struct pollfd fds[MAX_SOCKS] = { };
 		int ret;
 
-		thread_common_ops(arg, bufs, &sync_mutex_tx, &spinning_rx);
+		if (!bidi_pass)
+			thread_common_ops(arg, bufs, &sync_mutex_tx, &spinning_rx);
 
 		ksft_print_msg("Interface [%s] vector [Rx]\n", ((struct ifobject *)arg)->ifname);
 		xsk_populate_fill_ring(((struct ifobject *)arg)->umem);
@@ -868,8 +888,10 @@  static void *worker_testapp_validate(void *arg)
 			ksft_print_msg("Destroying socket\n");
 	}
 
-	xsk_socket__delete(((struct ifobject *)arg)->xsk->xsk);
-	(void)xsk_umem__delete(((struct ifobject *)arg)->umem->umem);
+	if (!opt_bidi || (opt_bidi && bidi_pass)) {
+		xsk_socket__delete(((struct ifobject *)arg)->xsk->xsk);
+		(void)xsk_umem__delete(((struct ifobject *)arg)->umem->umem);
+	}
 	pthread_exit(NULL);
 }
 
@@ -878,11 +900,26 @@  static void testapp_validate(void)
 	pthread_attr_init(&attr);
 	pthread_attr_setstacksize(&attr, THREAD_STACK);
 
+	if (opt_bidi && bidi_pass) {
+		pthread_init_mutex();
+		if (!switching_notify) {
+			ksft_print_msg("Switching Tx/Rx vectors\n");
+			switching_notify++;
+		}
+	}
+
 	pthread_mutex_lock(&sync_mutex);
 
 	/*Spawn RX thread */
-	if (pthread_create(&t0, &attr, worker_testapp_validate, (void *)ifdict[1]))
-		exit_with_error(errno);
+	if (!opt_bidi || (opt_bidi && !bidi_pass)) {
+		if (pthread_create(&t0, &attr, worker_testapp_validate, (void *)ifdict[1]))
+			exit_with_error(errno);
+	} else if (opt_bidi && bidi_pass) {
+		/*switch Tx/Rx vectors */
+		ifdict[0]->fv.vector = rx;
+		if (pthread_create(&t0, &attr, worker_testapp_validate, (void *)ifdict[0]))
+			exit_with_error(errno);
+	}
 
 	struct timespec max_wait = { 0, 0 };
 
@@ -896,8 +933,15 @@  static void testapp_validate(void)
 	pthread_mutex_unlock(&sync_mutex);
 
 	/*Spawn TX thread */
-	if (pthread_create(&t1, &attr, worker_testapp_validate, (void *)ifdict[0]))
-		exit_with_error(errno);
+	if (!opt_bidi || (opt_bidi && !bidi_pass)) {
+		if (pthread_create(&t1, &attr, worker_testapp_validate, (void *)ifdict[0]))
+			exit_with_error(errno);
+	} else if (opt_bidi && bidi_pass) {
+		/*switch Tx/Rx vectors */
+		ifdict[1]->fv.vector = tx;
+		if (pthread_create(&t1, &attr, worker_testapp_validate, (void *)ifdict[1]))
+			exit_with_error(errno);
+	}
 
 	pthread_join(t1, NULL);
 	pthread_join(t0, NULL);
@@ -911,18 +955,19 @@  static void testapp_validate(void)
 		free(pkt_buf);
 	}
 
-	if (!opt_teardown)
+	if (!opt_teardown && !opt_bidi)
 		print_ksft_result();
 }
 
 static void testapp_sockets(void)
 {
-	for (int i = 0; i < MAX_TEARDOWN_ITER; i++) {
+	for (int i = 0; i < (opt_teardown ? MAX_TEARDOWN_ITER : MAX_BIDI_ITER); i++) {
 		pkt_counter = 0;
 		prev_pkt = -1;
 		sigvar = 0;
 		ksft_print_msg("Creating socket\n");
 		testapp_validate();
+		opt_bidi ? bidi_pass++ : bidi_pass;
 	}
 
 	print_ksft_result();
@@ -991,7 +1036,14 @@  int main(int argc, char **argv)
 
 	ksft_set_plan(1);
 
-	opt_teardown ? testapp_sockets() : testapp_validate();
+	if (!opt_teardown && !opt_bidi) {
+		testapp_validate();
+	} else if (opt_teardown && opt_bidi) {
+		ksft_test_result_fail("ERROR: parameters -T and -B cannot be used together\n");
+		ksft_exit_xfail();
+	} else {
+		testapp_sockets();
+	}
 
 	for (int i = 0; i < MAX_INTERFACES; i++)
 		free(ifdict[i]);
diff --git a/tools/testing/selftests/bpf/xdpxceiver.h b/tools/testing/selftests/bpf/xdpxceiver.h
index 9d2670f28d86..d6630a19140b 100644
--- a/tools/testing/selftests/bpf/xdpxceiver.h
+++ b/tools/testing/selftests/bpf/xdpxceiver.h
@@ -22,6 +22,7 @@ 
 #define MAX_INTERFACES_NAMESPACE_CHARS 10
 #define MAX_SOCKS 1
 #define MAX_TEARDOWN_ITER 10
+#define MAX_BIDI_ITER 2
 #define PKT_HDR_SIZE (sizeof(struct ethhdr) + sizeof(struct iphdr) + \
 			sizeof(struct udphdr))
 #define MIN_PKT_SIZE 64
@@ -51,12 +52,15 @@  enum TESTS {
 u8 uut;
 u8 debug_pkt_dump;
 u32 num_frames;
+u8 switching_notify;
+u8 bidi_pass;
 
 static u32 opt_xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
 static int opt_queue;
 static int opt_pkt_count;
 static int opt_poll;
 static int opt_teardown;
+static int opt_bidi;
 static u32 opt_xdp_bind_flags = XDP_USE_NEED_WAKEUP;
 static u8 pkt_data[XSK_UMEM__DEFAULT_FRAME_SIZE];
 static u32 pkt_counter;