github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/runner/setup_container/setup_container.cc (about) 1 // Copyright 2021 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 <linux/capability.h> 16 #include <sys/ioctl.h> 17 #include <unistd.h> 18 19 #include "test/syscalls/linux/socket_netlink_util.h" 20 #include "test/syscalls/linux/socket_test_util.h" 21 #include "test/util/capability_util.h" 22 #include "test/util/posix_error.h" 23 24 namespace gvisor { 25 namespace testing { 26 27 // SetupContainer sets up the networking settings in the current container. 28 PosixError SetupContainer() { 29 const PosixErrorOr<bool> have_net_admin = HaveCapability(CAP_NET_ADMIN); 30 if (!have_net_admin.ok()) { 31 std::cerr << "Cannot determine if we have CAP_NET_ADMIN." << std::endl; 32 return have_net_admin.error(); 33 } 34 if (have_net_admin.ValueOrDie() && !IsRunningOnGvisor()) { 35 PosixErrorOr<FileDescriptor> sockfd = Socket(AF_INET, SOCK_DGRAM, 0); 36 if (!sockfd.ok()) { 37 std::cerr << "Cannot open socket." << std::endl; 38 return sockfd.error(); 39 } 40 int sock = sockfd.ValueOrDie().get(); 41 struct ifreq ifr = {}; 42 strncpy(ifr.ifr_name, "lo", IFNAMSIZ); 43 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { 44 std::cerr << "Cannot get 'lo' flags: " << strerror(errno) << std::endl; 45 return PosixError(errno); 46 } 47 if ((ifr.ifr_flags & IFF_UP) == 0) { 48 ifr.ifr_flags |= IFF_UP; 49 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { 50 std::cerr << "Cannot set 'lo' as UP: " << strerror(errno) << std::endl; 51 return PosixError(errno); 52 } 53 } 54 } 55 return NoError(); 56 } 57 58 } // namespace testing 59 } // namespace gvisor 60 61 using ::gvisor::testing::SetupContainer; 62 63 // Binary setup_container initializes the container environment in which tests 64 // with container=True will run, then execs the actual test binary. 65 // Usage: 66 // ./setup_container test_binary [arguments forwarded to test_binary...] 67 int main(int argc, char *argv[], char *envp[]) { 68 if (!SetupContainer().ok()) { 69 return 1; 70 } 71 if (argc < 2) { 72 std::cerr << "Must provide arguments to exec." << std::endl; 73 return 2; 74 } 75 if (execve(argv[1], &argv[1], envp) == -1) { 76 std::cerr << "execv returned errno " << errno << std::endl; 77 return 1; 78 } 79 }