lxcpp: network interface 66/46566/6
authorKrzysztof Dynowski <k.dynowski@samsung.com>
Fri, 21 Aug 2015 15:08:22 +0000 (17:08 +0200)
committerJan Olszak <j.olszak@samsung.com>
Thu, 27 Aug 2015 08:52:50 +0000 (01:52 -0700)
[Feature]       Network interface for lxcpp
[Cause]         N/A
[Solution]      N/A
[Verification]  Build, install, run tests

Change-Id: Ifcf03b46662168c198a8e36c268b6856639ff52e

libs/lxcpp/container-impl.cpp
libs/lxcpp/container-impl.hpp
libs/lxcpp/container.hpp
libs/lxcpp/exception.hpp
libs/lxcpp/network-config.cpp [new file with mode: 0644]
libs/lxcpp/network-config.hpp [new file with mode: 0644]
libs/lxcpp/network.cpp [new file with mode: 0644]
libs/lxcpp/network.hpp [new file with mode: 0644]

index 9af272f..cba0691 100644 (file)
@@ -33,7 +33,6 @@
 #include <unistd.h>
 #include <sys/mount.h>
 
-
 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<std::string> 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
index e236932..a57c340 100644 (file)
@@ -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<std::string> 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<Namespace> mNamespaces;
+    std::vector<NetworkInterfaceConfig> mInterfaceConfig;
 };
 
 } // namespace lxcpp
index 4f2d697..44a3567 100644 (file)
 #ifndef LXCPP_CONTAINER_HPP
 #define LXCPP_CONTAINER_HPP
 
+#include "lxcpp/network-config.hpp"
+
 #include <string>
 #include <functional>
+#include <vector>
 
 namespace lxcpp {
 
+enum class NetStatus {
+    DOWN,
+    UP
+};
+
+struct NetworkInterfaceInfo {
+    const std::string ifname;
+    const NetStatus status;
+    const std::vector<InetAddr> addrs;
+};
+
 class Container {
 public:
     typedef std::function<int()> 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<std::string> 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
index 9d8b2cd..51dc5ec 100644 (file)
@@ -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 (file)
index 0000000..77e220a
--- /dev/null
@@ -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 <algorithm>
+
+namespace lxcpp {
+
+void NetworkInterfaceConfig::addNetAddr(const InetAddr& addr)
+{
+    std::vector<InetAddr>::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<InetAddr>::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 (file)
index 0000000..b490aa0
--- /dev/null
@@ -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 <vector>
+#include <string>
+
+#include <string.h>
+#include <netinet/in.h>
+
+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<InetAddr> mIpAddrList;
+};
+
+} //namespace lxcpp
+
+#endif // LXCPP_NETWORK_CONFIG_HPP
diff --git a/libs/lxcpp/network.cpp b/libs/lxcpp/network.cpp
new file mode 100644 (file)
index 0000000..ad01f6f
--- /dev/null
@@ -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 <linux/rtnetlink.h>
+
+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<std::string> 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<ifinfomsg>();
+    info.ifi_family = AF_PACKET;
+    nlm.put(info);
+    NetlinkResponse response = send(nlm, initpid);
+
+    std::vector<std::string> iflist;
+    while (response.hasMessage()) {
+        std::string ifName;
+        response.skip<ifinfomsg>();
+        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 (file)
index 0000000..44ab268
--- /dev/null
@@ -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 <vector>
+
+namespace lxcpp {
+
+struct Attr {
+    std::string name;
+    std::string value;
+};
+
+typedef std::vector<Attr> 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<std::string> 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