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]);
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 *,
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;
__nl_cache_free(cache);
}
+void nl_cache_put(struct nl_cache *cache)
+{
+ return nl_cache_free(cache);
+}
+
/** @} */
/**
}
/**
- * 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)
{
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;
+}
+
/** @} */
/** @} */
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);
nl_dump(p, "SEQGLOBAL=%d ", msg->log_msg_seq_global);
nl_dump(p, "\n");
+
+ if (link_cache)
+ nl_cache_put(link_cache);
}
/**
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);
buf, sizeof(buf)));
nl_dump(p, "\n");
+
+ if (link_cache)
+ nl_cache_put(link_cache);
}
/**
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",
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)
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,
* 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);
rtnl_link_put(link);
neigh->ce_mask |= NEIGH_ATTR_MASTER;
}
+
+ nl_cache_put(lcache);
}
}
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)));
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)
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];
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
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");
}
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)
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");
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)
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, " ");
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)
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)));
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)
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,
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;