From 0caf6bde24f37a616b64075e65ad5eede73398ba Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 11 May 2010 12:44:58 -0700 Subject: [PATCH] ovs-ofctl: Add "snoop" command. The "snoop" command does roughly the same thing as "monitor", but it is easier to use in the common case where one just wants to look at the OpenFlow controller connection for a bridge. Instead of, for example, ovs-ofctl monitor unix:/var/run/openvswitch/br0.snoop one merely types ovs-ofctl snoop br0 --- utilities/ovs-ofctl.8.in | 27 +++++++++++++++++++----- utilities/ovs-ofctl.c | 44 +++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index 3c19be3d..d84b4819 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -143,8 +143,24 @@ omitted and the \fB--strict\fR option is not used, all flows in the switch's tables are removed. See \fBFlow Syntax\fR, below, for the syntax of \fIflows\fR. . -.TP -\fBmonitor \fIswitch\fR [\fImiss-len\fR] +.IP "\fBsnoop \fIswitch\fR" +Connects to \fIswitch\fR and prints to the console all OpenFlow +messages received. Unlike other \fBovs\-ofctl\fR commands, if +\fIswitch\fR is the name of a bridge, then the \fBsnoop\fR command +connects to a Unix domain socket named +\fB@RUNDIR@/\fIbridge\fB.snoop\fR. \fBovs\-vswitchd\fR listens on +such a socket for each bridge and sends to it all of the OpenFlow +messages sent to or received from its configured OpenFlow controller. +Thus, this command can be used to view OpenFlow protocol activity +between a switch and its controller. +.IP +When a switch has more than one controller configured, only the +protocol to and from a single controller, chosen arbitrarily by Open +vSwitch, is given. If a switch has no controller configured, or if +the configured controller is disconnected, no traffic is sent, so +monitoring will not show any traffic. +. +.IQ "\fBmonitor \fIswitch\fR [\fImiss-len\fR]" Connects to \fIswitch\fR and prints to the console all OpenFlow messages received. Usually, \fIswitch\fR should specify a connection named on \fBovs\-openflowd\fR(8)'s \fB-l\fR or \fB--listen\fR command line @@ -152,10 +168,11 @@ option. .IP If \fImiss-len\fR is provided, \fBovs\-ofctl\fR sends an OpenFlow ``set configuration'' message at connection setup time that requests -\fImiss-len\fR bytes of each packet that misses the flow table. The -OpenFlow reference implementation does not send these messages to the +\fImiss-len\fR bytes of each packet that misses the flow table. Open vSwitch +does not send these and other asynchronous messages to an \fBovs\-ofctl monitor\fR client connection unless a nonzero value is -specified on this argument. +specified on this argument. (Thus, if \fImiss\-len\fR is not +specified, very little traffic will ordinarily be printed.) .IP This command may be useful for debugging switch or controller implementations. diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 46994823..1a0c9363 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -214,13 +214,14 @@ open_vconn_socket(const char *name, struct vconn **vconnp) } static void -open_vconn(const char *name, struct vconn **vconnp) +open_vconn__(const char *name, const char *default_suffix, + 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); + bridge_path = xasprintf("%s/%s.%s", ovs_rundir, name, default_suffix); dp_parse_name(name, &datapath_name, &datapath_type); if (strstr(name, ":")) { @@ -241,7 +242,8 @@ open_vconn(const char *name, struct vconn **vconnp) VLOG_INFO("datapath %s is named %s", name, dpif_name); } - socket_name = xasprintf("%s/%s.mgmt", ovs_rundir, dpif_name); + socket_name = xasprintf("%s/%s.%s", + ovs_rundir, dpif_name, default_suffix); if (stat(socket_name, &s)) { ovs_fatal(errno, "cannot connect to %s: stat failed on %s", name, socket_name); @@ -261,6 +263,12 @@ open_vconn(const char *name, struct vconn **vconnp) free(bridge_path); } +static void +open_vconn(const char *name, struct vconn **vconnp) +{ + return open_vconn__(name, "mgmt", vconnp); +} + static void * alloc_stats_request(size_t body_len, uint16_t type, struct ofpbuf **bufferp) { @@ -1060,7 +1068,18 @@ do_tun_cookie(int argc OVS_UNUSED, char *argv[]) } static void -do_monitor(int argc OVS_UNUSED, char *argv[]) +monitor_vconn(struct vconn *vconn) +{ + for (;;) { + struct ofpbuf *b; + run(vconn_recv_block(vconn, &b), "vconn_recv"); + ofp_print(stderr, b->data, b->size, 2); + ofpbuf_delete(b); + } +} + +static void +do_monitor(int argc, char *argv[]) { struct vconn *vconn; @@ -1074,12 +1093,16 @@ do_monitor(int argc OVS_UNUSED, char *argv[]) osc->miss_send_len = htons(miss_send_len); send_openflow_buffer(vconn, buf); } - for (;;) { - struct ofpbuf *b; - run(vconn_recv_block(vconn, &b), "vconn_recv"); - ofp_print(stderr, b->data, b->size, 2); - ofpbuf_delete(b); - } + monitor_vconn(vconn); +} + +static void +do_snoop(int argc OVS_UNUSED, char *argv[]) +{ + struct vconn *vconn; + + open_vconn__(argv[1], "snoop", &vconn); + monitor_vconn(vconn); } static void @@ -1292,6 +1315,7 @@ static const struct command all_commands[] = { { "show", 1, 1, do_show }, { "status", 1, 2, do_status }, { "monitor", 1, 2, do_monitor }, + { "snoop", 1, 1, do_snoop }, { "dump-desc", 1, 1, do_dump_desc }, { "dump-tables", 1, 1, do_dump_tables }, { "dump-flows", 1, 2, do_dump_flows }, -- 2.30.2