From: Juan Agustin Niccolini <juanagusnicco@gmail.com>
To: davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
pabeni@redhat.com
Cc: horms@kernel.org, ncardwell@google.com, kuniyu@google.com,
josef@toxicpanda.com, jbacik@fb.com, shuah@kernel.org,
linux-kselftest@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org,
Juan Agustin Niccolini <juanagusnicco@gmail.com>
Subject: [PATCH net v2 2/2] selftests: net: Add SO_REUSEPORT bind cache test to bind_wildcard.c
Date: Wed, 11 Nov 2026 12:47:04 -0500 [thread overview]
Message-ID: <20261111174704.24312-3-juanagusnicco@gmail.com> (raw)
In-Reply-To: <20261111174704.24312-1-juanagusnicco@gmail.com>
Add a test for the bug fixed by "tcp: Fix the SO_REUSEPORT bind cache
admitting a conflicting socket". With a 0.0.0.0 listener on the port, a
v6only [::] SO_REUSEPORT socket fills the bind cache, and a dual-stack
[::] SO_REUSEPORT socket must then fail to bind with EADDRINUSE.
Without the fix:
# RUN global.reuseport_v6only_cache ...
# bind_wildcard.c:860:reuseport_v6only_cache:Expected ret (0) == -1 (-1)
# reuseport_v6only_cache: Test terminated by assertion
# FAIL global.reuseport_v6only_cache
not ok 1 global.reuseport_v6only_cache
With it:
# RUN global.reuseport_v6only_cache ...
# OK global.reuseport_v6only_cache
ok 1 global.reuseport_v6only_cache
Signed-off-by: Juan Agustin Niccolini <juanagusnicco@gmail.com>
---
tools/testing/selftests/net/bind_wildcard.c | 54 +++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/tools/testing/selftests/net/bind_wildcard.c b/tools/testing/selftests/net/bind_wildcard.c
index be3298c791b2..334a0cf87edf 100644
--- a/tools/testing/selftests/net/bind_wildcard.c
+++ b/tools/testing/selftests/net/bind_wildcard.c
@@ -811,4 +811,58 @@ TEST_F(bind_wildcard, reuseport)
bind_socket(_metadata, self, variant, i, SO_REUSEPORT);
}
+/* The SO_REUSEPORT bind cache (tb->fast_*) filled by a v6only [::] socket
+ * must not let a dual-stack [::] socket skip the conflict check against a
+ * 0.0.0.0 listener.
+ */
+TEST(reuseport_v6only_cache)
+{
+ struct sockaddr_in6 addr6 = {
+ .sin6_family = AF_INET6,
+ .sin6_addr = in6addr_any,
+ };
+ struct sockaddr_in addr4 = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = htonl(INADDR_ANY),
+ };
+ socklen_t addrlen;
+ int fd[3], ret;
+ int on = 1;
+
+ ASSERT_EQ(unshare(CLONE_NEWNET), 0);
+
+ /* bind(0.0.0.0:P), listen() */
+ fd[0] = socket(AF_INET, SOCK_STREAM, 0);
+ ASSERT_GT(fd[0], 0);
+ ASSERT_EQ(bind(fd[0], (struct sockaddr *)&addr4, sizeof(addr4)), 0);
+ ASSERT_EQ(listen(fd[0], 1), 0);
+
+ addrlen = sizeof(addr4);
+ ASSERT_EQ(getsockname(fd[0], (struct sockaddr *)&addr4, &addrlen), 0);
+ addr6.sin6_port = addr4.sin_port;
+
+ /* SO_REUSEPORT + IPV6_V6ONLY, bind([::]:P) fills the cache. */
+ fd[1] = socket(AF_INET6, SOCK_STREAM, 0);
+ ASSERT_GT(fd[1], 0);
+ ret = setsockopt(fd[1], SOL_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+ ASSERT_EQ(ret, 0);
+ ret = setsockopt(fd[1], SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
+ ASSERT_EQ(ret, 0);
+ ASSERT_EQ(bind(fd[1], (struct sockaddr *)&addr6, sizeof(addr6)), 0);
+
+ /* SO_REUSEPORT, bind([::]:P) conflicts with 0.0.0.0:P. */
+ fd[2] = socket(AF_INET6, SOCK_STREAM, 0);
+ ASSERT_GT(fd[2], 0);
+ ret = setsockopt(fd[2], SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
+ ASSERT_EQ(ret, 0);
+
+ ret = bind(fd[2], (struct sockaddr *)&addr6, sizeof(addr6));
+ ASSERT_EQ(ret, -1);
+ ASSERT_EQ(errno, EADDRINUSE);
+
+ close(fd[2]);
+ close(fd[1]);
+ close(fd[0]);
+}
+
TEST_HARNESS_MAIN
--
2.43.0
next prev parent reply other threads:[~2026-11-11 17:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 17:47 [PATCH net v2 0/2] tcp: Fix the SO_REUSEPORT bind cache admitting a conflicting socket Juan Agustin Niccolini
2026-11-11 17:47 ` [PATCH net v2 1/2] " Juan Agustin Niccolini
2026-11-14 7:28 ` Kuniyuki Iwashima
2026-11-11 17:47 ` Juan Agustin Niccolini [this message]
2026-11-14 7:29 ` [PATCH net v2 2/2] selftests: net: Add SO_REUSEPORT bind cache test to bind_wildcard.c Kuniyuki Iwashima
2026-11-11 17:51 ` [PATCH net v2 0/2] tcp: Fix the SO_REUSEPORT bind cache admitting a conflicting socket netdev-bot+sinfo
2026-11-11 18:16 ` Juan Agustin Niccolini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261111174704.24312-3-juanagusnicco@gmail.com \
--to=juanagusnicco@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=jbacik@fb.com \
--cc=josef@toxicpanda.com \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.