}
}
+VsmStatus Client::vsm_netdev_del_ipv4_addr(const char* zone,
+ const char* netdevId,
+ struct in_addr* addr,
+ int prefix) noexcept
+{
+ std::string ip;
+ try {
+ //CIDR notation
+ ip = toString(addr) + "/" + to_string(prefix);
+ } catch(const std::exception& ex) {
+ mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what());
+ return vsm_get_status();
+ }
+
+ GVariant* args_in = g_variant_new("(sss)", zone, netdevId, ip.c_str());
+ return callMethod(HOST_INTERFACE, api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, args_in);
+}
+
+VsmStatus Client::vsm_netdev_del_ipv6_addr(const char* zone,
+ const char* netdevId,
+ struct in6_addr* addr,
+ int prefix) noexcept
+{
+
+ std::string ip;
+ try {
+ //CIDR notation
+ ip = toString(addr) + "/" + to_string(prefix);
+ } catch(const std::exception& ex) {
+ mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what());
+ return vsm_get_status();
+ }
+
+ GVariant* args_in = g_variant_new("(sss)", zone, netdevId, ip.c_str());
+ return callMethod(HOST_INTERFACE, api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, args_in);
+}
+
+
VsmStatus Client::vsm_netdev_up(const char* zone, const char* netdevId) noexcept
{
try {
int prefix) noexcept;
/**
+ * @see ::vsm_netdev_del_ipv4_addr
+ */
+ VsmStatus vsm_netdev_del_ipv4_addr(const char* zone,
+ const char* netdevId,
+ struct in_addr* addr,
+ int prefix) noexcept;
+
+ /**
+ * @see ::vsm_netdev_del_ipv6_addr
+ */
+ VsmStatus vsm_netdev_del_ipv6_addr(const char* zone,
+ const char* netdevId,
+ struct in6_addr* addr,
+ int prefix) noexcept;
+
+ /**
* @see ::vsm_netdev_up
*/
VsmStatus vsm_netdev_up(const char* zone, const char* netdevId) noexcept;
return getClient(client).vsm_netdev_set_ipv6_addr(zone, netdevId, addr, prefix);
}
+API VsmStatus vsm_netdev_del_ipv4_addr(VsmClient client,
+ const char* zone,
+ const char* netdevId,
+ struct in_addr* addr,
+ int prefix)
+{
+ return getClient(client).vsm_netdev_del_ipv4_addr(zone, netdevId, addr, prefix);
+}
+
+API VsmStatus vsm_netdev_del_ipv6_addr(VsmClient client,
+ const char* zone,
+ const char* netdevId,
+ struct in6_addr* addr,
+ int prefix)
+{
+ return getClient(client).vsm_netdev_del_ipv6_addr(zone, netdevId, addr, prefix);
+}
+
API VsmStatus vsm_netdev_up(VsmClient client,
const char* zone,
const char* netdevId)
int prefix);
/**
+ * Remove ipv4 address from netdev
+ *
+ * @param[in] client vasum-server's client
+ * @param[in] zone zone name
+ * @param[in] netdevId network device id
+ * @param[in] addr ipv4 address
+ * @param[in] prefix bit-length of the network prefix
+ * @return status of this function call
+ */
+VsmStatus vsm_netdev_del_ipv4_addr(VsmClient client,
+ const char* zone,
+ const char* netdevId,
+ struct in_addr* addr,
+ int prefix);
+
+/**
+ * Remove ipv6 address from netdev
+ *
+ * @param[in] client vasum-server's client
+ * @param[in] zone zone name
+ * @param[in] netdevId network device id
+ * @param[in] addr ipv6 address
+ * @param[in] prefix bit-length of the network prefix
+ * @return status of this function call
+ */
+VsmStatus vsm_netdev_del_ipv6_addr(VsmClient client,
+ const char* zone,
+ const char* netdevId,
+ struct in6_addr* addr,
+ int prefix);
+
+/**
* Turn up a network device in the zone
*
* @param[in] client vasum-server's client
* @param data custom user's data pointer passed to vsm_add_notification_callback()
*/
typedef void (*VsmNotificationCallback)(const char* zone,
- const char* application,
- const char* message,
- void* data);
+ const char* application,
+ const char* message,
+ void* data);
/**
* Send message to active zone.
*
)
};
+struct DeleteNetdevIpAddressIn {
+ std::string zone;
+ std::string netdev;
+ std::string ip;
+
+ CONFIG_REGISTER
+ (
+ zone,
+ netdev,
+ ip
+ )
+};
+
struct DeclareFileIn {
std::string zone;
int32_t type;
mDestroyNetdevCallback = callback;
}
+void HostConnection::setDeleleNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback)
+{
+ mDeleteNetdevIpAddressCallback = callback;
+}
+
void HostConnection::setDeclareFileCallback(const DeclareFileCallback& callback)
{
mDeclareFileCallback = callback;
}
}
+ if (methodName == api::host::METHOD_DELETE_NETDEV_IP_ADDRESS) {
+ api::DeleteNetdevIpAddressIn data;
+ config::loadFromGVariant(parameters, data);
+ if (mDeleteNetdevIpAddressCallback) {
+ auto rb = std::make_shared<api::DbusMethodResultBuilder<api::Void>>(result);
+ mDeleteNetdevIpAddressCallback(data, rb);
+ }
+ }
+
if (methodName == api::host::METHOD_DECLARE_FILE) {
api::DeclareFileIn data;
config::loadFromGVariant(parameters, data);
typedef std::function<void(const api::CreateNetDevPhysIn& dataIn,
api::MethodResultBuilder::Pointer result
)> CreateNetdevPhysCallback;
+ typedef std::function<void(const api::DeleteNetdevIpAddressIn& dataIn,
+ api::MethodResultBuilder::Pointer result
+ )> DeleteNetdevIpAddressCallback;
typedef std::function<void(const api::DestroyNetDevIn& dataIn,
api::MethodResultBuilder::Pointer result
)> DestroyNetdevCallback;
void setDestroyNetdevCallback(const DestroyNetdevCallback& callback);
/**
+ * Register a callback called to remove ip address from netdev
+ */
+ void setDeleleNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback);
+
+ /**
* Register a callback called to declare file
*/
void setDeclareFileCallback(const DeclareFileCallback& callback);
CreateNetdevMacvlanCallback mCreateNetdevMacvlanCallback;
CreateNetdevPhysCallback mCreateNetdevPhysCallback;
DestroyNetdevCallback mDestroyNetdevCallback;
+ DeleteNetdevIpAddressCallback mDeleteNetdevIpAddressCallback;
DeclareFileCallback mDeclareFileCallback;
DeclareMountCallback mDeclareMountCallback;
DeclareLinkCallback mDeclareLinkCallback;
namespace api {
namespace host {
-const std::string BUS_NAME = "org.tizen.vasum.host";
-const std::string OBJECT_PATH = "/org/tizen/vasum/host";
-const std::string INTERFACE = "org.tizen.vasum.host.manager";
+const std::string BUS_NAME = "org.tizen.vasum.host";
+const std::string OBJECT_PATH = "/org/tizen/vasum/host";
+const std::string INTERFACE = "org.tizen.vasum.host.manager";
-const std::string ERROR_ZONE_NOT_RUNNING = "org.tizen.vasum.host.Error.ZonesNotRunning";
+const std::string ERROR_ZONE_NOT_RUNNING = "org.tizen.vasum.host.Error.ZonesNotRunning";
-const std::string METHOD_GET_ZONE_DBUSES = "GetZoneDbuses";
-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";
-const std::string METHOD_DESTROY_NETDEV = "DestroyNetdev";
-const std::string METHOD_DECLARE_FILE = "DeclareFile";
-const std::string METHOD_DECLARE_MOUNT = "DeclareMount";
-const std::string METHOD_DECLARE_LINK = "DeclareLink";
-const std::string METHOD_GET_DECLARATIONS = "GetDeclarations";
-const std::string METHOD_REMOVE_DECLARATION = "RemoveDeclaration";
-const std::string METHOD_SET_ACTIVE_ZONE = "SetActiveZone";
-const std::string METHOD_CREATE_ZONE = "CreateZone";
-const std::string METHOD_DESTROY_ZONE = "DestroyZone";
-const std::string METHOD_SHUTDOWN_ZONE = "ShutdownZone";
-const std::string METHOD_START_ZONE = "StartZone";
-const std::string METHOD_LOCK_ZONE = "LockZone";
-const std::string METHOD_UNLOCK_ZONE = "UnlockZone";
-const std::string METHOD_GRANT_DEVICE = "GrantDevice";
-const std::string METHOD_REVOKE_DEVICE = "RevokeDevice";
+const std::string METHOD_GET_ZONE_DBUSES = "GetZoneDbuses";
+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";
+const std::string METHOD_DESTROY_NETDEV = "DestroyNetdev";
+const std::string METHOD_DELETE_NETDEV_IP_ADDRESS = "DeleteNetdevIpAddress";
+const std::string METHOD_DECLARE_FILE = "DeclareFile";
+const std::string METHOD_DECLARE_MOUNT = "DeclareMount";
+const std::string METHOD_DECLARE_LINK = "DeclareLink";
+const std::string METHOD_GET_DECLARATIONS = "GetDeclarations";
+const std::string METHOD_REMOVE_DECLARATION = "RemoveDeclaration";
+const std::string METHOD_SET_ACTIVE_ZONE = "SetActiveZone";
+const std::string METHOD_CREATE_ZONE = "CreateZone";
+const std::string METHOD_DESTROY_ZONE = "DestroyZone";
+const std::string METHOD_SHUTDOWN_ZONE = "ShutdownZone";
+const std::string METHOD_START_ZONE = "StartZone";
+const std::string METHOD_LOCK_ZONE = "LockZone";
+const std::string METHOD_UNLOCK_ZONE = "UnlockZone";
+const std::string METHOD_GRANT_DEVICE = "GrantDevice";
+const std::string METHOD_REVOKE_DEVICE = "RevokeDevice";
-const std::string SIGNAL_ZONE_DBUS_STATE = "ZoneDbusState";
+const std::string SIGNAL_ZONE_DBUS_STATE = "ZoneDbusState";
const std::string DEFINITION =
" <arg type='s' name='id' direction='in'/>"
" <arg type='s' name='devId' direction='in'/>"
" </method>"
+ " <method name='" + METHOD_DELETE_NETDEV_IP_ADDRESS + "'>"
+ " <arg type='s' name='id' direction='in'/>"
+ " <arg type='s' name='devId' direction='in'/>"
+ " <arg type='s' name='ip' direction='in'/>"
+ " </method>"
" <method name='" + METHOD_DECLARE_FILE + "'>"
" <arg type='s' name='zone' direction='in'/>"
" <arg type='i' name='type' direction='in'/>"
return infoPeer.ifi_index;
}
+int getIpFamily(const std::string& ip)
+{
+ return ip.find(':') == std::string::npos ? AF_INET : AF_INET6;
+}
+
void validateNetdevName(const string& name)
{
if (name.size() <= 1 || name.size() >= IFNAMSIZ) {
send(nlm, nsPid);
}
+void deleteIpAddress(const pid_t nsPid,
+ const uint32_t index,
+ const std::string& ip,
+ int prefixlen,
+ int family)
+{
+ NetlinkMessage nlm(RTM_DELADDR, NLM_F_REQUEST | NLM_F_ACK);
+ ifaddrmsg infoAddr = utils::make_clean<ifaddrmsg>();
+ infoAddr.ifa_family = family;
+ infoAddr.ifa_index = index;
+ infoAddr.ifa_prefixlen = prefixlen;
+ nlm.put(infoAddr);
+ if (family == AF_INET6) {
+ in6_addr addr6;
+ if (inet_pton(AF_INET6, ip.c_str(), &addr6) != 1) {
+ throw VasumException("Can't delete ipv6 address");
+ };
+ nlm.put(IFA_ADDRESS, addr6);
+ nlm.put(IFA_LOCAL, addr6);
+ } else {
+ assert(family == AF_INET);
+ in_addr addr4;
+ if (inet_pton(AF_INET, ip.c_str(), &addr4) != 1) {
+ throw VasumException("Can't delete ipv4 address");
+ };
+ nlm.put(IFA_LOCAL, addr4);
+ }
+ send(nlm, nsPid);
+}
+
} // namespace
void createVeth(const pid_t& nsPid, const string& nsDev, const string& hostDev)
setIp(ipv6, infoPeer.ifi_index, AF_INET6);
}
+void deleteIpAddress(const pid_t nsPid,
+ const std::string& netdev,
+ const std::string& ip)
+{
+ uint32_t index = getInterfaceIndex(netdev, nsPid);
+ size_t slash = ip.find('/');
+ if (slash == string::npos) {
+ LOGE("Wrong address format: it is not CIDR notation: can't find '/'");
+ throw VasumException("Wrong address format");
+ }
+ int prefixlen = 0;
+ try {
+ prefixlen = stoi(ip.substr(slash + 1));
+ } catch (const std::exception& ex) {
+ LOGE("Wrong address format: invalid prefixlen");
+ throw VasumException("Wrong address format: invalid prefixlen");
+ }
+ deleteIpAddress(nsPid, index, ip.substr(0, slash), prefixlen, getIpFamily(ip));
+}
+
+
} //namespace netdev
} //namespace vasum
Attrs getAttrs(const pid_t nsPid, const std::string& netdev);
void setAttrs(const pid_t nsPid, const std::string& netdev, const Attrs& attrs);
+/**
+ * Remove ipv4/ipv6 address from interface
+ */
+void deleteIpAddress(const pid_t nsPid, const std::string& netdev, const std::string& ip);
+
} //namespace netdev
} //namespace vasum
return netdev::listNetdev(mZone.getInitPid());
}
+void ZoneAdmin::deleteNetdevIpAddress(const std::string& netdev, const std::string& ip)
+{
+ netdev::deleteIpAddress(mZone.getInitPid(), netdev, ip);
+}
+
} // namespace vasum
*/
std::vector<std::string> getNetdevList();
+ /**
+ * Remove ipv4/ipv6 address from network device
+ */
+ void deleteNetdevIpAddress(const std::string& netdev, const std::string& ip);
+
private:
const ZoneConfig& mConfig;
const ZoneDynamicConfig& mDynamicConfig;
return mAdmin->getNetdevList();
}
+void Zone::deleteNetdevIpAddress(const std::string& netdev, const std::string& ip)
+{
+ Lock lock(mReconnectMutex);
+ mAdmin->deleteNetdevIpAddress(netdev, ip);
+}
+
} // namespace vasum
*/
std::vector<std::string> getNetdevList();
+ /**
+ * Remove ipv4/ipv6 address from network device
+ */
+ void deleteNetdevIpAddress(const std::string& netdev, const std::string& ip);
+
private:
utils::Worker::Pointer mWorker;
ZoneConfig mConfig;
mHostConnection.setDestroyNetdevCallback(bind(&ZonesManager::handleDestroyNetdevCall,
this, _1, _2));
+ mHostConnection.setDeleleNetdevIpAddressCallback(bind(&ZonesManager::handleDeleteNetdevIpAddressCall,
+ this, _1, _2));
+
mHostConnection.setDeclareFileCallback(bind(&ZonesManager::handleDeclareFileCall,
this, _1, _2));
}
}
+void ZonesManager::handleDeleteNetdevIpAddressCall(const api::DeleteNetdevIpAddressIn& data,
+ api::MethodResultBuilder::Pointer result)
+{
+ LOGI("DelNetdevIpAddress call");
+ try {
+ Lock lock(mMutex);
+ getZone(data.zone).deleteNetdevIpAddress(data.netdev, data.ip);
+ result->setVoid();
+ } catch (const InvalidZoneIdException&) {
+ LOGE("No zone with id=" << data.zone);
+ result->setError(api::ERROR_INVALID_ID, "No such zone id");
+ } catch (const VasumException& ex) {
+ LOGE("Can't delete address: " << ex.what());
+ result->setError(api::ERROR_INTERNAL, ex.what());
+ }
+}
+
void ZonesManager::handleDeclareFileCall(const api::DeclareFileIn& data,
api::MethodResultBuilder::Pointer result)
{
api::MethodResultBuilder::Pointer result);
void handleDestroyNetdevCall(const api::DestroyNetDevIn& data,
api::MethodResultBuilder::Pointer result);
+ void handleDeleteNetdevIpAddressCall(const api::DeleteNetdevIpAddressIn& data,
+ api::MethodResultBuilder::Pointer result);
void handleDeclareFileCall(const api::DeclareFileIn& data,
api::MethodResultBuilder::Pointer result);
void handleDeclareMountCall(const api::DeclareMountIn& data,
c->stop(true);
}
-// TODO: DbusReconnectionTest
+// TODO: DbusReconnection
BOOST_AUTO_TEST_CASE(ListNetdev)
{
BOOST_CHECK(find(netdevs.begin(), netdevs.end(), ZONE_NETDEV) != netdevs.end());
}
-BOOST_AUTO_TEST_CASE(GetNetdevAttrsTest)
+BOOST_AUTO_TEST_CASE(GetNetdevAttrs)
{
setupBridge(BRIDGE_NAME);
auto c = create(TEST_CONFIG_PATH);
BOOST_CHECK(gotType);
}
-BOOST_AUTO_TEST_CASE(SetNetdevAttrsTest)
+BOOST_AUTO_TEST_CASE(SetNetdevAttrs)
{
setupBridge(BRIDGE_NAME);
auto c = create(TEST_CONFIG_PATH);
WhatEquals("Unsupported attribute: does_not_exists"));
}
-BOOST_AUTO_TEST_CASE(SetNetdevIpv4Test)
+BOOST_AUTO_TEST_CASE(SetNetdevIpv4)
{
setupBridge(BRIDGE_NAME);
auto c = create(TEST_CONFIG_PATH);
BOOST_CHECK_EQUAL(gotIp, 3);
}
-BOOST_AUTO_TEST_CASE(SetNetdevIpv6Test)
+BOOST_AUTO_TEST_CASE(SetNetdevIpv6)
{
setupBridge(BRIDGE_NAME);
auto c = create(TEST_CONFIG_PATH);
BOOST_CHECK_EQUAL(gotIp, 3);
}
+BOOST_AUTO_TEST_CASE(DelNetdevIpAddress)
+{
+ auto contain = [](const ZoneAdmin::NetdevAttrs& container, const std::string& key) {
+ return container.end() != find_if(container.begin(),
+ container.end(),
+ [&](const ZoneAdmin::NetdevAttrs::value_type& value) {
+ return std::get<0>(value) == key;
+ });
+ };
+
+ setupBridge(BRIDGE_NAME);
+ auto c = create(TEST_CONFIG_PATH);
+ c->start();
+ ensureStarted();
+ c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME);
+ ZoneAdmin::NetdevAttrs attrs;
+ attrs.push_back(std::make_tuple("ipv6", "ip:2001:db8::1,prefixlen:64"));
+ attrs.push_back(std::make_tuple("ipv4", "ip:192.168.4.1,prefixlen:24"));
+ c->setNetdevAttrs(ZONE_NETDEV, attrs);
+ attrs = c->getNetdevAttrs(ZONE_NETDEV);
+ BOOST_REQUIRE(contain(attrs, "ipv4"));
+ BOOST_REQUIRE(contain(attrs, "ipv6"));
+
+ c->deleteNetdevIpAddress(ZONE_NETDEV, "192.168.4.1/24");
+ attrs = c->getNetdevAttrs(ZONE_NETDEV);
+ BOOST_CHECK(!contain(attrs, "ipv4"));
+ BOOST_CHECK(contain(attrs, "ipv6"));
+
+ c->deleteNetdevIpAddress(ZONE_NETDEV, "2001:db8::1/64");
+ attrs = c->getNetdevAttrs(ZONE_NETDEV);
+ BOOST_REQUIRE(!contain(attrs, "ipv4"));
+ BOOST_REQUIRE(!contain(attrs, "ipv6"));
+
+ BOOST_CHECK_THROW(c->deleteNetdevIpAddress(ZONE_NETDEV, "192.168.4.1/24"), VasumException);
+ BOOST_CHECK_THROW(c->deleteNetdevIpAddress(ZONE_NETDEV, "2001:db8::1/64"), VasumException);
+}
+
BOOST_AUTO_TEST_SUITE_END()