1 /* Copyright (c) 2015 Nicira, Inc.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
21 #include "lib/vswitch-idl.h"
22 #include "openvswitch/vlog.h"
23 #include "ovn/lib/ovn-sb-idl.h"
24 #include "ovn-controller.h"
26 VLOG_DEFINE_THIS_MODULE(binding);
29 binding_init(struct controller_ctx *ctx)
31 ovsdb_idl_add_table(ctx->ovs_idl, &ovsrec_table_open_vswitch);
32 ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_open_vswitch_col_bridges);
34 ovsdb_idl_add_table(ctx->ovs_idl, &ovsrec_table_bridge);
35 ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_bridge_col_name);
36 ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_bridge_col_ports);
38 ovsdb_idl_add_table(ctx->ovs_idl, &ovsrec_table_port);
39 ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_port_col_name);
40 ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_port_col_interfaces);
42 ovsdb_idl_add_table(ctx->ovs_idl, &ovsrec_table_interface);
43 ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_interface_col_name);
44 ovsdb_idl_add_column(ctx->ovs_idl, &ovsrec_interface_col_external_ids);
48 get_local_iface_ids(struct controller_ctx *ctx, struct sset *lports)
52 for (i = 0; i < ctx->br_int->n_ports; i++) {
53 const struct ovsrec_port *port_rec = ctx->br_int->ports[i];
57 if (!strcmp(port_rec->name, ctx->br_int_name)) {
61 for (j = 0; j < port_rec->n_interfaces; j++) {
62 const struct ovsrec_interface *iface_rec;
64 iface_rec = port_rec->interfaces[j];
65 iface_id = smap_get(&iface_rec->external_ids, "iface-id");
69 sset_add(lports, iface_id);
75 binding_run(struct controller_ctx *ctx)
77 const struct sbrec_binding *binding_rec;
78 struct ovsdb_idl_txn *txn;
79 struct sset lports, all_lports;
84 sset_init(&all_lports);
85 get_local_iface_ids(ctx, &lports);
86 sset_clone(&all_lports, &lports);
88 txn = ovsdb_idl_txn_create(ctx->ovnsb_idl);
89 ovsdb_idl_txn_add_comment(txn,
90 "ovn-controller: updating bindings for '%s'",
93 SBREC_BINDING_FOR_EACH(binding_rec, ctx->ovnsb_idl) {
94 if (sset_find_and_delete(&lports, binding_rec->logical_port) ||
95 (binding_rec->parent_port && binding_rec->parent_port[0] &&
96 sset_contains(&all_lports, binding_rec->parent_port))) {
97 if (!strcmp(binding_rec->chassis, ctx->chassis_id)) {
100 if (binding_rec->chassis[0]) {
101 VLOG_INFO("Changing chassis for lport %s from %s to %s",
102 binding_rec->logical_port, binding_rec->chassis,
105 sbrec_binding_set_chassis(binding_rec, ctx->chassis_id);
106 } else if (!strcmp(binding_rec->chassis, ctx->chassis_id)) {
107 sbrec_binding_set_chassis(binding_rec, "");
111 retval = ovsdb_idl_txn_commit_block(txn);
112 if (retval == TXN_ERROR) {
113 VLOG_INFO("Problem committing binding information: %s",
114 ovsdb_idl_txn_status_to_string(retval));
117 ovsdb_idl_txn_destroy(txn);
119 SSET_FOR_EACH (name, &lports) {
120 VLOG_DBG("No binding record for lport %s", name);
122 sset_destroy(&lports);
123 sset_destroy(&all_lports);
127 binding_destroy(struct controller_ctx *ctx)
129 int retval = TXN_TRY_AGAIN;
131 ovs_assert(ctx->ovnsb_idl);
133 while (retval != TXN_SUCCESS && retval != TXN_UNCHANGED) {
134 const struct sbrec_binding *binding_rec;
135 struct ovsdb_idl_txn *txn;
137 txn = ovsdb_idl_txn_create(ctx->ovnsb_idl);
138 ovsdb_idl_txn_add_comment(txn,
139 "ovn-controller: removing all bindings for '%s'",
142 SBREC_BINDING_FOR_EACH(binding_rec, ctx->ovnsb_idl) {
143 if (!strcmp(binding_rec->chassis, ctx->chassis_id)) {
144 sbrec_binding_set_chassis(binding_rec, "");
148 retval = ovsdb_idl_txn_commit_block(txn);
149 if (retval == TXN_ERROR) {
150 VLOG_INFO("Problem removing bindings: %s",
151 ovsdb_idl_txn_status_to_string(retval));
154 ovsdb_idl_txn_destroy(txn);