gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/socket_bind_to_device_sequence.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 <linux/capability.h>
    17  #include <linux/if_tun.h>
    18  #include <net/if.h>
    19  #include <netinet/in.h>
    20  #include <sys/ioctl.h>
    21  #include <sys/socket.h>
    22  #include <sys/types.h>
    23  #include <sys/un.h>
    24  
    25  #include <cstdio>
    26  #include <cstring>
    27  #include <map>
    28  #include <memory>
    29  #include <unordered_map>
    30  #include <unordered_set>
    31  #include <utility>
    32  #include <vector>
    33  
    34  #include "gmock/gmock.h"
    35  #include "gtest/gtest.h"
    36  #include "absl/container/node_hash_map.h"
    37  #include "test/syscalls/linux/ip_socket_test_util.h"
    38  #include "test/syscalls/linux/socket_bind_to_device_util.h"
    39  #include "test/util/capability_util.h"
    40  #include "test/util/socket_util.h"
    41  #include "test/util/test_util.h"
    42  #include "test/util/thread_util.h"
    43  
    44  namespace gvisor {
    45  namespace testing {
    46  
    47  using std::string;
    48  using std::vector;
    49  
    50  // Test fixture for SO_BINDTODEVICE tests the results of sequences of socket
    51  // binding.
    52  class BindToDeviceSequenceTest : public ::testing::TestWithParam<SocketKind> {
    53   protected:
    54    void SetUp() override {
    55      printf("Testing case: %s\n", GetParam().description.c_str());
    56      ASSERT_TRUE(ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW)))
    57          << "CAP_NET_RAW is required to use SO_BINDTODEVICE";
    58      socket_factory_ = GetParam();
    59  
    60      interface_names_ = GetInterfaceNames();
    61    }
    62  
    63    PosixErrorOr<std::unique_ptr<FileDescriptor>> NewSocket() const {
    64      return socket_factory_.Create();
    65    }
    66  
    67    // Gets a device by device_id.  If the device_id has been seen before, returns
    68    // the previously returned device.  If not, finds or creates a new device.
    69    // Returns an empty string on failure.
    70    void GetDevice(int device_id, string* device_name) {
    71      auto device = devices_.find(device_id);
    72      if (device != devices_.end()) {
    73        *device_name = device->second;
    74        return;
    75      }
    76  
    77      // Need to pick a new device.  Try ethernet first.
    78      *device_name = absl::StrCat("eth", next_unused_eth_);
    79      if (interface_names_.find(*device_name) != interface_names_.end()) {
    80        devices_[device_id] = *device_name;
    81        next_unused_eth_++;
    82        return;
    83      }
    84  
    85      // Need to make a new tunnel device.  gVisor tests should have enough
    86      // ethernet devices to never reach here.
    87      ASSERT_FALSE(IsRunningOnGvisor());
    88      // Need a tunnel.
    89      tunnels_.push_back(ASSERT_NO_ERRNO_AND_VALUE(Tunnel::New()));
    90      devices_[device_id] = tunnels_.back()->GetName();
    91      *device_name = devices_[device_id];
    92    }
    93  
    94    // Release the socket
    95    void ReleaseSocket(int socket_id) {
    96      // Close the socket that was made in a previous action.  The socket_id
    97      // indicates which socket to close based on index into the list of actions.
    98      sockets_to_close_.erase(socket_id);
    99    }
   100  
   101    // SetDevice changes the bind_to_device option. It does not bind or re-bind.
   102    void SetDevice(int socket_id, int device_id) {
   103      auto socket_fd = sockets_to_close_[socket_id]->get();
   104      string device_name;
   105      ASSERT_NO_FATAL_FAILURE(GetDevice(device_id, &device_name));
   106      EXPECT_THAT(setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE,
   107                             device_name.c_str(), device_name.size() + 1),
   108                  SyscallSucceedsWithValue(0));
   109    }
   110  
   111    // Bind a socket with the reuse options and bind_to_device options. Checks
   112    // that all steps succeed and that the bind command's error matches want.
   113    // Sets the socket_id to uniquely identify the socket bound if it is not
   114    // nullptr.
   115    void BindSocket(bool reuse_port, bool reuse_addr, int device_id = 0,
   116                    int want = 0, int* socket_id = nullptr) {
   117      next_socket_id_++;
   118      sockets_to_close_[next_socket_id_] = ASSERT_NO_ERRNO_AND_VALUE(NewSocket());
   119      auto socket_fd = sockets_to_close_[next_socket_id_]->get();
   120      if (socket_id != nullptr) {
   121        *socket_id = next_socket_id_;
   122      }
   123  
   124      // If reuse_port is indicated, do that.
   125      if (reuse_port) {
   126        EXPECT_THAT(setsockopt(socket_fd, SOL_SOCKET, SO_REUSEPORT, &kSockOptOn,
   127                               sizeof(kSockOptOn)),
   128                    SyscallSucceedsWithValue(0));
   129      }
   130  
   131      // If reuse_addr is indicated, do that.
   132      if (reuse_addr) {
   133        EXPECT_THAT(setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &kSockOptOn,
   134                               sizeof(kSockOptOn)),
   135                    SyscallSucceedsWithValue(0));
   136      }
   137  
   138      // If the device is non-zero, bind to that device.
   139      if (device_id != 0) {
   140        string device_name;
   141        ASSERT_NO_FATAL_FAILURE(GetDevice(device_id, &device_name));
   142        EXPECT_THAT(setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE,
   143                               device_name.c_str(), device_name.size() + 1),
   144                    SyscallSucceedsWithValue(0));
   145        char get_device[100];
   146        socklen_t get_device_size = 100;
   147        EXPECT_THAT(getsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE, get_device,
   148                               &get_device_size),
   149                    SyscallSucceedsWithValue(0));
   150      }
   151  
   152      struct sockaddr_in addr = {};
   153      addr.sin_family = AF_INET;
   154      addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   155      addr.sin_port = port_;
   156      if (want == 0) {
   157        ASSERT_THAT(
   158            bind(socket_fd, reinterpret_cast<const struct sockaddr*>(&addr),
   159                 sizeof(addr)),
   160            SyscallSucceeds());
   161      } else {
   162        ASSERT_THAT(
   163            bind(socket_fd, reinterpret_cast<const struct sockaddr*>(&addr),
   164                 sizeof(addr)),
   165            SyscallFailsWithErrno(want));
   166      }
   167  
   168      if (port_ == 0) {
   169        // We don't yet know what port we'll be using so we need to fetch it and
   170        // remember it for future commands.
   171        socklen_t addr_size = sizeof(addr);
   172        ASSERT_THAT(
   173            getsockname(socket_fd, reinterpret_cast<struct sockaddr*>(&addr),
   174                        &addr_size),
   175            SyscallSucceeds());
   176        port_ = addr.sin_port;
   177      }
   178    }
   179  
   180   private:
   181    SocketKind socket_factory_;
   182    // devices maps from the device id in the test case to the name of the device.
   183    absl::node_hash_map<int, string> devices_;
   184    // These are the tunnels that were created for the test and will be destroyed
   185    // by the destructor.
   186    vector<std::unique_ptr<Tunnel>> tunnels_;
   187    // A list of all interface names before the test started.
   188    std::unordered_set<string> interface_names_;
   189    // The next ethernet device to use when requested a device.
   190    int next_unused_eth_ = 1;
   191    // The port for all tests.  Originally 0 (any) and later set to the port that
   192    // all further commands will use.
   193    in_port_t port_ = 0;
   194    // sockets_to_close_ is a map from action index to the socket that was
   195    // created.
   196    absl::node_hash_map<int,
   197                        std::unique_ptr<gvisor::testing::FileDescriptor>>
   198        sockets_to_close_;
   199    int next_socket_id_ = 0;
   200  };
   201  
   202  TEST_P(BindToDeviceSequenceTest, BindTwiceWithDeviceFails) {
   203    ASSERT_NO_FATAL_FAILURE(BindSocket(
   204        /* reuse_port */ false, /* reuse_addr */ false, /* bind_to_device */ 3));
   205    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   206                                       /* reuse_addr */ false,
   207                                       /* bind_to_device */ 3, EADDRINUSE));
   208  }
   209  
   210  TEST_P(BindToDeviceSequenceTest, BindToDevice) {
   211    ASSERT_NO_FATAL_FAILURE(BindSocket(
   212        /* reuse_port */ false, /* reuse_addr */ false, /* bind_to_device */ 1));
   213    ASSERT_NO_FATAL_FAILURE(BindSocket(
   214        /* reuse_port */ false, /* reuse_addr */ false, /* bind_to_device */ 2));
   215  }
   216  
   217  TEST_P(BindToDeviceSequenceTest, BindToDeviceAndThenWithoutDevice) {
   218    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   219                                       /* reuse_addr */ false,
   220                                       /* bind_to_device */ 123));
   221    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   222                                       /* reuse_addr */ false,
   223                                       /* bind_to_device */ 0, EADDRINUSE));
   224  }
   225  
   226  TEST_P(BindToDeviceSequenceTest, BindWithoutDevice) {
   227    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   228                                       /* reuse_addr */ false));
   229    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   230                                       /* reuse_addr */ false,
   231                                       /* bind_to_device */ 123, EADDRINUSE));
   232    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   233                                       /* reuse_addr */ false,
   234                                       /* bind_to_device */ 123, EADDRINUSE));
   235    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   236                                       /* reuse_addr */ false,
   237                                       /* bind_to_device */ 0, EADDRINUSE));
   238    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   239                                       /* reuse_addr */ false,
   240                                       /* bind_to_device */ 0, EADDRINUSE));
   241  }
   242  
   243  TEST_P(BindToDeviceSequenceTest, BindWithDevice) {
   244    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   245                                       /* reuse_addr */ false,
   246                                       /* bind_to_device */ 123, 0));
   247    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   248                                       /* reuse_addr */ false,
   249                                       /* bind_to_device */ 123, EADDRINUSE));
   250    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   251                                       /* reuse_addr */ false,
   252                                       /* bind_to_device */ 123, EADDRINUSE));
   253    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   254                                       /* reuse_addr */ false,
   255                                       /* bind_to_device */ 0, EADDRINUSE));
   256    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   257                                       /* reuse_addr */ false,
   258                                       /* bind_to_device */ 0, EADDRINUSE));
   259    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   260                                       /* reuse_addr */ false,
   261                                       /* bind_to_device */ 456, 0));
   262    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   263                                       /* reuse_addr */ false,
   264                                       /* bind_to_device */ 789, 0));
   265    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   266                                       /* reuse_addr */ false,
   267                                       /* bind_to_device */ 0, EADDRINUSE));
   268    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   269                                       /* reuse_addr */ false,
   270                                       /* bind_to_device */ 0, EADDRINUSE));
   271  }
   272  
   273  TEST_P(BindToDeviceSequenceTest, BindWithReuse) {
   274    ASSERT_NO_FATAL_FAILURE(
   275        BindSocket(/* reusePort */ true, /* reuse_addr */ false));
   276    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   277                                       /* reuse_addr */ false,
   278                                       /* bind_to_device */ 123, EADDRINUSE));
   279    ASSERT_NO_FATAL_FAILURE(BindSocket(
   280        /* reuse_port */ true, /* reuse_addr */ false,
   281        /* bind_to_device */ 123));
   282    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   283                                       /* reuse_addr */ false,
   284                                       /* bind_to_device */ 0, EADDRINUSE));
   285    ASSERT_NO_FATAL_FAILURE(BindSocket(
   286        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 0));
   287  }
   288  
   289  TEST_P(BindToDeviceSequenceTest, BindingWithReuseAndDevice) {
   290    ASSERT_NO_FATAL_FAILURE(BindSocket(
   291        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 123));
   292    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   293                                       /* reuse_addr */ false,
   294                                       /* bind_to_device */ 123, EADDRINUSE));
   295    ASSERT_NO_FATAL_FAILURE(BindSocket(
   296        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 123));
   297    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   298                                       /* reuse_addr */ false,
   299                                       /* bind_to_device */ 0, EADDRINUSE));
   300    ASSERT_NO_FATAL_FAILURE(BindSocket(
   301        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 456));
   302    ASSERT_NO_FATAL_FAILURE(
   303        BindSocket(/* reuse_port */ true, /* reuse_addr */ false));
   304    ASSERT_NO_FATAL_FAILURE(BindSocket(
   305        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 789));
   306    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   307                                       /* reuse_addr */ false,
   308                                       /* bind_to_device */ 999, EADDRINUSE));
   309  }
   310  
   311  TEST_P(BindToDeviceSequenceTest, MixingReuseAndNotReuseByBindingToDevice) {
   312    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   313                                       /* reuse_addr */ false,
   314                                       /* bind_to_device */ 123, 0));
   315    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   316                                       /* reuse_addr */ false,
   317                                       /* bind_to_device */ 456, 0));
   318    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   319                                       /* reuse_addr */ false,
   320                                       /* bind_to_device */ 789, 0));
   321    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   322                                       /* reuse_addr */ false,
   323                                       /* bind_to_device */ 999, 0));
   324  }
   325  
   326  TEST_P(BindToDeviceSequenceTest, CannotBindTo0AfterMixingReuseAndNotReuse) {
   327    ASSERT_NO_FATAL_FAILURE(BindSocket(
   328        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 123));
   329    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   330                                       /* reuse_addr */ false,
   331                                       /* bind_to_device */ 456));
   332    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   333                                       /* reuse_addr */ false,
   334                                       /* bind_to_device */ 0, EADDRINUSE));
   335  }
   336  
   337  TEST_P(BindToDeviceSequenceTest, BindAndRelease) {
   338    ASSERT_NO_FATAL_FAILURE(BindSocket(
   339        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 123));
   340    int to_release;
   341    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   342                                       /* reuse_addr */ false,
   343                                       /* bind_to_device */ 0, 0, &to_release));
   344    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   345                                       /* reuse_addr */ false,
   346                                       /* bind_to_device */ 345, EADDRINUSE));
   347    ASSERT_NO_FATAL_FAILURE(BindSocket(
   348        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 789));
   349    // Release the bind to device 0 and try again.
   350    ASSERT_NO_FATAL_FAILURE(ReleaseSocket(to_release));
   351    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   352                                       /* reuse_addr */ false,
   353                                       /* bind_to_device */ 345));
   354  }
   355  
   356  TEST_P(BindToDeviceSequenceTest, BindTwiceWithReuseOnce) {
   357    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   358                                       /* reuse_addr */ false,
   359                                       /* bind_to_device */ 123));
   360    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   361                                       /* reuse_addr */ false,
   362                                       /* bind_to_device */ 0, EADDRINUSE));
   363  }
   364  
   365  TEST_P(BindToDeviceSequenceTest, BindWithReuseAddr) {
   366    ASSERT_NO_FATAL_FAILURE(
   367        BindSocket(/* reusePort */ false, /* reuse_addr */ true));
   368    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   369                                       /* reuse_addr */ false,
   370                                       /* bind_to_device */ 123, EADDRINUSE));
   371    ASSERT_NO_FATAL_FAILURE(BindSocket(
   372        /* reuse_port */ false, /* reuse_addr */ true, /* bind_to_device */ 123));
   373    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   374                                       /* reuse_addr */ false,
   375                                       /* bind_to_device */ 0, EADDRINUSE));
   376    ASSERT_NO_FATAL_FAILURE(BindSocket(
   377        /* reuse_port */ false, /* reuse_addr */ true, /* bind_to_device */ 0));
   378  }
   379  
   380  TEST_P(BindToDeviceSequenceTest,
   381         CannotBindTo0AfterMixingReuseAddrAndNotReuseAddr) {
   382    ASSERT_NO_FATAL_FAILURE(BindSocket(
   383        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 123));
   384    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   385                                       /* reuse_addr */ false,
   386                                       /* bind_to_device */ 456));
   387    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   388                                       /* reuse_addr */ true,
   389                                       /* bind_to_device */ 0, EADDRINUSE));
   390  }
   391  
   392  TEST_P(BindToDeviceSequenceTest, BindReuseAddrReusePortThenReusePort) {
   393    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   394                                       /* reuse_addr */ true,
   395                                       /* bind_to_device */ 0));
   396    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   397                                       /* reuse_addr */ false,
   398                                       /* bind_to_device */ 0));
   399    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   400                                       /* reuse_addr */ true,
   401                                       /* bind_to_device */ 0, EADDRINUSE));
   402  }
   403  
   404  TEST_P(BindToDeviceSequenceTest, BindReuseAddrReusePortThenReuseAddr) {
   405    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   406                                       /* reuse_addr */ true,
   407                                       /* bind_to_device */ 0));
   408    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   409                                       /* reuse_addr */ true,
   410                                       /* bind_to_device */ 0));
   411    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   412                                       /* reuse_addr */ false,
   413                                       /* bind_to_device */ 0, EADDRINUSE));
   414  }
   415  
   416  TEST_P(BindToDeviceSequenceTest, BindDoubleReuseAddrReusePortThenReusePort) {
   417    ASSERT_NO_FATAL_FAILURE(BindSocket(
   418        /* reuse_port */ true, /* reuse_addr */ true, /* bind_to_device */ 0));
   419    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   420                                       /* reuse_addr */ true,
   421                                       /* bind_to_device */ 0));
   422    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   423                                       /* reuse_addr */ false,
   424                                       /* bind_to_device */ 0));
   425    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   426                                       /* reuse_addr */ true,
   427                                       /* bind_to_device */ 0, EADDRINUSE));
   428  }
   429  
   430  TEST_P(BindToDeviceSequenceTest, BindDoubleReuseAddrReusePortThenReuseAddr) {
   431    ASSERT_NO_FATAL_FAILURE(BindSocket(
   432        /* reuse_port */ true, /* reuse_addr */ true, /* bind_to_device */ 0));
   433    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   434                                       /* reuse_addr */ true,
   435                                       /* bind_to_device */ 0));
   436    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   437                                       /* reuse_addr */ true,
   438                                       /* bind_to_device */ 0));
   439    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   440                                       /* reuse_addr */ false,
   441                                       /* bind_to_device */ 0, EADDRINUSE));
   442  }
   443  
   444  TEST_P(BindToDeviceSequenceTest, BindReusePortThenReuseAddrReusePort) {
   445    ASSERT_NO_FATAL_FAILURE(BindSocket(
   446        /* reuse_port */ true, /* reuse_addr */ false, /* bind_to_device */ 0));
   447    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   448                                       /* reuse_addr */ true,
   449                                       /* bind_to_device */ 0));
   450    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   451                                       /* reuse_addr */ true,
   452                                       /* bind_to_device */ 0, EADDRINUSE));
   453  }
   454  
   455  TEST_P(BindToDeviceSequenceTest, BindReuseAddrThenReuseAddr) {
   456    ASSERT_NO_FATAL_FAILURE(BindSocket(
   457        /* reuse_port */ false, /* reuse_addr */ true, /* bind_to_device */ 0));
   458    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   459                                       /* reuse_addr */ false,
   460                                       /* bind_to_device */ 0, EADDRINUSE));
   461  }
   462  
   463  TEST_P(BindToDeviceSequenceTest,
   464         BindReuseAddrThenReuseAddrReusePortThenReuseAddr) {
   465    // The behavior described in this test seems like a Linux bug. It doesn't
   466    // make any sense and it is unlikely that any applications rely on it.
   467    //
   468    // Both SO_REUSEADDR and SO_REUSEPORT allow binding multiple UDP sockets to
   469    // the same address and deliver each packet to exactly one of the bound
   470    // sockets. If both are enabled, one of the strategies is selected to route
   471    // packets. The strategy is selected dynamically based on the settings of the
   472    // currently bound sockets. Usually, the strategy is selected based on the
   473    // common setting (SO_REUSEADDR or SO_REUSEPORT) amongst the sockets, but for
   474    // some reason, Linux allows binding sets of sockets with no overlapping
   475    // settings in some situations. In this case, it is not obvious which strategy
   476    // would be selected as the configured setting is a contradiction.
   477    SKIP_IF(IsRunningOnGvisor());
   478  
   479    ASSERT_NO_FATAL_FAILURE(BindSocket(
   480        /* reuse_port */ false, /* reuse_addr */ true, /* bind_to_device */ 0));
   481    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   482                                       /* reuse_addr */ true,
   483                                       /* bind_to_device */ 0));
   484    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ true,
   485                                       /* reuse_addr */ false,
   486                                       /* bind_to_device */ 0));
   487  }
   488  
   489  // Repro test for gvisor.dev/issue/1217. Not replicated in ports_test.go as this
   490  // test is different from the others and wouldn't fit well there.
   491  TEST_P(BindToDeviceSequenceTest, BindAndReleaseDifferentDevice) {
   492    int to_release;
   493    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   494                                       /* reuse_addr */ false,
   495                                       /* bind_to_device */ 3, 0, &to_release));
   496    ASSERT_NO_FATAL_FAILURE(BindSocket(/* reuse_port */ false,
   497                                       /* reuse_addr */ false,
   498                                       /* bind_to_device */ 3, EADDRINUSE));
   499    // Change the device. Since the socket was already bound, this should have no
   500    // effect.
   501    SetDevice(to_release, 2);
   502    // Release the bind to device 3 and try again.
   503    ASSERT_NO_FATAL_FAILURE(ReleaseSocket(to_release));
   504    ASSERT_NO_FATAL_FAILURE(BindSocket(
   505        /* reuse_port */ false, /* reuse_addr */ false, /* bind_to_device */ 3));
   506  }
   507  
   508  INSTANTIATE_TEST_SUITE_P(BindToDeviceTest, BindToDeviceSequenceTest,
   509                           ::testing::Values(IPv4UDPUnboundSocket(0),
   510                                             IPv4TCPUnboundSocket(0)));
   511  
   512  }  // namespace testing
   513  }  // namespace gvisor