Factor out printing the list of available vconns.
[openvswitch] / utilities / dpctl.c
index 1bf369965bf41951011b956886b9757ea870a759..8f1e77238d5e37879b23ea2e94d054a555b3da27 100644 (file)
@@ -1,22 +1,34 @@
-/* Copyright (C) 2007 Board of Trustees, Leland Stanford Jr. University.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
+/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
+ * Junior University
+ * 
+ * We are making the OpenFlow specification and associated documentation
+ * (Software) available for public use and benefit with the expectation
+ * that others will use, modify and enhance the Software and contribute
+ * those enhancements back to the community. However, since we would
+ * like to make the Software available for broadest use, with as few
+ * restrictions as possible permission is hereby granted, free of
+ * charge, to any person obtaining a copy of this Software to deal in
+ * the Software under the copyrights without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * 
+ * The name and trademarks of copyright holder(s) may NOT be used in
+ * advertising or publicity pertaining to the Software or any
+ * derivatives without specific, written prior permission.
  */
 
 #include <errno.h>
@@ -41,6 +53,7 @@
 #include "openflow.h"
 #include "ofp-print.h"
 #include "vconn.h"
+#include "vconn-ssl.h"
 
 #include "vlog.h"
 #define THIS_MODULE VLM_DPCTL
@@ -99,6 +112,11 @@ parse_options(int argc, char *argv[])
         {"verbose", optional_argument, 0, 'v'},
         {"help", no_argument, 0, 'h'},
         {"version", no_argument, 0, 'V'},
+#ifdef HAVE_OPENSSL
+        {"private-key", required_argument, 0, 'p'},
+        {"certificate", required_argument, 0, 'c'},
+        {"ca-cert",     required_argument, 0, 'C'},
+#endif
         {0, 0, 0, 0},
     };
     char *short_options = long_options_to_short_options(long_options);
@@ -124,6 +142,20 @@ parse_options(int argc, char *argv[])
             vlog_set_verbosity(optarg);
             break;
 
+#ifdef HAVE_OPENSSL
+        case 'p':
+            vconn_ssl_set_private_key_file(optarg);
+            break;
+
+        case 'c':
+            vconn_ssl_set_certificate_file(optarg);
+            break;
+
+        case 'C':
+            vconn_ssl_set_ca_cert_file(optarg);
+            break;
+#endif
+
         case '?':
             exit(EXIT_FAILURE);
 
@@ -137,25 +169,30 @@ parse_options(int argc, char *argv[])
 static void
 usage(void)
 {
-    printf("%s: Datapath Utility\n"
+    printf("%s: OpenFlow switch management utility\n"
            "usage: %s [OPTIONS] COMMAND [ARG...]\n"
-           "\nAvailable commands:\n"
-           "  adddp DP_ID                 add a new datapath with ID DP_ID\n"
-           "  deldp DP_ID                 delete datapath DP_ID\n"
-           "  show DP                     show information about DP\n"
-           "  addif DP_ID IFACE           add IFACE as a port on DP_ID\n"
-           "  delif DP_ID IFACE           delete IFACE as a port on DP_ID\n"
-           "  monitor DP_ID               print packets received on DP_ID\n"
-           "  dump-tables DP_ID           print stats for all tables in DP_ID\n"
-           "  dump-flows DP_ID T_ID       print all flow entries in table T_ID of DP_ID\n"
-           "  dump-flows DP_ID T_ID FLOW  print matching FLOWs in table T_ID of DP_ID\n"
-           "  add-flows DP FILE           add flows from FILE to DP\n"
-           "  benchmark-nl DP_ID N SIZE   send N packets of SIZE bytes up netlink\n"
-           "\nOptions:\n"
+#ifdef HAVE_NETLINK
+           "\nCommands that apply to local datapaths only:\n"
+           "  adddp nl:DP_ID              add a new local datapath DP_ID\n"
+           "  deldp nl:DP_ID              delete local datapath DP_ID\n"
+           "  addif nl:DP_ID IFACE        add IFACE as a port on DP_ID\n"
+           "  delif nl:DP_ID IFACE        delete IFACE as a port on DP_ID\n"
+           "  benchmark-nl nl:DP_ID N SIZE   send N packets of SIZE bytes\n"
+#endif
+           "\nCommands that apply to local datapaths and remote switches:\n"
+           "  show METHOD                 show information about METHOD\n"
+           "  monitor METHOD              print packets received on METHOD\n"
+           "  dump-tables METHOD          print table stats for METHOD\n"
+           "  dump-flows METHOD T_ID      print all flow entries in table T_ID of METHOD\n"
+           "  dump-flows METHOD T_ID FLOW print matching FLOWs in table T_ID of METHOD\n"
+           "  add-flows METHOD FILE       add flows from FILE to METHOD\n"
+           "where each METHOD is an active OpenFlow connection method.\n",
+           program_name, program_name);
+    vconn_usage(true, false);
+    printf("\nOptions:\n"
            "  -v, --verbose               set maximum verbosity level\n"
            "  -h, --help                  display this help message\n"
-           "  -V, --version               display version information\n",
-           program_name, program_name);
+           "  -V, --version               display version information\n");
     exit(EXIT_SUCCESS);
 }
 
@@ -165,6 +202,9 @@ static void run(int retval, const char *name)
         fatal(retval, "%s", name);
     }
 }
+\f
+#ifdef HAVE_NETLINK
+/* Netlink-only commands. */
 
 static int  if_up(const char* intf)
 {
@@ -174,10 +214,20 @@ static int  if_up(const char* intf)
     return system(command);
 }
 
+static void open_nl_vconn(const char *name, bool subscribe, struct dpif *dpif)
+{
+    if (strncmp(name, "nl:", 3)
+        || strlen(name) < 4
+        || name[strspn(name + 3, "0123456789") + 3]) {
+        fatal(0, "%s: argument is not of the form \"nl:DP_ID\"", name);
+    }
+    run(dpif_open(atoi(name + 3), subscribe, dpif), "opening datapath");
+}
+
 static void do_add_dp(int argc UNUSED, char *argv[])
 {
     struct dpif dp;
-    run(dpif_open(atoi(argv[1]), false, &dp), "dpif_open");
+    open_nl_vconn(argv[1], false, &dp);
     run(dpif_add_dp(&dp), "add_dp");
     dpif_close(&dp);
 }
@@ -185,24 +235,16 @@ static void do_add_dp(int argc UNUSED, char *argv[])
 static void do_del_dp(int argc UNUSED, char *argv[])
 {
     struct dpif dp;
-    run(dpif_open(atoi(argv[1]), false, &dp), "dpif_open");
+    open_nl_vconn(argv[1], false, &dp);
     run(dpif_del_dp(&dp), "del_dp");
     dpif_close(&dp);
 }
 
-static void do_show(int argc UNUSED, char *argv[])
-{
-    struct dpif dp;
-    run(dpif_open(atoi(argv[1]), false, &dp), "dpif_open");
-    run(dpif_show(&dp), "show");
-    dpif_close(&dp);
-}
-
 static void do_add_port(int argc UNUSED, char *argv[])
 {
     struct dpif dp;
     if_up(argv[2]);
-    run(dpif_open(atoi(argv[1]), false, &dp), "dpif_open");
+    open_nl_vconn(argv[1], false, &dp);
     run(dpif_add_port(&dp, argv[2]), "add_port");
     dpif_close(&dp);
 }
@@ -210,7 +252,7 @@ static void do_add_port(int argc UNUSED, char *argv[])
 static void do_del_port(int argc UNUSED, char *argv[])
 {
     struct dpif dp;
-    run(dpif_open(atoi(argv[1]), false, &dp), "dpif_open");
+    open_nl_vconn(argv[1], false, &dp);
     run(dpif_del_port(&dp, argv[2]), "del_port");
     dpif_close(&dp);
 }
@@ -223,7 +265,7 @@ static void do_benchmark_nl(int argc UNUSED, char *argv[])
     uint32_t num_packets, i, milestone;
     struct timeval start, end;
 
-    run(dpif_open(atoi(argv[1]), true, &dp), "dpif_open");
+    open_nl_vconn(argv[1], false, &dp);
     num_packets = atoi(argv[2]);
     milestone = BENCHMARK_INCR;
     run(dpif_benchmark_nl(&dp, num_packets, atoi(argv[3])), "benchmark_nl");
@@ -252,6 +294,19 @@ static void do_benchmark_nl(int argc UNUSED, char *argv[])
 
     dpif_close(&dp);
 }
+#endif /* HAVE_NETLINK */
+\f
+/* Generic commands. */
+
+static void do_show(int argc UNUSED, char *argv[])
+{
+#if 0
+    struct dpif dp;
+    run(dpif_open(atoi(argv[1]), false, &dp), "dpif_open");
+    run(dpif_show(&dp), "show");
+    dpif_close(&dp);
+#endif
+}
 
 static void do_monitor(int argc UNUSED, char *argv[])
 {
@@ -480,7 +535,7 @@ static void do_add_flows(int argc, char *argv[])
         ofm->group_id = htonl(0);
         str_to_flow(line, &ofm->match, &ofm->actions[0]);
 
-        retval = vconn_send_wait(vconn, buffer);
+        retval = vconn_send_block(vconn, buffer);
         if (retval) {
             fatal(retval, "sending to datapath");
         }
@@ -495,25 +550,19 @@ static void do_help(int argc UNUSED, char *argv[] UNUSED)
 }
 
 static struct command all_commands[] = {
-    { "add-dp", 1, 1, do_add_dp },
+#ifdef HAVE_NETLINK
     { "adddp", 1, 1, do_add_dp },
-
-    { "del-dp", 1, 1, do_del_dp },
     { "deldp", 1, 1, do_del_dp },
-
-    { "show", 1, 1, do_show },
-
-    { "add-port", 2, 2, do_add_port },
     { "addif", 2, 2, do_add_port },
-
-    { "del-port", 2, 2, do_del_port },
     { "delif", 2, 2, do_del_port },
+    { "benchmark-nl", 3, 3, do_benchmark_nl },
+#endif
+
+    { "show", 1, 1, do_show },
 
     { "help", 0, INT_MAX, do_help },
     { "monitor", 1, 1, do_monitor },
     { "dump-tables", 1, 1, do_dump_tables },
     { "dump-flows", 2, 3, do_dump_flows },
     { "add-flows", 2, 2, do_add_flows },
-
-    { "benchmark-nl", 3, 3, do_benchmark_nl },
 };