Add address information to link 61/195361/2
authorYu <jiung.yu@samsung.com>
Thu, 13 Dec 2018 01:37:41 +0000 (10:37 +0900)
committerYu <jiung.yu@samsung.com>
Fri, 14 Dec 2018 09:07:23 +0000 (18:07 +0900)
Change-Id: I4792bdcc0a6c248dff8e4547d6ec4fe06d0fbf14
Signed-off-by: Yu Jiung <jiung.yu@samsung.com>
src/inm-rtnl.c

index 1a55fff6cfcda999f0462b9298eded6076501c60..0761969fd5f90dcb26337b512b92dff3f192e267 100644 (file)
@@ -42,6 +42,15 @@ static inm_util_nl_data_s nl_data_arr[INM_UTIL_RTNL_TYPE_MAX];
 static gboolean is_initialized = FALSE;
 static GList *g_list_links;
 
+typedef struct {
+       int if_idx;
+       int family;
+       int prefix_length;
+       int scope;
+       char *address;
+} inm_rtnl_addr_s;
+
+
 typedef struct {
        char *iface_name;
        int if_idx;
@@ -84,6 +93,21 @@ struct {
                {NULL, NULL, NULL},
 };
 
+static inm_rtnl_link_s *__link_find(int if_index)
+{
+       inm_rtnl_link_s *p_link = NULL;
+       GList *current = NULL;
+       current = g_list_first(g_list_links);
+
+       while (current) {
+               p_link = (inm_rtnl_link_s *)current->data;
+               if (p_link && p_link->if_idx == if_index)
+                       return p_link;
+               current = current->next;
+       }
+       return NULL;
+}
+
 static struct {
        const char* str;
        int stat_num;
@@ -185,9 +209,7 @@ static inline void __link_copy(inm_rtnl_link_s *src, inm_rtnl_link_s *dst)
 {
 
        dst->if_idx = src->if_idx;
-       if (dst->iface_name)
-               g_free(dst->iface_name);
-       dst->iface_name = g_strdup(src->iface_name);
+       CHECK_STRING_AND_COPY(src->iface_name, dst->iface_name);
        dst->flags = src->flags;
        dst->operation_state = src->operation_state;
        dst->received_bytes =
@@ -218,9 +240,7 @@ static inline void __link_fill_info(struct rtnl_link *p_rtnl_link, inm_rtnl_link
 
        p_link->if_idx = rtnl_link_get_ifindex(p_rtnl_link);
        p_str_buf = rtnl_link_get_name(p_rtnl_link);
-       if (p_link->iface_name)
-               g_free(p_link->iface_name);
-       p_link->iface_name = g_strdup(p_str_buf);
+       CHECK_STRING_AND_COPY(p_str_buf, p_link->iface_name);
        p_link->flags = rtnl_link_get_flags(p_rtnl_link);
        p_link->operation_state = rtnl_link_get_operstate(p_rtnl_link);
        p_link->received_bytes =
@@ -229,6 +249,8 @@ static inline void __link_fill_info(struct rtnl_link *p_rtnl_link, inm_rtnl_link
                        rtnl_link_get_stat(p_rtnl_link, RTNL_LINK_TX_BYTES);
 }
 
+static void __addr_destroy(void *user_data);
+
 static void __link_destroy(void *user_data)
 {
        inm_rtnl_link_s *p_link;
@@ -237,6 +259,7 @@ static void __link_destroy(void *user_data)
                return;
 
        p_link = (inm_rtnl_link_s *)user_data;
+       g_list_free_full(p_link->list_addr, __addr_destroy);
        g_free(p_link->iface_name);
        g_free(p_link);
 }
@@ -261,7 +284,6 @@ static inline void __link_add(inm_rtnl_link_s *p_link)
                        __INM_FUNC_EXIT__;
                        return;
                }
-
                __link_copy(p_link, tmp);
                g_list_links = g_list_prepend(g_list_links, tmp);
        }
@@ -383,17 +405,143 @@ static inline void __rtnl_addr_log(struct rtnl_addr *p_rtnl_addr)
        }
 }
 
-static void __addr_recv_cb(gboolean added,
+static inline void __addr_copy(inm_rtnl_addr_s *src, inm_rtnl_addr_s *dst)
+{
+       if (!src || !dst)
+               return;
+
+       dst->if_idx = src->if_idx;
+       dst->scope = src->scope;
+
+       CHECK_STRING_AND_COPY(src->address, dst->address);
+       dst->family = src->family;
+       dst->prefix_length = src->prefix_length;
+}
+
+static gint __addr_compare(const void *src_data, const void *dst_data)
+{
+       inm_rtnl_addr_s *src;
+       inm_rtnl_addr_s *dst;
+       gint res;
+
+       if (!src_data || !dst_data)
+               return -1;
+
+       src = (inm_rtnl_addr_s *)src_data;
+       dst = (inm_rtnl_addr_s *)dst_data;
+
+       res = dst->if_idx - src->if_idx;
+       if (res != 0)
+               return res;
+
+       res = g_strcmp0(src->address, dst->address);
+       return res;
+}
+
+static void __addr_destroy(void *user_data)
+{
+       inm_rtnl_addr_s *p_addr;
+
+       if (!user_data)
+               return;
+
+       p_addr = (inm_rtnl_addr_s *)user_data;
+       g_free(p_addr->address);
+       g_free(p_addr);
+}
+
+static inline void __addr_fill_info(struct rtnl_addr *p_rtnl_addr, inm_rtnl_addr_s *p_addr)
+{
+       struct nl_addr *p_nl_addr;
+       char buf[128] = {0,};
+
+       if (!p_rtnl_addr || !p_addr)
+               return;
+
+       p_nl_addr = rtnl_addr_get_local(p_rtnl_addr);
+       if (!p_nl_addr)
+               return;
+
+       p_addr->if_idx = rtnl_addr_get_ifindex(p_rtnl_addr);
+       p_addr->scope = rtnl_addr_get_scope(p_rtnl_addr);
+
+       nl_addr2str(p_nl_addr, buf, sizeof(buf));
+       CHECK_STRING_AND_COPY(buf, p_addr->address);
+       p_addr->family = nl_addr_get_family(p_nl_addr);
+       p_addr->prefix_length = nl_addr_get_prefixlen(p_nl_addr);
+}
+
+static inline void __addr_add(inm_rtnl_addr_s *p_addr)
+{
+       GList *p_list;
+       inm_rtnl_link_s *link = NULL;
+       inm_rtnl_addr_s *tmp = NULL;
+       link = __link_find(p_addr->if_idx);
+       if (!link) {
+               return;
+       }
+
+       p_list = g_list_find_custom(link->list_addr,
+                       p_addr,
+                       __addr_compare);
+       if (p_list) {
+               __addr_copy(p_addr, (inm_rtnl_addr_s *)p_list->data);
+       } else {
+               tmp = (inm_rtnl_addr_s *)g_try_malloc0(sizeof(inm_rtnl_addr_s));
+               if (!tmp)
+                       return;
+               __addr_copy(p_addr, tmp);
+               link->list_addr = g_list_prepend(link->list_addr, tmp);
+       }
+}
+
+static inline void __addr_remove(inm_rtnl_addr_s *p_addr)
+{
+       GList *p_list;
+       inm_rtnl_link_s *link = NULL;
+       inm_rtnl_addr_s *tmp = NULL;
+
+       link = __link_find(p_addr->if_idx);
+       if (!link)
+               return;
+
+       p_list = g_list_find_custom(link->list_addr,
+                       p_addr,
+                       __addr_compare);
+       if (p_list) {
+               tmp = (inm_rtnl_addr_s *)p_list->data;
+               link->list_addr = g_list_remove(link->list_addr, p_list->data);
+               __addr_destroy(tmp);
+       }
+}
+
+static void __addr_recv_cb(int action,
                struct nl_object *obj,
                void *user_data)
 {
        __INM_FUNC_ENTER__;
+       inm_rtnl_addr_s *p_addr = NULL;
 
        if (!obj) {
                __INM_FUNC_EXIT__;
                return;
        }
 
+       p_addr = (inm_rtnl_addr_s *)g_try_malloc0(sizeof(inm_rtnl_addr_s));
+       if (!p_addr) {
+               INM_LOGE("addr mem alloc failed");
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       __addr_fill_info((struct rtnl_addr *)obj, p_addr);
+       if (action == NL_ACT_NEW || action == NL_ACT_CHANGE)
+               __addr_add(p_addr);
+       else if (action == NL_ACT_DEL)
+               __addr_remove(p_addr);
+
+       __addr_destroy(p_addr);
+
        util_foreach_nl_data(&(nl_data_arr[INM_UTIL_RTNL_TYPE_ADDR]),
                        rtnl_obj_cbs[INM_UTIL_RTNL_TYPE_ADDR].foreach_cb,
                        rtnl_obj_cbs[INM_UTIL_RTNL_TYPE_ADDR].user_data);
@@ -405,11 +553,23 @@ static void __addr_foreach_cb(struct nl_object *obj, void *user_data)
 {
        __INM_FUNC_ENTER__;
 
+       inm_rtnl_addr_s *p_addr = NULL;
        if (!obj) {
                __INM_FUNC_EXIT__;
                return;
        }
 
+       p_addr = (inm_rtnl_addr_s *)g_try_malloc0(sizeof(inm_rtnl_addr_s));
+       if (!p_addr) {
+               INM_LOGE("addr mem alloc failed");
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       __addr_fill_info((struct rtnl_addr *)obj, p_addr);
+       __addr_add(p_addr);
+       __addr_destroy(p_addr);
+
        __rtnl_addr_log((struct rtnl_addr *)obj);
 
        __INM_FUNC_EXIT__;