[ovs-dev] [PreQoS 12/13] netlink: Add function for dumping a table.
Ben Pfaff
blp at nicira.com
Thu May 27 20:33:11 UTC 2010
---
lib/netlink.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/netlink.h | 2 +
2 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/lib/netlink.c b/lib/netlink.c
index 193b23e..eee9239 100644
--- a/lib/netlink.c
+++ b/lib/netlink.c
@@ -445,6 +445,66 @@ recv:
return 0;
}
+/* Sends 'request' to the kernel via 'sock' and waits for a series of replies.
+ * Passes each reply in turn to 'reply_cb'. If successful, returns 0. On
+ * failure, returns a positive errno value.
+ *
+ * nlmsg_len in 'msg' will be finalized to match msg->size, and nlmsg_pid will
+ * be set to 'sock''s pid, before the message is sent. NLM_F_DUMP and
+ * NLM_F_ACK will be set in nlmsg_flags.
+ *
+ * The caller is responsible for destroying 'request'.
+ *
+ * Netlink "dump" replies are reliable.
+ */
+int
+nl_sock_dump(struct nl_sock *sock, const struct ofpbuf *request,
+ void (*reply_cb)(struct ofpbuf *, void *aux), void *aux)
+{
+ uint32_t seq = nl_msg_nlmsghdr(request)->nlmsg_seq;
+ struct nlmsghdr *nlmsghdr;
+ struct ofpbuf *reply;
+ int retval;
+
+ /* These semantics only make sense for "dump" requests. */
+ nl_msg_nlmsghdr(request)->nlmsg_flags |= NLM_F_DUMP | NLM_F_ACK;
+
+ retval = nl_sock_send(sock, request, true);
+ if (retval) {
+ return retval;
+ }
+
+ for (;;) {
+ retval = nl_sock_recv(sock, &reply, true);
+ if (retval) {
+ if (retval == EINTR) {
+ continue;
+ }
+ return retval;
+ }
+
+ nlmsghdr = nl_msg_nlmsghdr(reply);
+ if (seq != nlmsghdr->nlmsg_seq) {
+ VLOG_DBG_RL(&rl, "ignoring seq %"PRIu32" != expected %"PRIu32,
+ nl_msg_nlmsghdr(reply)->nlmsg_seq, seq);
+ ofpbuf_delete(reply);
+ continue;
+ }
+
+ /* If the reply is an error, return the error code. */
+ if (nl_msg_nlmsgerr(reply, &retval)) {
+ ofpbuf_delete(reply);
+ VLOG_DBG_RL(&rl, "netlink dump request failed (error %s)",
+ strerror(retval));
+ return retval && retval != EAGAIN ? retval : EPROTO;
+ }
+
+ reply_cb(reply, aux);
+ ofpbuf_delete(reply);
+ }
+}
+
+
/* Causes poll_block() to wake up when any of the specified 'events' (which is
* a OR'd combination of POLLIN, POLLOUT, etc.) occur on 'sock'. */
void
diff --git a/lib/netlink.h b/lib/netlink.h
index dba7f02..bc3f7b0 100644
--- a/lib/netlink.h
+++ b/lib/netlink.h
@@ -47,6 +47,8 @@ int nl_sock_sendv(struct nl_sock *sock, const struct iovec iov[], size_t n_iov,
int nl_sock_recv(struct nl_sock *, struct ofpbuf **, bool wait);
int nl_sock_transact(struct nl_sock *, const struct ofpbuf *request,
struct ofpbuf **reply);
+int nl_sock_dump(struct nl_sock *, const struct ofpbuf *request,
+ void (*reply_cb)(struct ofpbuf *, void *aux), void *aux);
void nl_sock_wait(const struct nl_sock *, short int events);
--
1.7.1
More information about the dev
mailing list