From: Ben Pfaff Date: Tue, 6 Aug 2013 16:45:07 +0000 (-0700) Subject: ovs-ofctl: Add "ofp-parse" command for printing OpenFlow from a file. X-Git-Tag: sliver-openvswitch-2.0.90-1~33^2~17 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=1ac0e975a2d9d37a31915d1c96007eacdfe47442;p=sliver-openvswitch.git ovs-ofctl: Add "ofp-parse" command for printing OpenFlow from a file. Test provided by Alex Wang . Signed-off-by: Ben Pfaff --- diff --git a/NEWS b/NEWS index 6f5d13a08..f9953ab36 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,8 @@ v1.12.0 - xx xxx xxxx should look like "--private-key=db:Open_vSwitch,SSL,private_key"). - Added ovs-dev.py, a utility script helpful for Open vSwitch developers. - Support for Linux kernels up to 3.9 + - ovs-ofctl: + * New "ofp-parse" for printing OpenFlow messages read from a file. v1.11.0 - xx xxx xxxx diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index 8133f75ed..18f915243 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -2272,3 +2272,21 @@ AT_CHECK([ovs-ofctl -F oxm -O openflow13], [1], [], [ovs-ofctl: missing command name; use --help for help ]) AT_CLEANUP + +AT_SETUP([ovs-ofctl ofp-parse]) +# Test the echo request/reply messages (0 payload). +AT_CHECK([printf '\1\2\0\10\0\0\0\0\1\3\0\10\0\0\0\0' > binary_ofp_msg]) +AT_CHECK([ovs-ofctl ofp-parse binary_ofp_msg], [0], [dnl +OFPT_ECHO_REQUEST (xid=0x0): 0 bytes of payload +OFPT_ECHO_REPLY (xid=0x0): 0 bytes of payload +]) + +# Test the hello (xid:1 3-byte payload). +AT_CHECK([printf '\1\0\0\13\0\0\0\1\101\102\103' > binary_ofp_msg]) +AT_CHECK([ovs-ofctl ofp-parse - < binary_ofp_msg], [0], [dnl +OFPT_HELLO (xid=0x1): + version bitmap: 0x01 + unknown data in hello: +00000000 01 00 00 0b 00 00 00 01-41 42 43 |........ABC | +]) +AT_CLEANUP diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index e66c60570..3e6c7fe48 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -370,6 +370,14 @@ response. Reports the total time required. This is a measure of the maximum bandwidth to \fItarget\fR for round-trips of \fIn\fR-byte messages. . +.SS "Other Commands" +. +.IP "\fBofp\-parse\fR \fIfile\fR" +Reads \fIfile\fR (or \fBstdin\fR if \fIfile\fR is \fB\-\fR) as a +series of OpenFlow messages in the binary format used on an OpenFlow +connection, and prints them to the console. This can be useful for +printing OpenFlow messages captured from a TCP stream. +. .SS "Flow Syntax" .PP Some \fBovs\-ofctl\fR commands accept an argument that describes a flow or diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 68b73bfaf..35a2ca749 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -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[]) { @@ -2932,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 },