]> git.proxmox.com Git - ovs.git/blame - ovn/controller/chassis.c
Move lib/dynamic-string.h to include/openvswitch directory
[ovs.git] / ovn / controller / chassis.c
CommitLineData
717c7fc5
JP
1/* Copyright (c) 2015 Nicira, Inc.
2 *
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:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
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.
14 */
15
16#include <config.h>
17#include "chassis.h"
18
717c7fc5 19#include "lib/vswitch-idl.h"
3e8a2ad1 20#include "openvswitch/dynamic-string.h"
717c7fc5 21#include "openvswitch/vlog.h"
e3df8838 22#include "ovn/lib/ovn-sb-idl.h"
717c7fc5
JP
23#include "ovn-controller.h"
24
25VLOG_DEFINE_THIS_MODULE(chassis);
26
27void
4a5a9e06 28chassis_register_ovs_idl(struct ovsdb_idl *ovs_idl)
717c7fc5 29{
4a5a9e06
BP
30 ovsdb_idl_add_table(ovs_idl, &ovsrec_table_open_vswitch);
31 ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_external_ids);
717c7fc5
JP
32}
33
bf388125
JP
34static const char *
35pop_tunnel_name(uint32_t *type)
36{
37 if (*type & GENEVE) {
38 *type &= ~GENEVE;
39 return "geneve";
40 } else if (*type & STT) {
41 *type &= ~STT;
42 return "stt";
43 } else if (*type & VXLAN) {
44 *type &= ~VXLAN;
45 return "vxlan";
46 }
47
48 OVS_NOT_REACHED();
49}
50
deab5e67 51void
4acc496e 52chassis_run(struct controller_ctx *ctx, const char *chassis_id)
717c7fc5 53{
deab5e67
BP
54 if (!ctx->ovnsb_idl_txn) {
55 return;
56 }
57
717c7fc5
JP
58 const struct sbrec_chassis *chassis_rec;
59 const struct ovsrec_open_vswitch *cfg;
60 const char *encap_type, *encap_ip;
61 static bool inited = false;
62
2ddf7558 63 chassis_rec = get_chassis(ctx->ovnsb_idl, chassis_id);
717c7fc5 64
717c7fc5
JP
65 cfg = ovsrec_open_vswitch_first(ctx->ovs_idl);
66 if (!cfg) {
67 VLOG_INFO("No Open_vSwitch row defined.");
68 return;
69 }
70
71 encap_type = smap_get(&cfg->external_ids, "ovn-encap-type");
72 encap_ip = smap_get(&cfg->external_ids, "ovn-encap-ip");
73 if (!encap_type || !encap_ip) {
74 VLOG_INFO("Need to specify an encap type and ip");
75 return;
76 }
77
bf388125
JP
78 char *tokstr = xstrdup(encap_type);
79 char *save_ptr = NULL;
80 char *token;
81 uint32_t req_tunnels = 0;
82 for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL;
83 token = strtok_r(NULL, ",", &save_ptr)) {
84 uint32_t type = get_tunnel_type(token);
85 if (!type) {
86 VLOG_INFO("Unknown tunnel type: %s", token);
87 }
88 req_tunnels |= type;
89 }
90 free(tokstr);
91
717c7fc5 92 if (chassis_rec) {
bf388125
JP
93 /* Compare desired tunnels against those currently in the database. */
94 uint32_t cur_tunnels = 0;
95 bool same = true;
96 for (int i = 0; i < chassis_rec->n_encaps; i++) {
97 cur_tunnels |= get_tunnel_type(chassis_rec->encaps[i]->type);
7fd06fc7 98 same = same && !strcmp(chassis_rec->encaps[i]->ip, encap_ip);
bf388125
JP
99 }
100 same = same && req_tunnels == cur_tunnels;
101
102 if (same) {
103 /* Nothing changed. */
104 inited = true;
105 return;
106 } else if (!inited) {
107 struct ds cur_encaps = DS_EMPTY_INITIALIZER;
108 for (int i = 0; i < chassis_rec->n_encaps; i++) {
109 ds_put_format(&cur_encaps, "%s,",
110 chassis_rec->encaps[i]->type);
717c7fc5 111 }
bf388125
JP
112 ds_chomp(&cur_encaps, ',');
113
114 VLOG_WARN("Chassis config changing on startup, make sure "
115 "multiple chassis are not configured : %s/%s->%s/%s",
116 ds_cstr(&cur_encaps),
117 chassis_rec->encaps[0]->ip,
118 encap_type, encap_ip);
119 ds_destroy(&cur_encaps);
717c7fc5
JP
120 }
121 }
122
f1fd7657 123 ovsdb_idl_txn_add_comment(ctx->ovnsb_idl_txn,
e4901fe0 124 "ovn-controller: registering chassis '%s'",
4acc496e 125 chassis_id);
e4901fe0
JP
126
127 if (!chassis_rec) {
f1fd7657 128 chassis_rec = sbrec_chassis_insert(ctx->ovnsb_idl_txn);
4acc496e 129 sbrec_chassis_set_name(chassis_rec, chassis_id);
e4901fe0
JP
130 }
131
bf388125
JP
132 int n_encaps = count_1bits(req_tunnels);
133 struct sbrec_encap **encaps = xmalloc(n_encaps * sizeof *encaps);
134 for (int i = 0; i < n_encaps; i++) {
135 const char *type = pop_tunnel_name(&req_tunnels);
136
137 encaps[i] = sbrec_encap_insert(ctx->ovnsb_idl_txn);
e4901fe0 138
bf388125
JP
139 sbrec_encap_set_type(encaps[i], type);
140 sbrec_encap_set_ip(encaps[i], encap_ip);
141 }
e4901fe0 142
bf388125
JP
143 sbrec_chassis_set_encaps(chassis_rec, encaps, n_encaps);
144 free(encaps);
e4901fe0 145
717c7fc5
JP
146 inited = true;
147}
148
f1fd7657
BP
149/* Returns true if the database is all cleaned up, false if more work is
150 * required. */
151bool
4acc496e 152chassis_cleanup(struct controller_ctx *ctx, const char *chassis_id)
717c7fc5 153{
30a4256f
BP
154 if (!chassis_id) {
155 return true;
156 }
157
f1fd7657
BP
158 /* Delete Chassis row. */
159 const struct sbrec_chassis *chassis_rec
2ddf7558 160 = get_chassis(ctx->ovnsb_idl, chassis_id);
deab5e67
BP
161 if (!chassis_rec) {
162 return true;
163 }
164 if (ctx->ovnsb_idl_txn) {
f1fd7657 165 ovsdb_idl_txn_add_comment(ctx->ovnsb_idl_txn,
717c7fc5 166 "ovn-controller: unregistering chassis '%s'",
4acc496e 167 chassis_id);
717c7fc5 168 sbrec_chassis_delete(chassis_rec);
e4901fe0 169 }
deab5e67 170 return false;
717c7fc5 171}