X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=utilities%2Fdpctl.c;h=0065cf712f19ba9e1882084395c41f505a1091ad;hb=ca7265a956ff004ee6bade2a2b58d219217c9ef0;hp=23b9db4f9868686eba9b2a640c2a33252b0fecc5;hpb=b6eb6bc746ebeee6027929e142f00b72fef57656;p=sliver-openvswitch.git diff --git a/utilities/dpctl.c b/utilities/dpctl.c index 23b9db4f9..0065cf712 100644 --- a/utilities/dpctl.c +++ b/utilities/dpctl.c @@ -47,16 +47,16 @@ #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 }, };