X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=utilities%2Fovs-ofctl.c;fp=utilities%2Fovs-ofctl.c;h=2447ba285cd53deb466da83ed37263edfc0bbeed;hb=a4af00400a835eb87569ba40e21874c05e872c0f;hp=199bd43ec07061adac2934c99594857975c8e69d;hpb=5819a7cdcf44f0277c538353672fb27701c764f9;p=sliver-openvswitch.git diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 199bd43ec..2447ba285 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -44,9 +44,9 @@ #include "packets.h" #include "random.h" #include "socket-util.h" +#include "stream-ssl.h" #include "timeval.h" #include "util.h" -#include "vconn-ssl.h" #include "vconn.h" #include "vlog.h" @@ -59,68 +59,28 @@ #define MOD_PORT_CMD_FLOOD "flood" #define MOD_PORT_CMD_NOFLOOD "noflood" +/* Use strict matching for flow mod commands? */ +static bool strict; -/* Settings that may be configured by the user. */ -struct settings { - bool strict; /* Use strict matching for flow mod commands */ -}; - -struct command { - const char *name; - int min_args; - int max_args; - void (*handler)(const struct settings *, int argc, char *argv[]); -}; - -static struct command all_commands[]; +static const struct command all_commands[]; static void usage(void) NO_RETURN; -static void parse_options(int argc, char *argv[], struct settings *); +static void parse_options(int argc, char *argv[]); -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { - struct settings s; - struct command *p; - set_program_name(argv[0]); time_init(); vlog_init(); - parse_options(argc, argv, &s); + parse_options(argc, argv); signal(SIGPIPE, SIG_IGN); - - argc -= optind; - argv += optind; - if (argc < 1) - ovs_fatal(0, "missing command name; use --help for help"); - - for (p = all_commands; p->name != NULL; p++) { - if (!strcmp(p->name, argv[0])) { - int n_arg = argc - 1; - if (n_arg < p->min_args) - ovs_fatal(0, "'%s' command requires at least %d arguments", - p->name, p->min_args); - else if (n_arg > p->max_args) - ovs_fatal(0, "'%s' command takes at most %d arguments", - p->name, p->max_args); - else { - p->handler(&s, argc, argv); - if (ferror(stdout)) { - ovs_fatal(0, "write to stdout failed"); - } - if (ferror(stderr)) { - ovs_fatal(0, "write to stderr failed"); - } - exit(0); - } - } - } - ovs_fatal(0, "unknown command '%s'; use --help for help", argv[0]); - + run_command(argc - optind, argv + optind, all_commands); return 0; } static void -parse_options(int argc, char *argv[], struct settings *s) +parse_options(int argc, char *argv[]) { enum { OPT_STRICT = UCHAR_MAX + 1, @@ -132,14 +92,11 @@ parse_options(int argc, char *argv[], struct settings *s) {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, VLOG_LONG_OPTIONS, - VCONN_SSL_LONG_OPTIONS + STREAM_SSL_LONG_OPTIONS {0, 0, 0, 0}, }; char *short_options = long_options_to_short_options(long_options); - /* Set defaults that we can figure out before parsing options. */ - s->strict = false; - for (;;) { unsigned long int timeout; int c; @@ -168,11 +125,11 @@ parse_options(int argc, char *argv[], struct settings *s) exit(EXIT_SUCCESS); case OPT_STRICT: - s->strict = true; + strict = true; break; VLOG_OPTION_HANDLERS - VCONN_SSL_OPTION_HANDLERS + STREAM_SSL_OPTION_HANDLERS case '?': exit(EXIT_FAILURE); @@ -205,7 +162,6 @@ usage(void) " mod-flows SWITCH FLOW modify actions of matching FLOWs\n" " del-flows SWITCH [FLOW] delete matching FLOWs\n" " monitor SWITCH MISSLEN EXP print packets received from SWITCH\n" - " execute SWITCH CMD [ARG...] execute CMD with ARGS on SWITCH\n" "\nFor OpenFlow switches and controllers:\n" " probe VCONN probe whether VCONN is up\n" " ping VCONN [N] latency of N-byte echos\n" @@ -246,25 +202,36 @@ static void run(int retval, const char *message, ...) /* Generic commands. */ +static void +open_vconn_socket(const char *name, struct vconn **vconnp) +{ + char *vconn_name = xasprintf("unix:%s", name); + VLOG_INFO("connecting to %s", vconn_name); + run(vconn_open_block(vconn_name, OFP_VERSION, vconnp), + "connecting to %s", vconn_name); + free(vconn_name); +} + static void open_vconn(const char *name, struct vconn **vconnp) { struct dpif *dpif; struct stat s; + char *bridge_path, *datapath_name, *datapath_type; + + bridge_path = xasprintf("%s/%s.mgmt", ovs_rundir, name); + dp_parse_name(name, &datapath_name, &datapath_type); if (strstr(name, ":")) { run(vconn_open_block(name, OFP_VERSION, vconnp), "connecting to %s", name); } else if (!stat(name, &s) && S_ISSOCK(s.st_mode)) { - char *vconn_name = xasprintf("unix:%s", name); - VLOG_INFO("connecting to %s", vconn_name); - run(vconn_open_block(vconn_name, OFP_VERSION, vconnp), - "connecting to %s", vconn_name); - free(vconn_name); - } else if (!dpif_open(name, &dpif)) { + open_vconn_socket(name, vconnp); + } else if (!stat(bridge_path, &s) && S_ISSOCK(s.st_mode)) { + open_vconn_socket(bridge_path, vconnp); + } else if (!dpif_open(datapath_name, datapath_type, &dpif)) { char dpif_name[IF_NAMESIZE + 1]; char *socket_name; - char *vconn_name; run(dpif_port_get_name(dpif, ODPP_LOCAL, dpif_name, sizeof dpif_name), "obtaining name of %s", dpif_name); @@ -282,15 +249,15 @@ open_vconn(const char *name, struct vconn **vconnp) name, socket_name); } - vconn_name = xasprintf("unix:%s", socket_name); - VLOG_INFO("connecting to %s", vconn_name); - run(vconn_open_block(vconn_name, OFP_VERSION, vconnp), - "connecting to %s", vconn_name); + open_vconn_socket(socket_name, vconnp); free(socket_name); - free(vconn_name); } else { ovs_fatal(0, "%s is not a valid connection method", name); } + + free(datapath_name); + free(datapath_type); + free(bridge_path); } static void * @@ -372,14 +339,14 @@ dump_trivial_stats_transaction(const char *vconn_name, uint8_t stats_type) } static void -do_show(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_show(int argc UNUSED, char *argv[]) { dump_trivial_transaction(argv[1], OFPT_FEATURES_REQUEST); dump_trivial_transaction(argv[1], OFPT_GET_CONFIG_REQUEST); } static void -do_status(const struct settings *s UNUSED, int argc, char *argv[]) +do_status(int argc, char *argv[]) { struct nicira_header *request, *reply; struct vconn *vconn; @@ -411,13 +378,13 @@ do_status(const struct settings *s UNUSED, int argc, char *argv[]) } static void -do_dump_desc(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_dump_desc(int argc UNUSED, char *argv[]) { dump_trivial_stats_transaction(argv[1], OFPST_DESC); } static void -do_dump_tables(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_dump_tables(int argc UNUSED, char *argv[]) { dump_trivial_stats_transaction(argv[1], OFPST_TABLE); } @@ -813,7 +780,7 @@ str_to_flow(char *string, struct ofp_match *match, struct ofpbuf *actions, } static void -do_dump_flows(const struct settings *s UNUSED, int argc, char *argv[]) +do_dump_flows(int argc, char *argv[]) { struct ofp_flow_stats_request *req; uint16_t out_port; @@ -829,7 +796,7 @@ do_dump_flows(const struct settings *s UNUSED, int argc, char *argv[]) } static void -do_dump_aggregate(const struct settings *s UNUSED, int argc, char *argv[]) +do_dump_aggregate(int argc, char *argv[]) { struct ofp_aggregate_stats_request *req; struct ofpbuf *request; @@ -845,7 +812,7 @@ do_dump_aggregate(const struct settings *s UNUSED, int argc, char *argv[]) } static void -do_add_flow(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_add_flow(int argc UNUSED, char *argv[]) { struct vconn *vconn; struct ofpbuf *buffer; @@ -873,7 +840,7 @@ do_add_flow(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) } static void -do_add_flows(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_add_flows(int argc UNUSED, char *argv[]) { struct vconn *vconn; FILE *file; @@ -926,7 +893,7 @@ do_add_flows(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) } static void -do_mod_flows(const struct settings *s, int argc UNUSED, char *argv[]) +do_mod_flows(int argc UNUSED, char *argv[]) { uint16_t priority, idle_timeout, hard_timeout; struct vconn *vconn; @@ -941,7 +908,7 @@ do_mod_flows(const struct settings *s, int argc UNUSED, char *argv[]) NULL, NULL, &priority, &idle_timeout, &hard_timeout); ofm = buffer->data; ofm->match = match; - if (s->strict) { + if (strict) { ofm->command = htons(OFPFC_MODIFY_STRICT); } else { ofm->command = htons(OFPFC_MODIFY); @@ -957,7 +924,7 @@ do_mod_flows(const struct settings *s, int argc UNUSED, char *argv[]) vconn_close(vconn); } -static void do_del_flows(const struct settings *s, int argc, char *argv[]) +static void do_del_flows(int argc, char *argv[]) { struct vconn *vconn; uint16_t priority; @@ -969,7 +936,7 @@ static void do_del_flows(const struct settings *s, int argc, char *argv[]) ofm = make_openflow(sizeof *ofm, OFPT_FLOW_MOD, &buffer); str_to_flow(argc > 2 ? argv[2] : "", &ofm->match, NULL, NULL, &out_port, &priority, NULL, NULL); - if (s->strict) { + if (strict) { ofm->command = htons(OFPFC_DELETE_STRICT); } else { ofm->command = htons(OFPFC_DELETE); @@ -987,7 +954,7 @@ static void do_del_flows(const struct settings *s, int argc, char *argv[]) } static void -do_monitor(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_monitor(int argc UNUSED, char *argv[]) { struct vconn *vconn; @@ -1012,13 +979,13 @@ do_monitor(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) } static void -do_dump_ports(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_dump_ports(int argc UNUSED, char *argv[]) { dump_trivial_stats_transaction(argv[1], OFPST_PORT); } static void -do_probe(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_probe(int argc UNUSED, char *argv[]) { struct ofpbuf *request; struct vconn *vconn; @@ -1035,7 +1002,7 @@ do_probe(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) } static void -do_mod_port(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_mod_port(int argc UNUSED, char *argv[]) { struct ofpbuf *request, *reply; struct ofp_switch_features *osf; @@ -1115,7 +1082,7 @@ do_mod_port(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) } static void -do_ping(const struct settings *s UNUSED, int argc, char *argv[]) +do_ping(int argc, char *argv[]) { size_t max_payload = 65535 - sizeof(struct ofp_header); unsigned int payload; @@ -1162,7 +1129,7 @@ do_ping(const struct settings *s UNUSED, int argc, char *argv[]) } static void -do_benchmark(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) +do_benchmark(int argc UNUSED, char *argv[]) { size_t max_payload = 65535 - sizeof(struct ofp_header); struct timeval start, end; @@ -1205,77 +1172,12 @@ do_benchmark(const struct settings *s UNUSED, int argc UNUSED, char *argv[]) } static void -do_execute(const struct settings *s UNUSED, 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) { - ovs_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)) { - ovs_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 UNUSED, int argc UNUSED, char *argv[] UNUSED) +do_help(int argc UNUSED, char *argv[] UNUSED) { usage(); } -static struct command all_commands[] = { +static const struct command all_commands[] = { { "show", 1, 1, do_show }, { "status", 1, 2, do_status }, { "monitor", 1, 3, do_monitor }, @@ -1292,7 +1194,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 }, { "help", 0, INT_MAX, do_help }, { NULL, 0, 0, NULL }, };