]> git.proxmox.com Git - mirror_ovs.git/blob - ovn/controller-vtep/ovn-controller-vtep.c
93a0458c0eed345ef34a73eb83c07dada53592d0
[mirror_ovs.git] / ovn / controller-vtep / ovn-controller-vtep.c
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
18 #include <errno.h>
19 #include <getopt.h>
20 #include <signal.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "command-line.h"
25 #include "compiler.h"
26 #include "daemon.h"
27 #include "dirs.h"
28 #include "dynamic-string.h"
29 #include "fatal-signal.h"
30 #include "poll-loop.h"
31 #include "stream.h"
32 #include "stream-ssl.h"
33 #include "unixctl.h"
34 #include "util.h"
35 #include "openvswitch/vconn.h"
36 #include "openvswitch/vlog.h"
37 #include "ovn/lib/ovn-sb-idl.h"
38 #include "vtep/vtep-idl.h"
39
40 #include "gateway.h"
41 #include "ovn-controller-vtep.h"
42
43 static unixctl_cb_func ovn_controller_vtep_exit;
44
45 static void parse_options(int argc, char *argv[]);
46 OVS_NO_RETURN static void usage(void);
47
48 static char *vtep_remote;
49 static char *ovnsb_remote;
50
51 int
52 main(int argc, char *argv[])
53 {
54 struct unixctl_server *unixctl;
55 bool exiting;
56 int retval;
57
58 ovs_cmdl_proctitle_init(argc, argv);
59 set_program_name(argv[0]);
60 parse_options(argc, argv);
61 fatal_ignore_sigpipe();
62
63 daemonize_start();
64
65 retval = unixctl_server_create(NULL, &unixctl);
66 if (retval) {
67 exit(EXIT_FAILURE);
68 }
69 unixctl_command_register("exit", "", 0, 0, ovn_controller_vtep_exit,
70 &exiting);
71
72 daemonize_complete();
73
74 vteprec_init();
75 sbrec_init();
76
77 /* Connect to VTEP database. */
78 struct ovsdb_idl_loop vtep_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
79 ovsdb_idl_create(vtep_remote, &vteprec_idl_class, true, true));
80 ovsdb_idl_get_initial_snapshot(vtep_idl_loop.idl);
81
82 /* Connect to OVN SB database. */
83 struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
84 ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true));
85 ovsdb_idl_get_initial_snapshot(ovnsb_idl_loop.idl);
86
87 /* Main loop. */
88 exiting = false;
89 while (!exiting) {
90 struct controller_vtep_ctx ctx = {
91 .vtep_idl = vtep_idl_loop.idl,
92 .vtep_idl_txn = ovsdb_idl_loop_run(&vtep_idl_loop),
93 .ovnsb_idl = ovnsb_idl_loop.idl,
94 .ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop),
95 };
96
97 gateway_run(&ctx);
98 unixctl_server_run(unixctl);
99
100 unixctl_server_wait(unixctl);
101 if (exiting) {
102 poll_immediate_wake();
103 }
104 ovsdb_idl_loop_commit_and_wait(&vtep_idl_loop);
105 ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop);
106 poll_block();
107 }
108
109 /* It's time to exit. Clean up the databases. */
110 bool done = false;
111 while (!done) {
112 struct controller_vtep_ctx ctx = {
113 .vtep_idl = vtep_idl_loop.idl,
114 .vtep_idl_txn = ovsdb_idl_loop_run(&vtep_idl_loop),
115 .ovnsb_idl = ovnsb_idl_loop.idl,
116 .ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop),
117 };
118
119 /* Run all of the cleanup functions, even if one of them returns false.
120 * We're done if all of them return true. */
121 done = gateway_cleanup(&ctx);
122 if (done) {
123 poll_immediate_wake();
124 }
125
126 ovsdb_idl_loop_commit_and_wait(&vtep_idl_loop);
127 ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop);
128 poll_block();
129 }
130
131 unixctl_server_destroy(unixctl);
132 ovsdb_idl_loop_destroy(&vtep_idl_loop);
133 ovsdb_idl_loop_destroy(&ovnsb_idl_loop);
134
135 free(ovnsb_remote);
136 free(vtep_remote);
137
138 exit(retval);
139 }
140
141 static char *
142 default_db(void)
143 {
144 static char *def;
145 if (!def) {
146 def = xasprintf("unix:%s/db.sock", ovs_rundir());
147 }
148 return def;
149 }
150
151 static void
152 parse_options(int argc, char *argv[])
153 {
154 enum {
155 OPT_PEER_CA_CERT = UCHAR_MAX + 1,
156 VLOG_OPTION_ENUMS,
157 DAEMON_OPTION_ENUMS
158 };
159
160 static struct option long_options[] = {
161 {"ovnsb-db", required_argument, NULL, 'd'},
162 {"vtep-db", required_argument, NULL, 'D'},
163 {"help", no_argument, NULL, 'h'},
164 {"version", no_argument, NULL, 'V'},
165 VLOG_LONG_OPTIONS,
166 DAEMON_LONG_OPTIONS,
167 STREAM_SSL_LONG_OPTIONS,
168 {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
169 {NULL, 0, NULL, 0}
170 };
171 char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
172
173 for (;;) {
174 int c;
175
176 c = getopt_long(argc, argv, short_options, long_options, NULL);
177 if (c == -1) {
178 break;
179 }
180
181 switch (c) {
182 case 'd':
183 ovnsb_remote = optarg;
184 break;
185
186 case 'D':
187 vtep_remote = optarg;
188 break;
189
190 case 'h':
191 usage();
192
193 case 'V':
194 ovs_print_version(OFP13_VERSION, OFP13_VERSION);
195 exit(EXIT_SUCCESS);
196
197 VLOG_OPTION_HANDLERS
198 DAEMON_OPTION_HANDLERS
199 STREAM_SSL_OPTION_HANDLERS
200
201 case OPT_PEER_CA_CERT:
202 stream_ssl_set_peer_ca_cert_file(optarg);
203 break;
204
205 case '?':
206 exit(EXIT_FAILURE);
207
208 default:
209 abort();
210 }
211 }
212 free(short_options);
213
214 argc -= optind;
215 argv += optind;
216
217 if (!ovnsb_remote) {
218 ovnsb_remote = default_db();
219 }
220
221 if (!vtep_remote) {
222 vtep_remote = default_db();
223 }
224 }
225
226 static void
227 usage(void)
228 {
229 printf("\
230 %s: OVN controller VTEP\n\
231 usage %s [OPTIONS]\n\
232 \n\
233 Options:\n\
234 --vtep-db=DATABASE connect to vtep database at DATABASE\n\
235 (default: %s)\n\
236 --ovnsb-db=DATABASE connect to ovn-sb database at DATABASE\n\
237 (default: %s)\n\
238 -h, --help display this help message\n\
239 -o, --options list available options\n\
240 -V, --version display version information\n\
241 ", program_name, program_name, default_db(), default_db());
242 stream_usage("database", true, false, false);
243 daemon_usage();
244 vlog_usage();
245 exit(EXIT_SUCCESS);
246 }
247
248 \f
249 static void
250 ovn_controller_vtep_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
251 const char *argv[] OVS_UNUSED, void *exiting_)
252 {
253 bool *exiting = exiting_;
254 *exiting = true;
255
256 unixctl_command_reply(conn, NULL);
257 }