+/* Sends 'request' to 'vconn' and blocks until it receives a reply with a
+ * matching transaction ID. Returns 0 if successful, in which case the reply
+ * is stored in '*replyp' for the caller to examine and free. Otherwise
+ * returns a positive errno value, or EOF, and sets '*replyp' to null.
+ *
+ * 'request' is always destroyed, regardless of the return value. */
+int
+vconn_transact(struct vconn *vconn, struct ofpbuf *request,
+ struct ofpbuf **replyp)
+{
+ uint32_t send_xid = ((struct ofp_header *) request->data)->xid;
+ int error;
+
+ *replyp = NULL;
+ error = vconn_send_block(vconn, request);
+ if (error) {
+ ofpbuf_delete(request);
+ }
+ return error ? error : vconn_recv_xid(vconn, send_xid, replyp);
+}
+