28 #include <netlink-private/netlink.h>
29 #include <netlink/netlink.h>
30 #include <netlink/cache.h>
31 #include <netlink/utils.h>
33 static struct nl_cache_ops *cache_ops;
34 static NL_RW_LOCK(cache_ops_lock);
41 static struct nl_cache_ops *__nl_cache_ops_lookup(
const char *name)
43 struct nl_cache_ops *ops;
45 for (ops = cache_ops; ops; ops = ops->co_next)
46 if (!strcmp(ops->co_name, name))
81 struct nl_cache_ops *ops;
83 nl_read_lock(&cache_ops_lock);
84 ops = __nl_cache_ops_lookup(name);
85 nl_read_unlock(&cache_ops_lock);
101 struct nl_cache_ops *ops;
103 nl_write_lock(&cache_ops_lock);
104 if ((ops = __nl_cache_ops_lookup(name)))
106 nl_write_unlock(&cache_ops_lock);
111 static struct nl_cache_ops *__cache_ops_associate(
int protocol,
int msgtype)
114 struct nl_cache_ops *ops;
116 for (ops = cache_ops; ops; ops = ops->co_next) {
117 if (ops->co_protocol != protocol)
120 for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++)
121 if (ops->co_msgtypes[i].mt_id == msgtype)
142 struct nl_cache_ops *ops;
144 nl_read_lock(&cache_ops_lock);
145 ops = __cache_ops_associate(protocol, msgtype);
146 nl_read_unlock(&cache_ops_lock);
166 struct nl_cache_ops *ops;
168 nl_write_lock(&cache_ops_lock);
169 if ((ops = __cache_ops_associate(protocol, msgtype)))
171 nl_write_unlock(&cache_ops_lock);
193 for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++)
194 if (ops->co_msgtypes[i].mt_id == msgtype)
195 return &ops->co_msgtypes[i];
201 static struct nl_cache_ops *cache_ops_lookup_for_obj(
struct nl_object_ops *obj_ops)
203 struct nl_cache_ops *ops;
205 for (ops = cache_ops; ops; ops = ops->co_next)
206 if (ops->co_obj_ops == obj_ops)
220 struct nl_cache_ops *ops;
222 nl_read_lock(&cache_ops_lock);
223 for (ops = cache_ops; ops; ops = ops->co_next)
225 nl_read_unlock(&cache_ops_lock);
238 nl_write_lock(&cache_ops_lock);
239 ops->co_flags |= flags;
240 nl_write_unlock(&cache_ops_lock);
254 if (!ops->co_name || !ops->co_obj_ops)
258 BUG_ON (ops->co_obj_ops->oo_keygen && !ops->co_obj_ops->oo_compare);
260 nl_write_lock(&cache_ops_lock);
261 if (__nl_cache_ops_lookup(ops->co_name)) {
262 nl_write_unlock(&cache_ops_lock);
267 ops->co_next = cache_ops;
269 nl_write_unlock(&cache_ops_lock);
271 NL_DBG(1,
"Registered cache operations %s\n", ops->co_name);
289 struct nl_cache_ops *t, **tp;
292 nl_write_lock(&cache_ops_lock);
294 if (ops->co_refcnt > 0) {
299 for (tp = &cache_ops; (t=*tp) != NULL; tp = &t->co_next)
308 NL_DBG(1,
"Unregistered cache operations %s\n", ops->co_name);
312 nl_write_unlock(&cache_ops_lock);
334 struct nl_cache_ops *ops;
336 nl_write_lock(&cache_ops_lock);
338 ops = cache_ops_lookup_for_obj(cache->c_ops->co_obj_ops);
348 if (!ops->co_major_cache)
351 ops->co_major_cache = cache;
354 nl_write_unlock(&cache_ops_lock);
367 struct nl_cache_ops *ops;
369 nl_write_lock(&cache_ops_lock);
371 ops = cache_ops_lookup_for_obj(cache->c_ops->co_obj_ops);
374 else if (ops->co_major_cache == cache) {
377 ops->co_major_cache = NULL;
380 nl_write_unlock(&cache_ops_lock);
383 struct nl_cache *__nl_cache_mngt_require(
const char *name)
385 struct nl_cache_ops *ops;
386 struct nl_cache *cache = NULL;
390 cache = ops->co_major_cache;
410 struct nl_cache *cache;
412 if (!(cache = __nl_cache_mngt_require(name)))
413 NL_DBG(1,
"Application BUG: Your application must "
414 "call nl_cache_mngt_provide() and\nprovide a valid "
415 "%s cache to be used for internal lookups.\nSee the "
416 " API documentation for more details.\n", name);
432 struct nl_cache *cache;
void nl_cache_mngt_provide(struct nl_cache *cache)
Provide a cache for global use.
void nl_cache_ops_put(struct nl_cache_ops *ops)
Decrement reference counter.
void nl_cache_ops_get(struct nl_cache_ops *ops)
Increment reference counter.
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
void nl_cache_get(struct nl_cache *cache)
Increase reference counter of cache.
struct nl_cache_ops * nl_cache_ops_lookup(const char *name)
Lookup cache operations by name.
void nl_cache_free(struct nl_cache *cache)
Free a cache.
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
struct nl_cache * nl_cache_mngt_require(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
struct nl_cache_ops * nl_cache_ops_lookup_safe(const char *name)
Lookup cache operations by name.
void nl_cache_mngt_unprovide(struct nl_cache *cache)
Unprovide a cache for global use.
void nl_cache_ops_set_flags(struct nl_cache_ops *ops, unsigned int flags)
Set default flags for caches of this type.
void nl_cache_ops_foreach(void(*cb)(struct nl_cache_ops *, void *), void *arg)
Call a function for each registered cache operation.
struct nl_cache_ops * nl_cache_ops_associate(int protocol, int msgtype)
Associate protocol and message type to cache operations.
struct nl_msgtype * nl_msgtype_lookup(struct nl_cache_ops *ops, int msgtype)
Lookup message type cache association.
struct nl_cache_ops * nl_cache_ops_associate_safe(int protocol, int msgtype)
Associate protocol and message type to cache operations.