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_register_ovs_idl(struct ovsdb_idl
*ovs_idl
)
31 ovsdb_idl_add_table(ovs_idl
, &ovsrec_table_open_vswitch
);
32 ovsdb_idl_add_column(ovs_idl
, &ovsrec_open_vswitch_col_bridges
);
34 ovsdb_idl_add_table(ovs_idl
, &ovsrec_table_bridge
);
35 ovsdb_idl_add_column(ovs_idl
, &ovsrec_bridge_col_name
);
36 ovsdb_idl_add_column(ovs_idl
, &ovsrec_bridge_col_ports
);
38 ovsdb_idl_add_table(ovs_idl
, &ovsrec_table_port
);
39 ovsdb_idl_add_column(ovs_idl
, &ovsrec_port_col_name
);
40 ovsdb_idl_add_column(ovs_idl
, &ovsrec_port_col_interfaces
);
42 ovsdb_idl_add_table(ovs_idl
, &ovsrec_table_interface
);
43 ovsdb_idl_add_column(ovs_idl
, &ovsrec_interface_col_name
);
44 ovsdb_idl_add_column(ovs_idl
, &ovsrec_interface_col_external_ids
);
48 get_local_iface_ids(const struct ovsrec_bridge
*br_int
, struct sset
*lports
)
52 for (i
= 0; i
< br_int
->n_ports
; i
++) {
53 const struct ovsrec_port
*port_rec
= br_int
->ports
[i
];
57 if (!strcmp(port_rec
->name
, 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
, const struct ovsrec_bridge
*br_int
,
76 const char *chassis_id
)
78 const struct sbrec_chassis
*chassis_rec
;
79 const struct sbrec_port_binding
*binding_rec
;
80 struct sset lports
, all_lports
;
83 if (!ctx
->ovnsb_idl_txn
) {
87 chassis_rec
= get_chassis_by_name(ctx
->ovnsb_idl
, chassis_id
);
93 sset_init(&all_lports
);
95 get_local_iface_ids(br_int
, &lports
);
97 /* We have no integration bridge, therefore no local logical ports.
98 * We'll remove our chassis from all port binding records below. */
100 sset_clone(&all_lports
, &lports
);
102 ovsdb_idl_txn_add_comment(
103 ctx
->ovnsb_idl_txn
,"ovn-controller: updating port bindings for '%s'",
106 SBREC_PORT_BINDING_FOR_EACH(binding_rec
, ctx
->ovnsb_idl
) {
107 if (sset_find_and_delete(&lports
, binding_rec
->logical_port
) ||
108 (binding_rec
->parent_port
&& binding_rec
->parent_port
[0] &&
109 sset_contains(&all_lports
, binding_rec
->parent_port
))) {
110 if (binding_rec
->chassis
== chassis_rec
) {
113 if (binding_rec
->chassis
) {
114 VLOG_INFO("Changing chassis for lport %s from %s to %s",
115 binding_rec
->logical_port
,
116 binding_rec
->chassis
->name
,
119 sbrec_port_binding_set_chassis(binding_rec
, chassis_rec
);
120 } else if (binding_rec
->chassis
== chassis_rec
) {
121 sbrec_port_binding_set_chassis(binding_rec
, NULL
);
125 SSET_FOR_EACH (name
, &lports
) {
126 VLOG_DBG("No port binding record for lport %s", name
);
128 sset_destroy(&lports
);
129 sset_destroy(&all_lports
);
132 /* Returns true if the database is all cleaned up, false if more work is
135 binding_cleanup(struct controller_ctx
*ctx
, const char *chassis_id
)
137 if (!ctx
->ovnsb_idl_txn
) {
144 const struct sbrec_chassis
*chassis_rec
145 = get_chassis_by_name(ctx
->ovnsb_idl
, chassis_id
);
150 ovsdb_idl_txn_add_comment(
152 "ovn-controller: removing all port bindings for '%s'", chassis_id
);
154 const struct sbrec_port_binding
*binding_rec
;
155 bool any_changes
= false;
156 SBREC_PORT_BINDING_FOR_EACH(binding_rec
, ctx
->ovnsb_idl
) {
157 if (binding_rec
->chassis
== chassis_rec
) {
158 sbrec_port_binding_set_chassis(binding_rec
, NULL
);