#include <fcntl.h>
#include <cassert>
#include <linux/if_link.h>
+#include <arpa/inet.h>
using namespace std;
argv[pos + 2]));
}
+void zone_get_netdevs(int pos, int argc, const char** argv)
+{
+ using namespace std::placeholders;
+
+ if (argc <= pos + 1) {
+ throw runtime_error("Not enough parameters");
+ }
+ VsmArrayString ids;
+ one_shot(bind(vsm_zone_get_netdevs,
+ _1,
+ argv[pos + 1],
+ &ids));
+ string delim;
+ for (VsmString* id = ids; *id; ++id) {
+ cout << delim << *id;
+ delim = ", ";
+ }
+ if (delim.empty()) {
+ cout << "There is no network device in zone";
+ }
+ cout << endl;
+ vsm_array_string_free(ids);
+}
+
+void netdev_get_ipv4_addr(int pos, int argc, const char** argv)
+{
+ using namespace std::placeholders;
+
+ if (argc <= pos + 2) {
+ throw runtime_error("Not enough parameters");
+ }
+ in_addr addr;
+ one_shot(bind(vsm_netdev_get_ipv4_addr,
+ _1,
+ argv[pos + 1],
+ argv[pos + 2],
+ &addr));
+ char buf[INET_ADDRSTRLEN];
+ if (inet_ntop(AF_INET, &addr, buf, INET_ADDRSTRLEN) == NULL) {
+ throw runtime_error("Server gave the wrong address format");
+ }
+ cout << buf << endl;
+}
+
+void netdev_get_ipv6_addr(int pos, int argc, const char** argv)
+{
+ using namespace std::placeholders;
+
+ if (argc <= pos + 2) {
+ throw runtime_error("Not enough parameters");
+ }
+ in6_addr addr;
+ one_shot(bind(vsm_netdev_get_ipv6_addr,
+ _1,
+ argv[pos + 1],
+ argv[pos + 2],
+ &addr));
+ char buf[INET6_ADDRSTRLEN];
+ if (inet_ntop(AF_INET6, &addr, buf, INET6_ADDRSTRLEN) == NULL) {
+ throw runtime_error("Server gave the wrong address format");
+ }
+ cout << buf << endl;
+}
+
+void netdev_set_ipv4_addr(int pos, int argc, const char** argv)
+{
+ using namespace std::placeholders;
+
+ if (argc <= pos + 4) {
+ throw runtime_error("Not enough parameters");
+ }
+ in_addr addr;
+ if (inet_pton(AF_INET, argv[pos + 3], &addr) != 1) {
+ throw runtime_error("Wrong address format");
+ };
+ one_shot(bind(vsm_netdev_set_ipv4_addr,
+ _1,
+ argv[pos + 1],
+ argv[pos + 2],
+ &addr,
+ stoi(argv[pos + 4])));
+}
+
+void netdev_set_ipv6_addr(int pos, int argc, const char** argv)
+{
+ using namespace std::placeholders;
+
+ if (argc <= pos + 4) {
+ throw runtime_error("Not enough parameters");
+ }
+ in6_addr addr;
+ if (inet_pton(AF_INET6, argv[pos + 3], &addr) != 1) {
+ throw runtime_error("Wrong address format");
+ };
+ one_shot(bind(vsm_netdev_set_ipv6_addr,
+ _1,
+ argv[pos + 1],
+ argv[pos + 2],
+ &addr,
+ stoi(argv[pos + 4])));
+}
+
+void netdev_up(int pos, int argc, const char** argv)
+{
+ using namespace std::placeholders;
+
+ if (argc <= pos + 2) {
+ throw runtime_error("Not enough parameters");
+ }
+ one_shot(bind(vsm_netdev_up,
+ _1,
+ argv[pos + 1],
+ argv[pos + 2]));
+}
+
+void netdev_down(int pos, int argc, const char** argv)
+{
+ using namespace std::placeholders;
+
+ if (argc <= pos + 2) {
+ throw runtime_error("Not enough parameters");
+ }
+ one_shot(bind(vsm_netdev_down,
+ _1,
+ argv[pos + 1],
+ argv[pos + 2]));
+}
+
} // namespace cli
} // namespace vasum
*/
void create_netdev_phys(int pos, int argc, const char** argv);
+/**
+ * Parses command line arguments and prints result of vsm_zone_get_netdevs
+ *
+ * @see vsm_zone_get_netdevs
+ */
+void zone_get_netdevs(int pos, int argc, const char** argv);
+
+/**
+ * Parses command line arguments and prints result of vsm_netdev_get_ipv4_addr
+ *
+ * @see vsm_netdev_get_ipv4_addr
+ */
+void netdev_get_ipv4_addr(int pos, int argc, const char** argv);
+
+/**
+ * Parses command line arguments and and prints result of vsm_netdev_get_ipv6_addr
+ *
+ * @see vsm_netdev_get_ipv6_addr
+ */
+void netdev_get_ipv6_addr(int pos, int argc, const char** argv);
+
+/**
+ * Parses command line arguments and call vsm_netdev_set_ipv4_addr
+ *
+ * @see vsm_netdev_set_ipv4_addr
+ */
+void netdev_set_ipv4_addr(int pos, int argc, const char** argv);
+
+/**
+ * Parses command line arguments and call vsm_netdev_set_ipv6_addr
+ *
+ * @see vsm_netdev_set_ipv6_addr
+ */
+void netdev_set_ipv6_addr(int pos, int argc, const char** argv);
+
+/**
+ * Parses command line arguments and call vsm_netdev_up
+ *
+ * @see vsm_netdev_up
+ */
+void netdev_up(int pos, int argc, const char** argv);
+
+/**
+ * Parses command line arguments and call vsm_netdev_down
+ *
+ * @see vsm_netdev_down
+ */
+void netdev_down(int pos, int argc, const char** argv);
+
} // namespace cli
} // namespace vasum
{{"zone_id", "id zone name"},
{"devId", "network device id"}}
}
+ },
+ {
+ "zone_get_netdevs", {
+ zone_get_netdevs,
+ "zone_get_netdevs zone_id",
+ "List network devices in the zone",
+ {{"zone_id", "id zone name"}}
+ }
+ },
+ {
+ "netdev_get_ipv4_addr", {
+ netdev_get_ipv4_addr,
+ "netdev_get_ipv4_addr zone_id netdev_id",
+ "Get ipv4 address",
+ {{"zone_id", "id zone name"},
+ {"netdev_id", "network device name"}}
+ }
+ },
+ {
+ "netdev_get_ipv6_addr", {
+ netdev_get_ipv6_addr,
+ "netdev_get_ipv6_addr zone_id netdev_id",
+ "Get ipv6 address",
+ {{"zone_id", "id zone name"},
+ {"netdev_id", "network device name"}}
+ }
+ },
+ {
+ "netdev_set_ipv4_addr", {
+ netdev_set_ipv4_addr,
+ "netdev_set_ipv4_addr zone_id netdev_id address prefix_len",
+ "Set ipv4 address",
+ {{"zone_id", "id zone name"},
+ {"netdev_id", "network device name"},
+ {"address", "ipv4 address"},
+ {"prefix_len", "bit length of prefix"}}
+ }
+ },
+ {
+ "netdev_set_ipv6_addr", {
+ netdev_set_ipv6_addr,
+ "netdev_set_ipv6_addr zone_id netdev_id address prefix_len",
+ "Set ipv6 address",
+ {{"zone_id", "id zone name"},
+ {"netdev_id", "network device name"},
+ {"address", "ipv6 address"},
+ {"prefix_len", "bit length of prefix"}}
+ }
+ },
+ {
+ "netdev_up", {
+ netdev_up,
+ "netdev_up zone_id netdev_id",
+ "Turn up a network device in the zone",
+ {{"zone_id", "id zone name"},
+ {"netdev_id", "network device id"}}
+ }
+ },
+ {
+ "zone_get_netdevs", {
+ zone_get_netdevs,
+ "zone_get_netdevs zone_id",
+ "Turn down a network device in the zone",
+ {{"zone_id", "id zone name"},
+ {"netdev_id", "network device id"}}
+ }
}
};
FILE(GLOB common_SRCS ${COMMON_FOLDER}/utils/callback-guard.hpp
${COMMON_FOLDER}/utils/callback-guard.cpp
${COMMON_FOLDER}/utils/glib-loop.cpp
- ${COMMON_FOLDER}/utils/glib-loop.hpp)
+ ${COMMON_FOLDER}/utils/glib-loop.hpp
+ ${COMMON_FOLDER}/base-exception.hpp
+ ${COMMON_FOLDER}/base-exception.cpp)
SET(_LIB_VERSION_ "0.0.1")
SET(_LIB_SOVERSION_ "0")
#include <utils/glib-loop.hpp>
#include <host-dbus-definitions.hpp>
#include <zone-dbus-definitions.hpp>
+#include <base-exception.hpp>
+#include <algorithm>
+#include <tuple>
+#include <vector>
#include <cstring>
#include <cassert>
#include <fstream>
+#include <arpa/inet.h>
using namespace std;
using namespace dbus;
*values = outv;
}
+vector<tuple<string, string>> toDict(GVariant* in)
+{
+ assert(in);
+
+ const gchar* key;
+ const gchar* value;
+ vector<tuple<string, string>> dict;
+ GVariantIter iter;
+ g_variant_iter_init(&iter, in);
+ while (g_variant_iter_loop(&iter, "(&s&s)", &key, &value)) {
+ dict.push_back(make_tuple<string, string>(key, value));
+ }
+ return dict;
+}
+
void toBasic(GVariant* in, char** str)
{
assert(in);
*scArray = ids;
}
+string toString(const in_addr* addr)
+{
+ char buf[INET_ADDRSTRLEN];
+ const char* ret = inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN);
+ if (ret == NULL) {
+ throw runtime_error(getSystemErrorMessage());
+ }
+ return ret;
+}
+
+string toString(const in6_addr* addr)
+{
+ char buf[INET6_ADDRSTRLEN];
+ const char* ret = inet_ntop(AF_INET6, addr, buf, INET6_ADDRSTRLEN);
+ if (ret == NULL) {
+ throw runtime_error(getSystemErrorMessage());
+ }
+ return ret;
+}
+
+GVariant* createTupleArray(const vector<tuple<string, string>>& dict)
+{
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ for (const auto entry : dict) {
+ g_variant_builder_add(&builder, "(ss)", get<0>(entry).c_str(), get<1>(entry).c_str());
+ }
+ return g_variant_builder_end(&builder);
+}
+
+
VsmStatus toStatus(const exception& ex)
{
if (typeid(DbusCustomException) == typeid(ex)) {
return callMethod(HOST_INTERFACE, api::host::METHOD_REVOKE_DEVICE, args_in);
}
-VsmStatus Client::vsm_zone_get_netdevs(const char*, VsmArrayString*) noexcept
+VsmStatus Client::vsm_zone_get_netdevs(const char* zone, VsmArrayString* netdevIds) noexcept
{
- mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
- return vsm_get_status();
+ assert(zone);
+ assert(netdevIds);
+
+ GVariant* out = NULL;
+ GVariant* args_in = g_variant_new("(s)", zone);
+ VsmStatus ret = callMethod(HOST_INTERFACE,
+ api::host::METHOD_GET_NETDEV_LIST,
+ args_in,
+ "(as)",
+ &out);
+ if (ret != VSMCLIENT_SUCCESS) {
+ return ret;
+ }
+ GVariant* unpacked;
+ g_variant_get(out, "(*)", &unpacked);
+ toArray(unpacked, netdevIds);
+ g_variant_unref(unpacked);
+ g_variant_unref(out);
+ return ret;
}
-VsmStatus Client::vsm_netdev_get_ipv4_addr(const char*, const char*, struct in_addr*) noexcept
+VsmStatus Client::vsm_netdev_get_ipv4_addr(const char* zone,
+ const char* netdevId,
+ struct in_addr* addr) noexcept
{
- mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
+ assert(zone);
+ assert(netdevId);
+ assert(addr);
+
+ GVariant* out = NULL;
+ GVariant* args_in = g_variant_new("(ss)", zone, netdevId);
+ VsmStatus ret = callMethod(HOST_INTERFACE,
+ api::host::METHOD_GET_NETDEV_ATTRS,
+ args_in,
+ "(a(ss))",
+ &out);
+ if (ret != VSMCLIENT_SUCCESS) {
+ return ret;
+ }
+ GVariant* unpacked;
+ g_variant_get(out, "(*)", &unpacked);
+ vector<tuple<string, string>> attrs = toDict(unpacked);
+ g_variant_unref(unpacked);
+ g_variant_unref(out);
+
+ auto it = find_if(attrs.begin(), attrs.end(), [](const tuple<string, string>& entry) {
+ return get<0>(entry) == "ipv4";
+ });
+ if (it != attrs.end()) {
+ if (inet_pton(AF_INET, get<1>(*it).c_str(), addr) != 1) {
+ mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Invalid response data");
+ return vsm_get_status();
+ }
+ mStatus = Status();
+ return vsm_get_status();
+ }
+ mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Address not found");
return vsm_get_status();
}
-VsmStatus Client::vsm_netdev_get_ipv6_addr(const char*, const char*, struct in6_addr*) noexcept
+VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* zone,
+ const char* netdevId,
+ struct in6_addr* addr) noexcept
{
- mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
+ assert(zone);
+ assert(netdevId);
+ assert(addr);
+
+ GVariant* out = NULL;
+ GVariant* args_in = g_variant_new("(ss)", zone, netdevId);
+ VsmStatus ret = callMethod(HOST_INTERFACE,
+ api::host::METHOD_GET_NETDEV_ATTRS,
+ args_in,
+ "(a(ss))",
+ &out);
+ if (ret != VSMCLIENT_SUCCESS) {
+ return ret;
+ }
+ GVariant* unpacked;
+ g_variant_get(out, "(*)", &unpacked);
+ vector<tuple<string, string>> attrs = toDict(unpacked);
+ g_variant_unref(unpacked);
+ g_variant_unref(out);
+
+ //XXX: return only one address
+ auto it = find_if(attrs.begin(), attrs.end(), [](const tuple<string, string>& entry) {
+ return get<0>(entry) == "ipv6";
+ });
+ if (it != attrs.end()) {
+ if (inet_pton(AF_INET6, get<1>(*it).c_str(), addr) != 1) {
+ mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Invalid response data");
+ return vsm_get_status();
+ }
+ mStatus = Status();
+ return vsm_get_status();
+ }
+ mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Address not found");
return vsm_get_status();
}
-VsmStatus Client::vsm_netdev_set_ipv4_addr(const char*, const char*, struct in_addr*, int) noexcept
+VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* zone,
+ const char* netdevId,
+ struct in_addr* addr,
+ int mask) noexcept
{
- mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
- return vsm_get_status();
+ try {
+ GVariant* dict = createTupleArray({make_tuple("ipv4", toString(addr)),
+ make_tuple("mask", to_string(mask))});
+ GVariant* args_in = g_variant_new("(ss@a(ss))", zone, netdevId, dict);
+ return callMethod(HOST_INTERFACE, api::host::METHOD_SET_NETDEV_ATTRS, args_in);
+ } catch (exception& ex) {
+ mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what());
+ return vsm_get_status();
+ }
}
-VsmStatus Client::vsm_netdev_set_ipv6_addr(const char*, const char*, struct in6_addr*, int) noexcept
+VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* zone,
+ const char* netdevId,
+ struct in6_addr* addr,
+ int mask) noexcept
{
- mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
- return vsm_get_status();
+ try {
+ GVariant* dict = createTupleArray({make_tuple("ipv6", toString(addr)),
+ make_tuple("mask", to_string(mask))});
+ GVariant* args_in = g_variant_new("(ss@a(ss))", zone, netdevId, dict);
+ return callMethod(HOST_INTERFACE, api::host::METHOD_SET_NETDEV_ATTRS, args_in);
+ } catch (exception& ex) {
+ mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what());
+ return vsm_get_status();
+ }
+}
+
+VsmStatus Client::vsm_netdev_up(const char* zone, const char* netdevId) noexcept
+{
+ try {
+ GVariant* dict = createTupleArray({make_tuple("up", "true")});
+ GVariant* args_in = g_variant_new("(ss@a(ss))", zone, netdevId, dict);
+ return callMethod(HOST_INTERFACE, api::host::METHOD_SET_NETDEV_ATTRS, args_in);
+ } catch (exception& ex) {
+ mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what());
+ return vsm_get_status();
+ }
+}
+
+VsmStatus Client::vsm_netdev_down(const char* zone, const char* netdevId) noexcept
+{
+ try {
+ GVariant* dict = createTupleArray({make_tuple("up", "false")});
+ GVariant* args_in = g_variant_new("(ss@a(ss))", zone, netdevId, dict);
+ return callMethod(HOST_INTERFACE, api::host::METHOD_SET_NETDEV_ATTRS, args_in);
+ } catch (exception& ex) {
+ mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what());
+ return vsm_get_status();
+ }
}
VsmStatus Client::vsm_create_netdev_veth(const char* zone,
int prefix) noexcept;
/**
+ * @see ::vsm_netdev_up
+ */
+ VsmStatus vsm_netdev_up(const char* zone, const char* netdevId) noexcept;
+
+ /**
+ * @see ::vsm_netdev_down
+ */
+ VsmStatus vsm_netdev_down(const char* zone, const char* netdevId) noexcept;
+
+ /**
* @see ::vsm_create_netdev_veth
*/
VsmStatus vsm_create_netdev_veth(const char* zone,
return getClient(client).vsm_netdev_set_ipv6_addr(zone, netdevId, addr, prefix);
}
+API VsmStatus vsm_netdev_up(VsmClient client,
+ const char* zone,
+ const char* netdevId)
+{
+ return getClient(client).vsm_netdev_up(zone, netdevId);
+}
+
+API VsmStatus vsm_netdev_down(VsmClient client,
+ const char* zone,
+ const char* netdevId)
+{
+ return getClient(client).vsm_netdev_down(zone, netdevId);
+}
+
API VsmStatus vsm_create_netdev_veth(VsmClient client,
const char* zone,
const char* zoneDev,
int prefix);
/**
+ * Turn up a network device in the zone
+ *
+ * @param[in] client vasum-server's client
+ * @param[in] zone zone name
+ * @param[in] netdevId netdev id
+ * @return status of this function call
+ */
+VsmStatus vsm_netdev_up(VsmClient client,
+ const char* zone,
+ const char* netdevId);
+
+/**
+ * Turn down a network device in the zone
+ *
+ * @param[in] client vasum-server's client
+ * @param[in] zone zone name
+ * @param[in] netdevId netdev id
+ * @return status of this function call
+ */
+VsmStatus vsm_netdev_down(VsmClient client,
+ const char* zone,
+ const char* netdevId);
+
+
+/**
* Create veth netdev in zone
*
* @param[in] client vasum-server's client
#define PAGE_SIZE 4096
#endif
+namespace {
+
const int NLMSG_GOOD_SIZE = 2*PAGE_SIZE;
-constexpr rtattr* NLMSG_TAIL(nlmsghdr* nmsg)
+inline rtattr* NLMSG_TAIL(nlmsghdr* nmsg)
{
return reinterpret_cast<rtattr*>(reinterpret_cast<char*>(nmsg) + NLMSG_ALIGN(nmsg->nlmsg_len));
}
+} // namespace
+
namespace vasum {
namespace netlink {
mGetZoneInfoCallback = callback;
}
+void HostConnection::setSetNetdevAttrsCallback(const SetNetdevAttrsCallback& callback)
+{
+ mSetNetdevAttrsCallback = callback;
+}
+
+void HostConnection::setGetNetdevAttrsCallback(const GetNetdevAttrsCallback& callback)
+{
+ mGetNetdevAttrsCallback = callback;
+}
+
+void HostConnection::setGetNetdevListCallback(const GetNetdevListCallback& callback)
+{
+ mGetNetdevListCallback = callback;
+}
+
void HostConnection::setCreateNetdevVethCallback(const CreateNetdevVethCallback& callback)
{
mCreateNetdevVethCallback = callback;
return;
}
+ if (methodName == api::host::METHOD_SET_NETDEV_ATTRS){
+ const gchar* zone = NULL;
+ const gchar* netdev = NULL;
+ GVariantIter* iter;
+ g_variant_get(parameters, "(&s&sa(ss))", &zone, &netdev, &iter);
+ gchar* key = NULL;
+ gchar* value = NULL;
+ std::vector<std::tuple<std::string, std::string>> attrs;
+ while (g_variant_iter_loop(iter, "(&s&s)", &key, &value)) {
+ attrs.push_back(std::make_tuple<std::string, std::string>(key, value));
+ }
+ g_variant_iter_free(iter);
+ if (mSetNetdevAttrsCallback) {
+ mSetNetdevAttrsCallback(zone, netdev, attrs, result);
+ }
+ return;
+ }
+
+ if (methodName == api::host::METHOD_GET_NETDEV_ATTRS){
+ const gchar* zone = NULL;
+ const gchar* netdev = NULL;
+ g_variant_get(parameters, "(&s&s)", &zone, &netdev);
+ if (mGetNetdevAttrsCallback) {
+ mGetNetdevAttrsCallback(zone, netdev, result);
+ }
+ return;
+ }
+
+ if (methodName == api::host::METHOD_GET_NETDEV_LIST){
+ const gchar* zone = NULL;
+ g_variant_get(parameters, "(&s)", &zone);
+ if (mGetNetdevListCallback) {
+ mGetNetdevListCallback(zone, result);
+ }
+ return;
+ }
+
+
if (methodName == api::host::METHOD_CREATE_NETDEV_VETH) {
const gchar* id = NULL;
const gchar* zoneDev = NULL;
#include <mutex>
#include <condition_variable>
+#include <tuple>
+#include <vector>
namespace vasum {
typedef std::function<void(const std::string& id,
dbus::MethodResultBuilder::Pointer result
)> GetZoneInfoCallback;
- typedef std::function<void(const std::string& id,
- const std::string& zoneDev,
+ typedef std::function<void(const std::string& zone,
+ const std::string& netdev,
+ const std::vector<std::tuple<std::string, std::string>>& attrs,
+ dbus::MethodResultBuilder::Pointer result
+ )> SetNetdevAttrsCallback;
+ typedef std::function<void(const std::string& zone,
+ const std::string& netdev,
+ dbus::MethodResultBuilder::Pointer result
+ )> GetNetdevAttrsCallback;
+ typedef std::function<void(const std::string& zone,
+ dbus::MethodResultBuilder::Pointer result
+ )> GetNetdevListCallback;
+ typedef std::function<void(const std::string& zone,
+ const std::string& netdev,
const std::string& hostDev,
dbus::MethodResultBuilder::Pointer result
)> CreateNetdevVethCallback;
void setGetZoneInfoCallback(const GetZoneInfoCallback& callback);
/**
+ * Register a callback called to set network device attributes
+ */
+ void setSetNetdevAttrsCallback(const SetNetdevAttrsCallback& callback);
+
+ /**
+ * Register a callback called to get network device attributes
+ */
+ void setGetNetdevAttrsCallback(const GetNetdevAttrsCallback& callback);
+
+ /**
+ * Register a callback called to get network device list
+ */
+ void setGetNetdevListCallback(const GetNetdevListCallback& callback);
+
+ /**
* Register a callback called to create veth
*/
void setCreateNetdevVethCallback(const CreateNetdevVethCallback& callback);
GetZoneIdsCallback mGetZoneIdsCallback;
GetActiveZoneIdCallback mGetActiveZoneIdCallback;
GetZoneInfoCallback mGetZoneInfoCallback;
+ SetNetdevAttrsCallback mSetNetdevAttrsCallback;
+ GetNetdevAttrsCallback mGetNetdevAttrsCallback;
+ GetNetdevListCallback mGetNetdevListCallback;
CreateNetdevVethCallback mCreateNetdevVethCallback;
CreateNetdevMacvlanCallback mCreateNetdevMacvlanCallback;
CreateNetdevPhysCallback mCreateNetdevPhysCallback;
const std::string METHOD_GET_ZONE_ID_LIST = "GetZoneIds";
const std::string METHOD_GET_ACTIVE_ZONE_ID = "GetActiveZoneId";
const std::string METHOD_GET_ZONE_INFO = "GetZoneInfo";
+const std::string METHOD_SET_NETDEV_ATTRS = "SetNetdevAttrs";
+const std::string METHOD_GET_NETDEV_ATTRS = "GetNetdevAttrs";
+const std::string METHOD_GET_NETDEV_LIST = "GetNetdevList";
const std::string METHOD_CREATE_NETDEV_VETH = "CreateNetdevVeth";
const std::string METHOD_CREATE_NETDEV_MACVLAN = "CreateNetdevMacvlan";
const std::string METHOD_CREATE_NETDEV_PHYS = "CreateNetdevPhys";
" <arg type='s' name='id' direction='in'/>"
" <arg type='(siss)' name='result' direction='out'/>"
" </method>"
+ " <method name='" + METHOD_SET_NETDEV_ATTRS + "'>"
+ " <arg type='s' name='zone' direction='in'/>"
+ " <arg type='s' name='netdev' direction='in'/>"
+ " <arg type='a(ss)' name='attributes' direction='in'/>"
+ " </method>"
+ " <method name='" + METHOD_GET_NETDEV_ATTRS + "'>"
+ " <arg type='s' name='zone' direction='in'/>"
+ " <arg type='s' name='netdev' direction='in'/>"
+ " <arg type='a(ss)' name='attributes' direction='out'/>"
+ " </method>"
+ " <method name='" + METHOD_GET_NETDEV_LIST + "'>"
+ " <arg type='s' name='zone' direction='in'/>"
+ " <arg type='as' name='list' direction='out'/>"
+ " </method>"
" <method name='" + METHOD_CREATE_NETDEV_VETH + "'>"
" <arg type='s' name='id' direction='in'/>"
" <arg type='s' name='zoneDev' direction='in'/>"
netdev::movePhys(mZone.getInitPid(), devId);
}
+void ZoneAdmin::setNetdevAttrs(const std::string& /* netdev */, const NetdevAttrs& /* attrs */)
+{
+ throw ZoneOperationException("Not implemented");
+}
+
+ZoneAdmin::NetdevAttrs ZoneAdmin::getNetdevAttrs(const std::string& /* netdev */)
+{
+ throw ZoneOperationException("Not implemented");
+}
+
+std::vector<std::string> ZoneAdmin::getNetdevList()
+{
+ throw ZoneOperationException("Not implemented");
+}
+
} // namespace vasum
class ZoneAdmin {
public:
+ typedef std::vector<std::tuple<std::string, std::string>> NetdevAttrs;
/**
* ZoneAdmin constructor
*/
void moveNetdev(const std::string& devId);
+ /**
+ * Set network device attributes
+ */
+ void setNetdevAttrs(const std::string& netdev, const NetdevAttrs& attrs);
+
+ /**
+ * Get network device attributes
+ */
+ NetdevAttrs getNetdevAttrs(const std::string& netdev);
+
+ /**
+ * Get network device list
+ */
+ std::vector<std::string> getNetdevList();
+
private:
const ZoneConfig& mConfig;
lxc::LxcZone mZone;
mProvision->remove(declarationId);
}
+void Zone::setNetdevAttrs(const std::string& netdev, const ZoneAdmin::NetdevAttrs& attrs)
+{
+ Lock lock(mReconnectMutex);
+ mAdmin->setNetdevAttrs(netdev, attrs);
+}
+
+ZoneAdmin::NetdevAttrs Zone::getNetdevAttrs(const std::string& netdev)
+{
+ Lock lock(mReconnectMutex);
+ return mAdmin->getNetdevAttrs(netdev);
+}
+
+std::vector<std::string> Zone::getNetdevList()
+{
+ Lock lock(mReconnectMutex);
+ return mAdmin->getNetdevList();
+}
+
} // namespace vasum
*/
void moveNetdev(const std::string& devId);
+ /**
+ * Set network device attributes
+ */
+ void setNetdevAttrs(const std::string& netdev, const ZoneAdmin::NetdevAttrs& attrs);
+
+ /**
+ * Get network device attributes
+ */
+ ZoneAdmin::NetdevAttrs getNetdevAttrs(const std::string& netdev);
+
+ /**
+ * Get network device list
+ */
+ std::vector<std::string> getNetdevList();
+
private:
utils::Worker::Pointer mWorker;
ZoneConfig mConfig;
mHostConnection.setGetZoneInfoCallback(bind(&ZonesManager::handleGetZoneInfoCall,
this, _1, _2));
+ mHostConnection.setSetNetdevAttrsCallback(bind(&ZonesManager::handleSetNetdevAttrsCall,
+ this, _1, _2, _3, _4));
+
+ mHostConnection.setGetNetdevAttrsCallback(bind(&ZonesManager::handleGetNetdevAttrsCall,
+ this, _1, _2, _3));
+
+ mHostConnection.setGetNetdevListCallback(bind(&ZonesManager::handleGetNetdevListCall,
+ this, _1, _2));
+
mHostConnection.setCreateNetdevVethCallback(bind(&ZonesManager::handleCreateNetdevVethCall,
this, _1, _2, _3, _4));
zone.getRootPath().c_str()));
}
+void ZonesManager::handleSetNetdevAttrsCall(const std::string& zone,
+ const std::string& netdev,
+ const std::vector<
+ std::tuple<std::string, std::string>>& attrs,
+ dbus::MethodResultBuilder::Pointer result)
+{
+ LOGI("SetNetdevAttrs call");
+ try {
+ Lock lock(mMutex);
+
+ getZone(zone).setNetdevAttrs(netdev, attrs);
+ result->setVoid();
+ } catch (const InvalidZoneIdException&) {
+ LOGE("No zone with id=" << zone);
+ result->setError(api::ERROR_INVALID_ID, "No such zone id");
+ } catch (const VasumException& ex) {
+ LOGE("Can't set attributes: " << ex.what());
+ result->setError(api::ERROR_INTERNAL, ex.what());
+ }
+}
+
+void ZonesManager::handleGetNetdevAttrsCall(const std::string& zone,
+ const std::string& netdev,
+ dbus::MethodResultBuilder::Pointer result)
+{
+ LOGI("GetNetdevAttrs call");
+ try {
+ Lock lock(mMutex);
+
+ const auto attrs = getZone(zone).getNetdevAttrs(netdev);
+
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ for (const auto entry : attrs) {
+ g_variant_builder_add(&builder,
+ "(ss)",
+ std::get<0>(entry).c_str(),
+ std::get<1>(entry).c_str());
+ }
+ result->set(g_variant_builder_end(&builder));
+ } catch (const InvalidZoneIdException&) {
+ LOGE("No zone with id=" << zone);
+ result->setError(api::ERROR_INVALID_ID, "No such zone id");
+ } catch (const VasumException& ex) {
+ LOGE("Can't set attributes: " << ex.what());
+ result->setError(api::ERROR_INTERNAL, ex.what());
+ }
+}
+
+void ZonesManager::handleGetNetdevListCall(const std::string& zone,
+ dbus::MethodResultBuilder::Pointer result)
+{
+ LOGI("GetNetdevList call");
+ try {
+ Lock lock(mMutex);
+ std::vector<GVariant*> netdevs;
+ for(auto& netdev: getZone(zone).getNetdevList()){
+ netdevs.push_back(g_variant_new_string(netdev.c_str()));
+ }
+ GVariant* array = g_variant_new_array(G_VARIANT_TYPE("s"),
+ netdevs.data(),
+ netdevs.size());
+ result->set(g_variant_new("(@as)", array));
+ } catch (const InvalidZoneIdException&) {
+ LOGE("No zone with id=" << zone);
+ result->setError(api::ERROR_INVALID_ID, "No such zone id");
+ } catch (const VasumException& ex) {
+ LOGE("Can't set attributes: " << ex.what());
+ result->setError(api::ERROR_INTERNAL, ex.what());
+ }
+}
+
void ZonesManager::handleCreateNetdevVethCall(const std::string& zone,
const std::string& zoneDev,
const std::string& hostDev,
getZone(zone).createNetdevVeth(zoneDev, hostDev);
result->setVoid();
- } catch (const std::out_of_range&) {
+ } catch (const InvalidZoneIdException&) {
LOGE("No zone with id=" << zone);
result->setError(api::ERROR_INVALID_ID, "No such zone id");
} catch (const VasumException& ex) {
getZone(zone).createNetdevMacvlan(zoneDev, hostDev, mode);
result->setVoid();
- } catch (const std::out_of_range&) {
+ } catch (const InvalidZoneIdException&) {
LOGE("No zone with id=" << zone);
result->setError(api::ERROR_INVALID_ID, "No such zone id");
} catch (const VasumException& ex) {
getZone(zone).moveNetdev(devId);
result->setVoid();
- } catch (const std::out_of_range&) {
+ } catch (const InvalidZoneIdException&) {
LOGE("No zone with id=" << zone);
result->setError(api::ERROR_INVALID_ID, "No such zone id");
} catch (const VasumException& ex) {
void handleGetZoneIdsCall(dbus::MethodResultBuilder::Pointer result);
void handleGetActiveZoneIdCall(dbus::MethodResultBuilder::Pointer result);
void handleGetZoneInfoCall(const std::string& id, dbus::MethodResultBuilder::Pointer result);
+ void handleSetNetdevAttrsCall(const std::string& zone,
+ const std::string& netdev,
+ const std::vector<std::tuple<std::string, std::string>>& attrs,
+ dbus::MethodResultBuilder::Pointer result);
+ void handleGetNetdevAttrsCall(const std::string& zone,
+ const std::string& netdev,
+ dbus::MethodResultBuilder::Pointer result);
+ void handleGetNetdevListCall(const std::string& zone,
+ dbus::MethodResultBuilder::Pointer result);
void handleCreateNetdevVethCall(const std::string& zone,
const std::string& zoneDev,
const std::string& hostDev,