84 #include <netlink-local.h>
85 #include <netlink/netlink.h>
86 #include <netlink/cache.h>
87 #include <netlink/utils.h>
91 struct nl_cache_assoc *ca = p->pp_arg;
93 NL_DBG(2,
"Including object %p into cache %p\n", obj, ca->ca_cache);
98 return nl_cache_include(ca->ca_cache, obj, ca->ca_change);
101 static int event_input(
struct nl_msg *msg,
void *arg)
103 struct nl_cache_mngr *mngr = arg;
104 int protocol = nlmsg_get_proto(msg);
112 NL_DBG(2,
"Cache manager %p, handling new message %p as event\n",
119 if (mngr->cm_protocol != protocol)
122 for (i = 0; i < mngr->cm_nassocs; i++) {
123 if (mngr->cm_assocs[i].ca_cache) {
124 ops = mngr->cm_assocs[i].ca_cache->c_ops;
125 for (n = 0; ops->co_msgtypes[n].
mt_id >= 0; n++)
126 if (ops->co_msgtypes[n].
mt_id == type)
134 NL_DBG(2,
"Associated message %p to cache %p\n",
135 msg, mngr->cm_assocs[i].ca_cache);
136 p.pp_arg = &mngr->cm_assocs[i];
138 return nl_cache_parse(ops, NULL,
nlmsg_hdr(msg), &p);
150 int protocol,
int flags)
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);
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++)
307 return nl_socket_get_fd(mngr->cm_handle);
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);
378 if (mngr->cm_handle) {
383 free(mngr->cm_assocs);
386 NL_DBG(1,
"Cache manager %p freed\n", mngr);
void nl_cache_mngt_provide(struct nl_cache *cache)
Provide a cache for global use.
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.
uint16_t nlmsg_type
Message type (content type)
void nl_disable_sequence_check(struct nl_handle *handle)
Disable sequence number checking.
int nl_cache_mngr_get_fd(struct nl_cache_mngr *mngr)
Get file descriptor.
void nl_handle_destroy(struct nl_handle *handle)
Destroy netlink handle.
Customized handler specified by the user.
int nl_recvmsgs_default(struct nl_handle *handle)
Receive a set of message from a netlink socket using handlers in nl_handle.
int nl_cache_mngr_poll(struct nl_cache_mngr *mngr, int timeout)
Check for event notifications.
int nl_socket_set_nonblocking(struct nl_handle *handle)
Set file descriptor of socket handle to non-blocking state.
struct nl_cache_ops * nl_cache_ops_lookup(const char *name)
Lookup the set cache operations of a certain cache type.
void nl_cache_free(struct nl_cache *cache)
Free a cache.
int nl_cache_refill(struct nl_handle *handle, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
void nl_object_dump(struct nl_object *obj, struct nl_dump_params *params)
Dump this object according to the specified parameters.
void nl_msg_dump(struct nl_msg *msg, FILE *ofd)
Dump message in human readable format to file descriptor.
struct nlmsghdr * nlmsg_hdr(struct nl_msg *n)
Return actual netlink message.
int ag_group
Netlink group identifier.
int nl_connect(struct nl_handle *handle, int protocol)
Create and connect netlink socket.
int nl_cache_mngr_data_ready(struct nl_cache_mngr *mngr)
Receive available event notifications.
struct nl_cache_mngr * nl_cache_mngr_alloc(struct nl_handle *handle, int protocol, int flags)
Allocate new cache manager.
int nl_socket_drop_membership(struct nl_handle *handle, int group)
Leave a group.
int mt_id
Netlink message type.
void nl_cache_mngr_free(struct nl_cache_mngr *mngr)
Free cache manager.
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_close(struct nl_handle *handle)
Close/Disconnect netlink socket.
Address family to netlink group association.
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate an empty cache.