Permalink
Browse files

ovn: Introduce ovn-controller.

Add new ovn-controller daemon that runs locally on transport nodes.
This initial version registers itself in the Chassis table and registers
logical ports to the appropriate rows in the Bindings table.

Signed-off-by: Justin Pettit <jpettit@nicira.com>
Acked-by: Russell Bryant <rbryant@redhat.com>
  • Loading branch information...
1 parent a0149f4 commit 717c7fc508044d08210c686c1e8576c29a108f86 @justinpettit justinpettit committed Apr 9, 2015
View
@@ -371,3 +371,4 @@ include vtep/automake.mk
include datapath-windows/automake.mk
include datapath-windows/include/automake.mk
include ovn/automake.mk
+include ovn/controller/automake.mk
View
@@ -1,5 +1,4 @@
/ovn-architecture.7
-/ovn-controller.8
/ovn-nb.5
/ovn-nb.gv
/ovn-nb.pic
View
@@ -129,17 +129,6 @@
** Interaction with Open_vSwitch and OVN databases:
-*** Monitor VIFs attached to the integration bridge in Open_vSwitch.
-
- In response to changes, add or remove corresponding rows in
- Bindings table in OVN.
-
-*** Populate Chassis row in OVN at startup. Maintain Chassis row over time.
-
- (Warn if any other Chassis claims the same IP address.)
-
-*** Remove Chassis and Bindings rows from OVN on exit.
-
*** Monitor Chassis table in OVN.
Populate Port records for tunnels to other chassis into
@@ -155,14 +144,6 @@
Default: VXLAN? Geneve?
-*** Location of Open_vSwitch database.
-
- We can probably use the same default as ovs-vsctl.
-
-*** Location of OVN Southbound database.
-
- Probably no useful default.
-
*** SSL configuration.
Can probably get this from Open_vSwitch database.
View
@@ -66,8 +66,8 @@ ovn/ovn-nb.5: \
$(srcdir)/ovn/ovn-nb.xml > $@.tmp && \
mv $@.tmp $@
-man_MANS += ovn/ovn-controller.8 ovn/ovn-architecture.7 ovn/ovn-nbctl.8
-EXTRA_DIST += ovn/ovn-controller.8.in ovn/ovn-architecture.7.xml ovn/ovn-nbctl.8.xml
+man_MANS += ovn/ovn-architecture.7 ovn/ovn-nbctl.8
+EXTRA_DIST += ovn/ovn-architecture.7.xml ovn/ovn-nbctl.8.xml
SUFFIXES += .xml
%: %.xml
@@ -0,0 +1,2 @@
+/ovn-controller
+/ovn-controller.8
@@ -0,0 +1,11 @@
+bin_PROGRAMS += ovn/controller/ovn-controller
+ovn_controller_ovn_controller_SOURCES = \
+ ovn/controller/bindings.c \
+ ovn/controller/bindings.h \
+ ovn/controller/chassis.c \
+ ovn/controller/chassis.h \
+ ovn/controller/ovn-controller.c \
+ ovn/controller/ovn-controller.h
+ovn_controller_ovn_controller_LDADD = ovn/libovn.la lib/libopenvswitch.la
+man_MANS += ovn/controller/ovn-controller.8
+EXTRA_DIST += ovn/controller/ovn-controller.8.xml
@@ -0,0 +1,179 @@
+/* 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 "bindings.h"
+
+#include "lib/sset.h"
+#include "lib/util.h"
+#include "lib/vswitch-idl.h"
+#include "openvswitch/vlog.h"
+#include "ovn/ovn-sb-idl.h"
+#include "ovn-controller.h"
+
+VLOG_DEFINE_THIS_MODULE(bindings);
+
+#define DEFAULT_BRIDGE_NAME "br-int"
+
+void
+bindings_init(struct controller_ctx *ctx)
+{
+ ovsdb_idl_add_table(ctx->ovs_idl, &ovsrec_table_open_vswitch);
+ ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_open_vswitch_col_bridges);
+
+ ovsdb_idl_add_table(ctx->ovs_idl, &ovsrec_table_bridge);
+ ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_bridge_col_name);
+ ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_bridge_col_ports);
+
+ ovsdb_idl_add_table(ctx->ovs_idl, &ovsrec_table_port);
+ ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_port_col_name);
+ ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_port_col_interfaces);
+
+ ovsdb_idl_add_table(ctx->ovs_idl, &ovsrec_table_interface);
+ ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_interface_col_name);
+ ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_interface_col_external_ids);
+}
+
+static void
+get_local_iface_ids(struct controller_ctx *ctx, struct sset *lports)
+{
+ const struct ovsrec_open_vswitch *cfg;
+ const struct ovsrec_bridge *bridge_rec;
+ const char *bridge_name;
+ int i;
+
+ cfg = ovsrec_open_vswitch_first(ctx->ovs_idl);
+ if (!cfg) {
+ VLOG_INFO("No Open_vSwitch row defined.");
+ return;
+ }
+
+ bridge_name = smap_get(&cfg->external_ids, "ovn-bridge");
+ if (!bridge_name) {
+ bridge_name = DEFAULT_BRIDGE_NAME;
+ }
+
+ OVSREC_BRIDGE_FOR_EACH(bridge_rec, ctx->ovs_idl) {
+ if (!strcmp(bridge_rec->name, bridge_name)) {
+ break;
+ }
+ }
+
+ if (!bridge_rec) {
+ VLOG_INFO("Could not find bridge '%s'", bridge_name);
+ return;
+ }
+
+ for (i = 0; i < bridge_rec->n_ports; i++) {
+ const struct ovsrec_port *port_rec = bridge_rec->ports[i];
+ const char *iface_id;
+ int j;
+
+ if (!strcmp(port_rec->name, bridge_rec->name)) {
+ continue;
+ }
+
+ for (j = 0; j < port_rec->n_interfaces; j++) {
+ const struct ovsrec_interface *iface_rec;
+
+ iface_rec = port_rec->interfaces[j];
+ iface_id = smap_get(&iface_rec->external_ids, "iface-id");
+ if (!iface_id) {
+ VLOG_DBG("Could not find iface-id for '%s'", iface_rec->name);
+ continue;
+ }
+ sset_add(lports, iface_id);
+ }
+ }
+}
+
+void
+bindings_run(struct controller_ctx *ctx)
+{
+ const struct sbrec_bindings *bindings_rec;
+ struct ovsdb_idl_txn *txn;
+ struct sset lports;
+ const char *name;
+ int retval;
+
+ sset_init(&lports);
+ get_local_iface_ids(ctx, &lports);
+
+ txn = ovsdb_idl_txn_create(ctx->ovnsb_idl);
+ ovsdb_idl_txn_add_comment(txn,
+ "ovn-controller: updating bindings for '%s'",
+ ctx->chassis_name);
+
+ SBREC_BINDINGS_FOR_EACH(bindings_rec, ctx->ovnsb_idl) {
+ if (sset_find_and_delete(&lports, bindings_rec->logical_port)) {
+ if (!strcmp(bindings_rec->chassis, ctx->chassis_name)) {
+ continue;
+ }
+ if (bindings_rec->chassis[0]) {
+ VLOG_INFO("Changing chassis for lport %s from %s to %s",
+ bindings_rec->logical_port, bindings_rec->chassis,
+ ctx->chassis_name);
+ }
+ sbrec_bindings_set_chassis(bindings_rec, ctx->chassis_name);
+ } else if (!strcmp(bindings_rec->chassis, ctx->chassis_name)) {
+ sbrec_bindings_set_chassis(bindings_rec, "");
+ }
+ }
+
+ retval = ovsdb_idl_txn_commit_block(txn);
+ if (retval == TXN_ERROR) {
+ VLOG_INFO("Problem committing bindings information: %s",
+ ovsdb_idl_txn_status_to_string(retval));
+ }
+
+ ovsdb_idl_txn_destroy(txn);
+
+ SSET_FOR_EACH (name, &lports) {
+ VLOG_DBG("No binding record for lport %s", name);
+ }
+ sset_destroy(&lports);
+}
+
+void
+bindings_destroy(struct controller_ctx *ctx)
+{
+ int retval = TXN_TRY_AGAIN;
+
+ ovs_assert(ctx->ovnsb_idl);
+
+ while (retval != TXN_SUCCESS && retval != TXN_UNCHANGED) {
+ const struct sbrec_bindings *bindings_rec;
+ struct ovsdb_idl_txn *txn;
+
+ txn = ovsdb_idl_txn_create(ctx->ovnsb_idl);
+ ovsdb_idl_txn_add_comment(txn,
+ "ovn-controller: removing all bindings for '%s'",
+ ctx->chassis_name);
+
+ SBREC_BINDINGS_FOR_EACH(bindings_rec, ctx->ovnsb_idl) {
+ if (!strcmp(bindings_rec->chassis, ctx->chassis_name)) {
+ sbrec_bindings_set_chassis(bindings_rec, "");
+ }
+ }
+
+ retval = ovsdb_idl_txn_commit_block(txn);
+ if (retval == TXN_ERROR) {
+ VLOG_INFO("Problem removing bindings: %s",
+ ovsdb_idl_txn_status_to_string(retval));
+ }
+
+ ovsdb_idl_txn_destroy(txn);
+ }
+}
@@ -0,0 +1,26 @@
+/* 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_BINDINGS_H
+#define OVN_BINDINGS_H 1
+
+struct controller_ctx;
+
+void bindings_init(struct controller_ctx *);
+void bindings_run(struct controller_ctx *);
+void bindings_destroy(struct controller_ctx *);
+
+#endif /* ovn/bindings.h */
Oops, something went wrong.

0 comments on commit 717c7fc

Please sign in to comment.