ipnetns.c revision 33724939097b8ebb5c37cc0dc2b5e57fe342c8fe
10dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#define _ATFILE_SOURCE 20dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <sys/types.h> 30dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <sys/stat.h> 40dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <sys/wait.h> 50dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <sys/inotify.h> 60dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <sys/mount.h> 70dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <sys/param.h> 80dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <sys/syscall.h> 90dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <stdio.h> 100dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <string.h> 110dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <sched.h> 120dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <fcntl.h> 130dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <dirent.h> 140dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <errno.h> 150dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include <unistd.h> 169a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman#include <ctype.h> 170dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 180dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include "utils.h" 190dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman#include "ip_common.h" 20eb67e4498aec35eb16eaf894329f85b6316dabe8Vadim Kochan#include "namespace.h" 210dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 228e2d47dce288d5a60d8c67f537860a3683d36df6Eric W. Biedermanstatic int usage(void) 230dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman{ 240dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fprintf(stderr, "Usage: ip netns list\n"); 250dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fprintf(stderr, " ip netns add NAME\n"); 2633724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan fprintf(stderr, " ip [-all] netns delete [NAME]\n"); 270948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk fprintf(stderr, " ip netns identify [PID]\n"); 289a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, " ip netns pids NAME\n"); 29b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan fprintf(stderr, " ip [-all] netns exec [NAME] cmd ...\n"); 300dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fprintf(stderr, " ip netns monitor\n"); 31a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger exit(-1); 320dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman} 330dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 340dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biedermanstatic int netns_list(int argc, char **argv) 350dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman{ 360dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman struct dirent *entry; 370dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman DIR *dir; 380dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 390dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman dir = opendir(NETNS_RUN_DIR); 400dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (!dir) 41a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return 0; 420dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 430dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman while ((entry = readdir(dir)) != NULL) { 440dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (strcmp(entry->d_name, ".") == 0) 450dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman continue; 460dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (strcmp(entry->d_name, "..") == 0) 470dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman continue; 480dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman printf("%s\n", entry->d_name); 490dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 500dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman closedir(dir); 51a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return 0; 520dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman} 530dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 54b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochanstatic int cmd_exec(const char *cmd, char **argv, bool do_fork) 550dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman{ 5695592b47be09bd9347026ff9aa298fc097733e56JunweiZhang fflush(stdout); 57b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan if (do_fork) { 5895592b47be09bd9347026ff9aa298fc097733e56JunweiZhang int status; 5995592b47be09bd9347026ff9aa298fc097733e56JunweiZhang pid_t pid; 6095592b47be09bd9347026ff9aa298fc097733e56JunweiZhang 6195592b47be09bd9347026ff9aa298fc097733e56JunweiZhang pid = fork(); 6295592b47be09bd9347026ff9aa298fc097733e56JunweiZhang if (pid < 0) { 6395592b47be09bd9347026ff9aa298fc097733e56JunweiZhang perror("fork"); 64a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger exit(1); 6595592b47be09bd9347026ff9aa298fc097733e56JunweiZhang } 6695592b47be09bd9347026ff9aa298fc097733e56JunweiZhang 6795592b47be09bd9347026ff9aa298fc097733e56JunweiZhang if (pid != 0) { 6895592b47be09bd9347026ff9aa298fc097733e56JunweiZhang /* Parent */ 6995592b47be09bd9347026ff9aa298fc097733e56JunweiZhang if (waitpid(pid, &status, 0) < 0) { 7095592b47be09bd9347026ff9aa298fc097733e56JunweiZhang perror("waitpid"); 71a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger exit(1); 7295592b47be09bd9347026ff9aa298fc097733e56JunweiZhang } 7395592b47be09bd9347026ff9aa298fc097733e56JunweiZhang 743c61c01a666d9f4dbb871305ab6791e19ede7d4aNicolas Dichtel if (WIFEXITED(status)) { 75b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan return WEXITSTATUS(status); 763c61c01a666d9f4dbb871305ab6791e19ede7d4aNicolas Dichtel } 7795592b47be09bd9347026ff9aa298fc097733e56JunweiZhang 783c61c01a666d9f4dbb871305ab6791e19ede7d4aNicolas Dichtel exit(1); 7995592b47be09bd9347026ff9aa298fc097733e56JunweiZhang } 8095592b47be09bd9347026ff9aa298fc097733e56JunweiZhang } 8195592b47be09bd9347026ff9aa298fc097733e56JunweiZhang 82b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan if (execvp(cmd, argv) < 0) 8314645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk fprintf(stderr, "exec of \"%s\" failed: %s\n", 84b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan cmd, strerror(errno)); 85a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger _exit(1); 860dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman} 870dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 88b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochanstatic int on_netns_exec(char *nsname, void *arg) 89b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan{ 90b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan char **argv = arg; 91b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan cmd_exec(argv[1], argv + 1, true); 92b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan return 0; 93b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan} 94b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan 95b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochanstatic int netns_exec(int argc, char **argv) 96b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan{ 97b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan /* Setup the proper environment for apps that are not netns 98b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan * aware, and execute a program in that environment. 99b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan */ 100b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan const char *cmd; 101b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan 102b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan if (argc < 1 && !do_all) { 103b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan fprintf(stderr, "No netns name specified\n"); 104b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan return -1; 105b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan } 106b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan if ((argc < 2 && !do_all) || (argc < 1 && do_all)) { 107b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan fprintf(stderr, "No command specified\n"); 108b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan return -1; 109b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan } 110b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan 111b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan if (do_all) 112b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan return do_each_netns(on_netns_exec, --argv, 1); 113b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan 114b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan if (netns_switch(argv[0])) 115b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan return -1; 116b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan 117b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan /* ip must return the status of the child, 118b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan * but do_cmd() will add a minus to this, 119b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan * so let's add another one here to cancel it. 120b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan */ 121b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan cmd = argv[1]; 122b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan return -cmd_exec(cmd, argv + 1, !!batch_mode); 123b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan} 124b13ba03f54e95de2b2209763f874ac6713d13dd1Vadim Kochan 1259a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biedermanstatic int is_pid(const char *str) 1269a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman{ 1279a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman int ch; 1289a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman for (; (ch = *str); str++) { 1299a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (!isdigit(ch)) 1309a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman return 0; 1319a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 1329a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman return 1; 1339a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman} 1349a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 1359a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biedermanstatic int netns_pids(int argc, char **argv) 1369a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman{ 1379a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman const char *name; 1389a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman char net_path[MAXPATHLEN]; 1399a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman int netns; 1409a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman struct stat netst; 1419a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman DIR *dir; 1429a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman struct dirent *entry; 1439a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 1449a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (argc < 1) { 1459a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, "No netns name specified\n"); 146a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 1479a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 1489a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (argc > 1) { 1499a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, "extra arguments specified\n"); 150a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 1519a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 1529a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 1539a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman name = argv[0]; 1549a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name); 1559a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman netns = open(net_path, O_RDONLY); 1569a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (netns < 0) { 1579a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, "Cannot open network namespace: %s\n", 1589a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman strerror(errno)); 159a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 1609a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 1619a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (fstat(netns, &netst) < 0) { 1629a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, "Stat of netns failed: %s\n", 1639a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman strerror(errno)); 164a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 1659a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 1669a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman dir = opendir("/proc/"); 1679a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (!dir) { 1689a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, "Open of /proc failed: %s\n", 1699a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman strerror(errno)); 170a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 1719a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 1729a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman while((entry = readdir(dir))) { 1739a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman char pid_net_path[MAXPATHLEN]; 1749a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman struct stat st; 1759a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (!is_pid(entry->d_name)) 1769a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman continue; 1779a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman snprintf(pid_net_path, sizeof(pid_net_path), "/proc/%s/ns/net", 1789a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman entry->d_name); 1799a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (stat(pid_net_path, &st) != 0) 1809a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman continue; 1819a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if ((st.st_dev == netst.st_dev) && 1829a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman (st.st_ino == netst.st_ino)) { 1839a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman printf("%s\n", entry->d_name); 1849a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 1859a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 1869a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman closedir(dir); 187a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return 0; 1880612519e011812276ade512d4a7f8113497f64edStephen Hemminger 1899a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman} 1909a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 1919a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biedermanstatic int netns_identify(int argc, char **argv) 1929a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman{ 1939a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman const char *pidstr; 1949a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman char net_path[MAXPATHLEN]; 1959a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman int netns; 1969a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman struct stat netst; 1979a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman DIR *dir; 1989a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman struct dirent *entry; 1999a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 2009a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (argc < 1) { 2010948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk pidstr = "self"; 2020948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk } else if (argc > 1) { 2039a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, "extra arguments specified\n"); 204a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 2050948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk } else { 2060948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk pidstr = argv[0]; 2070948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk if (!is_pid(pidstr)) { 2080948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk fprintf(stderr, "Specified string '%s' is not a pid\n", 2090948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk pidstr); 2100948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk return -1; 2110948adc01a3cee312e2bf81cfffe316f0b5f950bvadimk } 2129a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 2139a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 2149a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman snprintf(net_path, sizeof(net_path), "/proc/%s/ns/net", pidstr); 2159a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman netns = open(net_path, O_RDONLY); 2169a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (netns < 0) { 2179a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, "Cannot open network namespace: %s\n", 2189a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman strerror(errno)); 219a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 2209a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 2219a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (fstat(netns, &netst) < 0) { 2229a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, "Stat of netns failed: %s\n", 2239a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman strerror(errno)); 224a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 2259a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 2269a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman dir = opendir(NETNS_RUN_DIR); 2279a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (!dir) { 2289a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman /* Succeed treat a missing directory as an empty directory */ 2299a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (errno == ENOENT) 230a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return 0; 2319a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 2329a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman fprintf(stderr, "Failed to open directory %s:%s\n", 2339a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman NETNS_RUN_DIR, strerror(errno)); 234a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 2359a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 2369a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 2379a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman while((entry = readdir(dir))) { 2389a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman char name_path[MAXPATHLEN]; 2399a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman struct stat st; 2409a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 2419a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (strcmp(entry->d_name, ".") == 0) 2429a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman continue; 2439a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (strcmp(entry->d_name, "..") == 0) 2449a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman continue; 2459a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 2469a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman snprintf(name_path, sizeof(name_path), "%s/%s", NETNS_RUN_DIR, 2479a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman entry->d_name); 2489a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 2499a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (stat(name_path, &st) != 0) 2509a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman continue; 2519a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 2529a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if ((st.st_dev == netst.st_dev) && 2539a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman (st.st_ino == netst.st_ino)) { 2549a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman printf("%s\n", entry->d_name); 2559a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 2569a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman } 2579a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman closedir(dir); 258a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return 0; 2590612519e011812276ade512d4a7f8113497f64edStephen Hemminger 2609a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman} 2619a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 26233724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochanstatic int on_netns_del(char *nsname, void *arg) 2630dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman{ 2640dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman char netns_path[MAXPATHLEN]; 2650dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 26633724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan snprintf(netns_path, sizeof(netns_path), "%s/%s", NETNS_RUN_DIR, nsname); 2670dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman umount2(netns_path, MNT_DETACH); 2680dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (unlink(netns_path) < 0) { 26914645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk fprintf(stderr, "Cannot remove namespace file \"%s\": %s\n", 2700dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman netns_path, strerror(errno)); 271a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 2720dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 273a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return 0; 2740dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman} 2750dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 27633724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochanstatic int netns_delete(int argc, char **argv) 27733724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan{ 27833724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan if (argc < 1 && !do_all) { 27933724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan fprintf(stderr, "No netns name specified\n"); 28033724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan return -1; 28133724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan } 28233724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan 28333724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan if (do_all) 28433724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan return netns_foreach(on_netns_del, NULL); 28533724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan 28633724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan return on_netns_del(argv[0], NULL); 28733724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan} 28833724939097b8ebb5c37cc0dc2b5e57fe342c8feVadim Kochan 289c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimkstatic int create_netns_dir(void) 290c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk{ 291c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk /* Create the base netns directory if it doesn't exist */ 292c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk if (mkdir(NETNS_RUN_DIR, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) { 293c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk if (errno != EEXIST) { 294c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk fprintf(stderr, "mkdir %s failed: %s\n", 295c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk NETNS_RUN_DIR, strerror(errno)); 296c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk return -1; 297c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk } 298c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk } 299c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk 300c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk return 0; 301c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk} 302c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk 3030dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biedermanstatic int netns_add(int argc, char **argv) 3040dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman{ 3050dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman /* This function creates a new network namespace and 3060dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman * a new mount namespace and bind them into a well known 3070dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman * location in the filesystem based on the name provided. 3080dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman * 3090dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman * The mount namespace is created so that any necessary 3100dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman * userspace tweaks like remounting /sys, or bind mounting 3110dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman * a new /etc/resolv.conf can be shared between uers. 3120dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman */ 3130dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman char netns_path[MAXPATHLEN]; 3140dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman const char *name; 315223f4d8ea6803bd9288d54c819e54a88a63c1730Eric W. Biederman int fd; 31658a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman int made_netns_run_dir_mount = 0; 3170dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 3180dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (argc < 1) { 3190dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fprintf(stderr, "No netns name specified\n"); 320a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 3210dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 3220dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman name = argv[0]; 3230dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 3240dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman snprintf(netns_path, sizeof(netns_path), "%s/%s", NETNS_RUN_DIR, name); 3250dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 326c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk if (create_netns_dir()) 327c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk return -1; 3280dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 329d259f0302f02206d7eb448da2673487fe1e0f8f6Stephen Hemminger /* Make it possible for network namespace mounts to propagate between 33058a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman * mount namespaces. This makes it likely that a unmounting a network 33158a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman * namespace file in one namespace will unmount the network namespace 33258a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman * file in all namespaces allowing the network namespace to be freed 33358a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman * sooner. 33458a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman */ 33558a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman while (mount("", NETNS_RUN_DIR, "none", MS_SHARED | MS_REC, NULL)) { 33658a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman /* Fail unless we need to make the mount point */ 33758a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman if (errno != EINVAL || made_netns_run_dir_mount) { 33858a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman fprintf(stderr, "mount --make-shared %s failed: %s\n", 33958a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman NETNS_RUN_DIR, strerror(errno)); 340a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 34158a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman } 34258a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman 34358a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman /* Upgrade NETNS_RUN_DIR to a mount point */ 34458a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman if (mount(NETNS_RUN_DIR, NETNS_RUN_DIR, "none", MS_BIND, NULL)) { 34558a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman fprintf(stderr, "mount --bind %s %s failed: %s\n", 34658a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman NETNS_RUN_DIR, NETNS_RUN_DIR, strerror(errno)); 347a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 34858a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman } 34958a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman made_netns_run_dir_mount = 1; 35058a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman } 35158a3e8270fe72f8ed92687d3a3132c2a708582ddEric W. Biederman 3520dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman /* Create the filesystem state */ 353223f4d8ea6803bd9288d54c819e54a88a63c1730Eric W. Biederman fd = open(netns_path, O_RDONLY|O_CREAT|O_EXCL, 0); 354223f4d8ea6803bd9288d54c819e54a88a63c1730Eric W. Biederman if (fd < 0) { 35555713c8c72a6cb7f42b3faf8a3208c9bc73f1a94Mike Rapoport fprintf(stderr, "Cannot create namespace file \"%s\": %s\n", 3560dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman netns_path, strerror(errno)); 357a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 3580dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 359223f4d8ea6803bd9288d54c819e54a88a63c1730Eric W. Biederman close(fd); 3600dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (unshare(CLONE_NEWNET) < 0) { 36114645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk fprintf(stderr, "Failed to create a new network namespace \"%s\": %s\n", 36214645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk name, strerror(errno)); 3630dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman goto out_delete; 3640dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 3650dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 3660dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman /* Bind the netns last so I can watch for it */ 3670dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (mount("/proc/self/ns/net", netns_path, "none", MS_BIND, NULL) < 0) { 3680dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fprintf(stderr, "Bind /proc/self/ns/net -> %s failed: %s\n", 3690dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman netns_path, strerror(errno)); 3700dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman goto out_delete; 3710dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 372a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return 0; 3730dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biedermanout_delete: 3740dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman netns_delete(argc, argv); 375a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 3760dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman} 3770dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 3780dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 3790dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biedermanstatic int netns_monitor(int argc, char **argv) 3800dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman{ 3810dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman char buf[4096]; 3820dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman struct inotify_event *event; 3830dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman int fd; 3840dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fd = inotify_init(); 3850dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (fd < 0) { 3860dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fprintf(stderr, "inotify_init failed: %s\n", 3870dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman strerror(errno)); 388a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 3890dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 390c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk 391c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk if (create_netns_dir()) 392c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk return -1; 393c1cbb18adbf2f5abc13a840fb9dab7dd7d26b2aavadimk 3940dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (inotify_add_watch(fd, NETNS_RUN_DIR, IN_CREATE | IN_DELETE) < 0) { 3950dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fprintf(stderr, "inotify_add_watch failed: %s\n", 3960dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman strerror(errno)); 397a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 3980dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 3990dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman for(;;) { 4000dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman ssize_t len = read(fd, buf, sizeof(buf)); 4010dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (len < 0) { 4020dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fprintf(stderr, "read failed: %s\n", 4030dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman strerror(errno)); 404a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return -1; 4050dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 4060dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman for (event = (struct inotify_event *)buf; 4070dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman (char *)event < &buf[len]; 4080dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman event = (struct inotify_event *)((char *)event + sizeof(*event) + event->len)) { 4090dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (event->mask & IN_CREATE) 4100dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman printf("add %s\n", event->name); 4110dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (event->mask & IN_DELETE) 4120dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman printf("delete %s\n", event->name); 4130dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 4140dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman } 415a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger return 0; 4160dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman} 4170dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 4180dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biedermanint do_netns(int argc, char **argv) 4190dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman{ 4200dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (argc < 1) 4210dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman return netns_list(0, NULL); 4220dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 4230dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if ((matches(*argv, "list") == 0) || (matches(*argv, "show") == 0) || 4240dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman (matches(*argv, "lst") == 0)) 4250dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman return netns_list(argc-1, argv+1); 4260dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 4270dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (matches(*argv, "help") == 0) 4288e2d47dce288d5a60d8c67f537860a3683d36df6Eric W. Biederman return usage(); 4290dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 4300dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (matches(*argv, "add") == 0) 4310dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman return netns_add(argc-1, argv+1); 4320dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 4330dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (matches(*argv, "delete") == 0) 4340dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman return netns_delete(argc-1, argv+1); 4350dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 4369a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (matches(*argv, "identify") == 0) 4379a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman return netns_identify(argc-1, argv+1); 4389a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 4399a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman if (matches(*argv, "pids") == 0) 4409a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman return netns_pids(argc-1, argv+1); 4419a7b3d91b69ea9c3c128d973c4bda2324da1a795Eric W. Biederman 4420dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (matches(*argv, "exec") == 0) 4430dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman return netns_exec(argc-1, argv+1); 4440dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 4450dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if (matches(*argv, "monitor") == 0) 4460dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman return netns_monitor(argc-1, argv+1); 4470dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman 4480dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman fprintf(stderr, "Command \"%s\" is unknown, try \"ip netns help\".\n", *argv); 449a05f6511f5432257a5efdd8b369735228c167e94Stephen Hemminger exit(-1); 4500dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman} 451