diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go index a785a85e3..24ca8ff2d 100644 --- a/pkg/sentry/socket/netstack/netstack.go +++ b/pkg/sentry/socket/netstack/netstack.go @@ -1330,6 +1330,15 @@ func getSockOptICMPv6(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, nam return nil, syserr.ErrProtocolNotAvailable } +func defaultTTL(t *kernel.Task, network tcpip.NetworkProtocolNumber) (primitive.Int32, tcpip.Error) { + var opt tcpip.DefaultTTLOption + stack := inet.StackFromContext(t) + if err := stack.(*Stack).Stack.NetworkProtocolOption(network, &opt); err != nil { + return 0, err + } + return primitive.Int32(opt), nil +} + // getSockOptIPv6 implements GetSockOpt when level is SOL_IPV6. func getSockOptIPv6(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name int, outPtr hostarch.Addr, outLen int) (marshal.Marshallable, *syserr.Error) { if _, ok := ep.(tcpip.Endpoint); !ok { @@ -1377,9 +1386,10 @@ func getSockOptIPv6(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name // Fill in the default value, if needed. vP := primitive.Int32(v) if vP == -1 { - // TODO(https://github.com/google/gvisor/issues/6973): Retrieve the - // configured DefaultTTLOption of the IPv6 protocol. - vP = DefaultTTL + vP, err = defaultTTL(t, header.IPv6ProtocolNumber) + if err != nil { + return nil, syserr.TranslateNetstackError(err) + } } return &vP, nil @@ -1540,9 +1550,10 @@ func getSockOptIP(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name in // Fill in the default value, if needed. vP := primitive.Int32(v) if vP == 0 { - // TODO(https://github.com/google/gvisor/issues/6973): Retrieve the - // configured DefaultTTLOption of the IPv4 protocol. - vP = DefaultTTL + vP, err = defaultTTL(t, header.IPv4ProtocolNumber) + if err != nil { + return nil, syserr.TranslateNetstackError(err) + } } return &vP, nil diff --git a/test/syscalls/linux/socket_ip_unbound.cc b/test/syscalls/linux/socket_ip_unbound.cc index 930f19e59..d470a7206 100644 --- a/test/syscalls/linux/socket_ip_unbound.cc +++ b/test/syscalls/linux/socket_ip_unbound.cc @@ -96,6 +96,7 @@ TEST_P(IPUnboundSocketTest, ResetTtlToDefault) { EXPECT_THAT(getsockopt(socket->get(), IPPROTO_IP, IP_TTL, &get2, &get2_sz), SyscallSucceedsWithValue(0)); EXPECT_EQ(get2_sz, sizeof(get2)); + EXPECT_TRUE(get2 == 64 || get2 == 127); EXPECT_EQ(get2, get1); } diff --git a/test/syscalls/linux/socket_ipv6_unbound.cc b/test/syscalls/linux/socket_ipv6_unbound.cc index 5ac0072f2..1ca59001a 100644 --- a/test/syscalls/linux/socket_ipv6_unbound.cc +++ b/test/syscalls/linux/socket_ipv6_unbound.cc @@ -29,6 +29,7 @@ namespace testing { namespace { constexpr int kDefaultHopLimit = 64; +constexpr int kDefaultTtl = 64; using ::testing::ValuesIn; using IPv6UnboundSocketTest = SimpleSocketTest; @@ -37,13 +38,18 @@ TEST_P(IPv6UnboundSocketTest, HopLimitDefault) { std::unique_ptr socket = ASSERT_NO_ERRNO_AND_VALUE(NewSocket()); + const int set = -1; + ASSERT_THAT(setsockopt(socket->get(), IPPROTO_IPV6, IPV6_UNICAST_HOPS, &set, + sizeof(set)), + SyscallSucceedsWithValue(0)); + int get = -1; socklen_t get_sz = sizeof(get); ASSERT_THAT( getsockopt(socket->get(), IPPROTO_IPV6, IPV6_UNICAST_HOPS, &get, &get_sz), SyscallSucceedsWithValue(0)); ASSERT_EQ(get_sz, sizeof(get)); - EXPECT_EQ(get, kDefaultHopLimit); + EXPECT_EQ(get, kDefaultTtl); } TEST_P(IPv6UnboundSocketTest, SetHopLimit) {