Hold link information to pass it to user 71/195171/2
authorYu <jiung.yu@samsung.com>
Tue, 11 Dec 2018 07:49:23 +0000 (16:49 +0900)
committerYu <jiung.yu@samsung.com>
Fri, 14 Dec 2018 09:06:35 +0000 (18:06 +0900)
Change-Id: I9667f641d80310c501067d88797cbed5b9ed35e5
Signed-off-by: Yu Jiung <jiung.yu@samsung.com>
src/inm-rtnl.c

index 0741727d7476b28e48b8f92775b48470c6155398..1a55fff6cfcda999f0462b9298eded6076501c60 100644 (file)
 
 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 {
+       char *iface_name;
+       int if_idx;
+       int flags;
+       int operation_state;
+       unsigned long long received_bytes;
+       unsigned long long sent_bytes;
+       GList *list_addr;
+       GList *list_neigh;
+       GList *list_route;
+} inm_rtnl_link_s;
 
 static void __link_recv_cb(int action,
                struct nl_object *obj,
@@ -168,10 +181,116 @@ static inline void __rtnl_link_log(struct rtnl_link *p_rtnl_link)
        }
 }
 
+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);
+       dst->flags = src->flags;
+       dst->operation_state = src->operation_state;
+       dst->received_bytes =
+                       src->received_bytes;
+       dst->sent_bytes =
+                       src->sent_bytes;
+}
+
+static gint __link_compare(const void *src_data, const void *dst_data)
+{
+       inm_rtnl_link_s *src;
+       inm_rtnl_link_s *dst;
+       if (!src_data || !dst_data)
+               return -1;
+
+       src = (inm_rtnl_link_s *)src_data;
+       dst = (inm_rtnl_link_s *)dst_data;
+
+       return dst->if_idx - src->if_idx;
+}
+
+static inline void __link_fill_info(struct rtnl_link *p_rtnl_link, inm_rtnl_link_s *p_link)
+{
+       char *p_str_buf;
+
+       if (!p_rtnl_link || !p_link)
+               return;
+
+       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);
+       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 =
+                       rtnl_link_get_stat(p_rtnl_link, RTNL_LINK_RX_BYTES);
+       p_link->sent_bytes =
+                       rtnl_link_get_stat(p_rtnl_link, RTNL_LINK_TX_BYTES);
+}
+
+static void __link_destroy(void *user_data)
+{
+       inm_rtnl_link_s *p_link;
+
+       if (!user_data)
+               return;
+
+       p_link = (inm_rtnl_link_s *)user_data;
+       g_free(p_link->iface_name);
+       g_free(p_link);
+}
+
+static inline void __link_add(inm_rtnl_link_s *p_link)
+{
+       GList *p_list;
+       inm_rtnl_link_s *tmp = NULL;
+
+       __INM_FUNC_ENTER__;
+       p_list = g_list_find_custom(g_list_links,
+                       p_link,
+                       __link_compare);
+
+       if (p_list) {
+               INM_LOGI("Found");
+               __link_copy(p_link, p_list->data);
+       } else {
+               tmp = (inm_rtnl_link_s *)g_try_malloc0(sizeof(inm_rtnl_link_s));
+               if (!tmp) {
+                       INM_LOGE("link allocation failed");
+                       __INM_FUNC_EXIT__;
+                       return;
+               }
+
+               __link_copy(p_link, tmp);
+               g_list_links = g_list_prepend(g_list_links, tmp);
+       }
+       __INM_FUNC_EXIT__;
+}
+
+static inline void __link_remove(inm_rtnl_link_s *p_link)
+{
+       GList *p_list;
+       inm_rtnl_link_s *tmp = NULL;
+
+       __INM_FUNC_ENTER__;
+       p_list = g_list_find_custom(g_list_links,
+                       p_link,
+                       __link_compare);
+       if (p_list) {
+               INM_LOGI("Found");
+               tmp = (inm_rtnl_link_s *)p_list->data;
+               g_list_links = g_list_remove(g_list_links, p_list->data);
+               __link_destroy(tmp);
+       }
+       __INM_FUNC_EXIT__;
+}
+
 static void __link_recv_cb(int action,
                struct nl_object *obj,
                void *user_data)
 {
+       inm_rtnl_link_s *p_link = NULL;
        __INM_FUNC_ENTER__;
 
        if (!obj) {
@@ -179,6 +298,21 @@ static void __link_recv_cb(int action,
                return;
        }
 
+       p_link = (inm_rtnl_link_s *)g_try_malloc0(sizeof(inm_rtnl_link_s));
+       if (!p_link) {
+               INM_LOGE("link mem alloc failed");
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       __link_fill_info((struct rtnl_link *)obj, p_link);
+       if (action == NL_ACT_NEW || action == NL_ACT_CHANGE)
+               __link_add(p_link);
+       else if (action == NL_ACT_DEL)
+               __link_remove(p_link);
+
+       __link_destroy(p_link);
+
        util_foreach_nl_data(&(nl_data_arr[INM_UTIL_RTNL_TYPE_LINK]),
                        rtnl_obj_cbs[INM_UTIL_RTNL_TYPE_LINK].foreach_cb,
                        rtnl_obj_cbs[INM_UTIL_RTNL_TYPE_LINK].user_data);
@@ -188,6 +322,8 @@ static void __link_recv_cb(int action,
 
 static void __link_foreach_cb(struct nl_object *obj, void *user_data)
 {
+       inm_rtnl_link_s *p_link;
+
        __INM_FUNC_ENTER__;
 
        if (!obj) {
@@ -195,6 +331,17 @@ static void __link_foreach_cb(struct nl_object *obj, void *user_data)
                return;
        }
 
+       p_link = (inm_rtnl_link_s *)g_try_malloc0(sizeof(inm_rtnl_link_s));
+       if (!p_link) {
+               INM_LOGE("link mem alloc failed");
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       __link_fill_info((struct rtnl_link *)obj, p_link);
+       __link_add(p_link);
+       __link_destroy(p_link);
+
        __rtnl_link_log((struct rtnl_link *)obj);
 
        __INM_FUNC_EXIT__;
@@ -508,6 +655,9 @@ int inm_rtnl_mon_deinit(void)
                return INM_RTNL_ERROR_NOT_INITIALIZED;
        }
 
+       g_list_free_full(g_list_links, __link_destroy);
+       g_list_links = NULL;
+
        __clear_all_nl_data();
 
        memset(&nl_data_arr, 0x0, sizeof(nl_data_arr));