int state;
} inm_rtnl_neigh_s;
+typedef struct {
+ int if_idx;
+ char *dest;
+ char *gateway;
+ int type;
+} inm_rtnl_route_s;
typedef struct {
char *iface_name;
static void __addr_destroy(void *user_data);
static void __neigh_destroy(void *user_data);
+static void __route_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_list_free_full(p_link->list_route, __route_destroy);
g_free(p_link->iface_name);
g_free(p_link);
}
}
}
+static void inline __route_copy(inm_rtnl_route_s *src, inm_rtnl_route_s *dst)
+{
+ if (!src || !dst)
+ return;
+
+ dst->type = src->type;
+ dst->if_idx = src->if_idx;
+ CHECK_STRING_AND_COPY(src->dest, dst->dest);
+ CHECK_STRING_AND_COPY(src->gateway, dst->gateway);
+}
+
+static gint __route_compare(const void *src_data, const void *dst_data)
+{
+ inm_rtnl_route_s *src;
+ inm_rtnl_route_s *dst;
+ gint res;
+
+ if (!src_data || !dst_data)
+ return -1;
+
+ src = (inm_rtnl_route_s *)src_data;
+ dst = (inm_rtnl_route_s *)dst_data;
+
+ res = dst->if_idx - src->if_idx;
+ if (res != 0)
+ return res;
+
+ res = g_strcmp0(src->dest, dst->dest);
+ if (res != 0)
+ return res;
+
+ res = g_strcmp0(src->gateway, dst->gateway);
+
+ return res;
+}
+
+static inline void __route_fill_info(struct rtnl_route *p_rtnl_route, inm_rtnl_route_s *p_route)
+{
+ char buf[128] = {0,};
+ struct rtnl_nexthop *p_nh;
+ char *p_str = NULL;
+
+ if (!p_rtnl_route || !p_route)
+ return;
+
+ p_route->type = rtnl_route_get_type(p_rtnl_route);
+ p_str = nl_addr2str(rtnl_route_get_dst(p_rtnl_route), buf, sizeof(buf));
+ CHECK_STRING_AND_COPY(p_str, p_route->dest);
+
+ if (rtnl_route_get_nnexthops(p_rtnl_route) > 0) {
+ p_nh = rtnl_route_nexthop_n(p_rtnl_route, 0);
+ p_route->if_idx = rtnl_route_nh_get_ifindex(p_nh);
+
+ p_str = NULL;
+ p_str = nl_addr2str(rtnl_route_nh_get_gateway(p_nh), buf, sizeof(buf));
+ CHECK_STRING_AND_COPY(p_str, p_route->gateway);
+ }
+}
+
+static void __route_destroy(void *user_data)
+{
+ inm_rtnl_route_s *p_route;
+ if (!user_data)
+ return;
+
+ p_route = (inm_rtnl_route_s *)user_data;
+ g_free(p_route->dest);
+ g_free(p_route->gateway);
+ g_free(p_route);
+}
+
+static inline void __route_add(inm_rtnl_route_s *p_route)
+{
+ GList *p_list;
+ inm_rtnl_link_s *link = NULL;
+ inm_rtnl_route_s *tmp = NULL;
+
+ link = __link_find(p_route->if_idx);
+ if (!link)
+ return;
+
+ p_list = g_list_find_custom(link->list_route,
+ p_route,
+ __route_compare);
+ if (p_list) {
+ __route_copy(p_route, (inm_rtnl_route_s *)p_list->data);
+ } else {
+ tmp = (inm_rtnl_route_s *)g_try_malloc0(sizeof(inm_rtnl_route_s));
+ if (!tmp)
+ return;
+ __route_copy(p_route, tmp);
+ link->list_route = g_list_prepend(link->list_route, tmp);
+ }
+}
+
+static inline void __route_remove(inm_rtnl_route_s *p_route)
+{
+ GList *p_list;
+ inm_rtnl_link_s *link = NULL;
+ inm_rtnl_route_s *tmp = NULL;
+
+ link = __link_find(p_route->if_idx);
+ if (!link)
+ return;
+
+ p_list = g_list_find_custom(link->list_route,
+ p_route,
+ __route_compare);
+ if (p_list) {
+ tmp = (inm_rtnl_route_s *)p_list->data;
+ link->list_route = g_list_remove(link->list_route, tmp);
+ __route_destroy(tmp);
+ }
+}
+
static void __route_recv_cb(int action,
struct nl_object *obj,
void *user_data)
{
- __INM_FUNC_ENTER__;
+ inm_rtnl_route_s *p_route = NULL;
+ __INM_FUNC_ENTER__;
if (!obj) {
__INM_FUNC_EXIT__;
return;
}
+ p_route = (inm_rtnl_route_s *)g_try_malloc0(sizeof(inm_rtnl_route_s));
+ if (!p_route) {
+ INM_LOGE("route mem alloc failed");
+ __INM_FUNC_EXIT__;
+ return;
+ }
+
+ __route_fill_info((struct rtnl_route *)obj, p_route);
+ if (action == NL_ACT_NEW || action == NL_ACT_CHANGE)
+ __route_add(p_route);
+ else if (action == NL_ACT_DEL)
+ __route_remove(p_route);
+
+ __route_destroy(p_route);
+
util_foreach_nl_data(&(nl_data_arr[INM_UTIL_RTNL_TYPE_ROUTE]),
rtnl_obj_cbs[INM_UTIL_RTNL_TYPE_ROUTE].foreach_cb,
rtnl_obj_cbs[INM_UTIL_RTNL_TYPE_ROUTE].user_data);
static void __route_foreach_cb(struct nl_object *obj, void *user_data)
{
- __INM_FUNC_ENTER__;
+ inm_rtnl_route_s *p_route = NULL;
+ __INM_FUNC_ENTER__;
if (!obj) {
__INM_FUNC_EXIT__;
return;
}
+ p_route = (inm_rtnl_route_s *)g_try_malloc0(sizeof(inm_rtnl_route_s));
+ if (!p_route) {
+ INM_LOGE("route mem alloc failed");
+ __INM_FUNC_EXIT__;
+ return;
+ }
+
+ __route_fill_info((struct rtnl_route *)obj, p_route);
+ __route_add(p_route);
+ __route_destroy(p_route);
+
__rtnl_route_log((struct rtnl_route *)obj);
__INM_FUNC_EXIT__;