]>
Commit | Line | Data |
---|---|---|
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 | ||
25 | VLOG_DEFINE_THIS_MODULE(chassis); | |
26 | ||
27 | void | |
4a5a9e06 | 28 | chassis_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 |
34 | static const char * |
35 | pop_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 | 51 | void |
4acc496e | 52 | chassis_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. */ | |
151 | bool | |
4acc496e | 152 | chassis_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 | } |