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,
}
}
+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) {
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);
static void __link_foreach_cb(struct nl_object *obj, void *user_data)
{
+ inm_rtnl_link_s *p_link;
+
__INM_FUNC_ENTER__;
if (!obj) {
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__;
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));