Add support for managing remote connections, including
SSL configuration, to southbound db schema, and add necessary
commands to ovn-sbctl.

Signed-off-by: Lance Richardson <lrich...@redhat.com>
---
 NEWS                         |   2 +-
 manpages.mk                  |   6 ++
 ovn/ovn-sb.ovsschema         |  21 +++-
 ovn/ovn-sb.xml               |  48 +++++++++-
 ovn/utilities/ovn-sbctl.8.in |  85 ++++++++++++++++-
 ovn/utilities/ovn-sbctl.c    | 221 ++++++++++++++++++++++++++++++++++++++++++-
 tests/ovn.at                 |  52 ++++++++++
 7 files changed, 423 insertions(+), 12 deletions(-)

diff --git a/NEWS b/NEWS
index 2ec3dbb..3a33abf 100644
--- a/NEWS
+++ b/NEWS
@@ -8,7 +8,7 @@ Post-v2.6.0
      * IPAM now supports fixed MAC addresses.
      * Support for source IP address based routing.
      * Support for managing SSL and remote connection configuration in
-       northbound database.
+       northbound and southbound databases.
    - Fixed regression in table stats maintenance introduced in OVS
      2.3.0, wherein the number of OpenFlow table hits and misses was
      not accurate.
diff --git a/manpages.mk b/manpages.mk
index 2fb8ef4..11ec023 100644
--- a/manpages.mk
+++ b/manpages.mk
@@ -4,6 +4,9 @@ ovn/utilities/ovn-sbctl.8: \
        ovn/utilities/ovn-sbctl.8.in \
        lib/common.man \
        lib/db-ctl-base.man \
+       lib/ssl-bootstrap.man \
+       lib/ssl-peer-ca-cert.man \
+       lib/ssl.man \
        lib/table.man \
        lib/vlog.man \
        ovsdb/remote-active.man \
@@ -11,6 +14,9 @@ ovn/utilities/ovn-sbctl.8: \
 ovn/utilities/ovn-sbctl.8.in:
 lib/common.man:
 lib/db-ctl-base.man:
+lib/ssl-bootstrap.man:
+lib/ssl-peer-ca-cert.man:
+lib/ssl.man:
 lib/table.man:
 lib/vlog.man:
 ovsdb/remote-active.man:
diff --git a/ovn/ovn-sb.ovsschema b/ovn/ovn-sb.ovsschema
index 89342fe..0212a5e 100644
--- a/ovn/ovn-sb.ovsschema
+++ b/ovn/ovn-sb.ovsschema
@@ -1,7 +1,7 @@
 {
     "name": "OVN_Southbound",
     "version": "1.9.0",
-    "cksum": "239060528 9012",
+    "cksum": "2240045372 9719",
     "tables": {
         "SB_Global": {
             "columns": {
@@ -13,7 +13,11 @@
                     "type": {"key": {"type": "uuid",
                                      "refTable": "Connection"},
                                      "min": 0,
-                                     "max": "unlimited"}}},
+                                     "max": "unlimited"}},
+                "ssl": {
+                    "type": {"key": {"type": "uuid",
+                                     "refTable": "SSL"},
+                                     "min": 0, "max": 1}}},
             "maxRows": 1,
             "isRoot": true},
         "Chassis": {
@@ -183,4 +187,15 @@
                                     "min": 0,
                                     "max": "unlimited"},
                                     "ephemeral": true}},
-            "indexes": [["target"]]}}}
+            "indexes": [["target"]]},
+        "SSL": {
+            "columns": {
+                "private_key": {"type": "string"},
+                "certificate": {"type": "string"},
+                "ca_cert": {"type": "string"},
+                "bootstrap_ca_cert": {"type": "boolean"},
+                "external_ids": {"type": {"key": "string",
+                                          "value": "string",
+                                          "min": 0,
+                                          "max": "unlimited"}}},
+            "maxRows": 1}}}
diff --git a/ovn/ovn-sb.xml b/ovn/ovn-sb.xml
index 65191ed..e2f88b5 100644
--- a/ovn/ovn-sb.xml
+++ b/ovn/ovn-sb.xml
@@ -169,6 +169,9 @@
         connections should be configured.  See the <ref table="Connection"/>
         table for more information.
       </column>
+      <column name="ssl">
+        Global SSL configuration.
+      </column>
     </group>
   </table>
 
@@ -2309,7 +2312,9 @@ tcp.flags = RST;
             <p>
               The specified SSL <var>port</var> on the host at the given
               <var>ip</var>, which must be expressed as an IP address
-              (not a DNS name).
+              (not a DNS name). A valid SSL configuration must be provided
+              when this form is used, this configuration can be specified
+              via command-line options or the <ref table="SSL"/> table.
             </p>
             <p>
               If <var>port</var> is not specified, it defaults to 6640.
@@ -2345,6 +2350,9 @@ tcp.flags = RST;
               address, wrap in square brackets,
               e.g. <code>pssl:6640:[::1]</code>.  If <var>ip</var> is not
               specified then it listens only on IPv4 (but not IPv6) addresses.
+              A valid SSL configuration must be provided when this form is 
used,
+             this can be specified either via command-line options or the
+             <ref table="SSL"/> table.
             </p>
             <p>
               If <var>port</var> is not specified, it defaults to 6640.
@@ -2517,4 +2525,42 @@ tcp.flags = RST;
       <column name="other_config"/>
     </group>
   </table>
+  <table name="SSL">
+    SSL configuration for ovn-sb database access.
+
+    <column name="private_key">
+      Name of a PEM file containing the private key used as the switch's
+      identity for SSL connections to the controller.
+    </column>
+
+    <column name="certificate">
+      Name of a PEM file containing a certificate, signed by the
+      certificate authority (CA) used by the controller and manager,
+      that certifies the switch's private key, identifying a trustworthy
+      switch.
+    </column>
+
+    <column name="ca_cert">
+      Name of a PEM file containing the CA certificate used to verify
+      that the switch is connected to a trustworthy controller.
+    </column>
+
+    <column name="bootstrap_ca_cert">
+      If set to <code>true</code>, then Open vSwitch will attempt to
+      obtain the CA certificate from the controller on its first SSL
+      connection and save it to the named PEM file. If it is successful,
+      it will immediately drop the connection and reconnect, and from then
+      on all SSL connections must be authenticated by a certificate signed
+      by the CA certificate thus obtained.  <em>This option exposes the
+      SSL connection to a man-in-the-middle attack obtaining the initial
+      CA certificate.</em>  It may still be useful for bootstrapping.
+    </column>
+
+    <group title="Common Columns">
+      The overall purpose of these columns is described under <code>Common
+      Columns</code> at the beginning of this document.
+
+      <column name="external_ids"/>
+    </group>
+  </table>
 </database>
diff --git a/ovn/utilities/ovn-sbctl.8.in b/ovn/utilities/ovn-sbctl.8.in
index 8036397..9a6978a 100644
--- a/ovn/utilities/ovn-sbctl.8.in
+++ b/ovn/utilities/ovn-sbctl.8.in
@@ -22,10 +22,6 @@ ovn\-sbctl \- utility for querying and configuring 
\fBOVN_Southbound\fR database
 \fR[\fIargs\fR] [\fB\-\-\fR [\fIoptions\fR] \fIcommand \fR[\fIargs\fR]]...
 .
 .SH DESCRIPTION
-The command should only be used for advanced debugging and troubleshooting
-of the \fBOVN_Southbound\fR database; and should never be used in normal
-operation.
-.PP
 The \fBovn\-sbctl\fR program configures the \fBOVN_Southbound\fR database
 by providing a high\-level interface to its configuration database.  See
 \fBovn\-sb\fR(5) for comprehensive documentation of the database schema.
@@ -105,6 +101,11 @@ These options control the format of output from the 
\fBlist\fR and
 \fBfind\fR commands.
 .so lib/table.man
 .
+.SS "Public Key Infrastructure Options"
+.so lib/ssl.man
+.so lib/ssl-bootstrap.man
+.so lib/ssl-peer-ca-cert.man
+.
 .SH COMMANDS
 The commands implemented by \fBovn\-sbctl\fR are described in the
 sections below.
@@ -166,6 +167,82 @@ that logical datapath.
 .IP "\fBdump\-flows\fR [\fIlogical\-datapath\fR]"
 Alias for \fBlflow\-list\fB.
 .
+.SS "Remote Connectivity Commands"
+.
+These commands manipulate the \fBconnections\fR column in the \fBSB_Global\fR
+table and rows in the \fBConnection\fR table.  When \fBovsdb\-server\fR
+is configured to use the \fBconnections\fR column for OVSDB connections,
+this allows the administrator to use \fBovn\-sbctl\fR to configure database
+connections.
+.
+.IP "\fBget\-connection\fR"
+Prints the configured connection(s).
+.
+.IP "\fBdel\-connection\fR"
+Deletes the configured connection(s).
+.
+.IP "\fBset\-connection\fR [\fIaccess\-specifier\fR] \fItarget\fR\&..."
+Sets the configured manager target or targets.  Each \fItarget\fR may
+be preceded by an optional access-specifier (\fBread\-only\fR or
+\fBread\-write\fR) and may use any of the following forms:
+.
+.RS
+.so ovsdb/remote-active.man
+.so ovsdb/remote-passive.man
+.RE
+
+If provided, the effect of the access specifier persists for subsequent
+targets until changed by another access specifier.
+.
+.SS "SSL Configuration"
+When \fBovsdb\-server\fR is configured to connect using SSL, the
+following parameters are required:
+.TP
+\fIprivate-key\fR
+Specifies a PEM file containing the private key used for SSL connections.
+.TP
+\fIcertificate\fR
+Specifies a PEM file containing a certificate, signed by the
+certificate authority (CA) used by the connection peers, that
+certifies the private key, identifying a trustworthy peer.
+.TP
+\fIca-cert\fR
+Specifies a PEM file containing the CA certificate used to verify that
+the connection peers are trustworthy.
+.PP
+These SSL settings apply to all SSL connections made by the southbound
+database server.
+.
+.IP "\fBget\-ssl\fR"
+Prints the SSL configuration.
+.
+.IP "\fBdel\-ssl\fR"
+Deletes the current SSL configuration.
+.
+.IP "[\fB\-\-bootstrap\fR] \fBset\-ssl\fR \fIprivate-key\fR \fIcertificate\fR 
\fIca-cert\fR"
+Sets the SSL configuration.  The \fB\-\-bootstrap\fR option is described
+below.
+.
+.ST "CA Certificate Bootstrap"
+.PP
+Ordinarily, all of the files named in the SSL configuration must exist
+before SSL connectivity can be used.  However, if the \fIca-cert\fR file
+does not exist and the \fB\-\-bootstrap\fR
+option is given, then \fBovsdb\-server\fR will attempt to obtain the
+CA certificate from the target on its first SSL connection and
+save it to the named PEM file.  If it is successful, it will
+immediately drop the connection and reconnect, and from then on all
+SSL connections must be authenticated by a certificate signed by the
+CA certificate thus obtained.
+.PP
+\fBThis option exposes the SSL connection to a man-in-the-middle
+attack obtaining the initial CA certificate\fR, but it may be useful
+for bootstrapping.
+.PP
+This option is only useful if the SSL peer sends its CA certificate
+as part of the SSL certificate chain.  The SSL protocol does not
+require the controller to send the CA certificate.
+.
 .so lib/db-ctl-base.man
 .SH "EXIT STATUS"
 .IP "0"
diff --git a/ovn/utilities/ovn-sbctl.c b/ovn/utilities/ovn-sbctl.c
index 0763b79..92ae3e5 100644
--- a/ovn/utilities/ovn-sbctl.c
+++ b/ovn/utilities/ovn-sbctl.c
@@ -48,6 +48,7 @@
 #include "table.h"
 #include "timeval.h"
 #include "util.h"
+#include "svec.h"
 
 VLOG_DEFINE_THIS_MODULE(sbctl);
 
@@ -287,8 +288,6 @@ usage(void)
     printf("\
 %s: OVN southbound DB management utility\n\
 \n\
-For debugging and testing only, not for use in production.\n\
-\n\
 usage: %s [OPTIONS] COMMAND [ARG...]\n\
 \n\
 General commands:\n\
@@ -309,6 +308,16 @@ Logical flow commands:\n\
   lflow-list [DATAPATH]       List logical flows for all or a single 
datapath\n\
   dump-flows [DATAPATH]       Alias for lflow-list\n\
 \n\
+Connection commands:\n\
+  get-connection             print the connections\n\
+  del-connection             delete the connections\n\
+  set-connection TARGET...   set the list of connections to TARGET...\n\
+\n\
+SSL commands:\n\
+  get-ssl                     print the SSL configuration\n\
+  del-ssl                     delete the SSL configuration\n\
+  set-ssl PRIV-KEY CERT CA-CERT  set the SSL configuration\n\
+\n\
 %s\
 \n\
 Options:\n\
@@ -739,6 +748,199 @@ cmd_lflow_list(struct ctl_context *ctx)
     free(lflows);
 }
 
+static void
+verify_connections(struct ctl_context *ctx)
+{
+    const struct sbrec_sb_global *sb_global = sbrec_sb_global_first(ctx->idl);
+    const struct sbrec_connection *conn;
+
+    sbrec_sb_global_verify_connections(sb_global);
+
+    SBREC_CONNECTION_FOR_EACH(conn, ctx->idl) {
+        sbrec_connection_verify_target(conn);
+    }
+}
+
+static void
+pre_connection(struct ctl_context *ctx)
+{
+    ovsdb_idl_add_column(ctx->idl, &sbrec_sb_global_col_connections);
+    ovsdb_idl_add_column(ctx->idl, &sbrec_connection_col_target);
+    ovsdb_idl_add_column(ctx->idl, &sbrec_connection_col_read_only);
+}
+
+static void
+cmd_get_connection(struct ctl_context *ctx)
+{
+    const struct sbrec_connection *conn;
+    struct svec targets;
+    size_t i;
+
+    verify_connections(ctx);
+
+    /* Print the targets in sorted order for reproducibility. */
+    svec_init(&targets);
+
+    SBREC_CONNECTION_FOR_EACH(conn, ctx->idl) {
+        char *s;
+
+        s = xasprintf("%s %s", conn->read_only ? "read-only" : "read-write",
+                               conn->target);
+        svec_add(&targets, s);
+        free(s);
+    }
+
+    svec_sort_unique(&targets);
+    for (i = 0; i < targets.n; i++) {
+        ds_put_format(&ctx->output, "%s\n", targets.names[i]);
+    }
+    svec_destroy(&targets);
+}
+
+static void
+delete_connections(struct ctl_context *ctx)
+{
+    const struct sbrec_sb_global *sb_global = sbrec_sb_global_first(ctx->idl);
+    const struct sbrec_connection *conn, *next;
+
+    /* Delete Manager rows pointed to by 'connection_options' column. */
+    SBREC_CONNECTION_FOR_EACH_SAFE(conn, next, ctx->idl) {
+        sbrec_connection_delete(conn);
+    }
+
+    /* Delete 'Manager' row refs in 'manager_options' column. */
+    sbrec_sb_global_set_connections(sb_global, NULL, 0);
+}
+
+static void
+cmd_del_connection(struct ctl_context *ctx)
+{
+    verify_connections(ctx);
+    delete_connections(ctx);
+}
+
+static void
+insert_connections(struct ctl_context *ctx, char *targets[], size_t n)
+{
+    const struct sbrec_sb_global *sb_global = sbrec_sb_global_first(ctx->idl);
+    struct sbrec_connection **connections;
+    size_t i, conns=0;
+    bool read_only = false;
+
+    /* Insert each connection in a new row in Connection table. */
+    connections = xmalloc(n * sizeof *connections);
+    for (i = 0; i < n; i++) {
+        if (!strcmp(targets[i], "read-only")) {
+            read_only = true;
+            continue;
+        } else if (!strcmp(targets[i], "read-write")) {
+            read_only = false;
+            continue;
+        } else if (stream_verify_name(targets[i]) &&
+                   pstream_verify_name(targets[i])) {
+            VLOG_WARN("target type \"%s\" is possibly erroneous", targets[i]);
+        }
+
+        connections[conns] = sbrec_connection_insert(ctx->txn);
+        sbrec_connection_set_target(connections[conns], targets[i]);
+        sbrec_connection_set_read_only(connections[conns], read_only);
+        conns++;
+    }
+
+    /* Store uuids of new connection rows in 'connection' column. */
+    sbrec_sb_global_set_connections(sb_global, connections, conns);
+    free(connections);
+}
+
+static void
+cmd_set_connection(struct ctl_context *ctx)
+{
+    const size_t n = ctx->argc - 1;
+
+    verify_connections(ctx);
+    delete_connections(ctx);
+    insert_connections(ctx, &ctx->argv[1], n);
+}
+
+static void
+pre_cmd_get_ssl(struct ctl_context *ctx)
+{
+    ovsdb_idl_add_column(ctx->idl, &sbrec_sb_global_col_ssl);
+
+    ovsdb_idl_add_column(ctx->idl, &sbrec_ssl_col_private_key);
+    ovsdb_idl_add_column(ctx->idl, &sbrec_ssl_col_certificate);
+    ovsdb_idl_add_column(ctx->idl, &sbrec_ssl_col_ca_cert);
+    ovsdb_idl_add_column(ctx->idl, &sbrec_ssl_col_bootstrap_ca_cert);
+}
+
+static void
+cmd_get_ssl(struct ctl_context *ctx)
+{
+    const struct sbrec_sb_global *sb_global = sbrec_sb_global_first(ctx->idl);
+    const struct sbrec_ssl *ssl = sbrec_ssl_first(ctx->idl);
+
+    sbrec_sb_global_verify_ssl(sb_global);
+    if (ssl) {
+        sbrec_ssl_verify_private_key(ssl);
+        sbrec_ssl_verify_certificate(ssl);
+        sbrec_ssl_verify_ca_cert(ssl);
+        sbrec_ssl_verify_bootstrap_ca_cert(ssl);
+
+        ds_put_format(&ctx->output, "Private key: %s\n", ssl->private_key);
+        ds_put_format(&ctx->output, "Certificate: %s\n", ssl->certificate);
+        ds_put_format(&ctx->output, "CA Certificate: %s\n", ssl->ca_cert);
+        ds_put_format(&ctx->output, "Bootstrap: %s\n",
+                ssl->bootstrap_ca_cert ? "true" : "false");
+    }
+}
+
+static void
+pre_cmd_del_ssl(struct ctl_context *ctx)
+{
+    ovsdb_idl_add_column(ctx->idl, &sbrec_sb_global_col_ssl);
+}
+
+static void
+cmd_del_ssl(struct ctl_context *ctx)
+{
+    const struct sbrec_sb_global *sb_global = sbrec_sb_global_first(ctx->idl);
+    const struct sbrec_ssl *ssl = sbrec_ssl_first(ctx->idl);
+
+    if (ssl) {
+        sbrec_sb_global_verify_ssl(sb_global);
+        sbrec_ssl_delete(ssl);
+        sbrec_sb_global_set_ssl(sb_global, NULL);
+    }
+}
+
+static void
+pre_cmd_set_ssl(struct ctl_context *ctx)
+{
+    ovsdb_idl_add_column(ctx->idl, &sbrec_sb_global_col_ssl);
+}
+
+static void
+cmd_set_ssl(struct ctl_context *ctx)
+{
+    bool bootstrap = shash_find(&ctx->options, "--bootstrap");
+    const struct sbrec_sb_global *sb_global = sbrec_sb_global_first(ctx->idl);
+    const struct sbrec_ssl *ssl = sbrec_ssl_first(ctx->idl);
+
+    sbrec_sb_global_verify_ssl(sb_global);
+    if (ssl) {
+        sbrec_ssl_delete(ssl);
+    }
+    ssl = sbrec_ssl_insert(ctx->txn);
+
+    sbrec_ssl_set_private_key(ssl, ctx->argv[1]);
+    sbrec_ssl_set_certificate(ssl, ctx->argv[2]);
+    sbrec_ssl_set_ca_cert(ssl, ctx->argv[3]);
+
+    sbrec_ssl_set_bootstrap_ca_cert(ssl, bootstrap);
+
+    sbrec_sb_global_set_ssl(sb_global, ssl);
+}
+
 
 static const struct ctl_table_class tables[] = {
     {&sbrec_table_sb_global,
@@ -782,6 +984,9 @@ static const struct ctl_table_class tables[] = {
      {{&sbrec_table_connection, NULL, NULL},
       {NULL, NULL, NULL}}},
 
+    {&sbrec_table_ssl,
+     {{&sbrec_table_sb_global, NULL, &sbrec_sb_global_col_ssl}}},
+
     {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
 };
 
@@ -1044,7 +1249,17 @@ static const struct ctl_command_syntax sbctl_commands[] 
= {
     {"dump-flows", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL,
      "", RO}, /* Friendly alias for lflow-list */
 
-    /* SSL commands (To Be Added). */
+    /* Connection commands. */
+    {"get-connection", 0, 0, "", pre_connection, cmd_get_connection, NULL, "", 
RO},
+    {"del-connection", 0, 0, "", pre_connection, cmd_del_connection, NULL, "", 
RW},
+    {"set-connection", 1, INT_MAX, "TARGET...", pre_connection, 
cmd_set_connection,
+     NULL, "", RW},
+
+    /* SSL commands. */
+    {"get-ssl", 0, 0, "", pre_cmd_get_ssl, cmd_get_ssl, NULL, "", RO},
+    {"del-ssl", 0, 0, "", pre_cmd_del_ssl, cmd_del_ssl, NULL, "", RW},
+    {"set-ssl", 3, 3, "PRIVATE-KEY CERTIFICATE CA-CERT", pre_cmd_set_ssl,
+     cmd_set_ssl, NULL, "--bootstrap", RW},
 
     {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
 };
diff --git a/tests/ovn.at b/tests/ovn.at
index f9dcd0a..31b5ede 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -5639,6 +5639,58 @@ AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 
+AT_SETUP([ovn -- sb connection/ssl commands])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
+PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
+AT_SKIP_IF([expr "$PKIDIR" : ".*[      '\"
+\\]"])
+
+: > .$1.db.~lock~
+ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
+
+# Start sb db server using db connection/ssl entries (unpopulated initially)
+start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
+                          --remote=db:OVN_Southbound,SB_Global,connections \
+                          --private-key=db:OVN_Southbound,SSL,private_key \
+                          --certificate=db:OVN_Southbound,SSL,certificate \
+                          --ca-cert=db:OVN_Southbound,SSL,ca_cert \
+                          ovn-sb.db
+
+# Populate SSL configuration entries in sb db
+AT_CHECK(
+    [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
+                       $PKIDIR/testpki-cert.pem \
+                       $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
+
+# Populate a passive SSL connection in sb db
+AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
+
+PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
+
+# Verify SSL connetivity to sb db server
+AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
+                    --private-key=$PKIDIR/testpki-privkey.pem \
+                    --certificate=$PKIDIR/testpki-cert.pem \
+                    --ca-cert=$PKIDIR/testpki-cacert.pem \
+          list SB_Global],
+         [0], [stdout], [ignore])
+AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
+                    --private-key=$PKIDIR/testpki-privkey.pem \
+                    --certificate=$PKIDIR/testpki-cert.pem \
+                    --ca-cert=$PKIDIR/testpki-cacert.pem \
+          list Connection],
+         [0], [stdout], [ignore])
+AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
+                    --private-key=$PKIDIR/testpki-privkey.pem \
+                    --certificate=$PKIDIR/testpki-cert.pem \
+                    --ca-cert=$PKIDIR/testpki-cacert.pem \
+          get-connection],
+         [0], [stdout], [ignore])
+
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+AT_CLEANUP
+
 AT_SETUP([ovn -- nested containers])
 ovn_start
 
-- 
2.5.5

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to