[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