From e8f2a2a2fa62fcab47f7f9691e2fd64690d9e950 Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Fri, 12 Oct 2012 17:46:06 -0700 Subject: [PATCH] ovs-dpctl: Make specifying datapath optional for some commands. A future commit will make all bridges use a single backing datapath. This commit makes the "dp" argument for "dump-flows" and "del-flows" optional, since there will typically only be one actual datapath. Signed-off-by: Justin Pettit --- NEWS | 2 ++ utilities/ovs-dpctl.8.in | 12 ++++++--- utilities/ovs-dpctl.c | 55 +++++++++++++++++++++++++++++++++++----- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index ea412be2..5c66b5ea 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,8 @@ v1.9.0 - xx xxx xxxx - ovs-dpctl: - Support requesting the port number with the "port_no" option in the "add-if" command. + - The "dump-flows" and "del-flows" no longer require an argument + if only one datapath exists. - ovs-appctl: - New "dpif/dump-dps", "dpif/show", and "dpif/dump-flows" command that mimic the equivalent ovs-dpctl commands. diff --git a/utilities/ovs-dpctl.8.in b/utilities/ovs-dpctl.8.in index d031ea41..32362e5e 100644 --- a/utilities/ovs-dpctl.8.in +++ b/utilities/ovs-dpctl.8.in @@ -105,17 +105,21 @@ If one or more datapaths are specified, information on only those datapaths are displayed. Otherwise, \fBovs\-dpctl\fR displays information about all configured datapaths. . -.IP "\fBdump\-flows \fIdp\fR" +.IP "\fBdump\-flows\fR [\fIdp\fR]" Prints to the console all flow entries in datapath \fIdp\fR's -flow table. +flow table. If \fIdp\fR is not specified and exactly one datapath +exists, the flows for that datapath will be printed. .IP This command is primarily useful for debugging Open vSwitch. The flow table entries that it displays are not OpenFlow flow entries. Instead, they are different and considerably simpler flows maintained by the Open vSwitch kernel module. If you wish to see the OpenFlow flow entries, use \fBovs\-ofctl dump\-flows\fR. -.IP "\fBdel\-flows \fIdp\fR" -Deletes all flow entries from datapath \fIdp\fR's flow table. +. +.IP "\fBdel\-flows\fR [\fIdp\fR]" +Deletes all flow entries from datapath \fIdp\fR's flow table. If +\fIdp\fR is not specified and exactly one datapath exists, the flows for +that datapath will be deleted. .IP This command is primarily useful for debugging Open vSwitch. As discussed in \fBdump\-flows\fR, these entries are diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c index 52441b96..729c1e76 100644 --- a/utilities/ovs-dpctl.c +++ b/utilities/ovs-dpctl.c @@ -196,6 +196,42 @@ static int if_up(const char *netdev_name) return retval; } +/* Retrieve the name of the datapath if exactly one exists. The caller + * is responsible for freeing the returned string. If there is not one + * datapath, aborts with an error message. */ +static char * +get_one_dp(void) +{ + struct sset types; + const char *type; + char *dp_name = NULL; + size_t count = 0; + + sset_init(&types); + dp_enumerate_types(&types); + SSET_FOR_EACH (type, &types) { + struct sset names; + + sset_init(&names); + if (!dp_enumerate_names(type, &names)) { + count += sset_count(&names); + if (!dp_name && count == 1) { + dp_name = xasprintf("%s@%s", type, SSET_FIRST(&names)); + } + } + sset_destroy(&names); + } + sset_destroy(&types); + + if (!count) { + ovs_fatal(0, "no datapaths exist"); + } else if (count > 1) { + ovs_fatal(0, "multiple datapaths, specify one"); + } + + return dp_name; +} + static int parsed_dpif_open(const char *arg_, bool create, struct dpif **dpifp) { @@ -677,7 +713,7 @@ dpctl_dump_dps(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) } static void -dpctl_dump_flows(int argc OVS_UNUSED, char *argv[]) +dpctl_dump_flows(int argc, char *argv[]) { const struct dpif_flow_stats *stats; const struct nlattr *actions; @@ -687,8 +723,11 @@ dpctl_dump_flows(int argc OVS_UNUSED, char *argv[]) struct dpif *dpif; size_t key_len; struct ds ds; + char *name; - run(parsed_dpif_open(argv[1], false, &dpif), "opening datapath"); + name = (argc == 2) ? xstrdup(argv[1]) : get_one_dp(); + run(parsed_dpif_open(name, false, &dpif), "opening datapath"); + free(name); ds_init(&ds); dpif_flow_dump_start(&dump, dpif); @@ -708,11 +747,15 @@ dpctl_dump_flows(int argc OVS_UNUSED, char *argv[]) } static void -dpctl_del_flows(int argc OVS_UNUSED, char *argv[]) +dpctl_del_flows(int argc, char *argv[]) { struct dpif *dpif; + char *name; + + name = (argc == 2) ? xstrdup(argv[1]) : get_one_dp(); + run(parsed_dpif_open(name, false, &dpif), "opening datapath"); + free(name); - run(parsed_dpif_open(argv[1], false, &dpif), "opening datapath"); run(dpif_flow_flush(dpif), "deleting all flows"); dpif_close(dpif); } @@ -951,8 +994,8 @@ static const struct command all_commands[] = { { "set-if", 2, INT_MAX, dpctl_set_if }, { "dump-dps", 0, 0, dpctl_dump_dps }, { "show", 0, INT_MAX, dpctl_show }, - { "dump-flows", 1, 1, dpctl_dump_flows }, - { "del-flows", 1, 1, dpctl_del_flows }, + { "dump-flows", 0, 1, dpctl_dump_flows }, + { "del-flows", 0, 1, dpctl_del_flows }, { "help", 0, INT_MAX, dpctl_help }, /* Undocumented commands for testing. */ -- 2.30.2