summaryrefslogtreecommitdiffstats
path: root/lib/nl.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2011-04-11 10:34:01 (GMT)
committerThomas Graf <tgraf@suug.ch>2011-04-11 10:34:01 (GMT)
commit48d543cfdf49aef75b9898ebea379f2303d3935d (patch)
treeea0a9aa79176d18d5d94a4e28c7a5d55e6bafefe /lib/nl.c
parent41fb241b7bb88d10300145778e401ab34e3bf46b (diff)
downloadlibnl-48d543cfdf49aef75b9898ebea379f2303d3935d.zip
libnl-48d543cfdf49aef75b9898ebea379f2303d3935d.tar.gz
libnl-48d543cfdf49aef75b9898ebea379f2303d3935d.tar.bz2
API to issue direct GET requests to the kernel
Provide nl_pickup() to pick up an answer from a netlink request and parse it using the supplied parser. Add rtnl_link_get_kernel() which sends an RTM_GETLINK to the kernel to fetch a single link directly from the kernel. This can be faster than dumping the whole table, especially if lots of links are configured.
Diffstat (limited to 'lib/nl.c')
-rw-r--r--lib/nl.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/nl.c b/lib/nl.c
index b70242c..f5f94e3 100644
--- a/lib/nl.c
+++ b/lib/nl.c
@@ -799,6 +799,76 @@ int nl_wait_for_ack(struct nl_sock *sk)
return err;
}
+/** @cond SKIP */
+struct pickup_param
+{
+ int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
+ struct nlmsghdr *, struct nl_parser_param *);
+ struct nl_object *result;
+};
+
+static int __store_answer(struct nl_object *obj, struct nl_parser_param *p)
+{
+ struct pickup_param *pp = p->pp_arg;
+ /*
+ * the parser will put() the object at the end, expecting the cache
+ * to take the reference.
+ */
+ nl_object_get(obj);
+ pp->result = obj;
+
+ return 0;
+}
+
+static int __pickup_answer(struct nl_msg *msg, void *arg)
+{
+ struct pickup_param *pp = arg;
+ struct nl_parser_param parse_arg = {
+ .pp_cb = __store_answer,
+ .pp_arg = pp,
+ };
+
+ return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg);
+}
+
+/** @endcond */
+
+/**
+ * Pickup netlink answer, parse is and return object
+ * @arg sk Netlink socket
+ * @arg parser Parser function to parse answer
+ * @arg result Result pointer to return parsed object
+ *
+ * @return 0 on success or a negative error code.
+ */
+int nl_pickup(struct nl_sock *sk,
+ int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
+ struct nlmsghdr *, struct nl_parser_param *),
+ struct nl_object **result)
+{
+ struct nl_cb *cb;
+ int err;
+ struct pickup_param pp = {
+ .parser = parser,
+ };
+
+ cb = nl_cb_clone(sk->s_cb);
+ if (cb == NULL)
+ return -NLE_NOMEM;
+
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, __pickup_answer, &pp);
+
+ err = nl_recvmsgs(sk, cb);
+ if (err < 0)
+ goto errout;
+
+ *result = pp.result;
+errout:
+ nl_cb_put(cb);
+
+ return err;
+}
+
/** @} */
/** @} */