Merge "master" branch into "db".
[sliver-openvswitch.git] / utilities / ovs-dpctl.c
index 2702818..5e50d72 100644 (file)
 #include "dynamic-string.h"
 #include "netdev.h"
 #include "odp-util.h"
+#include "svec.h"
 #include "timeval.h"
 #include "util.h"
 
 #include "vlog.h"
 #define THIS_MODULE VLM_dpctl
 
-struct command {
-    const char *name;
-    int min_args;
-    int max_args;
-    void (*handler)(int argc, char *argv[]);
-};
-
-static struct command all_commands[];
+static const struct command all_commands[];
 
 static void usage(void) NO_RETURN;
 static void parse_options(int argc, char *argv[]);
 
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
 {
-    struct command *p;
-
     set_program_name(argv[0]);
     time_init();
     vlog_init();
     parse_options(argc, argv);
     signal(SIGPIPE, SIG_IGN);
-
-    argc -= optind;
-    argv += optind;
-    if (argc < 1)
-        ovs_fatal(0, "missing command name; use --help for help");
-
-    for (p = all_commands; p->name != NULL; p++) {
-        if (!strcmp(p->name, argv[0])) {
-            int n_arg = argc - 1;
-            if (n_arg < p->min_args)
-                ovs_fatal(0, "'%s' command requires at least %d arguments",
-                          p->name, p->min_args);
-            else if (n_arg > p->max_args)
-                ovs_fatal(0, "'%s' command takes at most %d arguments",
-                          p->name, p->max_args);
-            else {
-                p->handler(argc, argv);
-                if (ferror(stdout)) {
-                    ovs_fatal(0, "write to stdout failed");
-                }
-                if (ferror(stderr)) {
-                    ovs_fatal(0, "write to stderr failed");
-                }
-                exit(0);
-            }
-        }
-    }
-    ovs_fatal(0, "unknown command '%s'; use --help for help", argv[0]);
-
+    run_command(argc - optind, argv + optind, all_commands);
     return 0;
 }
 
@@ -157,6 +122,7 @@ usage(void)
            "  del-dp DP                delete local datapath DP\n"
            "  add-if DP IFACE...       add each IFACE as a port on DP\n"
            "  del-if DP IFACE...       delete each IFACE from DP\n"
+           "  dump-dps                 display names of all datapaths\n"
            "  show                     show basic info on all datapaths\n"
            "  show DP...               show basic info on each DP\n"
            "  dump-flows DP            display flows in DP\n"
@@ -369,9 +335,11 @@ show_dpif(struct dpif *dpif)
         printf("\tports: cur:%"PRIu32", max:%"PRIu32"\n",
                stats.n_ports, stats.max_ports);
         printf("\tgroups: max:%"PRIu16"\n", stats.max_groups);
-        printf("\tlookups: frags:%"PRIu64", hit:%"PRIu64", missed:%"PRIu64", "
-               "lost:%"PRIu64"\n",
-               stats.n_frags, stats.n_hit, stats.n_missed, stats.n_lost);
+        printf("\tlookups: frags:%llu, hit:%llu, missed:%llu, lost:%llu\n",
+               (unsigned long long int) stats.n_frags,
+               (unsigned long long int) stats.n_hit,
+               (unsigned long long int) stats.n_missed,
+               (unsigned long long int) stats.n_lost);
         printf("\tqueues: max-miss:%"PRIu16", max-action:%"PRIu16"\n",
                stats.max_miss_queue, stats.max_action_queue);
     }
@@ -388,7 +356,7 @@ show_dpif(struct dpif *dpif)
 }
 
 static void
-do_show(int argc UNUSED, char *argv[])
+do_show(int argc, char *argv[])
 {
     bool failure = false;
     if (argc > 1) {
@@ -428,6 +396,30 @@ do_show(int argc UNUSED, char *argv[])
     }
 }
 
+static void
+do_dump_dps(int argc UNUSED, char *argv[] UNUSED)
+{
+    struct svec all_dps;
+    unsigned int i;
+    int error;
+
+    svec_init(&all_dps);
+    error = dp_enumerate(&all_dps);
+
+    for (i = 0; i < all_dps.n; i++) {
+        struct dpif *dpif;
+        if (!dpif_open(all_dps.names[i], &dpif)) {
+            printf("%s\n", dpif_name(dpif));
+            dpif_close(dpif);
+        }
+    }
+
+    svec_destroy(&all_dps);
+    if (error) {
+        exit(EXIT_FAILURE);
+    }
+}
+
 static void
 do_dump_flows(int argc UNUSED, char *argv[])
 {
@@ -501,11 +493,12 @@ do_help(int argc UNUSED, char *argv[] UNUSED)
     usage();
 }
 
-static struct command all_commands[] = {
+static const struct command all_commands[] = {
     { "add-dp", 1, INT_MAX, do_add_dp },
     { "del-dp", 1, 1, do_del_dp },
     { "add-if", 2, INT_MAX, do_add_if },
     { "del-if", 2, INT_MAX, do_del_if },
+    { "dump-dps", 0, 0, do_dump_dps },
     { "show", 0, INT_MAX, do_show },
     { "dump-flows", 1, 1, do_dump_flows },
     { "del-flows", 1, 1, do_del_flows },