MACVLAN modes support
authorEli Zrihen <ezrihen@gmail.com>
Wed, 16 Jun 2021 13:59:12 +0000 (16:59 +0300)
committerEli Zrihen <ezrihen@gmail.com>
Wed, 16 Jun 2021 13:59:12 +0000 (16:59 +0300)
cmdline.cc
config.cc
config.proto
net.cc
nsjail.h

index fc04c1150d2efe0b912be69be03fbe63a1c3a42b..d29a35a363093210048d84638182e19755609051 100644 (file)
@@ -158,6 +158,7 @@ struct custom_option custom_opts[] = {
     { { "macvlan_vs_nm", required_argument, NULL, 0x702 }, "Netmask of the 'vs' interface (e.g. \"255.255.255.0\")" },
     { { "macvlan_vs_gw", required_argument, NULL, 0x703 }, "Default GW for the 'vs' interface (e.g. \"192.168.0.1\")" },
     { { "macvlan_vs_ma", required_argument, NULL, 0x705 }, "MAC-address of the 'vs' interface (e.g. \"ba:ad:ba:be:45:00\")" },
+    { { "macvlan_vs_mo", required_argument, NULL, 0x706 }, "Mode of the 'vs' interface. Can be either 'private', 'vepa', 'bridge' or 'passthru' (default: 'private')" },
 };
 // clang-format on
 
@@ -391,6 +392,19 @@ void setupUsers(nsjconf_t* nsjconf) {
        }
 }
 
+std::string parseMACVlanMode(const char* optarg) {
+       if (strcasecmp(optarg, "private") != 0  &&
+               strcasecmp(optarg, "vepa") != 0         &&
+               strcasecmp(optarg, "bridge") != 0       &&
+               strcasecmp(optarg, "passthru") != 0)  {
+               LOG_F(
+                   "macvlan mode can only be one of the values: 'private'/'vepa'/'bridge'/'passthru' ('%s' "
+                   "provided).",
+                   optarg);
+       } 
+       return std::string(optarg);
+}
+
 std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
        std::unique_ptr<nsjconf_t> nsjconf(new nsjconf_t);
 
@@ -451,6 +465,7 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
        nsjconf->iface_vs_nm = "255.255.255.0";
        nsjconf->iface_vs_gw = "0.0.0.0";
        nsjconf->iface_vs_ma = "";
+       nsjconf->iface_vs_mo = "private";
        nsjconf->orig_uid = getuid();
        nsjconf->orig_euid = geteuid();
        nsjconf->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
@@ -809,6 +824,9 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
                case 0x705:
                        nsjconf->iface_vs_ma = optarg;
                        break;
+               case 0x706:
+                       nsjconf->iface_vs_mo = parseMACVlanMode(optarg);
+                       break;
                case 0x801:
                        nsjconf->cgroup_mem_max = (size_t)strtoull(optarg, NULL, 0);
                        break;
index 5dacef6fc61f5b184f680eb93c797618f257be64..413f6fc33e794efa1aebe5b6b49a5a0debb99daa 100644 (file)
--- a/config.cc
+++ b/config.cc
@@ -267,6 +267,7 @@ static bool configParseInternal(nsjconf_t* nsjconf, const nsjail::NsJailConfig&
        nsjconf->iface_vs_nm = njc.macvlan_vs_nm();
        nsjconf->iface_vs_gw = njc.macvlan_vs_gw();
        nsjconf->iface_vs_ma = njc.macvlan_vs_ma();
+       nsjconf->iface_vs_mo = njc.macvlan_vs_mo();
 
        if (njc.has_exec_bin()) {
                if (njc.exec_bin().has_path()) {
index 25d6ee17ef45b5b71c828fd40d4fe242d4875e1f..8c55991054c36eada29833f197f6b01cde3064d0 100644 (file)
@@ -244,6 +244,7 @@ message NsJailConfig {
     optional string macvlan_vs_nm = 79 [default = "255.255.255.0"];
     optional string macvlan_vs_gw = 80 [default = "192.168.0.1"];
     optional string macvlan_vs_ma = 81 [default = ""];
+    optional string macvlan_vs_mo = 87 [default = "private"];
 
     /* Niceness level of the jailed process */
     optional int32 nice_level = 82 [default = 19];
diff --git a/net.cc b/net.cc
index 5259f9cc0c24f203a30c32d2830952ca95ef88ca..d8d750d6f9312643ee27ec9d26a81fa2c617fd04 100644 (file)
--- a/net.cc
+++ b/net.cc
@@ -84,7 +84,12 @@ static bool cloneIface(
                rtnl_link_set_addr(rmv, nladdr);
                nl_addr_put(nladdr);
        }
-
+       
+       if ((err = rtnl_link_macvlan_set_mode(rmv, rtnl_link_macvlan_str2mode(nsjconf->iface_vs_mo.c_str()))) < 0) {
+               LOG_E("rtnl_link_macvlan_set_mode(mode:'%s') failed: %s", 
+               nsjconf->iface_vs_mo.c_str(), nl_geterror(err));
+       }
+               
        if ((err = rtnl_link_add(sk, rmv, NLM_F_CREATE)) < 0) {
                LOG_E("rtnl_link_add(name:'%s' link:'%s'): %s", IFACE_NAME,
                    nsjconf->iface_vs.c_str(), nl_geterror(err));
index 5e686c7bf3bec21040f5503cb71d5a4dbb79baf7..7dd588e55ed31d9deee981645a78f733d8cc2e70 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
@@ -140,6 +140,7 @@ struct nsjconf_t {
        std::string iface_vs_nm;
        std::string iface_vs_gw;
        std::string iface_vs_ma;
+       std::string iface_vs_mo;
        std::string cgroup_mem_mount;
        std::string cgroup_mem_parent;
        size_t cgroup_mem_max;