}
else {
VsmNetdev netdev = NULL;
- in_addr ipv4;
- in6_addr ipv6;
char buf[INET_ADDRSTRLEN|INET6_ADDRSTRLEN];
CommandLineInterface::executeCallback(bind(vsm_lookup_netdev_by_name,
_1,
cout << netdevToString(netdev) << endl;
vsm_netdev_free(netdev);
- CommandLineInterface::executeCallback(bind(vsm_netdev_get_ipv4_addr,
+ VsmAddrList addrs = NULL;
+ CommandLineInterface::executeCallback(bind(vsm_netdev_get_ip_addr,
_1,
argv[1].c_str(),
argv[2].c_str(),
- &ipv4));
- if (inet_ntop(AF_INET, &ipv4, buf, INET_ADDRSTRLEN) == NULL) {
- throw runtime_error("Wrong address received");
+ &addrs));
+ unsigned listsize = vsm_addrlist_size(addrs);
+ for (unsigned i=0; i < listsize; ++i) {
+ int type=vsm_addrlist_get_type(addrs, i);
+ if (inet_ntop(type, vsm_addrlist_get_addr(addrs, i), buf, INET6_ADDRSTRLEN) == NULL) {
+ throw runtime_error("Wrong address received ["+std::to_string(i)+"] type="+std::to_string(type));
+ }
+ cout << buf << "/" << vsm_addrlist_get_prefix(addrs, i) << endl;
}
- cout << buf << endl;
-
- CommandLineInterface::executeCallback(bind(vsm_netdev_get_ipv6_addr,
- _1,
- argv[1].c_str(),
- argv[2].c_str(),
- &ipv6));
- if (inet_ntop(AF_INET6, &ipv6, buf, INET6_ADDRSTRLEN) == NULL) {
- throw runtime_error("Wrong address received");
- }
- cout << buf << endl;
+ vsm_addrlist_free(addrs);
}
}
if (inet_pton(AF_INET, argv[3].c_str(), &addr) != 1) {
throw runtime_error("Wrong address format");
};
- CommandLineInterface::executeCallback(bind(vsm_netdev_set_ipv4_addr,
+ CommandLineInterface::executeCallback(bind(vsm_netdev_add_ipv4_addr,
_1,
argv[1].c_str(),
argv[2].c_str(),
if (inet_pton(AF_INET6, argv[3].c_str(), &addr) != 1) {
throw runtime_error("Wrong address format");
};
- CommandLineInterface::executeCallback(bind(vsm_netdev_set_ipv6_addr,
+ CommandLineInterface::executeCallback(bind(vsm_netdev_add_ipv6_addr,
_1,
argv[1].c_str(),
argv[2].c_str(),
VsmStatus Client::vsm_netdev_get_ip_addr(const char* id,
const char* netdevId,
- int type,
- void* addr) noexcept
+ std::vector<InetAddr>& addrs) noexcept
{
using namespace boost::algorithm;
return coverException([&] {
IS_SET(id);
IS_SET(netdevId);
- IS_SET(addr);
+
+ addrs.clear();
api::GetNetDevAttrs attrs = *mClient->callSync<api::GetNetDevAttrsIn, api::GetNetDevAttrs>(
api::ipc::METHOD_GET_NETDEV_ATTRS,
std::make_shared<api::GetNetDevAttrsIn>(api::GetNetDevAttrsIn{ id, netdevId }));
- auto it = find_if(attrs.values.begin(),
- attrs.values.end(),
- [type](const api::StringPair& entry) {
- return entry.first == (type == AF_INET ? "ipv4" : "ipv6");
- });
+ for (const auto &attr : attrs.values) {
+ InetAddr addr;
+ if (attr.first == "ipv4") {
+ addr.type = AF_INET;
+ }
+ else if (attr.first == "ipv6") {
+ addr.type = AF_INET6;
+ }
+ else continue;
- if (it != attrs.values.end()) {
- vector<string> addrAttrs;
- for(auto addrAttr : split(addrAttrs, it->second, is_any_of(","))) {
+ std::vector<std::string> addrAttrs;
+ for(const auto& addrAttr : split(addrAttrs, attr.second, is_any_of(","))) {
size_t pos = addrAttr.find(":");
- if (addrAttr.substr(0, pos) == "ip") {
- if (pos != string::npos && pos < addrAttr.length() &&
- inet_pton(type, addrAttr.substr(pos + 1).c_str(), addr) == 1) {
- //XXX: return only one address
- return;
- } else {
- throw InvalidResponseException("Wrong address format returned");
+ if (pos == string::npos) continue;
+
+ if (addrAttr.substr(0, pos) == "prefixlen") {
+ addr.prefix = atoi(addrAttr.substr(pos + 1).c_str());
+ }
+ else if (addrAttr.substr(0, pos) == "ip") {
+ if (inet_pton(addr.type, addrAttr.substr(pos + 1).c_str(), &addr.addr) != 1) {
+ addr.type = -1;
+ break;
}
}
}
+ if (addr.type >= 0)
+ addrs.push_back(addr);
}
- throw OperationFailedException("Address not found");
});
}
const char* netdevId,
struct in_addr* addr) noexcept
{
- return vsm_netdev_get_ip_addr(id, netdevId, AF_INET, addr);
+ std::vector<InetAddr> addrs;
+ VsmStatus st=vsm_netdev_get_ip_addr(id, netdevId, addrs);
+ for (const auto& a : addrs) {
+ if (a.type == AF_INET) {
+ memcpy(addr, &a.addr, sizeof(*addr));
+ break;
+ }
+ }
+ return st;
}
VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* id,
const char* netdevId,
struct in6_addr* addr) noexcept
{
- return vsm_netdev_get_ip_addr(id, netdevId, AF_INET6, addr);
+ std::vector<InetAddr> addrs;
+ VsmStatus st=vsm_netdev_get_ip_addr(id, netdevId, addrs);
+ for (const auto& a : addrs) {
+ if (a.type == AF_INET6) {
+ memcpy(addr, &a.addr, sizeof(*addr));
+ break;
+ }
+ }
+ return st;
}
-VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* id,
+VsmStatus Client::vsm_netdev_add_ipv4_addr(const char* id,
const char* netdevId,
struct in_addr* addr,
int prefix) noexcept
});
}
-VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* id,
+VsmStatus Client::vsm_netdev_add_ipv6_addr(const char* id,
const char* netdevId,
struct in6_addr* addr,
int prefix) noexcept
} *Netdev;
/**
+ * Network interface information structure
+ */
+typedef struct {
+ int type;
+ int prefix;
+ union {
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+ } addr;
+} InetAddr;
+
+
+/**
* vasum's client definition.
*
* Client uses dbus API.
*/
VsmStatus vsm_zone_get_netdevs(const char* zone, VsmArrayString* netdevIds) noexcept;
+ VsmStatus vsm_netdev_get_ip_addr(const char* zone,
+ const char* netdevId,
+ std::vector<InetAddr>& addrs) noexcept;
+
/**
* @see ::vsm_netdev_get_ipv4_addr
*/
struct in6_addr *addr) noexcept;
/**
- * @see ::vsm_netdev_set_ipv4_addr
+ * @see ::vsm_netdev_add_ipv4_addr
*/
- VsmStatus vsm_netdev_set_ipv4_addr(const char* zone,
+ VsmStatus vsm_netdev_add_ipv4_addr(const char* zone,
const char* netdevId,
struct in_addr *addr,
int prefix) noexcept;
/**
- * @see ::vsm_netdev_set_ipv6_addr
+ * @see ::vsm_netdev_add_ipv6_addr
*/
- VsmStatus vsm_netdev_set_ipv6_addr(const char* zone,
+ VsmStatus vsm_netdev_add_ipv6_addr(const char* zone,
const char* netdevId,
struct in6_addr *addr,
int prefix) noexcept;
bool isInternalDispatcherEnabled() const;
ipc::epoll::EventPoll& getEventPoll() const;
VsmStatus coverException(const std::function<void(void)>& worker) noexcept;
- VsmStatus vsm_netdev_get_ip_addr(const char* zone,
- const char* netdevId,
- int type,
- void* addr) noexcept;
};
#endif /* VASUM_CLIENT_IMPL_HPP */
return getClient(client).vsm_zone_get_netdevs(zone, netdevIds);
}
+API VsmStatus vsm_netdev_get_ip_addr(VsmClient client,
+ const char* zone,
+ const char* netdevId,
+ VsmAddrList *addrs)
+{
+ std::vector<InetAddr> addrlist;
+ VsmStatus status = getClient(client).vsm_netdev_get_ip_addr(zone, netdevId, addrlist);
+ int n = addrlist.size();
+ InetAddr *a = (InetAddr *)malloc((n+1)*sizeof(InetAddr));
+ std::copy(addrlist.begin(), addrlist.end(), a);
+ a[n].type=-1;
+ *addrs = a;
+ return status;
+}
+
API VsmStatus vsm_netdev_get_ipv4_addr(VsmClient client,
const char* zone,
const char* netdevId,
return getClient(client).vsm_netdev_get_ipv6_addr(zone, netdevId, addr);
}
-API VsmStatus vsm_netdev_set_ipv4_addr(VsmClient client,
+API VsmStatus vsm_netdev_add_ipv4_addr(VsmClient client,
const char* zone,
const char* netdevId,
struct in_addr *addr,
int prefix)
{
- return getClient(client).vsm_netdev_set_ipv4_addr(zone, netdevId, addr, prefix);
+ return getClient(client).vsm_netdev_add_ipv4_addr(zone, netdevId, addr, prefix);
}
-API VsmStatus vsm_netdev_set_ipv6_addr(VsmClient client,
+API VsmStatus vsm_netdev_add_ipv6_addr(VsmClient client,
const char* zone,
const char* netdevId,
struct in6_addr *addr,
int prefix)
{
- return getClient(client).vsm_netdev_set_ipv6_addr(zone, netdevId, addr, prefix);
+ return getClient(client).vsm_netdev_add_ipv6_addr(zone, netdevId, addr, prefix);
}
API VsmStatus vsm_netdev_del_ipv4_addr(VsmClient client,
return getClient(client).vsm_clean_up_zones_root();
}
+API unsigned int vsm_addrlist_size(VsmAddrList addrs)
+{
+ InetAddr *a = static_cast<InetAddr*>(addrs);
+ unsigned int i;
+ for (i = 0; a[i].type >= 0; ++i) ;
+ return i;
+}
+
+API int vsm_addrlist_get_type(VsmAddrList addrs, unsigned int i)
+{
+ return static_cast<InetAddr*>(addrs)[i].type;
+}
+
+API const void *vsm_addrlist_get_addr(VsmAddrList addrs, unsigned int i)
+{
+ return &static_cast<InetAddr*>(addrs)[i].addr;
+}
+
+API unsigned int vsm_addrlist_get_prefix(VsmAddrList addrs, unsigned int i)
+{
+ return static_cast<InetAddr*>(addrs)[i].prefix;
+}
+
+API void vsm_addrlist_free(VsmAddrList addrs) {
+ free(addrs);
+}
*/
typedef VsmString* VsmArrayString;
+typedef void *VsmAddrList;
/**
* Completion status of libvasum-client's functions
*/
*/
VsmStatus vsm_zone_get_netdevs(VsmClient client, const char* zone, VsmArrayString* netdevIds);
+
+/**
+ * Get ipv4 address for given netdevId
+ *
+ * @param[in] client vasum-server's client
+ * @param[in] zone zone name
+ * @param[in] netdevId netdev id
+ * @param[out] addrs ip address array
+ * @return status of this function call
+ * @remark Use vsm_netdev_addr_free() to free memory occupied by address array.
+ */
+VsmStatus vsm_netdev_get_ip_addr(VsmClient client,
+ const char* zone,
+ const char* netdevId,
+ VsmAddrList *addrs);
+
+/**
+ * Release VsmAddrList
+ *
+ * @param addrs VsmAddrList
+ */
+void vsm_addrlist_free(VsmAddrList addrs);
+
/**
* Get ipv4 address for given netdevId
*
struct in6_addr *addr);
/**
- * Set ipv4 address for given netdevId
+ * Add ipv4 address for given netdevId
*
* @param[in] client vasum-server's client
* @param[in] zone zone name
* @param[in] prefix bit-length of the network prefix
* @return status of this function call
*/
-VsmStatus vsm_netdev_set_ipv4_addr(VsmClient client,
+VsmStatus vsm_netdev_add_ipv4_addr(VsmClient client,
const char* zone,
const char* netdevId,
struct in_addr *addr,
int prefix);
/**
- * Set ipv6 address for given netdevId
+ * Add ipv6 address for given netdevId
*
* @param[in] client vasum-server's client
* @param[in] zone zone name
* @param[in] prefix bit-length of the network prefix
* @return status of this function call
*/
-VsmStatus vsm_netdev_set_ipv6_addr(VsmClient client,
+VsmStatus vsm_netdev_add_ipv6_addr(VsmClient client,
const char* zone,
const char* netdevId,
struct in6_addr *addr,
*/
VsmStatus vsm_clean_up_zones_root(VsmClient client);
+/**
+ * Retrieve array size
+ *
+ * @return array size
+ */
+unsigned int vsm_addrlist_size(VsmAddrList addrs);
+
+/**
+ * Get address type for i'th entry
+ *
+ * @return network type (AF_INET or AF_INET6)
+ */
+int vsm_addrlist_get_type(VsmAddrList addrs, unsigned int i);
+
+/**
+ * Get pointer to in_addr property for i'th entry
+ * see inet_ntop man pages
+ *
+ * @return poiner of in_addr
+ */
+const void *vsm_addrlist_get_addr(VsmAddrList addrs, unsigned int i);
+
+/**
+ * Get address prefix for i'th entry
+ *
+ * @return adress prefix (mask bits count)
+ */
+unsigned int vsm_addrlist_get_prefix(VsmAddrList addrs, unsigned int i);
+
#endif /* __VASUM_WRAPPER_SOURCE__ */
#ifdef __cplusplus