Implementation of netSystemSbinIp
authorJagger <robert@swiecki.net>
Sun, 28 Feb 2016 22:40:34 +0000 (23:40 +0100)
committerJagger <robert@swiecki.net>
Sun, 28 Feb 2016 22:40:34 +0000 (23:40 +0100)
cmdline.c
common.h
net.c
net.h

index 89d6a37900ea199c52804180572d5f870513746d..e7f0490bd923bcbc00400d108d725e6208080585 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -24,6 +24,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <getopt.h>
 #include <grp.h>
 #include <limits.h>
@@ -35,7 +36,9 @@
 #include <strings.h>
 #include <sys/personality.h>
 #include <sys/mount.h>
+#include <sys/stat.h>
 #include <sys/time.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #include "common.h"
@@ -280,6 +283,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                .max_conns_per_ip = 0,
                .tmpfs_size = 4 * (1024 * 1024),
                .mount_proc = true,
+               .sbinip_fd = -1,
        };
        /*  *INDENT-OFF* */
 
@@ -598,5 +602,9 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                return false;
        }
 
+       if ((nsjconf->sbinip_fd = open("/sbin/ip", O_RDONLY)) == -1) {
+               PLOG_E("No /sbin/ip on your system. Networking support is limited");
+       }
+
        return true;
 }
index 37d83eb1622bc61e4bd3106484ac421c14647250..066453890179c1c8f4f3e6456542ecc7abebfbfe 100644 (file)
--- a/common.h
+++ b/common.h
@@ -99,6 +99,7 @@ struct nsjconf_t {
        unsigned int max_conns_per_ip;
        size_t tmpfs_size;
        bool mount_proc;
+       int sbinip_fd;
         TAILQ_HEAD(envlist, charptr_t) envs;
         TAILQ_HEAD(pidslist, pids_t) pids;
         TAILQ_HEAD(mountptslist, mounts_t) mountpts;
diff --git a/net.c b/net.c
index b48645afca2a8dad8eacc86fc554349159b81ca7..4638f36016ce647dc49df33ec48f9e344c2b5d96 100644 (file)
--- a/net.c
+++ b/net.c
@@ -40,7 +40,7 @@
 
 #include "log.h"
 
-static bool netSystem(const char *bin, char *const *argv)
+bool netSystemSbinIp(struct nsjconf_t *nsjconf, char *const *argv)
 {
        int pid = fork();
        if (pid == -1) {
@@ -48,8 +48,8 @@ static bool netSystem(const char *bin, char *const *argv)
                return false;
        }
        if (pid == 0) {
-               execv(bin, argv);
-               PLOG_E("execve('%s')", bin);
+               fexecve(nsjconf->sbinip_fd, argv, environ);
+               PLOG_E("fexecve('fd=%d')", nsjconf->sbinip_fd);
                _exit(1);
        }
 
@@ -60,19 +60,18 @@ static bool netSystem(const char *bin, char *const *argv)
                        if (WEXITSTATUS(status) == 0) {
                                return true;
                        }
-                       LOG_W("'%s' returned with exit status: %d", bin, WEXITSTATUS(status));
+                       LOG_W("'/sbin/ip' returned with exit status: %d", WEXITSTATUS(status));
                        return false;
                }
                if (WIFSIGNALED(status)) {
-                       LOG_W("'%s' killed with signal: %d", bin, WTERMSIG(status));
+                       LOG_W("'/sbin/ip' killed with signal: %d", WTERMSIG(status));
                        return false;
                }
-               LOG_E("Unknown exit status for '%s' (pid=%d): %d", bin, pid, status);
+               LOG_E("Unknown exit status for '/sbin/ip' (pid=%d): %d", pid, status);
                kill(pid, SIGKILL);
        }
 }
 
-#define SBIN_IP_PATH "/sbin/ip"
 bool netCloneMacVtapAndNS(struct nsjconf_t * nsjconf, int pid)
 {
        if (nsjconf->iface == NULL) {
@@ -83,8 +82,8 @@ bool netCloneMacVtapAndNS(struct nsjconf_t * nsjconf, int pid)
        snprintf(iface, sizeof(iface), "NS.TAP.%d", pid);
 
        char *const argv_add[] =
-           { SBIN_IP_PATH, "link", "add", "link", nsjconf->iface, iface, "type", "macvtap", NULL };
-       if (netSystem(SBIN_IP_PATH, argv_add) == false) {
+           { "ip", "link", "add", "link", nsjconf->iface, iface, "type", "macvtap", NULL };
+       if (netSystemSbinIp(nsjconf, argv_add) == false) {
                LOG_E("Couldn't create MACVTAP interface for '%s'", nsjconf->iface);
                return false;
        }
@@ -92,10 +91,10 @@ bool netCloneMacVtapAndNS(struct nsjconf_t * nsjconf, int pid)
        char pid_str[256];
        snprintf(pid_str, sizeof(pid_str), "%d", pid);
        char *const argv_netns[] =
-           { SBIN_IP_PATH, "link", "set", "dev", iface, "netns", pid_str, "name", "virt.ns",
+           { "ip", "link", "set", "dev", iface, "netns", pid_str, "name", "virt.ns",
                NULL
        };
-       if (netSystem(SBIN_IP_PATH, argv_netns) == false) {
+       if (netSystemSbinIp(nsjconf, argv_netns) == false) {
                LOG_E("Couldn't put interface '%s' into NS of PID '%d'", iface, pid);
                return false;
        }
diff --git a/net.h b/net.h
index 198439a67c6f0814305b358f029eeabbdee4ea61..76121cc50b1debacaf5e2d8a0bfc7b1f05231414 100644 (file)
--- a/net.h
+++ b/net.h
@@ -26,6 +26,7 @@
 
 #include "common.h"
 
+bool netSystemSbinIp(struct nsjconf_t *nsjconf, char *const *argv);
 bool netCloneMacVtapAndNS(struct nsjconf_t *nsjconf, int pid);
 bool netLimitConns(struct nsjconf_t *nsjconf, int connsock);
 int netGetRecvSocket(const char *bindhost, int port);