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;
{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;
{
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 =
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 =
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;
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);
}
__INM_FUNC_EXIT__;
return;
}
-
__link_copy(p_link, tmp);
g_list_links = g_list_prepend(g_list_links, tmp);
}
}
}
-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);
{
__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__;