Send openssl output to logfile on "ofp-pki self-sign" also.
[sliver-openvswitch.git] / utilities / dpctl.c
index 23b9db4..0065cf7 100644 (file)
 #ifdef HAVE_NETLINK
 #include "netdev.h"
 #include "netlink.h"
-#include "openflow-netlink.h"
+#include "openflow/openflow-netlink.h"
 #endif
 
 #include "command-line.h"
 #include "compiler.h"
 #include "dpif.h"
-#include "nicira-ext.h"
+#include "openflow/nicira-ext.h"
 #include "ofp-print.h"
 #include "ofpbuf.h"
-#include "openflow.h"
+#include "openflow/openflow.h"
 #include "packets.h"
 #include "random.h"
 #include "socket-util.h"
@@ -1286,6 +1286,71 @@ do_benchmark(const struct settings *s, int argc, char *argv[])
            count * message_size / (duration / 1000.0));
 }
 
+static void
+do_execute(const struct settings *s, int argc, char *argv[])
+{
+    struct vconn *vconn;
+    struct ofpbuf *request;
+    struct nicira_header *nicira;
+    struct nx_command_reply *ncr;
+    uint32_t xid;
+    int i;
+
+    nicira = make_openflow(sizeof *nicira, OFPT_VENDOR, &request);
+    xid = nicira->header.xid;
+    nicira->vendor = htonl(NX_VENDOR_ID);
+    nicira->subtype = htonl(NXT_COMMAND_REQUEST);
+    ofpbuf_put(request, argv[2], strlen(argv[2]));
+    for (i = 3; i < argc; i++) {
+        ofpbuf_put_zeros(request, 1);
+        ofpbuf_put(request, argv[i], strlen(argv[i]));
+    }
+    update_openflow_length(request);
+
+    open_vconn(argv[1], &vconn);
+    run(vconn_send_block(vconn, request), "send");
+
+    for (;;) {
+        struct ofpbuf *reply;
+        uint32_t status;
+
+        run(vconn_recv_xid(vconn, xid, &reply), "recv_xid");
+        if (reply->size < sizeof *ncr) {
+            ofp_fatal(0, "reply is too short (%zu bytes < %zu bytes)",
+                      reply->size, sizeof *ncr);
+        }
+        ncr = reply->data;
+        if (ncr->nxh.header.type != OFPT_VENDOR
+            || ncr->nxh.vendor != htonl(NX_VENDOR_ID)
+            || ncr->nxh.subtype != htonl(NXT_COMMAND_REPLY)) {
+            ofp_fatal(0, "reply is invalid");
+        }
+
+        status = ntohl(ncr->status);
+        if (status & NXT_STATUS_STARTED) {
+            /* Wait for a second reply. */
+            continue;
+        } else if (status & NXT_STATUS_EXITED) {
+            fprintf(stderr, "process terminated normally with exit code %d",
+                    status & NXT_STATUS_EXITSTATUS);
+        } else if (status & NXT_STATUS_SIGNALED) {
+            fprintf(stderr, "process terminated by signal %d",
+                    status & NXT_STATUS_TERMSIG);
+        } else if (status & NXT_STATUS_ERROR) {
+            fprintf(stderr, "error executing command");
+        } else {
+            fprintf(stderr, "process terminated for unknown reason");
+        }
+        if (status & NXT_STATUS_COREDUMP) {
+            fprintf(stderr, " (core dumped)");
+        }
+        putc('\n', stderr);
+
+        fwrite(ncr + 1, reply->size - sizeof *ncr, 1, stdout);
+        break;
+    }
+}
+
 static void do_help(const struct settings *s, int argc UNUSED, 
         char *argv[] UNUSED)
 {
@@ -1322,5 +1387,6 @@ static struct command all_commands[] = {
     { "probe", 1, 1, do_probe },
     { "ping", 1, 2, do_ping },
     { "benchmark", 3, 3, do_benchmark },
+    { "execute", 2, INT_MAX, do_execute },
     { NULL, 0, 0, NULL },
 };