X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=utilities%2Fovs-ofctl.c;h=35a2ca749aac3c3ee91c2843402e5e8ae6e4269b;hb=7aaeab4df24b7e9460705b1dad1010eef0354c50;hp=6453167218528fd364af22ee7514c6a63a228a78;hpb=bdda5aca7b376bcc8c88072d00011a9da04af65c;p=sliver-openvswitch.git diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 645316721..35a2ca749 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -98,7 +98,7 @@ struct sort_criterion { static struct sort_criterion *criteria; static size_t n_criteria, allocated_criteria; -static const struct command all_commands[]; +static const struct command *get_all_commands(void); static void usage(void) NO_RETURN; static void parse_options(int argc, char *argv[]); @@ -113,7 +113,7 @@ main(int argc, char *argv[]) set_program_name(argv[0]); parse_options(argc, argv); signal(SIGPIPE, SIG_IGN); - run_command(argc - optind, argv + optind, all_commands); + run_command(argc - optind, argv + optind, get_all_commands()); return 0; } @@ -305,7 +305,9 @@ usage(void) " probe TARGET probe whether TARGET is up\n" " ping TARGET [N] latency of N-byte echos\n" " benchmark TARGET N COUNT bandwidth of COUNT N-byte echos\n" - "where SWITCH or TARGET is an active OpenFlow connection method.\n", + "SWITCH or TARGET is an active OpenFlow connection method.\n" + "\nOther commands:\n" + " ofp-parse FILE print messages read from FILE\n", program_name, program_name); vconn_usage(true, false, false); daemon_usage(); @@ -1696,6 +1698,56 @@ ofctl_set_frags(int argc OVS_UNUSED, char *argv[]) vconn_close(vconn); } +static void +ofctl_ofp_parse(int argc OVS_UNUSED, char *argv[]) +{ + const char *filename = argv[1]; + struct ofpbuf b; + FILE *file; + + file = !strcmp(filename, "-") ? stdin : fopen(filename, "r"); + if (file == NULL) { + ovs_fatal(errno, "%s: open", filename); + } + + ofpbuf_init(&b, 65536); + for (;;) { + struct ofp_header *oh; + size_t length, tail_len; + void *tail; + size_t n; + + ofpbuf_clear(&b); + oh = ofpbuf_put_uninit(&b, sizeof *oh); + n = fread(oh, 1, sizeof *oh, file); + if (n == 0) { + break; + } else if (n < sizeof *oh) { + ovs_fatal(0, "%s: unexpected end of file mid-message", filename); + } + + length = ntohs(oh->length); + if (length < sizeof *oh) { + ovs_fatal(0, "%s: %zu-byte message is too short for OpenFlow", + filename, length); + } + + tail_len = length - sizeof *oh; + tail = ofpbuf_put_uninit(&b, tail_len); + n = fread(tail, 1, tail_len, file); + if (n < tail_len) { + ovs_fatal(0, "%s: unexpected end of file mid-message", filename); + } + + ofp_print(stdout, b.data, b.size, verbosity + 2); + } + ofpbuf_uninit(&b); + + if (file != stdin) { + fclose(file); + } +} + static void ofctl_ping(int argc, char *argv[]) { @@ -2079,6 +2131,7 @@ fte_make_flow_mod(const struct fte *fte, int index, uint16_t command, fm.cookie = htonll(0); fm.cookie_mask = htonll(0); fm.new_cookie = version->cookie; + fm.modify_cookie = true; fm.table_id = 0xff; fm.command = command; fm.idle_timeout = version->idle_timeout; @@ -2334,7 +2387,7 @@ ofctl_parse_nxm__(bool oxm) ofpbuf_init(&nx_match, 0); if (oxm) { match_len = oxm_put_match(&nx_match, &match); - out = oxm_match_to_string(nx_match.data, match_len); + out = oxm_match_to_string(&nx_match, match_len); } else { match_len = nx_put_match(&nx_match, &match, cookie, cookie_mask); @@ -2774,7 +2827,7 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[]) /* Convert to and from OXM. */ ofpbuf_init(&nxm, 0); nxm_match_len = oxm_put_match(&nxm, &match); - nxm_s = oxm_match_to_string(nxm.data, nxm_match_len); + nxm_s = oxm_match_to_string(&nxm, nxm_match_len); error = oxm_pull_match(&nxm, &nxm_match); printf("OXM: %s -> ", nxm_s); if (error) { @@ -2931,6 +2984,7 @@ static const struct command all_commands[] = { { "mod-port", 3, 3, ofctl_mod_port }, { "get-frags", 1, 1, ofctl_get_frags }, { "set-frags", 2, 2, ofctl_set_frags }, + { "ofp-parse", 1, 1, ofctl_ofp_parse }, { "probe", 1, 1, ofctl_probe }, { "ping", 1, 2, ofctl_ping }, { "benchmark", 3, 3, ofctl_benchmark }, @@ -2955,3 +3009,8 @@ static const struct command all_commands[] = { { NULL, 0, 0, NULL }, }; + +static const struct command *get_all_commands(void) +{ + return all_commands; +}