Helps keeping caches up to date.
More...
The purpose of a cache manager is to keep track of caches and automatically receive event notifications to keep the caches up to date with the kernel state. Each manager has exactly one netlink socket assigned which limits the scope of each manager to exactly one netlink family. Therefore all caches committed to a manager must be part of the same netlink family. Due to the nature of a manager, it is not possible to have a cache maintain two instances of the same cache type. The socket is subscribed to the event notification group of each cache and also put into non-blocking mode. Functions exist to poll() on the socket to wait for new events to be received.
App libnl Kernel
| |
+-----------------+ [ notification, link change ]
| | Cache Manager | | [ (IFF_UP | IFF_RUNNING) ]
| | |
| | +------------+| | | [ notification, new addr ]
<-------|---| route/link |<-------(async)--+ [ 10.0.1.1/32 dev eth1 ]
| | +------------+| | |
| +------------+| |
<---|---|---| route/addr |<------|-(async)--------------+
| +------------+|
| | +------------+| |
<-------|---| ... ||
| | +------------+| |
+-----------------+
| |
- 1) Creating a new cache manager
struct nl_cache_mngr *mngr;
- 2) Keep track of a cache
- 3) Make the manager receive updates
- 4) Release cache manager
-
◆ nl_cache_mngr_alloc()
| struct nl_cache_mngr* nl_cache_mngr_alloc |
( |
struct nl_handle * |
handle, |
|
|
int |
protocol, |
|
|
int |
flags |
|
) |
| |
- Parameters
-
| handle | Netlink socket/handle to be used |
| protocol | Netlink Protocol this manager is used for |
| flags | Flags |
- Returns
- Newly allocated cache manager or NULL on failure.
Definition at line 149 of file cache_mngr.c.
152 struct nl_cache_mngr *mngr;
157 mngr = calloc(1,
sizeof(*mngr));
161 mngr->cm_handle = handle;
162 mngr->cm_nassocs = 32;
163 mngr->cm_protocol = protocol;
164 mngr->cm_flags = flags;
165 mngr->cm_assocs = calloc(mngr->cm_nassocs,
166 sizeof(
struct nl_cache_assoc));
167 if (!mngr->cm_assocs)
177 if (
nl_connect(mngr->cm_handle, protocol) < 0)
183 NL_DBG(1,
"Allocated cache manager %p, protocol %d, %d caches\n",
184 mngr, protocol, mngr->cm_nassocs);
References NL_CB_CUSTOM, NL_CB_VALID, and nl_socket_modify_cb().
◆ nl_cache_mngr_add()
| struct nl_cache* nl_cache_mngr_add |
( |
struct nl_cache_mngr * |
mngr, |
|
|
const char * |
name, |
|
|
change_func_t |
cb |
|
) |
| |
- Parameters
-
| mngr | Cache manager. |
| name | Name of cache to keep track of |
| cb | Function to be called upon changes. |
Allocates a new cache of the specified type and adds it to the manager. The operation will trigger a full dump request from the kernel to initially fill the contents of the cache. The manager will subscribe to the notification group of the cache to keep track of any further changes.
- Returns
- The newly allocated cache or NULL on failure.
Definition at line 209 of file cache_mngr.c.
213 struct nl_cache *cache;
219 nl_error(ENOENT,
"Unknown cache type");
223 if (ops->co_protocol != mngr->cm_protocol) {
224 nl_error(EINVAL,
"Netlink protocol mismatch");
228 if (ops->co_groups == NULL) {
229 nl_error(EOPNOTSUPP, NULL);
233 for (i = 0; i < mngr->cm_nassocs; i++) {
234 if (mngr->cm_assocs[i].ca_cache &&
235 mngr->cm_assocs[i].ca_cache->c_ops == ops) {
236 nl_error(EEXIST,
"Cache of this type already managed");
242 for (i = 0; i < mngr->cm_nassocs; i++)
243 if (!mngr->cm_assocs[i].ca_cache)
246 if (i >= mngr->cm_nassocs) {
247 mngr->cm_nassocs += 16;
248 mngr->cm_assocs = realloc(mngr->cm_assocs,
250 sizeof(
struct nl_cache_assoc));
251 if (mngr->cm_assocs == NULL) {
255 NL_DBG(1,
"Increased capacity of cache manager %p " \
256 "to %d\n", mngr, mngr->cm_nassocs);
267 for (grp = ops->co_groups; grp->
ag_group; grp++) {
270 goto errout_free_cache;
275 goto errout_drop_membership;
277 mngr->cm_assocs[i].ca_cache = cache;
278 mngr->cm_assocs[i].ca_change = cb;
280 if (mngr->cm_flags & NL_AUTO_PROVIDE)
283 NL_DBG(1,
"Added cache %p <%s> to cache manager %p\n",
284 cache, nl_cache_name(cache), mngr);
288 errout_drop_membership:
289 for (grp = ops->co_groups; grp->
ag_group; grp++)
References nl_af_group::ag_group, nl_cache_alloc(), nl_cache_free(), nl_cache_mngt_provide(), nl_cache_ops_lookup(), nl_cache_refill(), nl_socket_add_membership(), and nl_socket_drop_membership().
◆ nl_cache_mngr_get_fd()
| int nl_cache_mngr_get_fd |
( |
struct nl_cache_mngr * |
mngr | ) |
|
- Parameters
-
Get the file descriptor of the socket associated to the manager. This can be used to change socket options or monitor activity using poll()/select().
Definition at line 305 of file cache_mngr.c.
307 return nl_socket_get_fd(mngr->cm_handle);
◆ nl_cache_mngr_poll()
| int nl_cache_mngr_poll |
( |
struct nl_cache_mngr * |
mngr, |
|
|
int |
timeout |
|
) |
| |
- Parameters
-
| mngr | Cache Manager |
| timeout | Upper limit poll() will block, in milliseconds. |
Causes poll() to be called to check for new event notifications being available. Automatically receives and handles available notifications.
This functionally is ideally called regularly during an idle period.
- Returns
- A positive value if at least one update was handled, 0 for none, or a negative error code.
Definition at line 325 of file cache_mngr.c.
328 struct pollfd fds = {
329 .fd = nl_socket_get_fd(mngr->cm_handle),
333 NL_DBG(3,
"Cache manager %p, poll() fd %d\n", mngr, fds.fd);
334 ret = poll(&fds, 1, timeout);
335 NL_DBG(3,
"Cache manager %p, poll() returned %d\n", mngr, ret);
337 return nl_errno(errno);
◆ nl_cache_mngr_data_ready()
| int nl_cache_mngr_data_ready |
( |
struct nl_cache_mngr * |
mngr | ) |
|
- Parameters
-
This function can be called if the socket associated to the manager contains updates to be received. This function should not be used if nl_cache_mngr_poll() is used.
- Returns
- A positive value if at least one update was handled, 0 for none, or a negative error code.
Definition at line 356 of file cache_mngr.c.
References nl_recvmsgs_default().
◆ nl_cache_mngr_free()
| void nl_cache_mngr_free |
( |
struct nl_cache_mngr * |
mngr | ) |
|
- Parameters
-
Release all resources after usage of a cache manager.
Definition at line 373 of file cache_mngr.c.
378 if (mngr->cm_handle) {
383 free(mngr->cm_assocs);
386 NL_DBG(1,
"Cache manager %p freed\n", mngr);
References nl_close(), and nl_handle_destroy().
void nl_cache_mngt_provide(struct nl_cache *cache)
Provide a cache for global use.
int ag_group
Netlink group identifier.
Address family to netlink group association.
int nl_recvmsgs_default(struct nl_handle *handle)
Receive a set of message from a netlink socket using handlers in nl_handle.
void nl_cache_dump(struct nl_cache *cache, struct nl_dump_params *params)
Dump all elements of a cache.
struct nl_cache_ops * nl_cache_ops_lookup(const char *name)
Lookup cache operations by name.
@ NL_CB_CUSTOM
Customized handler specified by the user.
int nl_socket_set_nonblocking(struct nl_handle *handle)
Set file descriptor of socket handle to non-blocking state.
void nl_disable_sequence_check(struct nl_handle *handle)
Disable sequence number checking.
struct nl_cache_mngr * nl_cache_mngr_alloc(struct nl_handle *handle, int protocol, int flags)
Allocate new cache manager.
void nl_cache_mngr_free(struct nl_cache_mngr *mngr)
Free cache manager.
int nl_cache_mngr_data_ready(struct nl_cache_mngr *mngr)
Receive available event notifications.
int nl_connect(struct nl_handle *handle, int protocol)
Create and connect netlink socket.
int nl_socket_modify_cb(struct nl_handle *handle, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg)
Modify the callback handler associated to the socket.
int nl_socket_add_membership(struct nl_handle *handle, int group)
Join a group.
void nl_handle_destroy(struct nl_handle *handle)
Destroy netlink handle.
void nl_close(struct nl_handle *handle)
Close/Disconnect netlink socket.
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate an empty cache.
struct nl_cache * nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name, change_func_t cb)
Add cache responsibility to cache manager.
int nl_cache_refill(struct nl_handle *handle, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
int nl_cache_mngr_poll(struct nl_cache_mngr *mngr, int timeout)
Check for event notifications.
@ NL_CB_VALID
Message is valid.
int nl_socket_drop_membership(struct nl_handle *handle, int group)
Leave a group.
void nl_cache_free(struct nl_cache *cache)
Free a cache.