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