The test script is provided by Kuniyuki in [1], which is used to test the
selection of the TCP reuseport socket problem.
Link: https://lore.kernel.org/netdev/20250801040757.1599996-1-kuniyu@google.com/ [1]
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
tools/testing/selftests/net/Makefile | 1 +
tools/testing/selftests/net/tcp_reuseport.py | 36 ++++++++++++++++++++
2 files changed, 37 insertions(+)
create mode 100755 tools/testing/selftests/net/tcp_reuseport.py
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index b31a71f2b372..0f4c3eea9709 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -117,6 +117,7 @@ TEST_GEN_FILES += tfo
TEST_PROGS += tfo_passive.sh
TEST_PROGS += broadcast_pmtu.sh
TEST_PROGS += ipv6_force_forwarding.sh
+TEST_PROGS += tcp_reuseport.py
# YNL files, must be before "include ..lib.mk"
YNL_GEN_FILES := busy_poller netlink-dumps
diff --git a/tools/testing/selftests/net/tcp_reuseport.py b/tools/testing/selftests/net/tcp_reuseport.py
new file mode 100755
index 000000000000..eaeb7096382e
--- /dev/null
+++ b/tools/testing/selftests/net/tcp_reuseport.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+import os
+
+from lib.py import ksft_run, ksft_exit
+from socket import *
+
+def test_reuseport_select() -> None:
+ s1 = socket()
+ s1.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
+ s1.setsockopt(SOL_SOCKET, SO_BINDTODEVICE, b'lo')
+ s1.listen()
+ s1.setblocking(False)
+
+ s2 = socket()
+ s2.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
+ s2.bind(s1.getsockname())
+ s2.listen()
+ s2.setblocking(False)
+
+ for i in range(3):
+ c = socket()
+ c.connect(s1.getsockname())
+ try:
+ print("SUCCESS: assigned properly:", s1.accept())
+ except:
+ print("FAIL: wrong assignment")
+ os.sys.exit(1)
+
+def main() -> None:
+ ksft_run([test_reuseport_select])
+ ksft_exit()
+
+if __name__ == "__main__":
+ main()
--
2.50.1
On Sat, Aug 2, 2025 at 2:24 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> The test script is provided by Kuniyuki in [1], which is used to test the
> selection of the TCP reuseport socket problem.
>
> Link: https://lore.kernel.org/netdev/20250801040757.1599996-1-kuniyu@google.com/ [1]
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> ---
> tools/testing/selftests/net/Makefile | 1 +
> tools/testing/selftests/net/tcp_reuseport.py | 36 ++++++++++++++++++++
> 2 files changed, 37 insertions(+)
> create mode 100755 tools/testing/selftests/net/tcp_reuseport.py
>
> diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
> index b31a71f2b372..0f4c3eea9709 100644
> --- a/tools/testing/selftests/net/Makefile
> +++ b/tools/testing/selftests/net/Makefile
> @@ -117,6 +117,7 @@ TEST_GEN_FILES += tfo
> TEST_PROGS += tfo_passive.sh
> TEST_PROGS += broadcast_pmtu.sh
> TEST_PROGS += ipv6_force_forwarding.sh
> +TEST_PROGS += tcp_reuseport.py
>
> # YNL files, must be before "include ..lib.mk"
> YNL_GEN_FILES := busy_poller netlink-dumps
> diff --git a/tools/testing/selftests/net/tcp_reuseport.py b/tools/testing/selftests/net/tcp_reuseport.py
> new file mode 100755
> index 000000000000..eaeb7096382e
> --- /dev/null
> +++ b/tools/testing/selftests/net/tcp_reuseport.py
> @@ -0,0 +1,36 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0
> +
> +import os
> +
> +from lib.py import ksft_run, ksft_exit
> +from socket import *
> +
> +def test_reuseport_select() -> None:
> + s1 = socket()
> + s1.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
> + s1.setsockopt(SOL_SOCKET, SO_BINDTODEVICE, b'lo')
> + s1.listen()
> + s1.setblocking(False)
> +
> + s2 = socket()
> + s2.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
> + s2.bind(s1.getsockname())
> + s2.listen()
> + s2.setblocking(False)
> +
> + for i in range(3):
> + c = socket()
> + c.connect(s1.getsockname())
> + try:
> + print("SUCCESS: assigned properly:", s1.accept())
> + except:
> + print("FAIL: wrong assignment")
> + os.sys.exit(1)
It seems you don't need to handle an exception with ksft.
You can see os.sys.exit(1) triggers another exception when
you run it without patch 1.
TAP version 13
1..1
# timeout set to 3600
# selftests: net: tcp_reuseport.py
# TAP version 13
# 1..1
# FAIL: wrong assignment
# # Exception| Traceback (most recent call last):
# # Exception| File
"/root/linux/tools/testing/selftests/net/./tcp_reuseport.py", line 26,
in test_reuseport_select
# # Exception| print("SUCCESS: assigned properly:", s1.accept())
# # Exception| ~~~~~~~~~^^
# # Exception| File "/usr/lib64/python3.13/socket.py", line 295, in accept
# # Exception| fd, addr = self._accept()
# # Exception| ~~~~~~~~~~~~^^
# # Exception| BlockingIOError: [Errno 11] Resource temporarily unavailable
# # Exception|
# # Exception| During handling of the above exception, another
exception occurred:
# # Exception|
# # Exception| Traceback (most recent call last):
# # Exception| File
"/root/linux/tools/testing/selftests/net/lib/py/ksft.py", line 244, in
ksft_run
# # Exception| case(*args)
# # Exception| ~~~~^^^^^^^
# # Exception| File
"/root/linux/tools/testing/selftests/net/./tcp_reuseport.py", line 29,
in test_reuseport_select
# # Exception| os.sys.exit(1)
# # Exception| ~~~~~~~~~~~^^^
# # Exception| SystemExit: 1
# not ok 1 tcp_reuseport.test_reuseport_select
# # Totals: pass:0 fail:1 xfail:0 xpass:0 skip:0 error:0
not ok 1 selftests: net: tcp_reuseport.py # exit=1
btw, I'd write an official uAPI selftest in plain C for socket as
python sometimes does a tricky thing and I don't trust it.
For example, this is...
from socket import *
s = socket()
s.listen(-1)
internally translated to:
socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 3
listen(3, 0) = 0
On Wed, Aug 6, 2025 at 3:01 AM Kuniyuki Iwashima <kuniyu@google.com> wrote:
>
> On Sat, Aug 2, 2025 at 2:24 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > The test script is provided by Kuniyuki in [1], which is used to test the
> > selection of the TCP reuseport socket problem.
> >
> > Link: https://lore.kernel.org/netdev/20250801040757.1599996-1-kuniyu@google.com/ [1]
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> > tools/testing/selftests/net/Makefile | 1 +
> > tools/testing/selftests/net/tcp_reuseport.py | 36 ++++++++++++++++++++
> > 2 files changed, 37 insertions(+)
> > create mode 100755 tools/testing/selftests/net/tcp_reuseport.py
> >
> > diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
> > index b31a71f2b372..0f4c3eea9709 100644
> > --- a/tools/testing/selftests/net/Makefile
> > +++ b/tools/testing/selftests/net/Makefile
> > @@ -117,6 +117,7 @@ TEST_GEN_FILES += tfo
> > TEST_PROGS += tfo_passive.sh
> > TEST_PROGS += broadcast_pmtu.sh
> > TEST_PROGS += ipv6_force_forwarding.sh
> > +TEST_PROGS += tcp_reuseport.py
> >
> > # YNL files, must be before "include ..lib.mk"
> > YNL_GEN_FILES := busy_poller netlink-dumps
> > diff --git a/tools/testing/selftests/net/tcp_reuseport.py b/tools/testing/selftests/net/tcp_reuseport.py
> > new file mode 100755
> > index 000000000000..eaeb7096382e
> > --- /dev/null
> > +++ b/tools/testing/selftests/net/tcp_reuseport.py
> > @@ -0,0 +1,36 @@
> > +#!/usr/bin/env python3
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +import os
> > +
> > +from lib.py import ksft_run, ksft_exit
> > +from socket import *
> > +
> > +def test_reuseport_select() -> None:
> > + s1 = socket()
> > + s1.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
> > + s1.setsockopt(SOL_SOCKET, SO_BINDTODEVICE, b'lo')
> > + s1.listen()
> > + s1.setblocking(False)
> > +
> > + s2 = socket()
> > + s2.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
> > + s2.bind(s1.getsockname())
> > + s2.listen()
> > + s2.setblocking(False)
> > +
> > + for i in range(3):
> > + c = socket()
> > + c.connect(s1.getsockname())
> > + try:
> > + print("SUCCESS: assigned properly:", s1.accept())
> > + except:
> > + print("FAIL: wrong assignment")
> > + os.sys.exit(1)
>
> It seems you don't need to handle an exception with ksft.
> You can see os.sys.exit(1) triggers another exception when
> you run it without patch 1.
>
> TAP version 13
> 1..1
> # timeout set to 3600
> # selftests: net: tcp_reuseport.py
> # TAP version 13
> # 1..1
> # FAIL: wrong assignment
> # # Exception| Traceback (most recent call last):
> # # Exception| File
> "/root/linux/tools/testing/selftests/net/./tcp_reuseport.py", line 26,
> in test_reuseport_select
> # # Exception| print("SUCCESS: assigned properly:", s1.accept())
> # # Exception| ~~~~~~~~~^^
> # # Exception| File "/usr/lib64/python3.13/socket.py", line 295, in accept
> # # Exception| fd, addr = self._accept()
> # # Exception| ~~~~~~~~~~~~^^
> # # Exception| BlockingIOError: [Errno 11] Resource temporarily unavailable
> # # Exception|
> # # Exception| During handling of the above exception, another
> exception occurred:
> # # Exception|
> # # Exception| Traceback (most recent call last):
> # # Exception| File
> "/root/linux/tools/testing/selftests/net/lib/py/ksft.py", line 244, in
> ksft_run
> # # Exception| case(*args)
> # # Exception| ~~~~^^^^^^^
> # # Exception| File
> "/root/linux/tools/testing/selftests/net/./tcp_reuseport.py", line 29,
> in test_reuseport_select
> # # Exception| os.sys.exit(1)
> # # Exception| ~~~~~~~~~~~^^^
> # # Exception| SystemExit: 1
> # not ok 1 tcp_reuseport.test_reuseport_select
> # # Totals: pass:0 fail:1 xfail:0 xpass:0 skip:0 error:0
> not ok 1 selftests: net: tcp_reuseport.py # exit=1
>
>
> btw, I'd write an official uAPI selftest in plain C for socket as
> python sometimes does a tricky thing and I don't trust it.
Yeah, sounds nice, and C has better compatibility and
reliability for the testing.
>
> For example, this is...
>
> from socket import *
>
> s = socket()
> s.listen(-1)
>
> internally translated to:
>
> socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 3
> listen(3, 0) = 0
© 2016 - 2026 Red Hat, Inc.