This commit lays down the foundation for a new controller in OVN, the ovn-controller-vtep, for controlling the vtep enabled physical switches.
Limitation: - How to make controller-vtep connect to OVN_SB? my understanding is that vtep should not know the location of ovnsb. but there is no "external_ids" column in vtep schema. and the manager for vtep should be the controller-gw. so, the implementation requires user to specify both vtep, and ovnsb location from command line. Signed-off-by: Alex Wang <al...@nicira.com> --- V2->V3: - rebase to master. PATCH->V2: - split into separate commit. - add manpage for ovn-controller-vtep. --- ovn/automake.mk | 1 + ovn/controller-vtep/.gitignore | 2 + ovn/controller-vtep/automake.mk | 8 + ovn/controller-vtep/ovn-controller-vtep.8.xml | 70 +++++++ ovn/controller-vtep/ovn-controller-vtep.c | 263 +++++++++++++++++++++++++ ovn/controller-vtep/ovn-controller-vtep.h | 27 +++ tests/automake.mk | 6 +- tests/ovn-controller-vtep.at | 1 + tests/testsuite.at | 1 + 9 files changed, 376 insertions(+), 3 deletions(-) create mode 100644 ovn/controller-vtep/.gitignore create mode 100644 ovn/controller-vtep/automake.mk create mode 100644 ovn/controller-vtep/ovn-controller-vtep.8.xml create mode 100644 ovn/controller-vtep/ovn-controller-vtep.c create mode 100644 ovn/controller-vtep/ovn-controller-vtep.h create mode 100644 tests/ovn-controller-vtep.at diff --git a/ovn/automake.mk b/ovn/automake.mk index 7d84c52..f650d22 100644 --- a/ovn/automake.mk +++ b/ovn/automake.mk @@ -75,6 +75,7 @@ EXTRA_DIST += \ ovn/CONTAINERS.OpenStack.md include ovn/controller/automake.mk +include ovn/controller-vtep/automake.mk include ovn/lib/automake.mk include ovn/northd/automake.mk include ovn/utilities/automake.mk diff --git a/ovn/controller-vtep/.gitignore b/ovn/controller-vtep/.gitignore new file mode 100644 index 0000000..3ec8072 --- /dev/null +++ b/ovn/controller-vtep/.gitignore @@ -0,0 +1,2 @@ +/ovn-controller-vtep +/ovn-controller-vtep.8 diff --git a/ovn/controller-vtep/automake.mk b/ovn/controller-vtep/automake.mk new file mode 100644 index 0000000..7adda15 --- /dev/null +++ b/ovn/controller-vtep/automake.mk @@ -0,0 +1,8 @@ +bin_PROGRAMS += ovn/controller-vtep/ovn-controller-vtep +ovn_controller_vtep_ovn_controller_vtep_SOURCES = \ + ovn/controller-vtep/ovn-controller-vtep.c \ + ovn/controller-vtep/ovn-controller-vtep.h +ovn_controller_vtep_ovn_controller_vtep_LDADD = ovn/lib/libovn.la lib/libopenvswitch.la vtep/libvtep.la +man_MANS += ovn/controller-vtep/ovn-controller-vtep.8 +EXTRA_DIST += ovn/controller-vtep/ovn-controller-vtep.8.xml +DISTCLEANFILES += ovn/controller-vtep/ovn-controller-vtep.8 diff --git a/ovn/controller-vtep/ovn-controller-vtep.8.xml b/ovn/controller-vtep/ovn-controller-vtep.8.xml new file mode 100644 index 0000000..c924f9f --- /dev/null +++ b/ovn/controller-vtep/ovn-controller-vtep.8.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8"?> +<manpage program="ovn-controller-vtep" section="8" title="ovn-controller-vtep"> + <h1>Name</h1> + <p>ovn-controller-vtep -- Open Virtual Network local controller for + vtep enabled physical switches. + </p> + + <h1>Synopsis</h1> + <p><code>ovn-controller-vtep</code> [<var>options</var>] + [<var>--vtep-db=vtep-database</var>] [<var>--ovnsb-db=ovnsb-database</var>] + </p> + + <h1>Description</h1> + <p> + <code>ovn-controller-vtep</code> is the local controller daemon in + OVN, the Open Virtual Network, for VTEP enabled physical switches. + It connects up to the OVN Southbound database (see + <code>ovn-sb</code>(5)) over the OVSDB protocol, and down to the VTEP + database (see <code>vtep</code>(5)) over the OVSDB protocol. + </p> + + <h1>Configuration</h1> + <p> + <code>ovn-controller-vtep</code> retrieves its configuration + information from both the ovnsb and the vtep database. If the + database locations are not given from command line, the default + is the <code>db.sock</code> in local OVSDB's 'run' directory. + The datapath location must take one of the following forms: + </p> + <ul> + <li> + <p> + <code>ssl:<var>ip</var>:<var>port</var></code> + </p> + <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) in IPv4 or IPv6 address format. If <var>ip</var> is an IPv6 + address, then wrap <var>ip</var> with square brackets, e.g.: + <code>ssl:[::1]:6640</code>. The <code>--private-key</code>, + <code>--certificate</code>, and <code>--ca-cert</code> options are + mandatory when this form is used. + </p> + </li> + <li> + <p> + <code>tcp:<var>ip</var>:<var>port</var></code> + </p> + <p> + Connect to the given TCP <var>port</var> on <var>ip</var>, where + <var>ip</var> can be IPv4 or IPv6 address. If <var>ip</var> is an + IPv6 address, then wrap <var>ip</var> with square brackets, e.g.: + <code>tcp:[::1]:6640</code>. + </p> + </li> + <li> + <p> + <code>unix:<var>file</var></code> + </p> + <p> + On POSIX, connect to the Unix domain server socket named + <var>file</var>. + </p> + <p> + On Windows, connect to a localhost TCP port whose value is written + in <var>file</var>. + </p> + </li> + </ul> +</manpage> diff --git a/ovn/controller-vtep/ovn-controller-vtep.c b/ovn/controller-vtep/ovn-controller-vtep.c new file mode 100644 index 0000000..50d727f --- /dev/null +++ b/ovn/controller-vtep/ovn-controller-vtep.c @@ -0,0 +1,263 @@ +/* Copyright (c) 2015 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <config.h> + +#include <errno.h> +#include <getopt.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> + +#include "command-line.h" +#include "compiler.h" +#include "daemon.h" +#include "dirs.h" +#include "dynamic-string.h" +#include "openvswitch/vconn.h" +#include "openvswitch/vlog.h" +#include "ovn/lib/ovn-sb-idl.h" +#include "poll-loop.h" +#include "fatal-signal.h" +#include "vtep/vtep-idl.h" +#include "smap.h" +#include "stream.h" +#include "stream-ssl.h" +#include "unixctl.h" +#include "util.h" + +#include "ovn-controller-vtep.h" + +VLOG_DEFINE_THIS_MODULE(ovn_vtep); + +static unixctl_cb_func ovn_controller_vtep_exit; + +static void parse_options(int argc, char *argv[]); +OVS_NO_RETURN static void usage(void); + +static char *vtep_remote; +static char *ovnsb_remote; + +static void +get_initial_snapshot(struct ovsdb_idl *idl) +{ + while (1) { + ovsdb_idl_run(idl); + if (ovsdb_idl_has_ever_connected(idl)) { + return; + } + ovsdb_idl_wait(idl); + poll_block(); + } +} + +int +main(int argc, char *argv[]) +{ + struct unixctl_server *unixctl; + struct controller_vtep_ctx ctx; + bool exiting; + int retval; + + ovs_cmdl_proctitle_init(argc, argv); + set_program_name(argv[0]); + parse_options(argc, argv); + fatal_ignore_sigpipe(); + + daemonize_start(); + + retval = unixctl_server_create(NULL, &unixctl); + if (retval) { + exit(EXIT_FAILURE); + } + unixctl_command_register("exit", "", 0, 0, ovn_controller_vtep_exit, + &exiting); + + daemonize_complete(); + + vteprec_init(); + sbrec_init(); + + /* Connect to VTEP OVSDB instance. We monitor all tables by + * default */ + ctx.vtep_idl = ovsdb_idl_create(vtep_remote, &vteprec_idl_class, true, true); + get_initial_snapshot(ctx.vtep_idl); + ctx.ovnsb_idl = ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, + true, true); + get_initial_snapshot(ctx.ovnsb_idl); + + ovs_assert(vteprec_global_first(ctx.vtep_idl)); + + exiting = false; + while (!exiting) { + ovsdb_idl_run(ctx.vtep_idl); + ovsdb_idl_run(ctx.ovnsb_idl); + + if (!ovsdb_idl_is_alive(ctx.ovnsb_idl)) { + int retval = ovsdb_idl_get_last_error(ctx.ovnsb_idl); + VLOG_ERR("%s: database connection failed (%s)", + ovnsb_remote, ovs_retval_to_string(retval)); + retval = EXIT_FAILURE; + break; + } + + if (!ovsdb_idl_is_alive(ctx.vtep_idl)) { + int retval = ovsdb_idl_get_last_error(ctx.vtep_idl); + VLOG_ERR("%s: database connection failed (%s)", + vtep_remote, ovs_retval_to_string(retval)); + retval = EXIT_FAILURE; + break; + } + + unixctl_server_run(unixctl); + + unixctl_server_wait(unixctl); + if (exiting) { + poll_immediate_wake(); + } + + ovsdb_idl_wait(ctx.vtep_idl); + ovsdb_idl_wait(ctx.ovnsb_idl); + poll_block(); + } + + unixctl_server_destroy(unixctl); + + ovsdb_idl_destroy(ctx.vtep_idl); + ovsdb_idl_destroy(ctx.ovnsb_idl); + + free(ovnsb_remote); + free(vtep_remote); + + exit(retval); +} + +static char * +default_db(void) +{ + static char *def; + if (!def) { + def = xasprintf("unix:%s/db.sock", ovs_rundir()); + } + return def; +} + +static void +parse_options(int argc, char *argv[]) +{ + enum { + OPT_PEER_CA_CERT = UCHAR_MAX + 1, + VLOG_OPTION_ENUMS, + DAEMON_OPTION_ENUMS + }; + + static struct option long_options[] = { + {"ovnsb-db", required_argument, NULL, 'd'}, + {"vtep-db", required_argument, NULL, 'D'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, + VLOG_LONG_OPTIONS, + DAEMON_LONG_OPTIONS, + STREAM_SSL_LONG_OPTIONS, + {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT}, + {NULL, 0, NULL, 0} + }; + char *short_options = ovs_cmdl_long_options_to_short_options(long_options); + + for (;;) { + int c; + + c = getopt_long(argc, argv, short_options, long_options, NULL); + if (c == -1) { + break; + } + + switch (c) { + case 'd': + ovnsb_remote = optarg; + break; + + case 'D': + vtep_remote = optarg; + break; + + case 'h': + usage(); + + case 'V': + ovs_print_version(OFP13_VERSION, OFP13_VERSION); + exit(EXIT_SUCCESS); + + VLOG_OPTION_HANDLERS + DAEMON_OPTION_HANDLERS + STREAM_SSL_OPTION_HANDLERS + + case OPT_PEER_CA_CERT: + stream_ssl_set_peer_ca_cert_file(optarg); + break; + + case '?': + exit(EXIT_FAILURE); + + default: + abort(); + } + } + free(short_options); + + argc -= optind; + argv += optind; + + if (!ovnsb_remote) { + ovnsb_remote = default_db(); + } + + if (!vtep_remote) { + vtep_remote = default_db(); + } +} + +static void +usage(void) +{ + printf("\ +%s: OVN controller VTEP\n\ +usage %s [OPTIONS]\n\ +\n\ +Options:\n\ + --vtep-db=DATABASE connect to vtep database at DATABASE\n\ + (default: %s)\n\ + --ovnsb-db=DATABASE connect to ovn-sb database at DATABASE\n\ + (default: %s)\n\ + -h, --help display this help message\n\ + -o, --options list available options\n\ + -V, --version display version information\n\ +", program_name, program_name, default_db(), default_db()); + stream_usage("database", true, false, false); + daemon_usage(); + vlog_usage(); + exit(EXIT_SUCCESS); +} + + +static void +ovn_controller_vtep_exit(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *exiting_) +{ + bool *exiting = exiting_; + *exiting = true; + + unixctl_command_reply(conn, NULL); +} diff --git a/ovn/controller-vtep/ovn-controller-vtep.h b/ovn/controller-vtep/ovn-controller-vtep.h new file mode 100644 index 0000000..121a9e3 --- /dev/null +++ b/ovn/controller-vtep/ovn-controller-vtep.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2015 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef OVN_CONTROLLER_VTEP_H +#define OVN_CONTROLLER_VTEP_H 1 + +#include "ovn/lib/ovn-sb-idl.h" + +struct controller_vtep_ctx { + struct ovsdb_idl *ovnsb_idl; + struct ovsdb_idl *vtep_idl; +}; + +#endif /* ovn/ovn-controller-vtep.h */ diff --git a/tests/automake.mk b/tests/automake.mk index 1f16f3c..b597e77 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -84,8 +84,8 @@ TESTSUITE_AT = \ tests/vtep-ctl.at \ tests/auto-attach.at \ tests/ovn.at \ - tests/ovn-sbctl.at - + tests/ovn-sbctl.at \ + tests/ovn-controller-vtep.at KMOD_TESTSUITE_AT = \ tests/kmod-testsuite.at \ tests/kmod-macros.at \ @@ -96,7 +96,7 @@ TESTSUITE_PATCH = $(srcdir)/tests/testsuite.patch KMOD_TESTSUITE = $(srcdir)/tests/kmod-testsuite DISTCLEANFILES += tests/atconfig tests/atlocal -AUTOTEST_PATH = utilities:vswitchd:ovsdb:vtep:tests:$(PTHREAD_WIN32_DIR_DLL):ovn:ovn/northd:ovn/utilities +AUTOTEST_PATH = utilities:vswitchd:ovsdb:vtep:tests:$(PTHREAD_WIN32_DIR_DLL):ovn:ovn/controller-vtep:ovn/northd:ovn/utilities check-local: tests/atconfig tests/atlocal $(TESTSUITE) $(SHELL) '$(TESTSUITE)' -C tests AUTOTEST_PATH=$(AUTOTEST_PATH) $(TESTSUITEFLAGS) diff --git a/tests/ovn-controller-vtep.at b/tests/ovn-controller-vtep.at new file mode 100644 index 0000000..bcae89c --- /dev/null +++ b/tests/ovn-controller-vtep.at @@ -0,0 +1 @@ +AT_BANNER([ovn_controller_vtep]) diff --git a/tests/testsuite.at b/tests/testsuite.at index f706f67..384efdf 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -18,6 +18,7 @@ m4_include([tests/ovs-macros.at]) m4_include([tests/ovsdb-macros.at]) m4_include([tests/ofproto-macros.at]) +m4_include([tests/ovn-controller-vtep.at]) m4_include([tests/completion.at]) m4_include([tests/bfd.at]) m4_include([tests/cfm.at]) -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev