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;
94 NL_DBG(2,
"Including object %p into cache %p\n", obj, ca->ca_cache);
104 return nl_cache_include(ca->ca_cache, obj, ca->ca_change, ca->ca_change_data);
107 static int event_input(
struct nl_msg *msg,
void *arg)
109 struct nl_cache_mngr *mngr = arg;
110 int protocol = nlmsg_get_proto(msg);
118 NL_DBG(2,
"Cache manager %p, handling new message %p as event\n",
125 if (mngr->cm_protocol != protocol)
128 for (i = 0; i < mngr->cm_nassocs; i++) {
129 if (mngr->cm_assocs[i].ca_cache) {
130 ops = mngr->cm_assocs[i].ca_cache->c_ops;
131 for (n = 0; ops->co_msgtypes[n].
mt_id >= 0; n++)
132 if (ops->co_msgtypes[n].
mt_id == type)
140 NL_DBG(2,
"Associated message %p to cache %p\n",
141 msg, mngr->cm_assocs[i].ca_cache);
142 p.
pp_arg = &mngr->cm_assocs[i];
144 return nl_cache_parse(ops, NULL,
nlmsg_hdr(msg), &p);
157 struct nl_cache_mngr **result)
159 struct nl_cache_mngr *mngr;
160 int err = -NLE_NOMEM;
165 mngr = calloc(1,
sizeof(*mngr));
169 mngr->cm_handle = sk;
170 mngr->cm_nassocs = 32;
171 mngr->cm_protocol = protocol;
172 mngr->cm_flags = flags;
173 mngr->cm_assocs = calloc(mngr->cm_nassocs,
174 sizeof(
struct nl_cache_assoc));
175 if (!mngr->cm_assocs)
184 if ((err =
nl_connect(mngr->cm_handle, protocol) < 0))
190 NL_DBG(1,
"Allocated cache manager %p, protocol %d, %d caches\n",
191 mngr, protocol, mngr->cm_nassocs);
218 change_func_t cb,
void *data,
struct nl_cache **result)
221 struct nl_cache *cache;
230 return -NLE_PROTO_MISMATCH;
233 return -NLE_OPNOTSUPP;
235 for (i = 0; i < mngr->cm_nassocs; i++)
236 if (mngr->cm_assocs[i].ca_cache &&
237 mngr->cm_assocs[i].ca_cache->c_ops == ops)
241 for (i = 0; i < mngr->cm_nassocs; i++)
242 if (!mngr->cm_assocs[i].ca_cache)
245 if (i >= mngr->cm_nassocs) {
246 mngr->cm_nassocs += 16;
247 mngr->cm_assocs = realloc(mngr->cm_assocs,
249 sizeof(
struct nl_cache_assoc));
250 if (mngr->cm_assocs == NULL)
253 NL_DBG(1,
"Increased capacity of cache manager %p " \
254 "to %d\n", mngr, mngr->cm_nassocs);
264 err = nl_socket_add_membership(mngr->cm_handle, grp->
ag_group);
266 goto errout_free_cache;
271 goto errout_drop_membership;
273 mngr->cm_assocs[i].ca_cache = cache;
274 mngr->cm_assocs[i].ca_change = cb;
275 mngr->cm_assocs[i].ca_change_data = data;
277 if (mngr->cm_flags & NL_AUTO_PROVIDE)
280 NL_DBG(1,
"Added cache %p <%s> to cache manager %p\n",
281 cache, nl_cache_name(cache), mngr);
286 errout_drop_membership:
288 nl_socket_drop_membership(mngr->cm_handle, grp->
ag_group);
305 return nl_socket_get_fd(mngr->cm_handle);
326 struct pollfd fds = {
327 .fd = nl_socket_get_fd(mngr->cm_handle),
331 NL_DBG(3,
"Cache manager %p, poll() fd %d\n", mngr, fds.fd);
332 ret = poll(&fds, 1, timeout);
333 NL_DBG(3,
"Cache manager %p, poll() returned %d\n", mngr, ret);
335 return -nl_syserr2nlerr(errno);
381 for (i = 0; i < mngr->cm_nassocs; i++) {
382 if (mngr->cm_assocs[i].ca_cache) {
388 free(mngr->cm_assocs);
391 NL_DBG(1,
"Cache manager %p freed\n", mngr);