ovs-dpctl: Make specifying datapath optional for some commands.
authorJustin Pettit <jpettit@nicira.com>
Sat, 13 Oct 2012 00:46:06 +0000 (17:46 -0700)
committerJustin Pettit <jpettit@nicira.com>
Fri, 2 Nov 2012 05:54:27 +0000 (22:54 -0700)
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 <jpettit@nicira.com>
NEWS
utilities/ovs-dpctl.8.in
utilities/ovs-dpctl.c

diff --git a/NEWS b/NEWS
index ea412be2cb49db0a5ee35ddd692044ca87537ab5..5c66b5eafc7f91b8813132d4f686cdfd13a498ca 100644 (file)
--- 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.
index d031ea414ad3d49e43b6ea30239dfc10808a8388..32362e5eda767bde3a1642ccf30112ca0f4804ab 100644 (file)
@@ -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
index 52441b96c07bce879ac54afdcb9ff3d5b47e9f0c..729c1e76477e5b5608fa352ae31ee6aefbbb66c5 100644 (file)
@@ -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. */