35 #include <netlink-local.h>
36 #include <netlink/netlink.h>
37 #include <netlink/cache.h>
38 #include <netlink/utils.h>
41 #define NASSOC_INIT 16
42 #define NASSOC_EXPAND 8
47 struct nl_cache_assoc *ca = p->
pp_arg;
50 NL_DBG(2,
"Including object %p into cache %p\n", obj, ca->ca_cache);
64 return nl_cache_include(ca->ca_cache, obj, ca->ca_change, ca->ca_change_data);
67 static int event_input(
struct nl_msg *msg,
void *arg)
69 struct nl_cache_mngr *mngr = arg;
70 int protocol = nlmsg_get_proto(msg);
78 NL_DBG(2,
"Cache manager %p, handling new message %p as event\n",
85 if (mngr->cm_protocol != protocol)
88 for (i = 0; i < mngr->cm_nassocs; i++) {
89 if (mngr->cm_assocs[i].ca_cache) {
90 ops = mngr->cm_assocs[i].ca_cache->c_ops;
91 for (n = 0; ops->co_msgtypes[n].
mt_id >= 0; n++)
92 if (ops->co_msgtypes[n].
mt_id == type)
100 NL_DBG(2,
"Associated message %p to cache %p\n",
101 msg, mngr->cm_assocs[i].ca_cache);
102 p.
pp_arg = &mngr->cm_assocs[i];
104 return nl_cache_parse(ops, NULL,
nlmsg_hdr(msg), &p);
136 struct nl_cache_mngr **result)
138 struct nl_cache_mngr *mngr;
139 int err = -NLE_NOMEM;
142 if (flags & NL_ALLOCATED_SOCK)
145 mngr = calloc(1,
sizeof(*mngr));
153 flags |= NL_ALLOCATED_SOCK;
157 mngr->cm_nassocs = NASSOC_INIT;
158 mngr->cm_protocol = protocol;
159 mngr->cm_flags = flags;
160 mngr->cm_assocs = calloc(mngr->cm_nassocs,
161 sizeof(
struct nl_cache_assoc));
162 if (!mngr->cm_assocs)
168 if ((err =
nl_connect(mngr->cm_sock, protocol) < 0))
174 NL_DBG(1,
"Allocated cache manager %p, protocol %d, %d caches\n",
175 mngr, protocol, mngr->cm_nassocs);
214 change_func_t cb,
void *data,
struct nl_cache **result)
217 struct nl_cache *cache;
226 return -NLE_PROTO_MISMATCH;
229 return -NLE_OPNOTSUPP;
231 for (i = 0; i < mngr->cm_nassocs; i++)
232 if (mngr->cm_assocs[i].ca_cache &&
233 mngr->cm_assocs[i].ca_cache->c_ops == ops)
237 for (i = 0; i < mngr->cm_nassocs; i++)
238 if (!mngr->cm_assocs[i].ca_cache)
241 if (i >= mngr->cm_nassocs) {
242 mngr->cm_nassocs += NASSOC_EXPAND;
243 mngr->cm_assocs = realloc(mngr->cm_assocs,
245 sizeof(
struct nl_cache_assoc));
246 if (mngr->cm_assocs == NULL)
249 memset(mngr->cm_assocs + (mngr->cm_nassocs - NASSOC_EXPAND), 0,
250 NASSOC_EXPAND *
sizeof(
struct nl_cache_assoc));
252 NL_DBG(1,
"Increased capacity of cache manager %p " \
253 "to %d\n", mngr, mngr->cm_nassocs);
262 err = nl_socket_add_membership(mngr->cm_sock, grp->
ag_group);
264 goto errout_free_cache;
269 goto errout_drop_membership;
271 mngr->cm_assocs[i].ca_cache = cache;
272 mngr->cm_assocs[i].ca_change = cb;
273 mngr->cm_assocs[i].ca_change_data = data;
275 if (mngr->cm_flags & NL_AUTO_PROVIDE)
278 NL_DBG(1,
"Added cache %p <%s> to cache manager %p\n",
279 cache, nl_cache_name(cache), mngr);
285 errout_drop_membership:
287 nl_socket_drop_membership(mngr->cm_sock, grp->
ag_group);
305 return nl_socket_get_fd(mngr->cm_sock);
330 struct pollfd fds = {
331 .fd = nl_socket_get_fd(mngr->cm_sock),
335 NL_DBG(3,
"Cache manager %p, poll() fd %d\n", mngr, fds.fd);
336 ret = poll(&fds, 1, timeout);
337 NL_DBG(3,
"Cache manager %p, poll() returned %d\n", mngr, ret);
339 return -nl_syserr2nlerr(errno);
368 NL_DBG(2,
"Cache manager %p, reading new data from fd %d\n",
369 mngr, nl_socket_get_fd(mngr->cm_sock));
378 NL_DBG(2,
"Cache manager %p, recvmsgs read %d messages\n",
404 nl_dump_line(p,
"cache-manager <%p>\n", mngr);
405 nl_dump_line(p,
" .protocol = %s\n",
406 nl_nlfamily2str(mngr->cm_protocol, buf,
sizeof(buf)));
407 nl_dump_line(p,
" .flags = %#x\n", mngr->cm_flags);
408 nl_dump_line(p,
" .nassocs = %u\n", mngr->cm_nassocs);
409 nl_dump_line(p,
" .sock = <%p>\n", mngr->cm_sock);
411 for (i = 0; i < mngr->cm_nassocs; i++) {
412 struct nl_cache_assoc *assoc = &mngr->cm_assocs[i];
414 if (assoc->ca_cache) {
415 nl_dump_line(p,
" .cache[%d] = <%p> {\n", i, assoc->ca_cache);
416 nl_dump_line(p,
" .name = %s\n", assoc->ca_cache->c_ops->co_name);
417 nl_dump_line(p,
" .change_func = <%p>\n", assoc->ca_change);
418 nl_dump_line(p,
" .change_data = <%p>\n", assoc->ca_change_data);
420 nl_dump_line(p,
" .objects = {\n");
426 nl_dump_line(p,
" }\n");
427 nl_dump_line(p,
" }\n");
448 if (mngr->cm_flags & NL_ALLOCATED_SOCK)
451 for (i = 0; i < mngr->cm_nassocs; i++) {
452 if (mngr->cm_assocs[i].ca_cache) {
458 free(mngr->cm_assocs);
461 NL_DBG(1,
"Cache manager %p freed\n", mngr);