Support getting list of ip/mask for one interface, change netdev_set_ip* to netdev_ad... 29/45029/5
authorKrzysztof Dynowski <k.dynowski@samsung.com>
Thu, 30 Jul 2015 12:04:25 +0000 (14:04 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Thu, 6 Aug 2015 14:30:19 +0000 (07:30 -0700)
[Feature]       Get list of configured ip/mask for zone interface
[Cause]         Many ip/mask entries can be assigned to one interface
[Solution]      Implement generic method getting list of network addresses
[Verification]  Build, install, use vsm net-add-ip to add ips
                vsm net-list to get configured ips

Change-Id: I8d4c1b59e03800aa513811992cc13e71df8d599e

cli/command-line-interface.cpp
client/vasum-client-impl.cpp
client/vasum-client-impl.hpp
client/vasum-client.cpp
client/vasum-client.h

index e8922ee..86bc808 100644 (file)
@@ -562,8 +562,6 @@ void netdev_list(const Args& argv)
     }
     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,
@@ -573,25 +571,21 @@ void netdev_list(const Args& argv)
         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);
     }
 }
 
@@ -606,7 +600,7 @@ void netdev_add_ip_addr(const Args& argv)
         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(),
@@ -618,7 +612,7 @@ void netdev_add_ip_addr(const Args& argv)
         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(),
index 15cccf6..e3aca1d 100644 (file)
@@ -525,42 +525,48 @@ VsmStatus Client::vsm_zone_get_netdevs(const char* id, VsmArrayString* netdevIds
 
 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");
     });
 }
 
@@ -568,17 +574,33 @@ VsmStatus Client::vsm_netdev_get_ipv4_addr(const char* id,
                                       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
@@ -596,7 +618,7 @@ VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* id,
     });
 }
 
-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
index 4297c95..dbc9001 100644 (file)
@@ -64,6 +64,19 @@ typedef struct NetdevStructure {
 } *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.
@@ -227,6 +240,10 @@ public:
      */
     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
      */
@@ -242,17 +259,17 @@ public:
                                        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;
@@ -376,10 +393,6 @@ private:
     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 */
index ee3e6d4..9cf15b3 100644 (file)
@@ -279,6 +279,21 @@ API VsmStatus vsm_zone_get_netdevs(VsmClient client,
     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,
@@ -295,22 +310,22 @@ API VsmStatus vsm_netdev_get_ipv6_addr(VsmClient client,
     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,
@@ -430,3 +445,29 @@ API VsmStatus vsm_clean_up_zones_root(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);
+}
index b696dcf..253306d 100644 (file)
@@ -186,6 +186,7 @@ typedef char* VsmString;
  */
 typedef VsmString* VsmArrayString;
 
+typedef void *VsmAddrList;
 /**
  * Completion status of libvasum-client's functions
  */
@@ -652,6 +653,29 @@ VsmStatus vsm_revoke_device(VsmClient client, const char* zone, const char* devi
  */
 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
  *
@@ -681,7 +705,7 @@ VsmStatus vsm_netdev_get_ipv6_addr(VsmClient client,
                                    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
@@ -690,14 +714,14 @@ VsmStatus vsm_netdev_get_ipv6_addr(VsmClient client,
  * @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
@@ -706,7 +730,7 @@ VsmStatus vsm_netdev_set_ipv4_addr(VsmClient client,
  * @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,
@@ -933,6 +957,35 @@ VsmStatus vsm_remove_declaration(VsmClient client,
  */
 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