1 // SPDX-License-Identifier: GPL-2.0 2 #define _GNU_SOURCE 3 #include <errno.h> 4 #include <fcntl.h> 5 #include <limits.h> 6 #include <sched.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <sys/ioctl.h> 11 #include <sys/socket.h> 12 #include <sys/stat.h> 13 #include <sys/types.h> 14 #include <sys/wait.h> 15 #include <unistd.h> 16 #include <linux/if.h> 17 #include <linux/sockios.h> 18 #include <linux/nsfs.h> 19 #include <arpa/inet.h> 20 #include "../kselftest_harness.h" 21 #include "../filesystems/utils.h" 22 #include "wrappers.h" 23 24 #ifndef SIOCGSKNS 25 #define SIOCGSKNS 0x894C 26 #endif 27 28 #ifndef FD_NSFS_ROOT 29 #define FD_NSFS_ROOT -10003 30 #endif 31 32 #ifndef FILEID_NSFS 33 #define FILEID_NSFS 0xf1 34 #endif 35 36 /* 37 * Test basic SIOCGSKNS functionality. 38 * Create a socket and verify SIOCGSKNS returns the correct network namespace. 39 */ 40 TEST(siocgskns_basic) 41 { 42 int sock_fd, netns_fd, current_netns_fd; 43 struct stat st1, st2; 44 45 /* Create a TCP socket */ 46 sock_fd = socket(AF_INET, SOCK_STREAM, 0); 47 ASSERT_GE(sock_fd, 0); 48 49 /* Use SIOCGSKNS to get network namespace */ 50 netns_fd = ioctl(sock_fd, SIOCGSKNS); 51 if (netns_fd < 0) { 52 close(sock_fd); 53 if (errno == ENOTTY || errno == EINVAL) 54 SKIP(return, "SIOCGSKNS not supported"); 55 ASSERT_GE(netns_fd, 0); 56 } 57 58 /* Get current network namespace */ 59 current_netns_fd = open("/proc/self/ns/net", O_RDONLY); 60 ASSERT_GE(current_netns_fd, 0); 61 62 /* Verify they match */ 63 ASSERT_EQ(fstat(netns_fd, &st1), 0); 64 ASSERT_EQ(fstat(current_netns_fd, &st2), 0); 65 ASSERT_EQ(st1.st_ino, st2.st_ino); 66 67 close(sock_fd); 68 close(netns_fd); 69 close(current_netns_fd); 70 } 71 72 TEST_HARNESS_MAIN 73