From 00132b46968fff7975eb8d20a307c626dfefe2f1 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Fri, 16 Nov 2012 01:11:55 +0100 Subject: cache: provide safe variant of nl_cache_mngt_require() and use it This makes runtime removal of cache operations possible if non-safe API is not in use by application. The non-safe API will be removed in the next major version. Signed-off-by: Thomas Graf --- include/netlink-local.h | 8 -------- include/netlink/cache.h | 2 ++ lib/cache.c | 5 +++++ lib/cache_mngt.c | 32 ++++++++++++++++++++++++++------ lib/netfilter/log_msg_obj.c | 5 ++++- lib/netfilter/queue_msg_obj.c | 5 ++++- lib/route/addr.c | 5 ++++- lib/route/link.c | 2 +- lib/route/neigh.c | 9 +++++++-- lib/route/neightbl.c | 3 ++- lib/route/nexthop.c | 10 ++++++++-- lib/route/route_obj.c | 5 ++++- lib/route/tc.c | 5 ++++- src/nl-addr-list.c | 5 ++++- 14 files changed, 75 insertions(+), 26 deletions(-) diff --git a/include/netlink-local.h b/include/netlink-local.h index 2bfae3e..b891d8c 100644 --- a/include/netlink-local.h +++ b/include/netlink-local.h @@ -117,14 +117,6 @@ extern int __str2flags(const char *, const struct trans_tbl *, size_t); extern void dump_from_ops(struct nl_object *, struct nl_dump_params *); -static inline struct nl_cache *dp_cache(struct nl_object *obj) -{ - if (obj->ce_cache == NULL) - return nl_cache_mngt_require(obj->ce_ops->oo_name); - - return obj->ce_cache; -} - static inline int nl_cb_call(struct nl_cb *cb, int type, struct nl_msg *msg) { return cb->cb_set[type](msg, cb->cb_args[type]); diff --git a/include/netlink/cache.h b/include/netlink/cache.h index f193c76..ac03842 100644 --- a/include/netlink/cache.h +++ b/include/netlink/cache.h @@ -52,6 +52,7 @@ extern struct nl_cache * nl_cache_clone(struct nl_cache *); extern void nl_cache_clear(struct nl_cache *); extern void nl_cache_get(struct nl_cache *); extern void nl_cache_free(struct nl_cache *); +extern void nl_cache_put(struct nl_cache *cache); /* Cache modification */ extern int nl_cache_add(struct nl_cache *, @@ -118,6 +119,7 @@ extern int nl_cache_mngt_unregister(struct nl_cache_ops *); extern void nl_cache_mngt_provide(struct nl_cache *); extern void nl_cache_mngt_unprovide(struct nl_cache *); extern struct nl_cache * nl_cache_mngt_require(const char *); +extern struct nl_cache * nl_cache_mngt_require_safe(const char *); extern struct nl_cache * __nl_cache_mngt_require(const char *); struct nl_cache_mngr; diff --git a/lib/cache.c b/lib/cache.c index aa17ad8..415e471 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -410,6 +410,11 @@ void nl_cache_free(struct nl_cache *cache) __nl_cache_free(cache); } +void nl_cache_put(struct nl_cache *cache) +{ + return nl_cache_free(cache); +} + /** @} */ /** diff --git a/lib/cache_mngt.c b/lib/cache_mngt.c index 914ab9b..fbb702f 100644 --- a/lib/cache_mngt.c +++ b/lib/cache_mngt.c @@ -390,14 +390,15 @@ struct nl_cache *__nl_cache_mngt_require(const char *name) } /** - * Demand the use of a global cache - * @arg name name of the required object type + * Return cache previously provided via nl_cache_mngt_provide() + * @arg name Name of cache to lookup * - * Trys to find a cache of the specified type for global - * use. + * @attention This function is not safe, it does not increment the reference + * counter. Please use nl_cache_mngt_require_safe(). + * + * @see nl_cache_mngt_require_safe() * - * @return A cache provided by another subsystem of the - * specified type marked to be available. + * @return Pointer to cache or NULL if none registered */ struct nl_cache *nl_cache_mngt_require(const char *name) { @@ -412,6 +413,25 @@ struct nl_cache *nl_cache_mngt_require(const char *name) return cache; } +/** + * Return cache previously provided via nl_cache_mngt_provide() + * @arg name Name of cache to lookup + * + * @note The reference counter of the returned cache is incremented + * and must be decremented after use with nl_cache_put(). + * + * @return Pointer to cache or NULL if none registered + */ +struct nl_cache *nl_cache_mngt_require_safe(const char *name) +{ + struct nl_cache *cache; + + if ((cache = nl_cache_mngt_require(name))) + nl_cache_get(cache); + + return cache; +} + /** @} */ /** @} */ diff --git a/lib/netfilter/log_msg_obj.c b/lib/netfilter/log_msg_obj.c index d2cde4e..d2ad0ff 100644 --- a/lib/netfilter/log_msg_obj.c +++ b/lib/netfilter/log_msg_obj.c @@ -76,7 +76,7 @@ static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p) struct nl_cache *link_cache; char buf[64]; - link_cache = nl_cache_mngt_require("route/link"); + link_cache = nl_cache_mngt_require_safe("route/link"); nl_new_line(p); @@ -167,6 +167,9 @@ static void log_msg_dump(struct nl_object *a, struct nl_dump_params *p) nl_dump(p, "SEQGLOBAL=%d ", msg->log_msg_seq_global); nl_dump(p, "\n"); + + if (link_cache) + nl_cache_put(link_cache); } /** diff --git a/lib/netfilter/queue_msg_obj.c b/lib/netfilter/queue_msg_obj.c index 33305ed..bfaafc5 100644 --- a/lib/netfilter/queue_msg_obj.c +++ b/lib/netfilter/queue_msg_obj.c @@ -66,7 +66,7 @@ static void nfnl_queue_msg_dump(struct nl_object *a, struct nl_dump_params *p) struct nl_cache *link_cache; char buf[64]; - link_cache = nl_cache_mngt_require("route/link"); + link_cache = nl_cache_mngt_require_safe("route/link"); nl_new_line(p); @@ -152,6 +152,9 @@ static void nfnl_queue_msg_dump(struct nl_object *a, struct nl_dump_params *p) buf, sizeof(buf))); nl_dump(p, "\n"); + + if (link_cache) + nl_cache_put(link_cache); } /** diff --git a/lib/route/addr.c b/lib/route/addr.c index 7e29529..c5e14bb 100644 --- a/lib/route/addr.c +++ b/lib/route/addr.c @@ -332,7 +332,7 @@ static void addr_dump_line(struct nl_object *obj, struct nl_dump_params *p) struct nl_cache *link_cache; char buf[128]; - link_cache = nl_cache_mngt_require("route/link"); + link_cache = nl_cache_mngt_require_safe("route/link"); if (addr->ce_mask & ADDR_ATTR_LOCAL) nl_dump_line(p, "%s", @@ -361,6 +361,9 @@ static void addr_dump_line(struct nl_object *obj, struct nl_dump_params *p) nl_dump(p, " <%s>", buf); nl_dump(p, "\n"); + + if (link_cache) + nl_cache_put(link_cache); } static void addr_dump_details(struct nl_object *obj, struct nl_dump_params *p) diff --git a/lib/route/link.c b/lib/route/link.c index b378f30..1cecd54 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -581,7 +581,7 @@ static int link_request_update(struct nl_cache *cache, struct nl_sock *sk) static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) { char buf[128]; - struct nl_cache *cache = dp_cache(obj); + struct nl_cache *cache = obj->ce_cache; struct rtnl_link *link = (struct rtnl_link *) obj; nl_dump_line(p, "%s %s ", link->l_name, diff --git a/lib/route/neigh.c b/lib/route/neigh.c index 4b5893a..4a85a85 100644 --- a/lib/route/neigh.c +++ b/lib/route/neigh.c @@ -401,7 +401,7 @@ int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result) * Get the bridge index for AF_BRIDGE family entries */ if (neigh->n_family == AF_BRIDGE) { - struct nl_cache *lcache = nl_cache_mngt_require("route/link"); + struct nl_cache *lcache = nl_cache_mngt_require_safe("route/link"); if (lcache ) { struct rtnl_link *link = rtnl_link_get(lcache, neigh->n_ifindex); @@ -410,6 +410,8 @@ int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result) rtnl_link_put(link); neigh->ce_mask |= NEIGH_ATTR_MASTER; } + + nl_cache_put(lcache); } } @@ -436,7 +438,7 @@ static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p) struct nl_cache *link_cache; char state[128], flags[64]; - link_cache = nl_cache_mngt_require("route/link"); + link_cache = nl_cache_mngt_require_safe("route/link"); if (n->n_family != AF_BRIDGE) nl_dump_line(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst))); @@ -462,6 +464,9 @@ static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p) if (state[0] || flags[0]) nl_dump(p, ">"); nl_dump(p, "\n"); + + if (link_cache) + nl_cache_put(link_cache); } static void neigh_dump_details(struct nl_object *a, struct nl_dump_params *p) diff --git a/lib/route/neightbl.c b/lib/route/neightbl.c index 1efa5cb..509617b 100644 --- a/lib/route/neightbl.c +++ b/lib/route/neightbl.c @@ -237,7 +237,7 @@ static void neightbl_dump_line(struct nl_object *arg, struct nl_dump_params *p) if (ntbl->nt_parms.ntp_mask & NEIGHTBLPARM_ATTR_IFINDEX) { struct nl_cache *link_cache; - link_cache = nl_cache_mngt_require("route/link"); + link_cache = nl_cache_mngt_require_safe("route/link"); if (link_cache) { char buf[32]; @@ -245,6 +245,7 @@ static void neightbl_dump_line(struct nl_object *arg, struct nl_dump_params *p) rtnl_link_i2name(link_cache, ntbl->nt_parms.ntp_ifindex, buf, sizeof(buf))); + nl_cache_put(link_cache); } else nl_dump(p, "<%u> ", ntbl->nt_parms.ntp_ifindex); } else diff --git a/lib/route/nexthop.c b/lib/route/nexthop.c index 189bccd..9990c51 100644 --- a/lib/route/nexthop.c +++ b/lib/route/nexthop.c @@ -109,7 +109,7 @@ static void nh_dump_line(struct rtnl_nexthop *nh, struct nl_dump_params *dp) struct nl_cache *link_cache; char buf[128]; - link_cache = nl_cache_mngt_require("route/link"); + link_cache = nl_cache_mngt_require_safe("route/link"); nl_dump(dp, "via"); @@ -128,6 +128,9 @@ static void nh_dump_line(struct rtnl_nexthop *nh, struct nl_dump_params *dp) } nl_dump(dp, " "); + + if (link_cache) + nl_cache_put(link_cache); } static void nh_dump_details(struct rtnl_nexthop *nh, struct nl_dump_params *dp) @@ -135,7 +138,7 @@ static void nh_dump_details(struct rtnl_nexthop *nh, struct nl_dump_params *dp) struct nl_cache *link_cache; char buf[128]; - link_cache = nl_cache_mngt_require("route/link"); + link_cache = nl_cache_mngt_require_safe("route/link"); nl_dump(dp, "nexthop"); @@ -164,6 +167,9 @@ static void nh_dump_details(struct rtnl_nexthop *nh, struct nl_dump_params *dp) if (nh->ce_mask & NH_ATTR_FLAGS) nl_dump(dp, " <%s>", rtnl_route_nh_flags2str(nh->rtnh_flags, buf, sizeof(buf))); + + if (link_cache) + nl_cache_put(link_cache); } void rtnl_route_nh_dump(struct rtnl_nexthop *nh, struct nl_dump_params *dp) diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c index 0ee9ca0..cc29746 100644 --- a/lib/route/route_obj.c +++ b/lib/route/route_obj.c @@ -210,7 +210,7 @@ static void route_dump_details(struct nl_object *a, struct nl_dump_params *p) char buf[128]; int i; - link_cache = nl_cache_mngt_require("route/link"); + link_cache = nl_cache_mngt_require_safe("route/link"); route_dump_line(a, p); nl_dump_line(p, " "); @@ -271,6 +271,9 @@ static void route_dump_details(struct nl_object *a, struct nl_dump_params *p) r->rt_metrics[i]); nl_dump(p, "]\n"); } + + if (link_cache) + nl_cache_put(link_cache); } static void route_dump_stats(struct nl_object *obj, struct nl_dump_params *p) diff --git a/lib/route/tc.c b/lib/route/tc.c index 6c72c15..5a0b783 100644 --- a/lib/route/tc.c +++ b/lib/route/tc.c @@ -822,7 +822,7 @@ void rtnl_tc_dump_line(struct nl_object *obj, struct nl_dump_params *p) nl_dump(p, "%s ", tc->tc_kind); - if ((link_cache = nl_cache_mngt_require("route/link"))) { + if ((link_cache = nl_cache_mngt_require_safe("route/link"))) { nl_dump(p, "dev %s ", rtnl_link_i2name(link_cache, tc->tc_ifindex, buf, sizeof(buf))); @@ -837,6 +837,9 @@ void rtnl_tc_dump_line(struct nl_object *obj, struct nl_dump_params *p) tc_dump(tc, NL_DUMP_LINE, p); nl_dump(p, "\n"); + + if (link_cache) + nl_cache_put(link_cache); } void rtnl_tc_dump_details(struct nl_object *obj, struct nl_dump_params *p) diff --git a/src/nl-addr-list.c b/src/nl-addr-list.c index 5044d5c..20995a8 100644 --- a/src/nl-addr-list.c +++ b/src/nl-addr-list.c @@ -65,7 +65,7 @@ static void env_dump(struct nl_object *obj, void *arg) nl_addr2str(rtnl_addr_get_local(addr), buf, sizeof(buf))); nl_dump_line(p, "%s_IFINDEX=%u\n", pfx, rtnl_addr_get_ifindex(addr)); - link_cache = nl_cache_mngt_require("route/link"); + link_cache = nl_cache_mngt_require_safe("route/link"); if (link_cache) nl_dump_line(p, "%s_IFNAME=%s\n", pfx, rtnl_link_i2name(link_cache, @@ -94,6 +94,9 @@ static void env_dump(struct nl_object *obj, void *arg) nl_dump_line(p, "%s_CACHEINFO_VALID=%u\n", pfx, rtnl_addr_get_valid_lifetime(addr)); + if (link_cache) + nl_cache_put(link_cache); + #if 0 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) { struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo; -- cgit v0.12