Add neighbor information to link 62/195362/3
authorYu <jiung.yu@samsung.com>
Thu, 13 Dec 2018 01:39:01 +0000 (10:39 +0900)
committerYu <jiung.yu@samsung.com>
Fri, 14 Dec 2018 09:07:57 +0000 (18:07 +0900)
Change-Id: I06a915b5f5542259db2c6d9c5253b80b3d1297a1
Signed-off-by: Yu Jiung <jiung.yu@samsung.com>
src/inm-rtnl.c

index 0761969fd5f90dcb26337b512b92dff3f192e267..885ad1ebd325f5f84bad5d48572401a8608da8d4 100644 (file)
@@ -50,6 +50,13 @@ typedef struct {
        char *address;
 } inm_rtnl_addr_s;
 
+typedef struct {
+       int if_idx;
+       char *dest;
+       char *ll;
+       int state;
+} inm_rtnl_neigh_s;
+
 
 typedef struct {
        char *iface_name;
@@ -250,6 +257,7 @@ static inline void __link_fill_info(struct rtnl_link *p_rtnl_link, inm_rtnl_link
 }
 
 static void __addr_destroy(void *user_data);
+static void __neigh_destroy(void *user_data);
 
 static void __link_destroy(void *user_data)
 {
@@ -260,6 +268,7 @@ static void __link_destroy(void *user_data)
 
        p_link = (inm_rtnl_link_s *)user_data;
        g_list_free_full(p_link->list_addr, __addr_destroy);
+       g_list_free_full(p_link->list_neigh, __neigh_destroy);
        g_free(p_link->iface_name);
        g_free(p_link);
 }
@@ -612,17 +621,145 @@ static inline void __rtnl_neigh_log(struct rtnl_neigh *p_rtnl_neigh)
        }
 }
 
+static inline void __neigh_copy(inm_rtnl_neigh_s *src, inm_rtnl_neigh_s *dst)
+{
+       if (!src || !dst)
+               return;
+
+       dst->if_idx = src->if_idx;
+       dst->state =    src->state;
+
+       CHECK_STRING_AND_COPY(src->ll, dst->ll);
+       CHECK_STRING_AND_COPY(src->dest, dst->dest);
+}
+
+static gint __neigh_compare(const void *src_data, const void *dst_data)
+{
+       inm_rtnl_neigh_s *src;
+       inm_rtnl_neigh_s *dst;
+       gint res;
+
+       if (!src_data || !dst_data)
+               return -1;
+
+       src = (inm_rtnl_neigh_s *)src_data;
+       dst = (inm_rtnl_neigh_s *)dst_data;
+
+       res = dst->if_idx - src->if_idx;
+       if (res != 0)
+               return res;
+
+       res = g_strcmp0(src->ll, dst->ll);
+       if (res != 0)
+               return res;
+
+       res = g_strcmp0(src->dest, dst->dest);
+
+       return res;
+}
+
+static inline void __neigh_fill_info(struct rtnl_neigh *p_rtnl_neigh,
+               inm_rtnl_neigh_s *p_neigh)
+{
+       char buf[128] = {0,};
+       gchar *p_str = NULL;
+
+       if (!p_rtnl_neigh || !p_neigh)
+               return;
+
+       p_neigh->if_idx = rtnl_neigh_get_ifindex(p_rtnl_neigh);
+       p_neigh->state = rtnl_neigh_get_state(p_rtnl_neigh);
+       p_str = nl_addr2str(rtnl_neigh_get_lladdr(p_rtnl_neigh), buf, sizeof(buf));
+       CHECK_STRING_AND_COPY(p_str, p_neigh->ll);
+
+       p_str = nl_addr2str(rtnl_neigh_get_dst(p_rtnl_neigh), buf, sizeof(buf));
+       CHECK_STRING_AND_COPY(p_str, p_neigh->dest);
+}
+
+static void __neigh_destroy(void *user_data)
+{
+       inm_rtnl_neigh_s *p_neigh;
+
+       if (!user_data)
+               return;
+
+       p_neigh = (inm_rtnl_neigh_s *)user_data;
+       g_free(p_neigh->ll);
+       g_free(p_neigh->dest);
+       g_free(p_neigh);
+}
+
+static inline void __neigh_add(inm_rtnl_neigh_s *p_neigh)
+{
+       GList *p_list;
+       inm_rtnl_link_s *link = NULL;
+       inm_rtnl_neigh_s *tmp = NULL;
+
+       link = __link_find(p_neigh->if_idx);
+       if (!link)
+               return;
+
+       p_list = g_list_find_custom(link->list_neigh,
+                       p_neigh,
+                       __neigh_compare);
+       if (p_list) {
+               __neigh_copy(p_neigh, (inm_rtnl_neigh_s *)p_list->data);
+       } else {
+               tmp = (inm_rtnl_neigh_s *)g_try_malloc0(sizeof(inm_rtnl_neigh_s));
+               if (!tmp)
+                       return;
+               __neigh_copy(p_neigh, tmp);
+               link->list_neigh = g_list_prepend(link->list_neigh, tmp);
+       }
+}
+
+static inline void __neigh_remove(inm_rtnl_neigh_s *p_neigh)
+{
+       GList *p_list;
+       inm_rtnl_link_s *link = NULL;
+       inm_rtnl_neigh_s *tmp = NULL;
+
+       link = __link_find(p_neigh->if_idx);
+       if (!link)
+               return;
+
+       p_list = g_list_find_custom(link->list_neigh,
+                       p_neigh,
+                       __neigh_compare);
+       if (p_list) {
+               tmp = (inm_rtnl_neigh_s *)p_list->data;
+               link->list_neigh = g_list_remove(link->list_neigh, tmp);
+               __neigh_destroy(tmp);
+       }
+}
+
 static void __neigh_recv_cb(int action,
                struct nl_object *obj,
                void *user_data)
 {
-       __INM_FUNC_ENTER__;
+       inm_rtnl_neigh_s *p_neigh = NULL;
 
+       __INM_FUNC_ENTER__;
        if (!obj) {
                __INM_FUNC_EXIT__;
                return;
        }
 
+       p_neigh = (inm_rtnl_neigh_s *)g_try_malloc0(sizeof(inm_rtnl_neigh_s));
+       if (!p_neigh) {
+               INM_LOGE("neigh mem alloc failed");
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       __neigh_fill_info((struct rtnl_neigh *)obj, p_neigh);
+       if (action == NL_ACT_NEW || action == NL_ACT_CHANGE)
+               __neigh_add(p_neigh);
+       else if (action == NL_ACT_DEL)
+               __neigh_remove(p_neigh);
+
+       __neigh_destroy(p_neigh);
+
        util_foreach_nl_data(&(nl_data_arr[INM_UTIL_RTNL_TYPE_NEIGH]),
                        rtnl_obj_cbs[INM_UTIL_RTNL_TYPE_NEIGH].foreach_cb,
                        rtnl_obj_cbs[INM_UTIL_RTNL_TYPE_NEIGH].user_data);
@@ -632,13 +769,25 @@ static void __neigh_recv_cb(int action,
 
 static void __neigh_foreach_cb(struct nl_object *obj, void *user_data)
 {
-       __INM_FUNC_ENTER__;
+       inm_rtnl_neigh_s *p_neigh = NULL;
 
+       __INM_FUNC_ENTER__;
        if (!obj) {
                __INM_FUNC_EXIT__;
                return;
        }
 
+       p_neigh = (inm_rtnl_neigh_s *)g_try_malloc0(sizeof(inm_rtnl_neigh_s));
+       if (!p_neigh) {
+               INM_LOGE("neigh mem alloc failed");
+               __INM_FUNC_EXIT__;
+               return;
+       }
+
+       __neigh_fill_info((struct rtnl_neigh *)obj, p_neigh);
+       __neigh_add(p_neigh);
+       __neigh_destroy(p_neigh);
+
        __rtnl_neigh_log((struct rtnl_neigh *)obj);
 
        __INM_FUNC_EXIT__;