libnl 3.9.0
cache_mngr.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
4 */
5
6/**
7 * @ingroup cache_mngt
8 * @defgroup cache_mngr Manager
9 * @brief Manager keeping caches up to date automatically.
10 *
11 * The cache manager keeps caches up to date automatically by listening to
12 * netlink notifications and integrating the received information into the
13 * existing cache.
14 *
15 * @note This functionality is still considered experimental.
16 *
17 * Related sections in the development guide:
18 * - @core_doc{_cache_manager,Cache Manager}
19 *
20 * @{
21 *
22 * Header
23 * ------
24 * ~~~~{.c}
25 * #include <netlink/cache.h>
26 * ~~~~
27 */
28
29#include "nl-default.h"
30
31#include <netlink/netlink.h>
32#include <netlink/cache.h>
33#include <netlink/utils.h>
34
35#include "nl-core.h"
36#include "nl-priv-dynamic-core/nl-core.h"
37#include "nl-priv-dynamic-core/cache-api.h"
38#include "nl-aux-core/nl-core.h"
39
40/** @cond SKIP */
41struct nl_cache_mngr
42{
43 int cm_protocol;
44 int cm_flags;
45 int cm_nassocs;
46 struct nl_sock * cm_sock;
47 struct nl_sock * cm_sync_sock;
48 struct nl_cache_assoc * cm_assocs;
49};
50
51#define NASSOC_INIT 16
52#define NASSOC_EXPAND 8
53/** @endcond */
54
55static int include_cb(struct nl_object *obj, struct nl_parser_param *p)
56{
57 struct nl_cache_assoc *ca = p->pp_arg;
58 struct nl_cache_ops *ops = ca->ca_cache->c_ops;
59
60 NL_DBG(2, "Including object %p into cache %p\n", obj, ca->ca_cache);
61#ifdef NL_DEBUG
62 if (nl_debug >= 4)
63 nl_object_dump(obj, &nl_debug_dp);
64#endif
65
66 if (ops->co_event_filter)
67 if (ops->co_event_filter(ca->ca_cache, obj) != NL_OK)
68 return 0;
69
70 if (ops->co_include_event)
71 return ops->co_include_event(ca->ca_cache, obj, ca->ca_change,
72 ca->ca_change_v2,
73 ca->ca_change_data);
74 else {
75 if (ca->ca_change_v2)
76 return nl_cache_include_v2(ca->ca_cache, obj, ca->ca_change_v2, ca->ca_change_data);
77 else
78 return nl_cache_include(ca->ca_cache, obj, ca->ca_change, ca->ca_change_data);
79 }
80
81}
82
83static int event_input(struct nl_msg *msg, void *arg)
84{
85 struct nl_cache_mngr *mngr = arg;
86 int protocol = nlmsg_get_proto(msg);
87 int type = nlmsg_hdr(msg)->nlmsg_type;
88 struct nl_cache_ops *ops;
89 int i, n;
90 struct nl_parser_param p = {
91 .pp_cb = include_cb,
92 };
93
94 NL_DBG(2, "Cache manager %p, handling new message %p as event\n",
95 mngr, msg);
96#ifdef NL_DEBUG
97 if (nl_debug >= 4)
98 nl_msg_dump(msg, stderr);
99#endif
100
101 if (mngr->cm_protocol != protocol)
102 BUG();
103
104 for (i = 0; i < mngr->cm_nassocs; i++) {
105 if (mngr->cm_assocs[i].ca_cache) {
106 ops = mngr->cm_assocs[i].ca_cache->c_ops;
107 for (n = 0; ops->co_msgtypes[n].mt_id >= 0; n++)
108 if (ops->co_msgtypes[n].mt_id == type)
109 goto found;
110 }
111 }
112
113 return NL_SKIP;
114
115found:
116 NL_DBG(2, "Associated message %p to cache %p\n",
117 msg, mngr->cm_assocs[i].ca_cache);
118 p.pp_arg = &mngr->cm_assocs[i];
119
120 return nl_cache_parse(ops, NULL, nlmsg_hdr(msg), &p);
121}
122
123/**
124 * Allocate new cache manager
125 * @arg sk Netlink socket or NULL to auto allocate
126 * @arg protocol Netlink protocol this manager is used for
127 * @arg flags Flags (\c NL_AUTO_PROVIDE)
128 * @arg result Result pointer
129 *
130 * Allocates a new cache manager for the specified netlink protocol.
131 *
132 * 1. If sk is not specified (\c NULL) a netlink socket matching the
133 * specified protocol will be automatically allocated.
134 *
135 * 2. The socket will be put in non-blocking mode and sequence checking
136 * will be disabled regardless of whether the socket was provided by
137 * the caller or automatically allocated.
138 *
139 * 3. The socket will be connected.
140 *
141 * If the flag \c NL_AUTO_PROVIDE is specified, any cache added to the
142 * manager will automatically be made available to other users using
143 * nl_cache_mngt_provide().
144 *
145 * @note If the socket is provided by the caller, it is NOT recommended
146 * to use the socket for anything else besides receiving netlink
147 * notifications.
148 *
149 * @return 0 on success or a negative error code.
150 */
151int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags,
152 struct nl_cache_mngr **result)
153{
154 struct nl_cache_mngr *mngr;
155 int err = -NLE_NOMEM;
156
157 /* Catch abuse of flags */
158 if (flags & NL_ALLOCATED_SOCK)
159 BUG();
160
161 mngr = calloc(1, sizeof(*mngr));
162 if (!mngr)
163 return -NLE_NOMEM;
164
165 if (!sk) {
166 if (!(sk = nl_socket_alloc()))
167 goto errout;
168
169 flags |= NL_ALLOCATED_SOCK;
170 }
171
172 mngr->cm_sock = sk;
173 mngr->cm_nassocs = NASSOC_INIT;
174 mngr->cm_protocol = protocol;
175 mngr->cm_flags = flags;
176 mngr->cm_assocs = calloc(mngr->cm_nassocs,
177 sizeof(struct nl_cache_assoc));
178 if (!mngr->cm_assocs)
179 goto errout;
180
181 /* Required to receive async event notifications */
182 nl_socket_disable_seq_check(mngr->cm_sock);
183
184 if ((err = nl_connect(mngr->cm_sock, protocol)) < 0)
185 goto errout;
186
187 if ((err = nl_socket_set_nonblocking(mngr->cm_sock)) < 0)
188 goto errout;
189
190 /* Create and allocate socket for sync cache fills */
191 mngr->cm_sync_sock = nl_socket_alloc();
192 if (!mngr->cm_sync_sock) {
193 err = -NLE_NOMEM;
194 goto errout;
195 }
196 if ((err = nl_connect(mngr->cm_sync_sock, protocol)) < 0)
197 goto errout_free_sync_sock;
198
199 NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n",
200 mngr, protocol, mngr->cm_nassocs);
201
202 *result = mngr;
203 return 0;
204
205errout_free_sync_sock:
206 nl_socket_free(mngr->cm_sync_sock);
207errout:
208 nl_cache_mngr_free(mngr);
209 return err;
210}
211
212/**
213 * Set change_func_v2 for cache manager
214 * @arg mngr Cache manager.
215 * @arg cache Cache associated with the callback
216 * @arg cb Function to be called upon changes.
217 * @arg data Argument passed on to change callback
218 *
219 * Adds callback change_func_v2 to a registered cache. This callback provides
220 * in like the standard change_func the added or remove netlink object. In case
221 * of a change the old and the new object is provided as well as the according
222 * diff. If this callback is registered this has a higher priority then the
223 * change_func registered during cache registration. Hence only one callback is
224 * executed.
225 *
226 * The first netlink object in the callback is refering to the old object and
227 * the second to the new. This means on NL_ACT_CHANGE the first is the previous
228 * object in the cache and the second the updated version. On NL_ACT_DEL the
229 * first is the deleted object the second is NULL. On NL_ACT_NEW the first is
230 * NULL and the second the new netlink object.
231 *
232 * The user is responsible for calling nl_cache_mngr_poll() or monitor
233 * the socket and call nl_cache_mngr_data_ready() to allow the library
234 * to process netlink notification events.
235 *
236 * @see nl_cache_mngr_poll()
237 * @see nl_cache_mngr_data_ready()
238 *
239 * @return 0 on success or a negative error code.
240 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
241 * cache type
242 * @return -NLE_OPNOTSUPP Cache type does not support updates
243 * @return -NLE_RANGE Cache of this type is not registered
244 */
245static int nl_cache_mngr_set_change_func_v2(struct nl_cache_mngr *mngr,
246 struct nl_cache *cache,
247 change_func_v2_t cb, void *data)
248{
249 struct nl_cache_ops *ops;
250 int i;
251
252 ops = cache->c_ops;
253 if (!ops)
254 return -NLE_INVAL;
255
256 if (ops->co_protocol != mngr->cm_protocol)
257 return -NLE_PROTO_MISMATCH;
258
259 if (ops->co_groups == NULL)
260 return -NLE_OPNOTSUPP;
261
262 for (i = 0; i < mngr->cm_nassocs; i++)
263 if (mngr->cm_assocs[i].ca_cache == cache)
264 break;
265
266 if (i >= mngr->cm_nassocs) {
267 return -NLE_RANGE;
268 }
269
270 mngr->cm_assocs[i].ca_change_v2 = cb;
271 mngr->cm_assocs[i].ca_change_data = data;
272
273 return 0;
274}
275
276/**
277 * Add cache to cache manager
278 * @arg mngr Cache manager.
279 * @arg cache Cache to be added to cache manager
280 * @arg cb Function to be called upon changes.
281 * @arg data Argument passed on to change callback
282 *
283 * Adds cache to the manager. The operation will trigger a full
284 * dump request from the kernel to initially fill the contents
285 * of the cache. The manager will subscribe to the notification group
286 * of the cache and keep track of any further changes.
287 *
288 * The user is responsible for calling nl_cache_mngr_poll() or monitor
289 * the socket and call nl_cache_mngr_data_ready() to allow the library
290 * to process netlink notification events.
291 *
292 * @see nl_cache_mngr_poll()
293 * @see nl_cache_mngr_data_ready()
294 *
295 * @return 0 on success or a negative error code.
296 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
297 * cache type
298 * @return -NLE_OPNOTSUPP Cache type does not support updates
299 * @return -NLE_EXIST Cache of this type already being managed
300 */
301int nl_cache_mngr_add_cache(struct nl_cache_mngr *mngr, struct nl_cache *cache,
302 change_func_t cb, void *data)
303{
304 struct nl_cache_ops *ops;
305 struct nl_af_group *grp;
306 int err, i;
307
308 ops = cache->c_ops;
309 if (!ops)
310 return -NLE_INVAL;
311
312 if (ops->co_protocol != mngr->cm_protocol)
313 return -NLE_PROTO_MISMATCH;
314
315 if (ops->co_groups == NULL)
316 return -NLE_OPNOTSUPP;
317
318 for (i = 0; i < mngr->cm_nassocs; i++)
319 if (mngr->cm_assocs[i].ca_cache &&
320 mngr->cm_assocs[i].ca_cache->c_ops == ops)
321 return -NLE_EXIST;
322
323 for (i = 0; i < mngr->cm_nassocs; i++)
324 if (!mngr->cm_assocs[i].ca_cache)
325 break;
326
327 if (i >= mngr->cm_nassocs) {
328 struct nl_cache_assoc *cm_assocs;
329 int cm_nassocs = mngr->cm_nassocs + NASSOC_EXPAND;
330
331 cm_assocs = realloc(mngr->cm_assocs,
332 cm_nassocs * sizeof(struct nl_cache_assoc));
333 if (cm_assocs == NULL)
334 return -NLE_NOMEM;
335
336 memset(cm_assocs + mngr->cm_nassocs, 0,
337 NASSOC_EXPAND * sizeof(struct nl_cache_assoc));
338 mngr->cm_assocs = cm_assocs;
339 mngr->cm_nassocs = cm_nassocs;
340
341 NL_DBG(1, "Increased capacity of cache manager %p " \
342 "to %d\n", mngr, mngr->cm_nassocs);
343 }
344
345 for (grp = ops->co_groups; grp->ag_group; grp++) {
346 err = nl_socket_add_membership(mngr->cm_sock, grp->ag_group);
347 if (err < 0)
348 return err;
349 }
350
351 err = nl_cache_refill(mngr->cm_sync_sock, cache);
352 if (err < 0)
353 goto errout_drop_membership;
354
355 mngr->cm_assocs[i].ca_cache = cache;
356 mngr->cm_assocs[i].ca_change = cb;
357 mngr->cm_assocs[i].ca_change_data = data;
358
359 if (mngr->cm_flags & NL_AUTO_PROVIDE)
361
362 NL_DBG(1, "Added cache %p <%s> to cache manager %p\n",
363 cache, nl_cache_name(cache), mngr);
364
365 return 0;
366
367errout_drop_membership:
368 for (grp = ops->co_groups; grp->ag_group; grp++)
369 nl_socket_drop_membership(mngr->cm_sock, grp->ag_group);
370
371 return err;
372}
373
374/**
375 * Add cache to cache manager
376 * @arg mngr Cache manager.
377 * @arg cache Cache to be added to cache manager
378 * @arg cb V2 function to be called upon changes.
379 * @arg data Argument passed on to change callback
380 *
381 * Adds cache to the manager. The operation will trigger a full
382 * dump request from the kernel to initially fill the contents
383 * of the cache. The manager will subscribe to the notification group
384 * of the cache and keep track of any further changes.
385 *
386 * The user is responsible for calling nl_cache_mngr_poll() or monitor
387 * the socket and call nl_cache_mngr_data_ready() to allow the library
388 * to process netlink notification events.
389 *
390 * @see nl_cache_mngr_poll()
391 * @see nl_cache_mngr_data_ready()
392 *
393 * @return 0 on success or a negative error code.
394 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
395 * cache type
396 * @return -NLE_OPNOTSUPP Cache type does not support updates
397 * @return -NLE_EXIST Cache of this type already being managed
398 */
399int nl_cache_mngr_add_cache_v2(struct nl_cache_mngr *mngr, struct nl_cache *cache,
400 change_func_v2_t cb, void *data) {
401 int err;
402 err = nl_cache_mngr_add_cache(mngr, cache, NULL, NULL);
403 if (err < 0)
404 return err;
405
406 return nl_cache_mngr_set_change_func_v2(mngr, cache, cb, data);
407}
408
409/**
410 * Add cache to cache manager
411 * @arg mngr Cache manager.
412 * @arg name Name of cache to keep track of
413 * @arg cb Function to be called upon changes.
414 * @arg data Argument passed on to change callback
415 * @arg result Pointer to store added cache (optional)
416 *
417 * Allocates a new cache of the specified type and adds it to the manager.
418 * The operation will trigger a full dump request from the kernel to
419 * initially fill the contents of the cache. The manager will subscribe
420 * to the notification group of the cache and keep track of any further
421 * changes.
422 *
423 * The user is responsible for calling nl_cache_mngr_poll() or monitor
424 * the socket and call nl_cache_mngr_data_ready() to allow the library
425 * to process netlink notification events.
426 *
427 * @note Versions up to 3.4.0 actually required the result argument, preventing
428 * NULL to be passed.
429 *
430 * @see nl_cache_mngr_poll()
431 * @see nl_cache_mngr_data_ready()
432 *
433 * @return 0 on success or a negative error code.
434 * @return -NLE_NOCACHE Unknown cache type
435 * @return -NLE_PROTO_MISMATCH Protocol mismatch between cache manager and
436 * cache type
437 * @return -NLE_OPNOTSUPP Cache type does not support updates
438 * @return -NLE_EXIST Cache of this type already being managed
439 */
440int nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name,
441 change_func_t cb, void *data, struct nl_cache **result)
442{
443 struct nl_cache_ops *ops;
444 struct nl_cache *cache;
445 int err;
446
447 ops = nl_cache_ops_lookup_safe(name);
448 if (!ops)
449 return -NLE_NOCACHE;
450
451 cache = nl_cache_alloc(ops);
452 nl_cache_ops_put(ops);
453 if (!cache)
454 return -NLE_NOMEM;
455
456 err = nl_cache_mngr_add_cache(mngr, cache, cb, data);
457 if (err < 0)
458 goto errout_free_cache;
459
460 if (result)
461 *result = cache;
462 return 0;
463
464errout_free_cache:
465 nl_cache_free(cache);
466
467 return err;
468}
469
470/**
471 * Get socket file descriptor
472 * @arg mngr Cache Manager
473 *
474 * Get the file descriptor of the socket associated with the manager.
475 *
476 * @note Do not use the socket for anything besides receiving
477 * notifications.
478 */
479int nl_cache_mngr_get_fd(struct nl_cache_mngr *mngr)
480{
481 return nl_socket_get_fd(mngr->cm_sock);
482}
483
484/**
485 * Check for event notifications
486 * @arg mngr Cache Manager
487 * @arg timeout Upper limit poll() will block, in milliseconds.
488 *
489 * Causes poll() to be called to check for new event notifications
490 * being available. Calls nl_cache_mngr_data_ready() to process
491 * available data.
492 *
493 * This functionally is ideally called regularly during an idle
494 * period.
495 *
496 * A timeout can be specified in milliseconds to limit the time the
497 * function will wait for updates.
498 *
499 * @see nl_cache_mngr_data_ready()
500 *
501 * @return The number of messages processed or a negative error code.
502 */
503int nl_cache_mngr_poll(struct nl_cache_mngr *mngr, int timeout)
504{
505 int ret;
506 struct pollfd fds = {
507 .fd = nl_socket_get_fd(mngr->cm_sock),
508 .events = POLLIN,
509 };
510
511 NL_DBG(3, "Cache manager %p, poll() fd %d\n", mngr, fds.fd);
512 ret = poll(&fds, 1, timeout);
513 NL_DBG(3, "Cache manager %p, poll() returned %d\n", mngr, ret);
514 if (ret < 0) {
515 NL_DBG(4, "nl_cache_mngr_poll(%p): poll() failed with %d (%s)\n",
516 mngr, errno, nl_strerror_l(errno));
517 return -nl_syserr2nlerr(errno);
518 }
519
520 /* No events, return */
521 if (ret == 0)
522 return 0;
523
524 return nl_cache_mngr_data_ready(mngr);
525}
526
527/**
528 * Receive available event notifications
529 * @arg mngr Cache manager
530 *
531 * This function can be called if the socket associated to the manager
532 * contains updates to be received. This function should only be used
533 * if nl_cache_mngr_poll() is not used.
534 *
535 * The function will process messages until there is no more data to
536 * be read from the socket.
537 *
538 * @see nl_cache_mngr_poll()
539 *
540 * @return The number of messages processed or a negative error code.
541 */
542int nl_cache_mngr_data_ready(struct nl_cache_mngr *mngr)
543{
544 int err, nread = 0;
545 struct nl_cb *cb;
546
547 NL_DBG(2, "Cache manager %p, reading new data from fd %d\n",
548 mngr, nl_socket_get_fd(mngr->cm_sock));
549
550 cb = nl_cb_clone(mngr->cm_sock->s_cb);
551 if (cb == NULL)
552 return -NLE_NOMEM;
553
554 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, event_input, mngr);
555
556 while ((err = nl_recvmsgs_report(mngr->cm_sock, cb)) > 0) {
557 NL_DBG(2, "Cache manager %p, recvmsgs read %d messages\n",
558 mngr, err);
559 nread += err;
560 }
561
562 nl_cb_put(cb);
563 if (err < 0 && err != -NLE_AGAIN)
564 return err;
565
566 return nread;
567}
568
569/**
570 * Print information about cache manager
571 * @arg mngr Cache manager
572 * @arg p Dumping parameters
573 *
574 * Prints information about the cache manager including all managed caches.
575 *
576 * @note This is a debugging function.
577 */
578void nl_cache_mngr_info(struct nl_cache_mngr *mngr, struct nl_dump_params *p)
579{
580 char buf[128];
581 int i;
582
583 nl_dump_line(p, "cache-manager <%p>\n", mngr);
584 nl_dump_line(p, " .protocol = %s\n",
585 nl_nlfamily2str(mngr->cm_protocol, buf, sizeof(buf)));
586 nl_dump_line(p, " .flags = %#x\n", mngr->cm_flags);
587 nl_dump_line(p, " .nassocs = %u\n", mngr->cm_nassocs);
588 nl_dump_line(p, " .sock = <%p>\n", mngr->cm_sock);
589
590 for (i = 0; i < mngr->cm_nassocs; i++) {
591 struct nl_cache_assoc *assoc = &mngr->cm_assocs[i];
592
593 if (assoc->ca_cache) {
594 nl_dump_line(p, " .cache[%d] = <%p> {\n", i, assoc->ca_cache);
595 nl_dump_line(p, " .name = %s\n", assoc->ca_cache->c_ops->co_name);
596 nl_dump_line(p, " .change_func = <%p>\n", assoc->ca_change);
597 nl_dump_line(p, " .change_data = <%p>\n", assoc->ca_change_data);
598 nl_dump_line(p, " .nitems = %u\n", nl_cache_nitems(assoc->ca_cache));
599 nl_dump_line(p, " .objects = {\n");
600
601 p->dp_prefix += 6;
602 nl_cache_dump(assoc->ca_cache, p);
603 p->dp_prefix -= 6;
604
605 nl_dump_line(p, " }\n");
606 nl_dump_line(p, " }\n");
607 }
608 }
609}
610
611/**
612 * Free cache manager and all caches.
613 * @arg mngr Cache manager.
614 *
615 * Release all resources held by a cache manager.
616 */
617void nl_cache_mngr_free(struct nl_cache_mngr *mngr)
618{
619 int i;
620
621 if (!mngr)
622 return;
623
624 if (mngr->cm_sock)
625 nl_close(mngr->cm_sock);
626
627 if (mngr->cm_sync_sock) {
628 nl_close(mngr->cm_sync_sock);
629 nl_socket_free(mngr->cm_sync_sock);
630 }
631
632 if (mngr->cm_flags & NL_ALLOCATED_SOCK)
633 nl_socket_free(mngr->cm_sock);
634
635 for (i = 0; i < mngr->cm_nassocs; i++) {
636 if (mngr->cm_assocs[i].ca_cache) {
637 nl_cache_mngt_unprovide(mngr->cm_assocs[i].ca_cache);
638 nl_cache_free(mngr->cm_assocs[i].ca_cache);
639 }
640 }
641
642 free(mngr->cm_assocs);
643
644 NL_DBG(1, "Cache manager %p freed\n", mngr);
645
646 free(mngr);
647}
648
649/** @} */
int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags, struct nl_cache_mngr **result)
Allocate new cache manager.
Definition cache_mngr.c:151
void nl_cache_mngr_free(struct nl_cache_mngr *mngr)
Free cache manager and all caches.
Definition cache_mngr.c:617
void nl_cache_mngr_info(struct nl_cache_mngr *mngr, struct nl_dump_params *p)
Print information about cache manager.
Definition cache_mngr.c:578
int nl_cache_mngr_poll(struct nl_cache_mngr *mngr, int timeout)
Check for event notifications.
Definition cache_mngr.c:503
int nl_cache_mngr_add_cache_v2(struct nl_cache_mngr *mngr, struct nl_cache *cache, change_func_v2_t cb, void *data)
Add cache to cache manager.
Definition cache_mngr.c:399
int nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name, change_func_t cb, void *data, struct nl_cache **result)
Add cache to cache manager.
Definition cache_mngr.c:440
int nl_cache_mngr_get_fd(struct nl_cache_mngr *mngr)
Get socket file descriptor.
Definition cache_mngr.c:479
int nl_cache_mngr_data_ready(struct nl_cache_mngr *mngr)
Receive available event notifications.
Definition cache_mngr.c:542
int nl_cache_mngr_add_cache(struct nl_cache_mngr *mngr, struct nl_cache *cache, change_func_t cb, void *data)
Add cache to cache manager.
Definition cache_mngr.c:301
void nl_cache_mngt_unprovide(struct nl_cache *cache)
Unprovide a cache for global use.
Definition cache_mngt.c:365
void nl_cache_mngt_provide(struct nl_cache *cache)
Provide a cache for global use.
Definition cache_mngt.c:332
struct nl_cache_ops * nl_cache_ops_lookup_safe(const char *name)
Lookup cache operations by name.
Definition cache_mngt.c:99
void nl_cache_ops_put(struct nl_cache_ops *ops)
Decrement reference counter.
Definition cache_mngt.c:65
int nl_cache_refill(struct nl_sock *sk, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
Definition cache.c:1041
int nl_cache_nitems(struct nl_cache *cache)
Return the number of items in the cache.
Definition cache.c:69
void nl_cache_free(struct nl_cache *cache)
Free a cache.
Definition cache.c:409
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate new cache.
Definition cache.c:184
void nl_cache_dump(struct nl_cache *cache, struct nl_dump_params *params)
Dump all elements of a cache.
Definition cache.c:1203
int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg)
Set up a callback.
Definition handlers.c:290
struct nl_cb * nl_cb_clone(struct nl_cb *orig)
Clone an existing callback handle.
Definition handlers.c:227
@ NL_OK
Proceed with whatever would come next.
Definition handlers.h:58
@ NL_SKIP
Skip this message.
Definition handlers.h:60
@ NL_CB_VALID
Message is valid.
Definition handlers.h:89
@ NL_CB_CUSTOM
Customized handler specified by the user.
Definition handlers.h:77
void nl_msg_dump(struct nl_msg *msg, FILE *ofd)
Dump message in human readable format to file descriptor.
Definition msg.c:977
struct nlmsghdr * nlmsg_hdr(struct nl_msg *n)
Return actual netlink message.
Definition msg.c:544
void nl_object_dump(struct nl_object *obj, struct nl_dump_params *params)
Dump this object according to the specified parameters.
Definition object.c:294
int nl_connect(struct nl_sock *sk, int protocol)
Create file descriptor and bind socket.
Definition nl.c:102
int nl_recvmsgs_report(struct nl_sock *sk, struct nl_cb *cb)
Receive a set of messages from a netlink socket and report parsed messages.
Definition nl.c:1051
void nl_close(struct nl_sock *sk)
Close Netlink socket.
Definition nl.c:229
int nl_socket_get_fd(const struct nl_sock *sk)
Return the file descriptor of the backing socket.
Definition socket.c:603
struct nl_sock * nl_socket_alloc(void)
Allocate new netlink socket.
Definition socket.c:225
int nl_socket_set_nonblocking(const struct nl_sock *sk)
Set file descriptor of socket to non-blocking state.
Definition socket.c:722
void nl_socket_disable_seq_check(struct nl_sock *sk)
Disable sequence number checking.
Definition socket.c:302
void nl_socket_free(struct nl_sock *sk)
Free a netlink socket.
Definition socket.c:263
int nl_debug
Global variable indicating the desired level of debugging output.
Definition utils.c:52
Dumping parameters.
Definition types.h:32
int dp_prefix
Specifies the number of whitespaces to be put in front of every new line (indentation).
Definition types.h:42