summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/tcpip/stack/nic.go6
-rw-r--r--pkg/tcpip/tests/integration/loopback_test.go40
-rw-r--r--test/syscalls/linux/BUILD19
-rw-r--r--test/syscalls/linux/socket_ip_udp_unbound_netlink_util.cc58
-rw-r--r--test/syscalls/linux/socket_ip_udp_unbound_netlink_util.h34
-rw-r--r--test/syscalls/linux/socket_ipv4_udp_unbound_netlink.cc32
-rw-r--r--test/syscalls/linux/socket_ipv4_udp_unbound_netlink.h4
-rw-r--r--test/syscalls/linux/socket_ipv6_udp_unbound_netlink.cc28
-rw-r--r--test/syscalls/linux/socket_ipv6_udp_unbound_netlink.h4
9 files changed, 49 insertions, 176 deletions
diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go
index 8e700990d..863ef6bee 100644
--- a/pkg/tcpip/stack/nic.go
+++ b/pkg/tcpip/stack/nic.go
@@ -676,10 +676,10 @@ func (n *NIC) getRefOrCreateTemp(protocol tcpip.NetworkProtocolNumber, address t
}
// A usable reference was not found, create a temporary one if requested by
- // the caller or if the address is found in the NIC's subnets and the NIC is
- // a loopback interface.
+ // the caller or if the IPv4 address is found in the NIC's subnets and the NIC
+ // is a loopback interface.
createTempEP := spoofingOrPromiscuous
- if !createTempEP && n.isLoopback() {
+ if !createTempEP && n.isLoopback() && protocol == header.IPv4ProtocolNumber {
for _, r := range n.mu.endpoints {
addr := r.addrWithPrefix()
subnet := addr.Subnet()
diff --git a/pkg/tcpip/tests/integration/loopback_test.go b/pkg/tcpip/tests/integration/loopback_test.go
index 3a2f75837..1b18023c5 100644
--- a/pkg/tcpip/tests/integration/loopback_test.go
+++ b/pkg/tcpip/tests/integration/loopback_test.go
@@ -110,51 +110,11 @@ func TestLoopbackAcceptAllInSubnet(t *testing.T) {
expectRx: true,
},
{
- name: "IPv6 bind to wildcard and send to assigned address",
- addAddress: ipv6ProtocolAddress,
- dstAddr: ipv6Addr.Address,
- expectRx: true,
- },
- {
name: "IPv6 bind to wildcard and send to other subnet-local address",
addAddress: ipv6ProtocolAddress,
dstAddr: otherIPv6Address,
- expectRx: true,
- },
- {
- name: "IPv6 bind to wildcard send to other address",
- addAddress: ipv6ProtocolAddress,
- dstAddr: remoteIPv6Addr,
- expectRx: false,
- },
- {
- name: "IPv6 bind to other subnet-local address and send to assigned address",
- addAddress: ipv6ProtocolAddress,
- bindAddr: otherIPv6Address,
- dstAddr: ipv6Addr.Address,
- expectRx: false,
- },
- {
- name: "IPv6 bind and send to other subnet-local address",
- addAddress: ipv6ProtocolAddress,
- bindAddr: otherIPv6Address,
- dstAddr: otherIPv6Address,
- expectRx: true,
- },
- {
- name: "IPv6 bind to assigned address and send to other subnet-local address",
- addAddress: ipv6ProtocolAddress,
- bindAddr: ipv6Addr.Address,
- dstAddr: otherIPv6Address,
expectRx: false,
},
- {
- name: "IPv6 bind and send to assigned address",
- addAddress: ipv6ProtocolAddress,
- bindAddr: ipv6Addr.Address,
- dstAddr: ipv6Addr.Address,
- expectRx: true,
- },
}
for _, test := range tests {
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD
index 5a323d331..fad3be7bf 100644
--- a/test/syscalls/linux/BUILD
+++ b/test/syscalls/linux/BUILD
@@ -2417,21 +2417,6 @@ cc_library(
)
cc_library(
- name = "socket_ip_udp_unbound_netlink_test_utils",
- testonly = 1,
- srcs = [
- "socket_ip_udp_unbound_netlink_util.cc",
- ],
- hdrs = [
- "socket_ip_udp_unbound_netlink_util.h",
- ],
- deps = [
- ":socket_test_util",
- ],
- alwayslink = 1,
-)
-
-cc_library(
name = "socket_ipv4_udp_unbound_netlink_test_cases",
testonly = 1,
srcs = [
@@ -2441,8 +2426,8 @@ cc_library(
"socket_ipv4_udp_unbound_netlink.h",
],
deps = [
- ":socket_ip_udp_unbound_netlink_test_utils",
":socket_netlink_route_util",
+ ":socket_test_util",
"//test/util:capability_util",
gtest,
],
@@ -2459,8 +2444,8 @@ cc_library(
"socket_ipv6_udp_unbound_netlink.h",
],
deps = [
- ":socket_ip_udp_unbound_netlink_test_utils",
":socket_netlink_route_util",
+ ":socket_test_util",
"//test/util:capability_util",
gtest,
],
diff --git a/test/syscalls/linux/socket_ip_udp_unbound_netlink_util.cc b/test/syscalls/linux/socket_ip_udp_unbound_netlink_util.cc
deleted file mode 100644
index 13ffafde7..000000000
--- a/test/syscalls/linux/socket_ip_udp_unbound_netlink_util.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2020 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "test/syscalls/linux/socket_ip_udp_unbound_netlink_util.h"
-
-namespace gvisor {
-namespace testing {
-
-const size_t kSendBufSize = 200;
-
-void IPUDPUnboundSocketNetlinkTest::TestSendRecv(TestAddress sender_addr,
- TestAddress receiver_addr) {
- auto snd_sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket());
- auto rcv_sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket());
-
- EXPECT_THAT(
- bind(snd_sock->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr),
- sender_addr.addr_len),
- SyscallSucceeds());
-
- EXPECT_THAT(
- bind(rcv_sock->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr),
- receiver_addr.addr_len),
- SyscallSucceeds());
- socklen_t receiver_addr_len = receiver_addr.addr_len;
- ASSERT_THAT(getsockname(rcv_sock->get(),
- reinterpret_cast<sockaddr*>(&receiver_addr.addr),
- &receiver_addr_len),
- SyscallSucceeds());
- EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len);
- char send_buf[kSendBufSize];
- RandomizeBuffer(send_buf, kSendBufSize);
- EXPECT_THAT(
- RetryEINTR(sendto)(snd_sock->get(), send_buf, kSendBufSize, 0,
- reinterpret_cast<sockaddr*>(&receiver_addr.addr),
- receiver_addr.addr_len),
- SyscallSucceedsWithValue(kSendBufSize));
-
- // Check that we received the packet.
- char recv_buf[kSendBufSize] = {};
- ASSERT_THAT(RetryEINTR(recv)(rcv_sock->get(), recv_buf, kSendBufSize, 0),
- SyscallSucceedsWithValue(kSendBufSize));
- EXPECT_EQ(0, memcmp(send_buf, recv_buf, kSendBufSize));
-}
-
-} // namespace testing
-} // namespace gvisor
diff --git a/test/syscalls/linux/socket_ip_udp_unbound_netlink_util.h b/test/syscalls/linux/socket_ip_udp_unbound_netlink_util.h
deleted file mode 100644
index 157fb0939..000000000
--- a/test/syscalls/linux/socket_ip_udp_unbound_netlink_util.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2020 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IP_UDP_UNBOUND_NETLINK_UTIL_H_
-#define GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IP_UDP_UNBOUND_NETLINK_UTIL_H_
-
-#include "test/syscalls/linux/socket_test_util.h"
-
-namespace gvisor {
-namespace testing {
-
-// Test fixture for tests that apply to IP UDP sockets.
-class IPUDPUnboundSocketNetlinkTest : public SimpleSocketTest {
- public:
- // TestSendRecv tests sending and receiving a UDP packet from |sender_addr| to
- // |receiver_addr|.
- void TestSendRecv(TestAddress sender_addr, TestAddress receiver_addr);
-};
-
-} // namespace testing
-} // namespace gvisor
-
-#endif // GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IP_UDP_UNBOUND_NETLINK_UTIL_H_
diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.cc
index 696fbb189..79eb48afa 100644
--- a/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.cc
+++ b/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.cc
@@ -23,6 +23,8 @@
namespace gvisor {
namespace testing {
+constexpr size_t kSendBufSize = 200;
+
// Checks that the loopback interface considers itself bound to all IPs in an
// associated subnet.
TEST_P(IPv4UDPUnboundSocketNetlinkTest, JoinSubnet) {
@@ -35,6 +37,9 @@ TEST_P(IPv4UDPUnboundSocketNetlinkTest, JoinSubnet) {
EXPECT_NO_ERRNO(LinkAddLocalAddr(loopback_link.index, AF_INET,
/*prefixlen=*/24, &addr, sizeof(addr)));
+ auto snd_sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket());
+ auto rcv_sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket());
+
// Send from an unassigned address but an address that is in the subnet
// associated with the loopback interface.
TestAddress sender_addr("V4NotAssignd1");
@@ -43,6 +48,10 @@ TEST_P(IPv4UDPUnboundSocketNetlinkTest, JoinSubnet) {
EXPECT_EQ(1, inet_pton(AF_INET, "192.0.2.2",
&(reinterpret_cast<sockaddr_in*>(&sender_addr.addr)
->sin_addr.s_addr)));
+ EXPECT_THAT(
+ bind(snd_sock->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr),
+ sender_addr.addr_len),
+ SyscallSucceeds());
// Send the packet to an unassigned address but an address that is in the
// subnet associated with the loopback interface.
@@ -52,8 +61,29 @@ TEST_P(IPv4UDPUnboundSocketNetlinkTest, JoinSubnet) {
EXPECT_EQ(1, inet_pton(AF_INET, "192.0.2.254",
&(reinterpret_cast<sockaddr_in*>(&receiver_addr.addr)
->sin_addr.s_addr)));
+ EXPECT_THAT(
+ bind(rcv_sock->get(), reinterpret_cast<sockaddr*>(&receiver_addr.addr),
+ receiver_addr.addr_len),
+ SyscallSucceeds());
+ socklen_t receiver_addr_len = receiver_addr.addr_len;
+ ASSERT_THAT(getsockname(rcv_sock->get(),
+ reinterpret_cast<sockaddr*>(&receiver_addr.addr),
+ &receiver_addr_len),
+ SyscallSucceeds());
+ EXPECT_EQ(receiver_addr_len, receiver_addr.addr_len);
+ char send_buf[kSendBufSize];
+ RandomizeBuffer(send_buf, kSendBufSize);
+ EXPECT_THAT(
+ RetryEINTR(sendto)(snd_sock->get(), send_buf, kSendBufSize, 0,
+ reinterpret_cast<sockaddr*>(&receiver_addr.addr),
+ receiver_addr.addr_len),
+ SyscallSucceedsWithValue(kSendBufSize));
- TestSendRecv(sender_addr, receiver_addr);
+ // Check that we received the packet.
+ char recv_buf[kSendBufSize] = {};
+ ASSERT_THAT(RetryEINTR(recv)(rcv_sock->get(), recv_buf, kSendBufSize, 0),
+ SyscallSucceedsWithValue(kSendBufSize));
+ EXPECT_EQ(0, memcmp(send_buf, recv_buf, kSendBufSize));
}
} // namespace testing
diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.h b/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.h
index fcfb3318e..73e7836d5 100644
--- a/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.h
+++ b/test/syscalls/linux/socket_ipv4_udp_unbound_netlink.h
@@ -15,13 +15,13 @@
#ifndef GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_NETLINK_UTIL_H_
#define GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV4_UDP_UNBOUND_NETLINK_UTIL_H_
-#include "test/syscalls/linux/socket_ip_udp_unbound_netlink_util.h"
+#include "test/syscalls/linux/socket_test_util.h"
namespace gvisor {
namespace testing {
// Test fixture for tests that apply to IPv4 UDP sockets.
-using IPv4UDPUnboundSocketNetlinkTest = IPUDPUnboundSocketNetlinkTest;
+using IPv4UDPUnboundSocketNetlinkTest = SimpleSocketTest;
} // namespace testing
} // namespace gvisor
diff --git a/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.cc b/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.cc
index 539a4ec55..2ee218231 100644
--- a/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.cc
+++ b/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.cc
@@ -23,13 +23,10 @@
namespace gvisor {
namespace testing {
-// Checks that the loopback interface considers itself bound to all IPs in an
-// associated subnet.
+// Checks that the loopback interface does not consider itself bound to all IPs
+// in an associated subnet.
TEST_P(IPv6UDPUnboundSocketNetlinkTest, JoinSubnet) {
- // TODO(b/166440211): Only run this test on gvisor or remove if the loopback
- // interface should not consider itself bound to all IPs in an IPv6 subnet.
- SKIP_IF(!IsRunningOnGvisor() ||
- !ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
+ SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
// Add an IP address to the loopback interface.
Link loopback_link = ASSERT_NO_ERRNO_AND_VALUE(LoopbackLink());
@@ -38,25 +35,18 @@ TEST_P(IPv6UDPUnboundSocketNetlinkTest, JoinSubnet) {
EXPECT_NO_ERRNO(LinkAddLocalAddr(loopback_link.index, AF_INET6,
/*prefixlen=*/64, &addr, sizeof(addr)));
- // Send from an unassigned address but an address that is in the subnet
- // associated with the loopback interface.
+ // Binding to an unassigned address but an address that is in the subnet
+ // associated with the loopback interface should fail.
TestAddress sender_addr("V6NotAssignd1");
sender_addr.addr.ss_family = AF_INET6;
sender_addr.addr_len = sizeof(sockaddr_in6);
EXPECT_EQ(1, inet_pton(AF_INET6, "2001:db8::2",
reinterpret_cast<sockaddr_in6*>(&sender_addr.addr)
->sin6_addr.s6_addr));
-
- // Send the packet to an unassigned address but an address that is in the
- // subnet associated with the loopback interface.
- TestAddress receiver_addr("V6NotAssigned2");
- receiver_addr.addr.ss_family = AF_INET6;
- receiver_addr.addr_len = sizeof(sockaddr_in6);
- EXPECT_EQ(1, inet_pton(AF_INET6, "2001:db8::ffff:ffff:ffff:ffff",
- reinterpret_cast<sockaddr_in6*>(&receiver_addr.addr)
- ->sin6_addr.s6_addr));
-
- TestSendRecv(sender_addr, receiver_addr);
+ auto sock = ASSERT_NO_ERRNO_AND_VALUE(NewSocket());
+ EXPECT_THAT(bind(sock->get(), reinterpret_cast<sockaddr*>(&sender_addr.addr),
+ sender_addr.addr_len),
+ SyscallFailsWithErrno(EADDRNOTAVAIL));
}
} // namespace testing
diff --git a/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.h b/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.h
index 6a2b0a5be..88098be82 100644
--- a/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.h
+++ b/test/syscalls/linux/socket_ipv6_udp_unbound_netlink.h
@@ -15,13 +15,13 @@
#ifndef GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV6_UDP_UNBOUND_NETLINK_UTIL_H_
#define GVISOR_TEST_SYSCALLS_LINUX_SOCKET_IPV6_UDP_UNBOUND_NETLINK_UTIL_H_
-#include "test/syscalls/linux/socket_ip_udp_unbound_netlink_util.h"
+#include "test/syscalls/linux/socket_test_util.h"
namespace gvisor {
namespace testing {
// Test fixture for tests that apply to IPv6 UDP sockets.
-using IPv6UDPUnboundSocketNetlinkTest = IPUDPUnboundSocketNetlinkTest;
+using IPv6UDPUnboundSocketNetlinkTest = SimpleSocketTest;
} // namespace testing
} // namespace gvisor