From f01e93f1f9fd3ea3dade4e291b965abf3a928794 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 29 Jun 2016 20:43:33 +0200 Subject: xxxx --- include/netlink-private/object-api.h | 13 ++++++++++++- include/netlink-private/types.h | 1 + lib/cache.c | 6 +++--- lib/object.c | 11 +++++++++++ lib/route/route.c | 2 +- lib/route/route_obj.c | 17 ++++++++++++++--- 6 files changed, 42 insertions(+), 8 deletions(-) diff --git a/include/netlink-private/object-api.h b/include/netlink-private/object-api.h index e94b67c..91e3fb4 100644 --- a/include/netlink-private/object-api.h +++ b/include/netlink-private/object-api.h @@ -27,6 +27,13 @@ enum oo_update_flags { OO_UPDATE_FLAGS_IS_DUMP = 1, }; +enum oo_objflags { + OO_OBJFLAGS_NONE = 0, + + /* whether to append or prepend the object in the hash bucket. */ + OO_OBJFLAGS_CACHE_APPEND = 1, +}; + /** * @ingroup object * @defgroup object_api Object API @@ -197,7 +204,6 @@ enum oo_update_flags { struct nl_cache * ce_cache; \ struct nl_list_head ce_list; \ int ce_msgtype; \ - int ce_msgflags; \ int ce_flags; \ uint64_t ce_mask; @@ -381,12 +387,17 @@ struct nl_object_ops * Get attributes used in hash key */ uint32_t (*oo_hash_attrs_get)(struct nl_object *); + + int (*oo_check_objflags)(struct nl_object *, enum oo_objflags flags); }; int _nl_object_update(struct nl_object *dst, struct nl_object *src, enum oo_update_flags flags); +int _nl_object_check_objflags (struct nl_object *obj, + enum oo_objflags flags); + /** @} */ #ifdef __cplusplus diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h index 0f67ddd..bf6a7ba 100644 --- a/include/netlink-private/types.h +++ b/include/netlink-private/types.h @@ -281,6 +281,7 @@ struct rtnl_route { NLHDR_COMMON + int rt_msgflags; uint8_t rt_family; uint8_t rt_dst_len; uint8_t rt_src_len; diff --git a/lib/cache.c b/lib/cache.c index 20330d6..3487fb3 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -484,7 +484,7 @@ static int __cache_add(struct nl_cache *cache, struct nl_object *obj, int append int nl_cache_add(struct nl_cache *cache, struct nl_object *obj) { return _nl_cache_add(cache, obj, - (obj->ce_msgflags & NLM_F_APPEND)); + _nl_object_check_objflags (obj, OO_OBJFLAGS_CACHE_APPEND) > 0); } static int _nl_cache_add(struct nl_cache *cache, struct nl_object *obj, int append) @@ -538,7 +538,7 @@ int nl_cache_move(struct nl_cache *cache, struct nl_object *obj) NL_DBG(3, "Moving object %p from cache %p to cache %p\n", obj, obj->ce_cache, cache); - + /* Acquire reference, if already in a cache this will be * reverted during removal */ nl_object_get(obj); @@ -547,7 +547,7 @@ int nl_cache_move(struct nl_cache *cache, struct nl_object *obj) nl_cache_remove(obj); return __cache_add(cache, obj, - (obj->ce_msgflags & NLM_F_APPEND)); + _nl_object_check_objflags (obj, OO_OBJFLAGS_CACHE_APPEND) > 0); } /** diff --git a/lib/object.c b/lib/object.c index 4951885..7405437 100644 --- a/lib/object.c +++ b/lib/object.c @@ -144,6 +144,17 @@ struct nl_object *nl_object_clone(struct nl_object *obj) return new; } +int _nl_object_check_objflags (struct nl_object *obj, + enum oo_objflags flags) +{ + struct nl_object_ops *ops = obj_ops(obj); + + if (ops->oo_check_objflags) + return ops->oo_check_objflags(obj, flags); + + return -NLE_OPNOTSUPP; +} + int _nl_object_update(struct nl_object *dst, struct nl_object *src, enum oo_update_flags flags) diff --git a/lib/route/route.c b/lib/route/route.c index cb9d243..f35f2e9 100644 --- a/lib/route/route.c +++ b/lib/route/route.c @@ -40,7 +40,7 @@ uint32_t route_cache_search_attr_get(struct nl_cache *cache, * in the cache. So, look for the first object * that matches the hash key attributes */ - if ((needle->ce_msgflags & NLM_F_REPLACE) || + if ((new_route->rt_msgflags & NLM_F_REPLACE) || rtnl_route_is_likely_ipv6_multipath(new_route)) return ops->oo_hash_attrs_get(needle); else diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c index f495ade..611e125 100644 --- a/lib/route/route_obj.c +++ b/lib/route/route_obj.c @@ -520,7 +520,7 @@ static int route_update(struct nl_object *old_obj, struct nl_object *new_obj, * replace. And the replace flag is only set * for the first nexthop */ - if (new_obj->ce_msgflags & NLM_F_REPLACE) + if (new_route->rt_msgflags & NLM_F_REPLACE) return -NLE_OPNOTSUPP; cloned_nh = rtnl_route_nh_clone(new_nh); @@ -548,7 +548,7 @@ static int route_update(struct nl_object *old_obj, struct nl_object *new_obj, sizeof(nbuf)); nl_object_dump_buf(old_obj, obuf, sizeof(obuf)); - NL_DBG(2, "%s: ignoring duplicate nexthop: ce_msgflags = (%x, %x), rt_flags = (%x, %x), rtnh_flags = (%x, %x), objs = (%s, %s)\n", __FUNCTION__, old_obj->ce_msgflags, new_obj->ce_msgflags, old_route->rt_flags, new_route->rt_flags, old_nh->rtnh_flags, new_nh->rtnh_flags, obuf, nbuf); + NL_DBG(2, "%s: ignoring duplicate nexthop: ce_msgflags = (%x, %x), rt_flags = (%x, %x), rtnh_flags = (%x, %x), objs = (%s, %s)\n", __FUNCTION__, old_route->rt_msgflags, new_route->rt_msgflags, old_route->rt_flags, new_route->rt_flags, old_nh->rtnh_flags, new_nh->rtnh_flags, obuf, nbuf); } #endif rtnl_route_nh_free(cloned_nh); @@ -639,6 +639,15 @@ static char *route_attrs2str(int attrs, char *buf, size_t len) ARRAY_SIZE(route_attrs)); } +static int route_check_objflags(struct nl_object *obj, enum oo_objflags flags) +{ + if (flags & OO_OBJFLAGS_CACHE_APPEND) { + if (((struct rtnl_route *) obj)->rt_msgflags & NLM_F_APPEND) + return 1; + } + return 0; +} + /** * @name Allocation/Freeing * @{ @@ -1097,7 +1106,8 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result) } route->ce_msgtype = nlh->nlmsg_type; - route->ce_msgflags = nlh->nlmsg_flags; + + route->rt_msgflags = nlh->nlmsg_flags; err = nlmsg_parse(nlh, sizeof(struct rtmsg), tb, RTA_MAX, route_policy); if (err < 0) @@ -1384,6 +1394,7 @@ struct nl_object_ops route_obj_ops = { .oo_keygen = route_keygen, .oo_update = route_update, .oo_attrs2str = route_attrs2str, + .oo_check_objflags = route_check_objflags, .oo_id_attrs = (ROUTE_ATTR_FAMILY | ROUTE_ATTR_TOS | ROUTE_ATTR_TABLE | ROUTE_ATTR_DST | ROUTE_ATTR_PRIO), -- cgit v0.12