From 660b87bd77704b1ffb0195de462a6b16a9f89be2 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Wed, 25 May 2022 12:07:36 -0700 Subject: [PATCH] Move BindToDeviceReusePort to socket_inet_loopback_isolated SO_BINDTODEVICE required CAP_NET_RAW beofre the 5.7 kernel. This was fixed in the kernel by c427bfec18f2 ("net: core: enable SO_BINDTODEVICE for non-root users"). --- test/syscalls/linux/socket_inet_loopback.cc | 39 ------------------- .../linux/socket_inet_loopback_isolated.cc | 39 +++++++++++++++++++ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/test/syscalls/linux/socket_inet_loopback.cc b/test/syscalls/linux/socket_inet_loopback.cc index e7a3cac62..0ba88735f 100644 --- a/test/syscalls/linux/socket_inet_loopback.cc +++ b/test/syscalls/linux/socket_inet_loopback.cc @@ -2471,45 +2471,6 @@ TEST_P(SocketMultiProtocolInetLoopbackTest, PortReuseTwoSockets) { } } -TEST_P(SocketMultiProtocolInetLoopbackTest, BindToDeviceReusePort) { - ProtocolTestParam const& param = GetParam(); - TestAddress const& test_addr = V4Loopback(); - - auto socket1 = - ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - auto socket2 = - ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); - - const char kLoopbackDeviceName[] = "lo"; - - // Bind socket1 with REUSEPORT and BINDTODEVICE. - ASSERT_THAT(setsockopt(socket1.get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, - sizeof(kSockOptOn)), - SyscallSucceeds()); - ASSERT_THAT(setsockopt(socket1.get(), SOL_SOCKET, SO_BINDTODEVICE, - kLoopbackDeviceName, strlen(kLoopbackDeviceName)), - SyscallSucceeds()); - - // Bind the first socket to the loopback and take note of the selected port. - auto addr = V4Loopback(); - ASSERT_THAT(bind(socket1.get(), AsSockAddr(&addr.addr), addr.addr_len), - SyscallSucceeds()); - socklen_t addr_len = addr.addr_len; - ASSERT_THAT(getsockname(socket1.get(), AsSockAddr(&addr.addr), &addr_len), - SyscallSucceeds()); - EXPECT_EQ(addr_len, addr.addr_len); - - // Bind socket2 to the same device and address as socket1. - ASSERT_THAT(setsockopt(socket2.get(), SOL_SOCKET, SO_BINDTODEVICE, - kLoopbackDeviceName, strlen(kLoopbackDeviceName)), - SyscallSucceeds()); - ASSERT_THAT(setsockopt(socket2.get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, - sizeof(kSockOptOn)), - SyscallSucceeds()); - ASSERT_THAT(bind(socket2.get(), AsSockAddr(&addr.addr), addr.addr_len), - SyscallSucceeds()); -} - // Check that when a socket was bound to an address with REUSEPORT and then // closed, we can bind a different socket to the same address without needing // REUSEPORT. diff --git a/test/syscalls/linux/socket_inet_loopback_isolated.cc b/test/syscalls/linux/socket_inet_loopback_isolated.cc index 182d20a9e..c123bf3ae 100644 --- a/test/syscalls/linux/socket_inet_loopback_isolated.cc +++ b/test/syscalls/linux/socket_inet_loopback_isolated.cc @@ -297,6 +297,45 @@ INSTANTIATE_TEST_SUITE_P(All, SocketInetLoopbackIsolatedTest, using SocketMultiProtocolInetLoopbackIsolatedTest = ::testing::TestWithParam; +TEST_P(SocketMultiProtocolInetLoopbackIsolatedTest, BindToDeviceReusePort) { + ProtocolTestParam const& param = GetParam(); + TestAddress const& test_addr = V4Loopback(); + + auto socket1 = + ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); + auto socket2 = + ASSERT_NO_ERRNO_AND_VALUE(Socket(test_addr.family(), param.type, 0)); + + const char kLoopbackDeviceName[] = "lo"; + + // Bind socket1 with REUSEPORT and BINDTODEVICE. + ASSERT_THAT(setsockopt(socket1.get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceeds()); + ASSERT_THAT(setsockopt(socket1.get(), SOL_SOCKET, SO_BINDTODEVICE, + kLoopbackDeviceName, strlen(kLoopbackDeviceName)), + SyscallSucceeds()); + + // Bind the first socket to the loopback and take note of the selected port. + auto addr = V4Loopback(); + ASSERT_THAT(bind(socket1.get(), AsSockAddr(&addr.addr), addr.addr_len), + SyscallSucceeds()); + socklen_t addr_len = addr.addr_len; + ASSERT_THAT(getsockname(socket1.get(), AsSockAddr(&addr.addr), &addr_len), + SyscallSucceeds()); + EXPECT_EQ(addr_len, addr.addr_len); + + // Bind socket2 to the same device and address as socket1. + ASSERT_THAT(setsockopt(socket2.get(), SOL_SOCKET, SO_BINDTODEVICE, + kLoopbackDeviceName, strlen(kLoopbackDeviceName)), + SyscallSucceeds()); + ASSERT_THAT(setsockopt(socket2.get(), SOL_SOCKET, SO_REUSEPORT, &kSockOptOn, + sizeof(kSockOptOn)), + SyscallSucceeds()); + ASSERT_THAT(bind(socket2.get(), AsSockAddr(&addr.addr), addr.addr_len), + SyscallSucceeds()); +} + TEST_P(SocketMultiProtocolInetLoopbackIsolatedTest, V4EphemeralPortReservedReuseAddr) { ProtocolTestParam const& param = GetParam();