From 9c3710942aac6095d0f28587286868783ec1ef6a Mon Sep 17 00:00:00 2001 From: Krzysztof Dynowski Date: Fri, 21 Aug 2015 17:08:22 +0200 Subject: [PATCH] lxcpp: network interface [Feature] Network interface for lxcpp [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: Ifcf03b46662168c198a8e36c268b6856639ff52e --- libs/lxcpp/container-impl.cpp | 56 +++++++++++++++++- libs/lxcpp/container-impl.hpp | 22 +++++++ libs/lxcpp/container.hpp | 34 +++++++++++ libs/lxcpp/exception.hpp | 5 ++ libs/lxcpp/network-config.cpp | 47 +++++++++++++++ libs/lxcpp/network-config.hpp | 116 ++++++++++++++++++++++++++++++++++++ libs/lxcpp/network.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++ libs/lxcpp/network.hpp | 73 +++++++++++++++++++++++ 8 files changed, 486 insertions(+), 1 deletion(-) create mode 100644 libs/lxcpp/network-config.cpp create mode 100644 libs/lxcpp/network-config.hpp create mode 100644 libs/lxcpp/network.cpp create mode 100644 libs/lxcpp/network.hpp diff --git a/libs/lxcpp/container-impl.cpp b/libs/lxcpp/container-impl.cpp index 9af272f..cba0691 100644 --- a/libs/lxcpp/container-impl.cpp +++ b/libs/lxcpp/container-impl.cpp @@ -33,7 +33,6 @@ #include #include - namespace lxcpp { ContainerImpl::ContainerImpl() @@ -185,6 +184,61 @@ void ContainerImpl::attach(Container::AttachCall& call) } } +void ContainerImpl::addInterfaceConfig(const std::string& hostif, + const std::string& zoneif, + InterfaceType type, + MacVLanMode mode) +{ + mInterfaceConfig.push_back(NetworkInterfaceConfig(hostif,zoneif,type,mode)); +} + +void ContainerImpl::addAddrConfig(const std::string& /*ifname*/, const InetAddr& /*addr*/) +{ + throw NotImplementedException(); +} + +std::vector ContainerImpl::getInterfaces() +{ + return NetworkInterface::getInterfaces(getInitPid()); +} + +NetworkInterfaceInfo ContainerImpl::getInterfaceInfo(const std::string& /*ifname*/) +{ + throw NotImplementedException(); +} + +void ContainerImpl::createInterface(const std::string& hostif, + const std::string& zoneif, + InterfaceType type, + MacVLanMode mode) +{ + NetworkInterface ni(*this, zoneif); + ni.create(hostif, type, mode); +} + +void ContainerImpl::destroyInterface(const std::string& /*ifname*/) +{ + throw NotImplementedException(); +} + +void ContainerImpl::setUp(const std::string& /*ifname*/) +{ + throw NotImplementedException(); +} + +void ContainerImpl::setDown(const std::string& /*ifname*/) +{ + throw NotImplementedException(); +} +void ContainerImpl::addAddr(const std::string& /*ifname*/, const InetAddr& /*addr*/) +{ + throw NotImplementedException(); +} + +void ContainerImpl::delAddr(const std::string& /*ifname*/, const InetAddr& /*addr*/) +{ + throw NotImplementedException(); +} } // namespace lxcpp diff --git a/libs/lxcpp/container-impl.hpp b/libs/lxcpp/container-impl.hpp index e236932..a57c340 100644 --- a/libs/lxcpp/container-impl.hpp +++ b/libs/lxcpp/container-impl.hpp @@ -26,6 +26,7 @@ #include "lxcpp/container.hpp" #include "lxcpp/namespace.hpp" +#include "lxcpp/network.hpp" #include "utils/channel.hpp" @@ -56,6 +57,26 @@ public: // Other void attach(Container::AttachCall& attachCall); + // Network interfaces setup/config + void addInterfaceConfig(const std::string& hostif, + const std::string& zoneif, + InterfaceType type, + MacVLanMode mode); + void addAddrConfig(const std::string& ifname, const InetAddr& addr); + + // Network interfaces (runtime) + std::vector getInterfaces(); + NetworkInterfaceInfo getInterfaceInfo(const std::string& ifname); + void createInterface(const std::string& hostif, + const std::string& zoneif, + InterfaceType type, + MacVLanMode mode); + void destroyInterface(const std::string& ifname); + void setUp(const std::string& ifname); + void setDown(const std::string& ifname); + void addAddr(const std::string& ifname, const InetAddr& addr); + void delAddr(const std::string& ifname, const InetAddr& addr); + private: // Methods for different stages of setting up the attachment @@ -65,6 +86,7 @@ private: pid_t mInitPid; std::vector mNamespaces; + std::vector mInterfaceConfig; }; } // namespace lxcpp diff --git a/libs/lxcpp/container.hpp b/libs/lxcpp/container.hpp index 4f2d697..44a3567 100644 --- a/libs/lxcpp/container.hpp +++ b/libs/lxcpp/container.hpp @@ -24,11 +24,25 @@ #ifndef LXCPP_CONTAINER_HPP #define LXCPP_CONTAINER_HPP +#include "lxcpp/network-config.hpp" + #include #include +#include namespace lxcpp { +enum class NetStatus { + DOWN, + UP +}; + +struct NetworkInterfaceInfo { + const std::string ifname; + const NetStatus status; + const std::vector addrs; +}; + class Container { public: typedef std::function AttachCall; @@ -54,6 +68,26 @@ public: // Other virtual void attach(AttachCall& attachCall) = 0; + + // Network interfaces setup/config + virtual void addInterfaceConfig(const std::string& hostif, + const std::string& zoneif, + InterfaceType type, + MacVLanMode mode) = 0; + virtual void addAddrConfig(const std::string& ifname, const InetAddr& addr) = 0; + + // Network interfaces (runtime) + virtual std::vector getInterfaces() = 0; + virtual NetworkInterfaceInfo getInterfaceInfo(const std::string& ifname) = 0; + virtual void createInterface(const std::string& hostif, + const std::string& zoneif, + InterfaceType type, + MacVLanMode mode) = 0; + virtual void destroyInterface(const std::string& ifname) = 0; + virtual void setUp(const std::string& ifname) = 0; + virtual void setDown(const std::string& ifname) = 0; + virtual void addAddr(const std::string& ifname, const InetAddr& addr) = 0; + virtual void delAddr(const std::string& ifname, const InetAddr& addr) = 0; }; } // namespace lxcpp diff --git a/libs/lxcpp/exception.hpp b/libs/lxcpp/exception.hpp index 9d8b2cd..51dc5ec 100644 --- a/libs/lxcpp/exception.hpp +++ b/libs/lxcpp/exception.hpp @@ -61,6 +61,11 @@ struct BadArgument: public Exception { : Exception(message) {} }; +struct NetworkException : public Exception { + NetworkException (const std::string& message = "Error during setting up a network") + : Exception(message) {} +}; + } // namespace lxcpp #endif // LXCPP_EXCEPTION_HPP diff --git a/libs/lxcpp/network-config.cpp b/libs/lxcpp/network-config.cpp new file mode 100644 index 0000000..77e220a --- /dev/null +++ b/libs/lxcpp/network-config.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +/** + * @file + * @author Krzysztof Dynowski (k.dynowski@samsumg.com) + * @brief Network configuration classes + */ + +#include "lxcpp/network-config.hpp" +#include "lxcpp/exception.hpp" +#include + +namespace lxcpp { + +void NetworkInterfaceConfig::addNetAddr(const InetAddr& addr) +{ + std::vector::iterator exists = std::find(mIpAddrList.begin(), mIpAddrList.end(), addr); + if (exists != mIpAddrList.end()) { + std::string msg("Address alredy assigned"); + throw NetworkException(msg); + } + mIpAddrList.push_back(addr); +} + +void NetworkInterfaceConfig::delNetAddr(const InetAddr& addr) +{ + std::vector::iterator exists = std::find(mIpAddrList.begin(), mIpAddrList.end(), addr); + mIpAddrList.erase(exists); +} + +} //namespace lxcpp diff --git a/libs/lxcpp/network-config.hpp b/libs/lxcpp/network-config.hpp new file mode 100644 index 0000000..b490aa0 --- /dev/null +++ b/libs/lxcpp/network-config.hpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @author Krzysztof Dynowski (k.dynowski@samsumg.com) + * @brief Network configuration classes + */ + +#ifndef LXCPP_NETWORK_CONFIG_HPP +#define LXCPP_NETWORK_CONFIG_HPP + +#include +#include + +#include +#include + +namespace lxcpp { + +/** + * Created interface type + */ +enum class InterfaceType { + VETH, + BRIDGE, + MACVLAN, + MOVE +}; + +/** + * Suported MacVLan modes + */ +enum class MacVLanMode { + PRIVATE, + VEPA, + BRIDGE, + PASSTHRU +}; + +/** + * Suported address types + */ +enum class InetAddrType { + IPV4, + IPV6 +}; + +/** + * Unified ip address + */ +struct InetAddr { + InetAddrType type; + int prefix; + union { + struct in_addr ipv4; + struct in6_addr ipv6; + } addr; +}; + +static inline bool operator==(const InetAddr& a, const InetAddr& b) { + if (a.type == b.type && a.prefix == b.prefix) { + if (a.type == InetAddrType::IPV4) { + return ::memcmp(&a.addr.ipv4, &b.addr.ipv4, sizeof(a.addr.ipv4)) == 0; + } + if (a.type == InetAddrType::IPV6) { + return ::memcmp(&a.addr.ipv6, &b.addr.ipv6, sizeof(a.addr.ipv6)) == 0; + } + } + return false; +} + + +/** + * Network interface configuration + */ +class NetworkInterfaceConfig { +public: + NetworkInterfaceConfig(const std::string& hostif, + const std::string& zoneif, + InterfaceType type, + MacVLanMode mode = MacVLanMode::PRIVATE) : + mHostIf(hostif), + mZoneIf(zoneif), + mType(type), + mMode(mode) + { + } + void addNetAddr(const InetAddr&); + void delNetAddr(const InetAddr&); + +private: + const std::string mHostIf; + const std::string mZoneIf; + const InterfaceType mType; + const MacVLanMode mMode; + std::vector mIpAddrList; +}; + +} //namespace lxcpp + +#endif // LXCPP_NETWORK_CONFIG_HPP diff --git a/libs/lxcpp/network.cpp b/libs/lxcpp/network.cpp new file mode 100644 index 0000000..ad01f6f --- /dev/null +++ b/libs/lxcpp/network.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @author Krzysztof Dynowski (k.dynowski@samsumg.com) + * @brief Actions on network interace in the container + */ + + +#include "lxcpp/network.hpp" +#include "lxcpp/exception.hpp" +#include "netlink/netlink-message.hpp" +#include "utils/make-clean.hpp" + +#include + +using namespace vasum::netlink; + +namespace lxcpp { + +void NetworkInterface::create(const std::string& hostif, + InterfaceType type, + MacVLanMode mode) +{ + switch (type) { + case InterfaceType::VETH: + createVeth(hostif); + break; + case InterfaceType::BRIDGE: + createBridge(hostif); + break; + case InterfaceType::MACVLAN: + createMacVLan(hostif, mode); + break; + case InterfaceType::MOVE: + move(hostif); + break; + default: + throw NetworkException("Unsuported interface type"); + } +} + +void NetworkInterface::createVeth(const std::string& /*hostif*/) +{ + throw NotImplementedException(); +} + +void NetworkInterface::createBridge(const std::string& /*hostif*/) +{ + throw NotImplementedException(); +} + +void NetworkInterface::createMacVLan(const std::string& /*hostif*/, MacVLanMode /*mode*/) +{ + throw NotImplementedException(); +} + +void NetworkInterface::move(const std::string& /*hostif*/) +{ + throw NotImplementedException(); +} + +void NetworkInterface::destroy() +{ + throw NotImplementedException(); +} + +NetStatus NetworkInterface::status() +{ + throw NotImplementedException(); + /* + //TODO get container status, if stopped return CONFIGURED + if (mContainer.getInitPid()<=0) return CONFIGURED; + // read netlink + return DOWN;*/ +} + + +void NetworkInterface::up() +{ + throw NotImplementedException(); +} + +void NetworkInterface::down() +{ + throw NotImplementedException(); +} + +void NetworkInterface::setAttrs(const Attrs& /*attrs*/) +{ + throw NotImplementedException(); +} + +const Attrs NetworkInterface::getAttrs() const +{ + throw NotImplementedException(); +} + +std::vector NetworkInterface::getInterfaces(pid_t initpid) +{ + // get interfaces seen by netlink + NetlinkMessage nlm(RTM_GETLINK, NLM_F_REQUEST|NLM_F_DUMP|NLM_F_ROOT); + ifinfomsg info = utils::make_clean(); + info.ifi_family = AF_PACKET; + nlm.put(info); + NetlinkResponse response = send(nlm, initpid); + + std::vector iflist; + while (response.hasMessage()) { + std::string ifName; + response.skip(); + response.fetch(IFLA_IFNAME, ifName); + iflist.push_back(ifName); + response.fetchNextMessage(); + } + return iflist; +} + +} // namespace lxcpp diff --git a/libs/lxcpp/network.hpp b/libs/lxcpp/network.hpp new file mode 100644 index 0000000..44ab268 --- /dev/null +++ b/libs/lxcpp/network.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @author Krzysztof Dynowski (k.dynowski@samsumg.com) + * @brief Actions on network interace in the container + */ + +#ifndef LXCPP_NETWORK_HPP +#define LXCPP_NETWORK_HPP + +#include "lxcpp/container.hpp" +#include + +namespace lxcpp { + +struct Attr { + std::string name; + std::string value; +}; + +typedef std::vector Attrs; + + +/// Network operations to be performed on given container and interface +/// operates on netlink device +class NetworkInterface { +public: + NetworkInterface(Container& c, const std::string& ifname) : + mContainer(c), + mIfname(ifname) + { } + + //Network actions on Container + void create(const std::string& hostif, InterfaceType type, MacVLanMode mode=MacVLanMode::PRIVATE); + void destroy(); + + NetStatus status(); + void up(); + void down(); + void setAttrs(const Attrs& attrs); + const Attrs getAttrs() const; + + static std::vector getInterfaces(pid_t initpid); + +private: + void createVeth(const std::string& hostif); + void createBridge(const std::string& hostif); + void createMacVLan(const std::string& hostif, MacVLanMode mode); + void move(const std::string& hostif); + + Container& mContainer; ///< Container to operate on + const std::string mIfname; ///< network interface name inside zone +}; + +} // namespace lxcpp + +#endif // LXCPP_NETWORK_HPP -- 2.7.4