cmdline: add iface_own to take ownership of one of the global interfaces
authorRobert Swiecki <robert@swiecki.net>
Wed, 30 May 2018 13:26:09 +0000 (15:26 +0200)
committerRobert Swiecki <robert@swiecki.net>
Wed, 30 May 2018 13:26:09 +0000 (15:26 +0200)
cmdline.cc
net.cc
nsjail.h

index 7455e6864cd98dddab5534048737451cbe9ae2d4..6a03185a73e5eeec6a8d4a4b5fc8fd0c295acb94 100644 (file)
@@ -145,6 +145,7 @@ struct custom_option custom_opts[] = {
     { { "cgroup_cpu_mount", required_argument, NULL, 0x0822 }, "Location of cpu cgroup FS (default: '/sys/fs/cgroup/net_cls')" },
     { { "cgroup_cpu_parent", required_argument, NULL, 0x0833 }, "Which pre-existing cpu cgroup to use as a parent (default: 'NSJAIL')" },
     { { "iface_no_lo", no_argument, NULL, 0x700 }, "Don't bring the 'lo' interface up" },
+    { { "iface_own", required_argument, NULL, 0x704 }, "Move this existing network interface into the new NET namespace" },
     { { "macvlan_iface", required_argument, NULL, 'I' }, "Interface which will be cloned (MACVLAN) and put inside the subprocess' namespace as 'vs'" },
     { { "macvlan_vs_ip", required_argument, NULL, 0x701 }, "IP of the 'vs' interface (e.g. \"192.168.0.1\")" },
     { { "macvlan_vs_nm", required_argument, NULL, 0x702 }, "Netmask of the 'vs' interface (e.g. \"255.255.255.0\")" },
@@ -780,6 +781,9 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
                case 0x703:
                        nsjconf->iface_vs_gw = optarg;
                        break;
+               case 0x704:
+                       nsjconf->ifaces.push_back(optarg);
+                       break;
                case 0x801:
                        nsjconf->cgroup_mem_max = (size_t)strtoull(optarg, NULL, 0);
                        break;
diff --git a/net.cc b/net.cc
index 8d76c12a92c413f75272c2922b78654cda1ce21f..6a0c4b8d17324b226f40ed818e489c949a9dc78f 100644 (file)
--- a/net.cc
+++ b/net.cc
@@ -53,6 +53,7 @@ namespace net {
 #if defined(NSJAIL_NL3_WITH_MACVLAN)
 #include <netlink/route/link.h>
 #include <netlink/route/link/macvlan.h>
+
 bool initNsFromParent(nsjconf_t* nsjconf, int pid) {
        if (!nsjconf->clone_newnet) {
                return true;
@@ -121,10 +122,26 @@ bool initNsFromParent(nsjconf_t* nsjconf, int pid) {
 }
 #else   // defined(NSJAIL_NL3_WITH_MACVLAN)
 
+bool moveToNs(const std::string& iface, pid_t pid) {
+       const std::vector<std::string> argv{
+           "/sbin/ip", "link", "set", iface, "netns", std::to_string(pid)};
+       if (subproc::systemExe(argv, environ) != 0) {
+               LOG_E("Couldn't create put interface '%s' into NET ns of the PID=%d", iface.c_str(),
+                   (int)pid);
+               return false;
+       }
+       return true;
+}
+
 bool initNsFromParent(nsjconf_t* nsjconf, int pid) {
        if (!nsjconf->clone_newnet) {
                return true;
        }
+       for (const auto& iface : nsjconf->ifaces) {
+               if (!moveToNs(iface, pid)) {
+                       return false;
+               }
+       }
        if (nsjconf->iface_vs.empty()) {
                return true;
        }
@@ -132,11 +149,8 @@ bool initNsFromParent(nsjconf_t* nsjconf, int pid) {
        LOG_D("Putting iface:'%s' into namespace of PID:%d (with /sbin/ip)",
            nsjconf->iface_vs.c_str(), pid);
 
-       char pid_str[256];
-       snprintf(pid_str, sizeof(pid_str), "%d", pid);
-
        const std::vector<std::string> argv{"/sbin/ip", "link", "add", "link", nsjconf->iface_vs,
-           "name", IFACE_NAME, "netns", pid_str, "type", "macvlan", "mode", "bridge"};
+           "name", IFACE_NAME, "netns", std::to_string(pid), "type", "macvlan", "mode", "bridge"};
        if (subproc::systemExe(argv, environ) != 0) {
                LOG_E("Couldn't create MACVTAP interface for '%s'", nsjconf->iface_vs.c_str());
                return false;
index 99f904fc1439225ce69f08ced3210c5f5ad73499..132d7e53011689a092698343e7d49581d0075611 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
@@ -153,6 +153,7 @@ struct nsjconf_t {
        std::vector<std::string> envs;
        std::vector<int> openfds;
        std::vector<int> caps;
+       std::vector<std::string> ifaces;
 };
 
 #endif /* _NSJAIL_H */