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);