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;
}
static void __addr_destroy(void *user_data);
+static void __neigh_destroy(void *user_data);
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);
}
}
}
+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);
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__;