gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/packet_socket_raw.cc (about)

     1  // Copyright 2019 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  #include <arpa/inet.h>
    16  #include <errno.h>
    17  #include <net/ethernet.h>
    18  #include <net/if_arp.h>
    19  #include <netinet/in.h>
    20  #include <netinet/ip.h>
    21  #include <netinet/udp.h>
    22  #include <netpacket/packet.h>
    23  #include <poll.h>
    24  #include <sys/socket.h>
    25  #include <sys/types.h>
    26  #include <unistd.h>
    27  
    28  #include <functional>
    29  
    30  #include "gmock/gmock.h"
    31  #include "gtest/gtest.h"
    32  #include "absl/base/internal/endian.h"
    33  #include "test/syscalls/linux/ip_socket_test_util.h"
    34  #include "test/syscalls/linux/unix_domain_socket_test_util.h"
    35  #include "test/util/capability_util.h"
    36  #include "test/util/cleanup.h"
    37  #include "test/util/file_descriptor.h"
    38  #include "test/util/posix_error.h"
    39  #include "test/util/socket_util.h"
    40  #include "test/util/test_util.h"
    41  
    42  // Some of these tests involve sending packets via AF_PACKET sockets and the
    43  // loopback interface. Because AF_PACKET circumvents so much of the networking
    44  // stack, Linux sees these packets as "martian", i.e. they claim to be to/from
    45  // localhost but don't have the usual associated data. Thus Linux drops them by
    46  // default. You can see where this happens by following the code at:
    47  //
    48  // - net/ipv4/ip_input.c:ip_rcv_finish, which calls
    49  // - net/ipv4/route.c:ip_route_input_noref, which calls
    50  // - net/ipv4/route.c:ip_route_input_slow, which finds and drops martian
    51  //   packets.
    52  //
    53  // To tell Linux not to drop these packets, you need to tell it to accept our
    54  // funny packets (which are completely valid and correct, but lack associated
    55  // in-kernel data because we use AF_PACKET):
    56  //
    57  // echo 1 >> /proc/sys/net/ipv4/conf/lo/accept_local
    58  // echo 1 >> /proc/sys/net/ipv4/conf/lo/route_localnet
    59  //
    60  // These tests require CAP_NET_RAW to run.
    61  
    62  namespace gvisor {
    63  namespace testing {
    64  
    65  namespace {
    66  
    67  using ::testing::AnyOf;
    68  using ::testing::Eq;
    69  
    70  constexpr char kMessage[] = "soweoneul malhaebwa";
    71  constexpr in_port_t kPort = 0x409c;  // htons(40000)
    72  
    73  // Send kMessage via sock to loopback
    74  void SendUDPMessage(int sock) {
    75    struct sockaddr_in dest = {};
    76    dest.sin_port = kPort;
    77    dest.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    78    dest.sin_family = AF_INET;
    79    EXPECT_THAT(sendto(sock, kMessage, sizeof(kMessage), 0,
    80                       reinterpret_cast<struct sockaddr*>(&dest), sizeof(dest)),
    81                SyscallSucceedsWithValue(sizeof(kMessage)));
    82  }
    83  
    84  //
    85  // Raw tests. Packets sent with raw AF_PACKET sockets always include link layer
    86  // headers.
    87  //
    88  
    89  // Tests for "raw" (SOCK_RAW) packet(7) sockets.
    90  class RawPacketTest : public ::testing::TestWithParam<int> {
    91   protected:
    92    // Creates a socket to be used in tests.
    93    void SetUp() override;
    94  
    95    // Closes the socket created by SetUp().
    96    void TearDown() override;
    97  
    98    // Gets the device index of the loopback device.
    99    int GetLoopbackIndex();
   100  
   101    // The socket used for both reading and writing.
   102    int s_;
   103  
   104    // The function to restore the original system configuration.
   105    std::function<PosixError()> restore_config_;
   106  };
   107  
   108  void RawPacketTest::SetUp() {
   109    if (!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability())) {
   110      ASSERT_THAT(socket(AF_PACKET, SOCK_RAW, htons(GetParam())),
   111                  SyscallFailsWithErrno(EPERM));
   112      GTEST_SKIP();
   113    }
   114  
   115    ASSERT_THAT(s_ = socket(AF_PACKET, SOCK_RAW, htons(GetParam())),
   116                SyscallSucceeds());
   117  
   118    auto restore_config = AllowMartianPacketsOnLoopback();
   119    if (restore_config.ok()) {
   120      restore_config_ = restore_config.ValueOrDie();
   121    } else {
   122      ASSERT_THAT(restore_config.error(), PosixErrorIs(EACCES));
   123      GTEST_SKIP();
   124    }
   125  }
   126  
   127  void RawPacketTest::TearDown() {
   128    if (restore_config_) {
   129      EXPECT_NO_ERRNO(restore_config_());
   130    }
   131  
   132    // TearDown will be run even if we skip the test.
   133    if (ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability())) {
   134      EXPECT_THAT(close(s_), SyscallSucceeds());
   135    }
   136  }
   137  
   138  int RawPacketTest::GetLoopbackIndex() {
   139    int v = EXPECT_NO_ERRNO_AND_VALUE(gvisor::testing::GetLoopbackIndex());
   140    EXPECT_NE(v, 0);
   141    return v;
   142  }
   143  
   144  // Receive via a packet socket.
   145  TEST_P(RawPacketTest, Receive) {
   146    // Let's use a simple IP payload: a UDP datagram.
   147    FileDescriptor udp_sock =
   148        ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_DGRAM, 0));
   149    SendUDPMessage(udp_sock.get());
   150  
   151    // Wait for the socket to become readable.
   152    struct pollfd pfd = {};
   153    pfd.fd = s_;
   154    pfd.events = POLLIN;
   155    EXPECT_THAT(RetryEINTR(poll)(&pfd, 1, 2000), SyscallSucceedsWithValue(1));
   156  
   157    // Read and verify the data.
   158    constexpr size_t packet_size = sizeof(struct ethhdr) + sizeof(struct iphdr) +
   159                                   sizeof(struct udphdr) + sizeof(kMessage);
   160    char buf[64];
   161    struct sockaddr_ll src = {};
   162    socklen_t src_len = sizeof(src);
   163    ASSERT_THAT(recvfrom(s_, buf, sizeof(buf), 0,
   164                         reinterpret_cast<struct sockaddr*>(&src), &src_len),
   165                SyscallSucceedsWithValue(packet_size));
   166    // sockaddr_ll ends with an 8 byte physical address field, but ethernet
   167    // addresses only use 6 bytes.  Linux used to return sizeof(sockaddr_ll)-2
   168    // here, but since commit b2cf86e1563e33a14a1c69b3e508d15dc12f804c returns
   169    // sizeof(sockaddr_ll).
   170    ASSERT_THAT(src_len, AnyOf(Eq(sizeof(src)), Eq(sizeof(src) - 2)));
   171  
   172    // Verify the source address.
   173    EXPECT_EQ(src.sll_family, AF_PACKET);
   174    EXPECT_EQ(src.sll_ifindex, GetLoopbackIndex());
   175    EXPECT_EQ(src.sll_halen, ETH_ALEN);
   176    EXPECT_EQ(ntohs(src.sll_protocol), ETH_P_IP);
   177    // This came from the loopback device, so the address is all 0s.
   178    for (int i = 0; i < src.sll_halen; i++) {
   179      EXPECT_EQ(src.sll_addr[i], 0);
   180    }
   181  
   182    // Verify the ethernet header. We memcpy to deal with pointer alignment.
   183    struct ethhdr eth = {};
   184    memcpy(&eth, buf, sizeof(eth));
   185    // The destination and source address should be 0, for loopback.
   186    for (int i = 0; i < ETH_ALEN; i++) {
   187      EXPECT_EQ(eth.h_dest[i], 0);
   188      EXPECT_EQ(eth.h_source[i], 0);
   189    }
   190    EXPECT_EQ(eth.h_proto, htons(ETH_P_IP));
   191  
   192    // Verify the IP header. We memcpy to deal with pointer aligment.
   193    struct iphdr ip = {};
   194    memcpy(&ip, buf + sizeof(ethhdr), sizeof(ip));
   195    EXPECT_EQ(ip.ihl, 5);
   196    EXPECT_EQ(ip.version, 4);
   197    EXPECT_EQ(ip.tot_len, htons(packet_size - sizeof(eth)));
   198    EXPECT_EQ(ip.protocol, IPPROTO_UDP);
   199    EXPECT_EQ(ip.daddr, htonl(INADDR_LOOPBACK));
   200    EXPECT_EQ(ip.saddr, htonl(INADDR_LOOPBACK));
   201  
   202    // Verify the UDP header. We memcpy to deal with pointer aligment.
   203    struct udphdr udp = {};
   204    memcpy(&udp, buf + sizeof(eth) + sizeof(iphdr), sizeof(udp));
   205    EXPECT_EQ(udp.dest, kPort);
   206    EXPECT_EQ(udp.len, htons(sizeof(udphdr) + sizeof(kMessage)));
   207  
   208    // Verify the payload.
   209    char* payload = reinterpret_cast<char*>(buf + sizeof(eth) + sizeof(iphdr) +
   210                                            sizeof(udphdr));
   211    EXPECT_EQ(strncmp(payload, kMessage, sizeof(kMessage)), 0);
   212  }
   213  
   214  void ValidateSend(int sendfd, in_addr_t src_addr, int dst_ifindex) {
   215    // TODO(b/267210840): Fix this test for hostinet. Something is wrong with
   216    // poll().
   217    SKIP_IF(IsRunningWithHostinet());
   218  
   219    // Let's send a UDP packet and receive it using a regular UDP socket.
   220    FileDescriptor udp_sock =
   221        ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_DGRAM, 0));
   222    struct sockaddr_in bind_addr = {};
   223    bind_addr.sin_family = AF_INET;
   224    bind_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   225    bind_addr.sin_port = kPort;
   226    ASSERT_THAT(
   227        bind(udp_sock.get(), reinterpret_cast<struct sockaddr*>(&bind_addr),
   228             sizeof(bind_addr)),
   229        SyscallSucceeds());
   230  
   231    // Set up the destination physical address.
   232    struct sockaddr_ll dest = {};
   233    dest.sll_family = AF_PACKET;
   234    dest.sll_halen = ETH_ALEN;
   235    dest.sll_ifindex = dst_ifindex;
   236    dest.sll_protocol = htons(ETH_P_IP);
   237    // We're sending to the loopback device, so the address is all 0s.
   238    memset(dest.sll_addr, 0x00, ETH_ALEN);
   239  
   240    // Set up the ethernet header. The kernel takes care of the footer.
   241    // We're sending to and from hardware address 0 (loopback).
   242    struct ethhdr eth = {};
   243    eth.h_proto = htons(ETH_P_IP);
   244  
   245    // Set up the IP header.
   246    struct iphdr iphdr = {};
   247    iphdr.ihl = 5;
   248    iphdr.version = 4;
   249    iphdr.tos = 0;
   250    iphdr.tot_len =
   251        htons(sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(kMessage));
   252    // Get a pseudo-random ID. If we clash with an in-use ID the test will fail,
   253    // but we have no way of getting an ID we know to be good.
   254    srand(*reinterpret_cast<unsigned int*>(&iphdr));
   255    iphdr.id = rand();
   256    // Linux sets this bit ("do not fragment") for small packets.
   257    iphdr.frag_off = 1 << 6;
   258    iphdr.ttl = 64;
   259    iphdr.protocol = IPPROTO_UDP;
   260    iphdr.daddr = htonl(INADDR_LOOPBACK);
   261    iphdr.saddr = htonl(src_addr);
   262    iphdr.check = IPChecksum(iphdr);
   263  
   264    // Set up the UDP header.
   265    struct udphdr udphdr = {};
   266    udphdr.source = kPort;
   267    udphdr.dest = kPort;
   268    udphdr.len = htons(sizeof(udphdr) + sizeof(kMessage));
   269    udphdr.check = UDPChecksum(iphdr, udphdr, kMessage, sizeof(kMessage));
   270  
   271    // Copy both headers and the payload into our packet buffer.
   272    char
   273        send_buf[sizeof(eth) + sizeof(iphdr) + sizeof(udphdr) + sizeof(kMessage)];
   274    memcpy(send_buf, &eth, sizeof(eth));
   275    memcpy(send_buf + sizeof(ethhdr), &iphdr, sizeof(iphdr));
   276    memcpy(send_buf + sizeof(ethhdr) + sizeof(iphdr), &udphdr, sizeof(udphdr));
   277    memcpy(send_buf + sizeof(ethhdr) + sizeof(iphdr) + sizeof(udphdr), kMessage,
   278           sizeof(kMessage));
   279  
   280    // Send it.
   281    ASSERT_THAT(sendto(sendfd, send_buf, sizeof(send_buf), 0,
   282                       reinterpret_cast<struct sockaddr*>(&dest), sizeof(dest)),
   283                SyscallSucceedsWithValue(sizeof(send_buf)));
   284  
   285    // Wait for the packet to become available on both sockets.
   286    struct pollfd pfd = {};
   287    pfd.fd = udp_sock.get();
   288    pfd.events = POLLIN;
   289    ASSERT_THAT(RetryEINTR(poll)(&pfd, 1, 5000), SyscallSucceedsWithValue(1));
   290    pfd.fd = sendfd;
   291    pfd.events = POLLIN;
   292    ASSERT_THAT(RetryEINTR(poll)(&pfd, 1, 5000), SyscallSucceedsWithValue(1));
   293  
   294    // Receive on the packet socket.
   295    char recv_buf[sizeof(send_buf)];
   296    ASSERT_THAT(recv(sendfd, recv_buf, sizeof(recv_buf), 0),
   297                SyscallSucceedsWithValue(sizeof(recv_buf)));
   298    ASSERT_EQ(memcmp(recv_buf, send_buf, sizeof(send_buf)), 0);
   299  
   300    // Receive on the UDP socket.
   301    struct sockaddr_in src;
   302    socklen_t src_len = sizeof(src);
   303    ASSERT_THAT(recvfrom(udp_sock.get(), recv_buf, sizeof(recv_buf), MSG_DONTWAIT,
   304                         reinterpret_cast<struct sockaddr*>(&src), &src_len),
   305                SyscallSucceedsWithValue(sizeof(kMessage)));
   306    // Check src and payload.
   307    EXPECT_EQ(strncmp(recv_buf, kMessage, sizeof(kMessage)), 0);
   308    EXPECT_EQ(src.sin_family, AF_INET);
   309    EXPECT_EQ(src.sin_port, kPort);
   310    EXPECT_EQ(src.sin_addr.s_addr, htonl(src_addr));
   311  }
   312  
   313  // Send via a packet socket.
   314  TEST_P(RawPacketTest, SendFromLoopback) {
   315    ASSERT_NO_FATAL_FAILURE(
   316        ValidateSend(s_, INADDR_LOOPBACK, GetLoopbackIndex()));
   317  }
   318  
   319  TEST_P(RawPacketTest, SendFromUnspec) {
   320    ASSERT_NO_FATAL_FAILURE(ValidateSend(s_, INADDR_ANY, GetLoopbackIndex()));
   321  }
   322  
   323  // Check that setting SO_RCVBUF below min is clamped to the minimum
   324  // receive buffer size.
   325  TEST_P(RawPacketTest, SetSocketRecvBufBelowMin) {
   326    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   327  
   328    // Discover minimum receive buf size by trying to set it to zero.
   329    // See:
   330    // https://github.com/torvalds/linux/blob/a5dc8300df75e8b8384b4c82225f1e4a0b4d9b55/net/core/sock.c#L820
   331    constexpr int kRcvBufSz = 0;
   332    ASSERT_THAT(
   333        setsockopt(s_, SOL_SOCKET, SO_RCVBUF, &kRcvBufSz, sizeof(kRcvBufSz)),
   334        SyscallSucceeds());
   335  
   336    int min = 0;
   337    socklen_t min_len = sizeof(min);
   338    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_RCVBUF, &min, &min_len),
   339                SyscallSucceeds());
   340  
   341    // Linux doubles the value so let's use a value that when doubled will still
   342    // be smaller than min.
   343    int below_min = min / 2 - 1;
   344    ASSERT_THAT(
   345        setsockopt(s_, SOL_SOCKET, SO_RCVBUF, &below_min, sizeof(below_min)),
   346        SyscallSucceeds());
   347  
   348    int val = 0;
   349    socklen_t val_len = sizeof(val);
   350    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_RCVBUF, &val, &val_len),
   351                SyscallSucceeds());
   352  
   353    ASSERT_EQ(min, val);
   354  }
   355  
   356  // Check that setting SO_RCVBUF above max is clamped to the maximum
   357  // receive buffer size.
   358  TEST_P(RawPacketTest, SetSocketRecvBufAboveMax) {
   359    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   360  
   361    // Discover max buf size by trying to set the largest possible buffer size.
   362    constexpr int kRcvBufSz = 0xffffffff;
   363    ASSERT_THAT(
   364        setsockopt(s_, SOL_SOCKET, SO_RCVBUF, &kRcvBufSz, sizeof(kRcvBufSz)),
   365        SyscallSucceeds());
   366  
   367    int max = 0;
   368    socklen_t max_len = sizeof(max);
   369    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_RCVBUF, &max, &max_len),
   370                SyscallSucceeds());
   371  
   372    int above_max = max + 1;
   373    ASSERT_THAT(
   374        setsockopt(s_, SOL_SOCKET, SO_RCVBUF, &above_max, sizeof(above_max)),
   375        SyscallSucceeds());
   376  
   377    int val = 0;
   378    socklen_t val_len = sizeof(val);
   379    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_RCVBUF, &val, &val_len),
   380                SyscallSucceeds());
   381    ASSERT_EQ(max, val);
   382  }
   383  
   384  // Check that setting SO_RCVBUF min <= kRcvBufSz <= max is honored.
   385  TEST_P(RawPacketTest, SetSocketRecvBuf) {
   386    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   387  
   388    int max = 0;
   389    int min = 0;
   390    {
   391      // Discover max buf size by trying to set a really large buffer size.
   392      constexpr int kRcvBufSz = 0xffffffff;
   393      ASSERT_THAT(
   394          setsockopt(s_, SOL_SOCKET, SO_RCVBUF, &kRcvBufSz, sizeof(kRcvBufSz)),
   395          SyscallSucceeds());
   396  
   397      max = 0;
   398      socklen_t max_len = sizeof(max);
   399      ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_RCVBUF, &max, &max_len),
   400                  SyscallSucceeds());
   401    }
   402  
   403    {
   404      // Discover minimum buffer size by trying to set a zero size receive buffer
   405      // size.
   406      // See:
   407      // https://github.com/torvalds/linux/blob/a5dc8300df75e8b8384b4c82225f1e4a0b4d9b55/net/core/sock.c#L820
   408      constexpr int kRcvBufSz = 0;
   409      ASSERT_THAT(
   410          setsockopt(s_, SOL_SOCKET, SO_RCVBUF, &kRcvBufSz, sizeof(kRcvBufSz)),
   411          SyscallSucceeds());
   412  
   413      socklen_t min_len = sizeof(min);
   414      ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_RCVBUF, &min, &min_len),
   415                  SyscallSucceeds());
   416    }
   417  
   418    const int quarter_sz = min + (max - min) / 4;
   419    ASSERT_THAT(
   420        setsockopt(s_, SOL_SOCKET, SO_RCVBUF, &quarter_sz, sizeof(quarter_sz)),
   421        SyscallSucceeds());
   422  
   423    int val = 0;
   424    socklen_t val_len = sizeof(val);
   425    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_RCVBUF, &val, &val_len),
   426                SyscallSucceeds());
   427  
   428  #ifndef __Fuchsia__
   429    ASSERT_EQ(val, quarter_sz * 2);
   430  #else
   431    ASSERT_THAT(val, AnyOf(quarter_sz, quarter_sz * 2));
   432  #endif  // __Fuchsia__
   433  }
   434  
   435  // Check that setting SO_SNDBUF below min is clamped to the minimum
   436  // receive buffer size.
   437  TEST_P(RawPacketTest, SetSocketSendBufBelowMin) {
   438    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   439  
   440    // Discover minimum buffer size by trying to set it to zero.
   441    constexpr int kSndBufSz = 0;
   442    ASSERT_THAT(
   443        setsockopt(s_, SOL_SOCKET, SO_SNDBUF, &kSndBufSz, sizeof(kSndBufSz)),
   444        SyscallSucceeds());
   445  
   446    int min = 0;
   447    socklen_t min_len = sizeof(min);
   448    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_SNDBUF, &min, &min_len),
   449                SyscallSucceeds());
   450  
   451    // Linux doubles the value so let's use a value that when doubled will still
   452    // be smaller than min.
   453    int below_min = min / 2 - 1;
   454    ASSERT_THAT(
   455        setsockopt(s_, SOL_SOCKET, SO_SNDBUF, &below_min, sizeof(below_min)),
   456        SyscallSucceeds());
   457  
   458    int val = 0;
   459    socklen_t val_len = sizeof(val);
   460    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_SNDBUF, &val, &val_len),
   461                SyscallSucceeds());
   462  
   463    ASSERT_EQ(min, val);
   464  }
   465  
   466  // Check that setting SO_SNDBUF above max is clamped to the maximum
   467  // send buffer size.
   468  TEST_P(RawPacketTest, SetSocketSendBufAboveMax) {
   469    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   470  
   471    // Discover maximum buffer size by trying to set it to a large value.
   472    constexpr int kSndBufSz = 0xffffffff;
   473    ASSERT_THAT(
   474        setsockopt(s_, SOL_SOCKET, SO_SNDBUF, &kSndBufSz, sizeof(kSndBufSz)),
   475        SyscallSucceeds());
   476  
   477    int max = 0;
   478    socklen_t max_len = sizeof(max);
   479    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_SNDBUF, &max, &max_len),
   480                SyscallSucceeds());
   481  
   482    int above_max = max + 1;
   483    ASSERT_THAT(
   484        setsockopt(s_, SOL_SOCKET, SO_SNDBUF, &above_max, sizeof(above_max)),
   485        SyscallSucceeds());
   486  
   487    int val = 0;
   488    socklen_t val_len = sizeof(val);
   489    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_SNDBUF, &val, &val_len),
   490                SyscallSucceeds());
   491    ASSERT_EQ(max, val);
   492  }
   493  
   494  // Check that setting SO_SNDBUF min <= kSndBufSz <= max is honored.
   495  TEST_P(RawPacketTest, SetSocketSendBuf) {
   496    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   497  
   498    int max = 0;
   499    int min = 0;
   500    {
   501      // Discover maximum buffer size by trying to set it to a large value.
   502      constexpr int kSndBufSz = 0xffffffff;
   503      ASSERT_THAT(
   504          setsockopt(s_, SOL_SOCKET, SO_SNDBUF, &kSndBufSz, sizeof(kSndBufSz)),
   505          SyscallSucceeds());
   506  
   507      max = 0;
   508      socklen_t max_len = sizeof(max);
   509      ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_SNDBUF, &max, &max_len),
   510                  SyscallSucceeds());
   511    }
   512  
   513    {
   514      // Discover minimum buffer size by trying to set it to zero.
   515      constexpr int kSndBufSz = 0;
   516      ASSERT_THAT(
   517          setsockopt(s_, SOL_SOCKET, SO_SNDBUF, &kSndBufSz, sizeof(kSndBufSz)),
   518          SyscallSucceeds());
   519  
   520      socklen_t min_len = sizeof(min);
   521      ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_SNDBUF, &min, &min_len),
   522                  SyscallSucceeds());
   523    }
   524  
   525    const int quarter_sz = min + (max - min) / 4;
   526    ASSERT_THAT(
   527        setsockopt(s_, SOL_SOCKET, SO_SNDBUF, &quarter_sz, sizeof(quarter_sz)),
   528        SyscallSucceeds());
   529  
   530    int val = 0;
   531    socklen_t val_len = sizeof(val);
   532    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_SNDBUF, &val, &val_len),
   533                SyscallSucceeds());
   534  
   535  #ifndef __Fuchsia__
   536    ASSERT_EQ(val, quarter_sz * 2);
   537  #else
   538    ASSERT_THAT(val, AnyOf(quarter_sz, quarter_sz * 2));
   539  #endif  // __Fuchsia__
   540  }
   541  
   542  TEST_P(RawPacketTest, GetSocketError) {
   543    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   544  
   545    int val = 0;
   546    socklen_t val_len = sizeof(val);
   547    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_ERROR, &val, &val_len),
   548                SyscallSucceeds());
   549    ASSERT_EQ(val, 0);
   550  }
   551  
   552  TEST_P(RawPacketTest, GetSocketErrorBind) {
   553    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   554  
   555    {
   556      // Bind to the loopback device.
   557      struct sockaddr_ll bind_addr = {};
   558      bind_addr.sll_family = AF_PACKET;
   559      bind_addr.sll_protocol = htons(GetParam());
   560      bind_addr.sll_ifindex = GetLoopbackIndex();
   561  
   562      ASSERT_THAT(bind(s_, reinterpret_cast<struct sockaddr*>(&bind_addr),
   563                       sizeof(bind_addr)),
   564                  SyscallSucceeds());
   565  
   566      // SO_ERROR should return no errors.
   567      int val = 0;
   568      socklen_t val_len = sizeof(val);
   569      ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_ERROR, &val, &val_len),
   570                  SyscallSucceeds());
   571      ASSERT_EQ(val, 0);
   572    }
   573  
   574    {
   575      // Now try binding to an invalid interface.
   576      struct sockaddr_ll bind_addr = {};
   577      bind_addr.sll_family = AF_PACKET;
   578      bind_addr.sll_protocol = htons(GetParam());
   579      bind_addr.sll_ifindex = 0xffff;  // Just pick a really large number.
   580  
   581      // Binding should fail with EINVAL
   582      ASSERT_THAT(bind(s_, reinterpret_cast<struct sockaddr*>(&bind_addr),
   583                       sizeof(bind_addr)),
   584                  SyscallFailsWithErrno(ENODEV));
   585  
   586      // SO_ERROR does not return error when the device is invalid.
   587      // On Linux there is just one odd ball condition where this can return
   588      // an error where the device was valid and then removed or disabled
   589      // between the first check for index and the actual registration of
   590      // the packet endpoint. On Netstack this is not possible as the stack
   591      // global mutex is held during registration and check.
   592      int val = 0;
   593      socklen_t val_len = sizeof(val);
   594      ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_ERROR, &val, &val_len),
   595                  SyscallSucceeds());
   596      ASSERT_EQ(val, 0);
   597    }
   598  }
   599  
   600  TEST_P(RawPacketTest, SetSocketDetachFilterNoInstalledFilter) {
   601    // TODO(gvisor.dev/2746): Support SO_ATTACH_FILTER/SO_DETACH_FILTER.
   602    //
   603    // gVisor returns no error on SO_DETACH_FILTER even if there is no filter
   604    // attached unlike linux which does return ENOENT in such cases. This is
   605    // because gVisor doesn't support SO_ATTACH_FILTER and just silently returns
   606    // success.
   607    if (IsRunningOnGvisor()) {
   608      constexpr int val = 0;
   609      ASSERT_THAT(setsockopt(s_, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val)),
   610                  SyscallSucceeds());
   611      return;
   612    }
   613    constexpr int val = 0;
   614    ASSERT_THAT(setsockopt(s_, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val)),
   615                SyscallFailsWithErrno(ENOENT));
   616  }
   617  
   618  TEST_P(RawPacketTest, GetSocketDetachFilter) {
   619    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   620  
   621    int val = 0;
   622    socklen_t val_len = sizeof(val);
   623    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_DETACH_FILTER, &val, &val_len),
   624                SyscallFailsWithErrno(ENOPROTOOPT));
   625  }
   626  
   627  TEST_P(RawPacketTest, SetAndGetSocketLinger) {
   628    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   629  
   630    int level = SOL_SOCKET;
   631    int type = SO_LINGER;
   632  
   633    struct linger sl;
   634    sl.l_onoff = 1;
   635    sl.l_linger = 5;
   636    ASSERT_THAT(setsockopt(s_, level, type, &sl, sizeof(sl)),
   637                SyscallSucceedsWithValue(0));
   638  
   639    struct linger got_linger = {};
   640    socklen_t length = sizeof(sl);
   641    ASSERT_THAT(getsockopt(s_, level, type, &got_linger, &length),
   642                SyscallSucceedsWithValue(0));
   643  
   644    ASSERT_EQ(length, sizeof(got_linger));
   645    EXPECT_EQ(0, memcmp(&sl, &got_linger, length));
   646  }
   647  
   648  TEST_P(RawPacketTest, GetSocketAcceptConn) {
   649    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   650  
   651    int got = -1;
   652    socklen_t length = sizeof(got);
   653    ASSERT_THAT(getsockopt(s_, SOL_SOCKET, SO_ACCEPTCONN, &got, &length),
   654                SyscallSucceedsWithValue(0));
   655  
   656    ASSERT_EQ(length, sizeof(got));
   657    EXPECT_EQ(got, 0);
   658  }
   659  INSTANTIATE_TEST_SUITE_P(AllInetTests, RawPacketTest,
   660                           ::testing::Values(ETH_P_IP, ETH_P_ALL));
   661  
   662  class RawPacketMsgSizeTest : public ::testing::TestWithParam<TestAddress> {};
   663  
   664  TEST_P(RawPacketMsgSizeTest, SendTooLong) {
   665    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   666  
   667    TestAddress addr = GetParam().WithPort(kPort);
   668  
   669    FileDescriptor udp_sock =
   670        ASSERT_NO_ERRNO_AND_VALUE(Socket(addr.family(), SOCK_RAW, IPPROTO_UDP));
   671  
   672    ASSERT_THAT(
   673        connect(udp_sock.get(), reinterpret_cast<struct sockaddr*>(&addr.addr),
   674                addr.addr_len),
   675        SyscallSucceeds());
   676  
   677    const char buf[65536] = {};
   678    ASSERT_THAT(send(udp_sock.get(), buf, sizeof(buf), 0),
   679                SyscallFailsWithErrno(EMSGSIZE));
   680  }
   681  
   682  // TODO(https://fxbug.dev/42156918): Run this test on Fuchsia once splice is
   683  // available.
   684  #ifndef __Fuchsia__
   685  TEST_P(RawPacketMsgSizeTest, SpliceTooLong) {
   686    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HavePacketSocketCapability()));
   687  
   688    const char buf[65536] = {};
   689    int fds[2];
   690    ASSERT_THAT(pipe(fds), SyscallSucceeds());
   691    ASSERT_THAT(write(fds[1], buf, sizeof(buf)),
   692                SyscallSucceedsWithValue(sizeof(buf)));
   693  
   694    TestAddress addr = GetParam().WithPort(kPort);
   695  
   696    FileDescriptor udp_sock =
   697        ASSERT_NO_ERRNO_AND_VALUE(Socket(addr.family(), SOCK_RAW, IPPROTO_UDP));
   698  
   699    ASSERT_THAT(
   700        connect(udp_sock.get(), reinterpret_cast<struct sockaddr*>(&addr.addr),
   701                addr.addr_len),
   702        SyscallSucceeds());
   703  
   704    ssize_t n = splice(fds[0], nullptr, udp_sock.get(), nullptr, sizeof(buf), 0);
   705    if (IsRunningOnGvisor()) {
   706      EXPECT_THAT(n, SyscallFailsWithErrno(EMSGSIZE));
   707    } else {
   708      // TODO(gvisor.dev/issue/138): Linux sends out multiple UDP datagrams, each
   709      // of the size of a page.
   710      EXPECT_THAT(n, SyscallSucceedsWithValue(sizeof(buf)));
   711    }
   712  }
   713  #endif  // __Fuchsia__
   714  
   715  INSTANTIATE_TEST_SUITE_P(AllRawPacketMsgSizeTest, RawPacketMsgSizeTest,
   716                           ::testing::Values(V4Loopback(), V6Loopback()));
   717  
   718  }  // namespace
   719  
   720  }  // namespace testing
   721  }  // namespace gvisor