[ovs-dev] [Single DP 12/15] ovs-dpctl: Make specifying datapath optional for some commands.

Justin Pettit jpettit at nicira.com
Thu Oct 18 19:51:57 UTC 2012


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 at nicira.com>
---
 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 97097dd..e97386a 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@ post-v1.8.0
     - 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 042bcd5..3800cb7 100644
--- a/utilities/ovs-dpctl.8.in
+++ b/utilities/ovs-dpctl.8.in
@@ -105,16 +105,20 @@ 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.
-.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 52441b9..729c1e7 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. */
-- 
1.7.5.4




More information about the dev mailing list