From a2bfdea7f5bb1e2126701e0cf7d691f326afa9c4 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Thu, 12 Feb 2015 16:39:58 +0100 Subject: [PATCH] Creating netdev [Feature] Filled stubs for creating netdev (create_netdev_phys, create_netdev_macvlan, create_netdev_veth) [Cause] N/A [Solution] Manage netdev through netlink interface [Verification] Build, install, run vasum-server, create zone (vasum-cli create_zone zone1), start zone (vasum-cli start_zone zone1), move interface f.e. p2p1 to zone (vasum-cli create_netdev_phys zone1 p2p1) enter to zone (lxc-console -n zone1 --lxcpath=/usr/local/share/.zones -t 0) check interfaces (ifconfig -a) do analogous for create_netdev_macvlan and create_netdev_veth Change-Id: I299d3ebeb8f101a386f5b156dbe79d7779600ef6 --- common/lxc/zone.cpp | 5 + common/lxc/zone.hpp | 7 ++ common/netlink/netlink-message.cpp | 164 +++++++++++++++++++++++++ common/netlink/netlink-message.hpp | 116 ++++++++++++++++++ common/netlink/netlink.cpp | 155 ++++++++++++++++++++++++ common/netlink/netlink.hpp | 79 ++++++++++++ server/netdev.cpp | 242 +++++++++++++++++++++++++++++++++++++ server/netdev.hpp | 45 +++++++ server/zone-admin.cpp | 19 +-- 9 files changed, 823 insertions(+), 9 deletions(-) create mode 100644 common/netlink/netlink-message.cpp create mode 100644 common/netlink/netlink-message.hpp create mode 100644 common/netlink/netlink.cpp create mode 100644 common/netlink/netlink.hpp create mode 100644 server/netdev.cpp create mode 100644 server/netdev.hpp diff --git a/common/lxc/zone.cpp b/common/lxc/zone.cpp index dc148e4..bbb1e02 100644 --- a/common/lxc/zone.cpp +++ b/common/lxc/zone.cpp @@ -313,6 +313,11 @@ bool LxcZone::waitForState(State state, int timeout) return true; } +pid_t LxcZone::getInitPid() const +{ + return mLxcContainer->init_pid(mLxcContainer); +} + bool LxcZone::setRunLevel(int runLevel) { auto callback = [](void* param) -> int { diff --git a/common/lxc/zone.hpp b/common/lxc/zone.hpp index 1573c7d..0ed19a3 100644 --- a/common/lxc/zone.hpp +++ b/common/lxc/zone.hpp @@ -26,6 +26,7 @@ #define COMMON_LXC_ZONE_HPP #include +#include // fwd declaration of lxc internals struct lxc_container; @@ -136,6 +137,12 @@ public: * Unfreeze zone */ bool unfreeze(); + + /** + * Get pid of init process + */ + pid_t getInitPid() const; + private: lxc_container* mLxcContainer; diff --git a/common/netlink/netlink-message.cpp b/common/netlink/netlink-message.cpp new file mode 100644 index 0000000..72d3597 --- /dev/null +++ b/common/netlink/netlink-message.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Netlink message class definition + */ + +#include "config.hpp" +#include "netlink-message.hpp" +#include "netlink.hpp" +#include "base-exception.hpp" + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#ifndef PAGE_SIZE +#define PAGE_SIZE 4096 +#endif + +const int NLMSG_GOOD_SIZE = 2*PAGE_SIZE; +constexpr rtattr* NLMSG_TAIL(nlmsghdr* nmsg) +{ + return reinterpret_cast(reinterpret_cast(nmsg) + NLMSG_ALIGN(nmsg->nlmsg_len)); +} + +namespace vasum { +namespace netlink { + +NetlinkMessage::NetlinkMessage(uint16_t type, uint16_t flags) +{ + static uint32_t seq = 0; + mNlmsg.resize(NLMSG_GOOD_SIZE, 0); + hdr().nlmsg_len = NLMSG_HDRLEN; + hdr().nlmsg_flags = flags | NLM_F_ACK; + hdr().nlmsg_type = type; + hdr().nlmsg_seq = ++seq; + hdr().nlmsg_pid = getpid(); +} + +NetlinkMessage& NetlinkMessage::beginNested(int ifla) +{ + struct rtattr *nest = NLMSG_TAIL(&hdr()); + put(ifla, NULL, 0); + mNested.push(nest); + return *this; +} + +NetlinkMessage& NetlinkMessage::endNested() +{ + assert(!mNested.empty()); + rtattr *nest = reinterpret_cast(mNested.top()); + nest->rta_len = std::distance(reinterpret_cast(nest), + reinterpret_cast(NLMSG_TAIL(&hdr()))); + mNested.pop(); + return *this; +} + +NetlinkMessage& NetlinkMessage::put(int ifla, const std::string& value) +{ + return put(ifla, value.c_str(), value.size() + 1); +} + +NetlinkMessage& NetlinkMessage::put(int ifla, const void* data, int len) +{ + struct rtattr *rta; + size_t rtalen = RTA_LENGTH(len); + int newLen = NLMSG_ALIGN(hdr().nlmsg_len) + RTA_ALIGN(rtalen); + + setMinCapacity(newLen); + rta = NLMSG_TAIL(&hdr()); + rta->rta_type = ifla; + rta->rta_len = rtalen; + memcpy(RTA_DATA(rta), data, len); + hdr().nlmsg_len = newLen; + return *this; +} + +NetlinkMessage& NetlinkMessage::put(const void* data, int len) +{ + setMinCapacity(hdr().nlmsg_len + len); + memcpy((reinterpret_cast(&hdr()) + hdr().nlmsg_len), data, len); + hdr().nlmsg_len += len; + return *this; +} + +nlmsghdr& NetlinkMessage::hdr() { + return *reinterpret_cast(mNlmsg.data()); +} + +const nlmsghdr& NetlinkMessage::hdr() const { + return *reinterpret_cast(mNlmsg.data()); +} + +void NetlinkMessage::setMinCapacity(unsigned int size) +{ + if (mNlmsg.size() < size) { + mNlmsg.resize(size, 0); + } +} + +void send(const NetlinkMessage& msg) +{ + //TODO: Handle messages with responses + assert(msg.hdr().nlmsg_flags & NLM_F_ACK); + + const int answerLen = NLMSG_ALIGN(msg.hdr().nlmsg_len + sizeof(nlmsgerr)); + std::unique_ptr answerBuff(new char[answerLen]); + nlmsghdr* answer = reinterpret_cast(answerBuff.get()); + answer->nlmsg_len = answerLen; + + Netlink nl; + nl.open(); + try { + nl.send(&msg.hdr()); + //Receive ACK Netlink Message + do { + nl.rcv(answer); + } while (answer->nlmsg_type == NLMSG_NOOP); + } catch (const std::exception& ex) { + LOGE("Sending failed (" << ex.what() << ")"); + nl.close(); + throw; + } + nl.close(); + if (answer->nlmsg_type != NLMSG_ERROR) { + // It is not NACK/ACK message + throw VasumException("Sending failed ( unrecognized message type )"); + } + nlmsgerr *err = reinterpret_cast(NLMSG_DATA(answer)); + if (answer->nlmsg_seq != msg.hdr().nlmsg_seq) { + throw VasumException("Sending failed ( answer message was mismatched )"); + } + if (err->error) { + throw VasumException("Sending failed (" + getSystemErrorMessage(-err->error) + ")"); + } +} + +} // namespace netlink +} // namespace vasum diff --git a/common/netlink/netlink-message.hpp b/common/netlink/netlink-message.hpp new file mode 100644 index 0000000..e828feb --- /dev/null +++ b/common/netlink/netlink-message.hpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Netlink message class declaration + */ + +#ifndef COMMON_NETLINK_NETLINK_MESSAGE_HPP +#define COMMON_NETLINK_NETLINK_MESSAGE_HPP + +#include +#include +#include +#include +#include +#include + +namespace vasum { +namespace netlink { + +/** + * NetlinkMessage is used to creatie a netlink messages + */ +class NetlinkMessage { +public: + /** + * Create netlink message + * + * @param type rtnetlink message type (see man 7 rtnetlink) + * @param flags nlmsg flags (see man 7 netlink) + */ + NetlinkMessage(std::uint16_t type, std::uint16_t flags); + + /** + * Add nested atribute type + * + * All future attributes will be nested in this attribute (till call to endNested) + * + * @param ifla attribute name + */ + NetlinkMessage& beginNested(int ifla); + + /** + * End nested atribute + */ + NetlinkMessage& endNested(); + + ///@{ + /*Add sample attribute */ + NetlinkMessage& put(int ifla, const std::string& value); + template + NetlinkMessage& put(int ifla, const T& value); + ///@} + + /** + * Add raw data + * + * Add raw data to end of netlink message + */ + template + NetlinkMessage& put(const T& value); + + /** + * Send netlink message + * + * It is not thread safe + */ + friend void send(const NetlinkMessage& msg); +private: + std::vector mNlmsg; + std::stack mNested; + + NetlinkMessage& put(int ifla, const void* data, int len); + NetlinkMessage& put(const void* data, int len); + nlmsghdr& hdr(); + const nlmsghdr& hdr() const; + void setMinCapacity(unsigned int size); + + +}; + +template +NetlinkMessage& NetlinkMessage::put(int ifla, const T& value) +{ + static_assert(std::is_pod::value, "Require trivial and standard-layout"); + return put(ifla, &value, sizeof(value)); +} + +template +NetlinkMessage& NetlinkMessage::put(const T& value) +{ + static_assert(std::is_pod::value, "Require trivial and standard-layout structure"); + return put(&value, sizeof(value)); +} + +} // namespace netlink +} // namespace vasum + +#endif // COMMON_NETLINK_NETLINK_MESSAGE_HPP diff --git a/common/netlink/netlink.cpp b/common/netlink/netlink.cpp new file mode 100644 index 0000000..fa86b45 --- /dev/null +++ b/common/netlink/netlink.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Netlink class definition + */ + +#include "config.hpp" +#include "netlink.hpp" +#include "utils.hpp" +#include "base-exception.hpp" + +#include +#include +#include +#include +#include +#include + +namespace vasum { + +namespace { + +template +T make_clean() +{ + static_assert(std::is_pod::value, "make_clean require trivial and standard-layout"); + T value; + std::fill_n(reinterpret_cast(&value), sizeof(value), 0); + return value; +} + +} // namespace + +Netlink::Netlink() : mFd(-1) +{ +} + +Netlink::~Netlink() +{ + close(); +} + +void Netlink::open() +{ + assert(mFd == -1); + mFd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (mFd == -1) { + LOGE("Can't open socket (" << getSystemErrorMessage() << ")"); + throw VasumException("Can't open netlink connection"); + } + + sockaddr_nl local = make_clean(); + local.nl_family = AF_NETLINK; + + if (bind(mFd, (struct sockaddr *)&local, sizeof(local)) < 0) { + int err = errno; + close(); + LOGE("Can't bind to socket (" << getSystemErrorMessage(err) << ")"); + throw VasumException("Can't set up netlink connection"); + } +} + +void Netlink::close() +{ + if (mFd != -1) { + ::close(mFd); + mFd = -1; + } +} + +void Netlink::send(const nlmsghdr *nlmsg) +{ + msghdr msg = make_clean(); + sockaddr_nl nladdr = make_clean(); + iovec iov = make_clean(); + + iov.iov_base = (void *)nlmsg; + iov.iov_len = nlmsg->nlmsg_len; + msg.msg_name = &nladdr; + msg.msg_namelen = sizeof(nladdr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + nladdr.nl_family = AF_NETLINK; + + int ret = sendmsg(mFd, &msg, 0); + if (ret < 0) { + LOGE("Can't send message (" << getSystemErrorMessage() << ")"); + throw VasumException("Can't send netlink message"); + } +} + +int Netlink::rcv(nlmsghdr *answer) +{ + //TODO: Handle too small buffer situation (buffer resizing) + msghdr msg = make_clean(); + sockaddr_nl nladdr = make_clean(); + iovec iov = make_clean(); + + iov.iov_base = answer; + iov.iov_len = answer->nlmsg_len; + msg.msg_name = &nladdr; + msg.msg_namelen = sizeof(nladdr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + nladdr.nl_family = AF_NETLINK; + + int ret = recvmsg(mFd, &msg, 0); + if (ret < 0) { + LOGE("Can't receive message (" + getSystemErrorMessage() + ")"); + throw VasumException("Can't receive netlink message"); + } + if (ret == 0) { + LOGE("Peer has performed an orderly shutdown"); + throw VasumException("Can't receive netlink message"); + } + if (msg.msg_flags & MSG_TRUNC) { + LOGE("Can't receive message (" + getSystemErrorMessage(EMSGSIZE) + ")"); + throw VasumException("Can't receive netlink message"); + } + if (msg.msg_flags & MSG_ERRQUEUE) { + LOGE("No data was received but an extended error"); + throw VasumException("Can't receive netlink message"); + } + if (msg.msg_flags & MSG_OOB) { + LOGE("Internal error (expedited or out-of-band data were received)"); + throw VasumException("Can't receive netlink message"); + } + if (msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) { + assert(!"This should not happen!"); + LOGE("Internal error (" << std::to_string(msg.msg_flags) << ")"); + throw VasumException("Internal error while recaiving netlink message"); + } + + return ret; +} + +} //namespace vasum diff --git a/common/netlink/netlink.hpp b/common/netlink/netlink.hpp new file mode 100644 index 0000000..2e73ce8 --- /dev/null +++ b/common/netlink/netlink.hpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Netlink class declaration + */ + +#ifndef COMMON_NETLINK_NETLINK_HPP +#define COMMON_NETLINK_NETLINK_HPP + +#include + +namespace vasum { + +/** + * Netlink class is responsible for communicating + * with kernel through netlink interface + */ +class Netlink { +public: + Netlink(); + ~Netlink(); + + Netlink(const Netlink& other) = delete; + Netlink& operator=(const Netlink& other) = delete; + + /** + * Open connnection + */ + void open(); + + /** + * Close connection + */ + void close(); + + /** + * Send message + * + * It is not thread safe and even you shouldn't call this function on + * different instances at the same time + * + * @param nlmsg pointer to message + */ + void send(const nlmsghdr *nlmsg); + + /** + * Receive message + * + * It is not thread safe and even you shouldn't call this function on + * different instances at the same time + * + * @param answer pointer to answer buffer + */ + int rcv(nlmsghdr *answer); +private: + int mFd; +}; + +} // namespace vasum + +#endif /* COMMON_NETLINK_NETLINK_HPP */ diff --git a/server/netdev.cpp b/server/netdev.cpp new file mode 100644 index 0000000..b4a2d21 --- /dev/null +++ b/server/netdev.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Network devices management functions definition + */ + +#include "config.hpp" +#include "netdev.hpp" +#include "netlink/netlink-message.hpp" +#include "utils.hpp" +#include "exception.hpp" + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace vasum; +using namespace vasum::netlink; + +namespace vasum { +namespace netdev { + +namespace { + +template +T make_clean() +{ + static_assert(std::is_pod::value, "make_clean require trivial and standard-layout"); + T value; + std::fill_n(reinterpret_cast(&value), sizeof(value), 0); + return value; +} + +string getUniqueVethName() +{ + auto find = [](const ifaddrs* ifaddr, const string& name) -> bool { + for (const ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (name == ifa->ifa_name) { + return true; + } + } + return false; + }; + + ifaddrs* ifaddr; + getifaddrs(&ifaddr); + string newName; + int i = 0; + do { + newName = "veth0" + to_string(++i); + } while (find(ifaddr, newName)); + + freeifaddrs(ifaddr); + return newName; +} + +uint32_t getInterfaceIndex(const string& name) { + uint32_t index = if_nametoindex(name.c_str()); + if (!index) { + LOGE("Can't get " << name << " interface index (" << getSystemErrorMessage() << ")"); + throw ZoneOperationException("Can't find interface"); + } + return index; +} + +void validateNetdevName(const string& name) +{ + if (name.size() <= 1 || name.size() >= IFNAMSIZ) { + throw ZoneOperationException("Invalid netdev name format"); + } +} + +void createPipedNetdev(const string& netdev1, const string& netdev2) +{ + validateNetdevName(netdev1); + validateNetdevName(netdev2); + + NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); + ifinfomsg infoPeer = make_clean(); + infoPeer.ifi_family = AF_UNSPEC; + infoPeer.ifi_change = 0xFFFFFFFF; + nlm.put(infoPeer) + .beginNested(IFLA_LINKINFO) + .put(IFLA_INFO_KIND, "veth") + .beginNested(IFLA_INFO_DATA) + .beginNested(VETH_INFO_PEER) + .put(infoPeer) + .put(IFLA_IFNAME, netdev2) + .endNested() + .endNested() + .endNested() + .put(IFLA_IFNAME, netdev1); + send(nlm); +} + +void attachToBridge(const string& bridge, const string& netdev) +{ + validateNetdevName(bridge); + validateNetdevName(netdev); + + uint32_t index = getInterfaceIndex(netdev); + int fd = socket(AF_LOCAL, SOCK_STREAM, 0); + if (fd < 0) { + LOGE("Can't open socket (" << getSystemErrorMessage() << ")"); + throw ZoneOperationException("Can't attach to bridge"); + } + + struct ifreq ifr = make_clean(); + strncpy(ifr.ifr_name, bridge.c_str(), IFNAMSIZ); + ifr.ifr_ifindex = index; + int err = ioctl(fd, SIOCBRADDIF, &ifr); + if (err < 0) { + int error = errno; + //TODO: Close can be interrupted. Move util functions from ipc + ::close(fd); + LOGE("Can't attach to bridge (" + getSystemErrorMessage(error) + ")"); + throw ZoneOperationException("Can't attach to bridge"); + } + close(fd); +} + +int setFlags(const string& name, uint32_t mask, uint32_t flags) +{ + uint32_t index = getInterfaceIndex(name); + NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK); + ifinfomsg infoPeer = make_clean(); + infoPeer.ifi_family = AF_UNSPEC; + infoPeer.ifi_index = index; + infoPeer.ifi_flags = flags; + // since kernel v2.6.22 ifi_change is used to change only selected flags; + infoPeer.ifi_change = mask; + nlm.put(infoPeer); + send(nlm); + return 0; +} + +void up(const string& netdev) +{ + setFlags(netdev, IFF_UP, IFF_UP); +} + +void moveToNS(const string& netdev, pid_t pid) +{ + uint32_t index = getInterfaceIndex(netdev); + NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK); + ifinfomsg infopeer = make_clean(); + infopeer.ifi_family = AF_UNSPEC; + infopeer.ifi_index = index; + nlm.put(infopeer) + .put(IFLA_NET_NS_PID, pid); + send(nlm); +} + +void createMacvlan(const string& master, const string& slave, const macvlan_mode& mode) +{ + validateNetdevName(master); + validateNetdevName(slave); + + uint32_t index = getInterfaceIndex(master); + NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK); + ifinfomsg infopeer = make_clean(); + infopeer.ifi_family = AF_UNSPEC; + infopeer.ifi_change = 0xFFFFFFFF; + nlm.put(infopeer) + .beginNested(IFLA_LINKINFO) + .put(IFLA_INFO_KIND, "macvlan") + .beginNested(IFLA_INFO_DATA) + .put(IFLA_MACVLAN_MODE, static_cast(mode)) + .endNested() + .endNested() + .put(IFLA_LINK, index) + .put(IFLA_IFNAME, slave); + send(nlm); +} + +} // namespace + +void createVeth(const pid_t& nsPid, const string& nsDev, const string& hostDev) +{ + string hostVeth = getUniqueVethName(); + LOGT("Creating veth: bridge: " << hostDev << ", port: " << hostVeth << ", zone: " << nsDev); + createPipedNetdev(nsDev, hostVeth); + //TODO: clean up if following instructions fail + attachToBridge(hostDev, hostVeth); + up(hostVeth); + moveToNS(nsDev, nsPid); +} + +void createMacvlan(const pid_t& nsPid, + const string& nsDev, + const string& hostDev, + const macvlan_mode& mode) +{ + LOGT("Creating macvlan: host: " << hostDev << ", zone: " << nsDev << ", mode: " << mode); + createMacvlan(hostDev, nsDev, mode); + //TODO: clean up if following instructions fail + up(nsDev); + moveToNS(nsDev, nsPid); +} + +void movePhys(const pid_t& nsPid, const string& devId) +{ + LOGT("Creating phys: dev: " << devId); + moveToNS(devId, nsPid); +} + +} //namespace netdev +} //namespace vasum + diff --git a/server/netdev.hpp b/server/netdev.hpp new file mode 100644 index 0000000..de761ca --- /dev/null +++ b/server/netdev.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Network devices management functions declaration + */ + +#ifndef SERVER_NETDEV_HPP +#define SERVER_NETDEV_HPP + +#include +#include +#include + +namespace vasum { +namespace netdev { + +void createVeth(const pid_t& nsPid, const std::string& nsDev, const std::string& hostDev); +void createMacvlan(const pid_t& nsPid, + const std::string& nsDev, + const std::string& hostDev, + const macvlan_mode& mode); +void movePhys(const pid_t& nsPid, const std::string& devId); + +} //namespace netdev +} //namespace vasum + +#endif // SERVER_NETDEV_HPP diff --git a/server/zone-admin.cpp b/server/zone-admin.cpp index c5e994d..5a4adfa 100644 --- a/server/zone-admin.cpp +++ b/server/zone-admin.cpp @@ -26,6 +26,7 @@ #include "zone-admin.hpp" #include "exception.hpp" +#include "netdev.hpp" #include "logger/logger.hpp" #include "utils/paths.hpp" @@ -270,22 +271,22 @@ std::int64_t ZoneAdmin::getSchedulerQuota() return std::stoll(ret); } -void ZoneAdmin::createNetdevVeth(const std::string& /* zoneDev */, - const std::string& /* hostDev */) +void ZoneAdmin::createNetdevVeth(const std::string& zoneDev, + const std::string& hostDev) { - throw ZoneOperationException("Not implemented"); + netdev::createVeth(mZone.getInitPid(), zoneDev, hostDev); } -void ZoneAdmin::createNetdevMacvlan(const std::string& /* zoneDev */, - const std::string& /* hostDev */, - const uint32_t& /* mode */) +void ZoneAdmin::createNetdevMacvlan(const std::string& zoneDev, + const std::string& hostDev, + const uint32_t& mode) { - throw ZoneOperationException("Not implemented"); + netdev::createMacvlan(mZone.getInitPid(), zoneDev, hostDev, static_cast(mode)); } -void ZoneAdmin::moveNetdev(const std::string& /* devId */) +void ZoneAdmin::moveNetdev(const std::string& devId) { - throw ZoneOperationException("Not implemented"); + netdev::movePhys(mZone.getInitPid(), devId); } } // namespace vasum -- 2.7.4