static int netns_exec(int argc, char **argv) { /* Setup the proper environment for apps that are not netns * aware, and execute a program in that environment. */ const char *name, *cmd; char net_path[MAXPATHLEN]; int netns; if (argc < 1) { fprintf(stderr, "No netns name specified\n"); return EXIT_FAILURE; } if (argc < 2) { fprintf(stderr, "No command specified\n"); return EXIT_FAILURE; } name = argv[0]; cmd = argv[1]; snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name); netns = open(net_path, O_RDONLY); if (netns < 0) { fprintf(stderr, "Cannot open network namespace \"%s\": %s\n", name, strerror(errno)); return EXIT_FAILURE; } if (setns(netns, CLONE_NEWNET) < 0) { fprintf(stderr, "seting the network namespace \"%s\" failed: %s\n", name, strerror(errno)); return EXIT_FAILURE; } if (unshare(CLONE_NEWNS) < 0) { fprintf(stderr, "unshare failed: %s\n", strerror(errno)); return EXIT_FAILURE; } /* Don't let any mounts propogate back to the parent */ if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL)) { fprintf(stderr, "\"mount --make-rslave /\" failed: %s\n", strerror(errno)); return EXIT_FAILURE; } /* Mount a version of /sys that describes the network namespace */ if (umount2("/sys", MNT_DETACH) < 0) { fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno)); return EXIT_FAILURE; } if (mount(name, "/sys", "sysfs", 0, NULL) < 0) { fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno)); return EXIT_FAILURE; } /* Setup bind mounts for config files in /etc */ bind_etc(name); if (execvp(cmd, argv + 1) < 0) fprintf(stderr, "exec of \"%s\" failed: %s\n", cmd, strerror(errno)); return EXIT_FAILURE; }
static int netns_exec(int argc, char **argv) { /* Setup the proper environment for apps that are not netns * aware, and execute a program in that environment. */ const char *name, *cmd; char net_path[MAXPATHLEN]; int netns; if (argc < 1) { fprintf(stderr, "No netns name specified\n"); return -1; } if (argc < 2) { fprintf(stderr, "No cmd specified\n"); return -1; } name = argv[0]; cmd = argv[1]; snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name); netns = open(net_path, O_RDONLY); if (netns < 0) { fprintf(stderr, "Cannot open network namespace: %s\n", strerror(errno)); return -1; } if (setns(netns, CLONE_NEWNET) < 0) { fprintf(stderr, "seting the network namespace failed: %s\n", strerror(errno)); return -1; } /* if (unshare(CLONE_NEWNS) < 0) { fprintf(stderr, "unshare failed: %s\n", strerror(errno)); return -1; } */ /* Mount a version of /sys that describes the network namespace */ if (umount2("/sys", MNT_DETACH) < 0) { fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno)); return -1; } if (mount(name, "/sys", "sysfs", 0, NULL) < 0) { fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno)); return -1; } /* Setup bind mounts for config files in /etc */ bind_etc(name); if (execvp(cmd, argv + 1) < 0) fprintf(stderr, "exec of %s failed: %s\n", cmd, strerror(errno)); exit(-1); }
int netns_switch(char *name) { char net_path[MAXPATHLEN]; int netns; snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name); netns = open(net_path, O_RDONLY | O_CLOEXEC); if (netns < 0) { fprintf(stderr, "Cannot open network namespace \"%s\": %s\n", name, strerror(errno)); return -1; } if (setns(netns, CLONE_NEWNET) < 0) { fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n", name, strerror(errno)); return -1; } if (unshare(CLONE_NEWNS) < 0) { fprintf(stderr, "unshare failed: %s\n", strerror(errno)); return -1; } /* Don't let any mounts propagate back to the parent */ if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL)) { fprintf(stderr, "\"mount --make-rslave /\" failed: %s\n", strerror(errno)); return -1; } /* Mount a version of /sys that describes the network namespace */ if (umount2("/sys", MNT_DETACH) < 0) { fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno)); return -1; } if (mount(name, "/sys", "sysfs", 0, NULL) < 0) { fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno)); return -1; } /* Setup bind mounts for config files in /etc */ bind_etc(name); return 0; }