]> git.proxmox.com Git - ovs.git/blob - ovn/utilities/ovn-sbctl.c
util: New function nullable_xstrdup().
[ovs.git] / ovn / utilities / ovn-sbctl.c
1 /*
2 * Copyright (c) 2015, 2016 Nicira, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <config.h>
18
19 #include <ctype.h>
20 #include <errno.h>
21 #include <float.h>
22 #include <getopt.h>
23 #include <inttypes.h>
24 #include <signal.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29
30 #include "db-ctl-base.h"
31 #include "dirs.h"
32
33 #include "command-line.h"
34 #include "compiler.h"
35 #include "openvswitch/dynamic-string.h"
36 #include "fatal-signal.h"
37 #include "json.h"
38 #include "ovsdb-data.h"
39 #include "ovsdb-idl.h"
40 #include "poll-loop.h"
41 #include "process.h"
42 #include "sset.h"
43 #include "shash.h"
44 #include "stream-ssl.h"
45 #include "stream.h"
46 #include "table.h"
47 #include "timeval.h"
48 #include "util.h"
49 #include "openvswitch/vlog.h"
50 #include "ovn/lib/ovn-sb-idl.h"
51
52 VLOG_DEFINE_THIS_MODULE(sbctl);
53
54 struct sbctl_context;
55
56 /* --db: The database server to contact. */
57 static const char *db;
58
59 /* --oneline: Write each command's output as a single line? */
60 static bool oneline;
61
62 /* --dry-run: Do not commit any changes. */
63 static bool dry_run;
64
65 /* --timeout: Time to wait for a connection to 'db'. */
66 static int timeout;
67
68 /* Format for table output. */
69 static struct table_style table_style = TABLE_STYLE_DEFAULT;
70
71 /* The IDL we're using and the current transaction, if any.
72 * This is for use by sbctl_exit() only, to allow it to clean up.
73 * Other code should use its context arguments. */
74 static struct ovsdb_idl *the_idl;
75 static struct ovsdb_idl_txn *the_idl_txn;
76 OVS_NO_RETURN static void sbctl_exit(int status);
77
78 static void sbctl_cmd_init(void);
79 OVS_NO_RETURN static void usage(void);
80 static void parse_options(int argc, char *argv[], struct shash *local_options);
81 static const char *sbctl_default_db(void);
82 static void run_prerequisites(struct ctl_command[], size_t n_commands,
83 struct ovsdb_idl *);
84 static bool do_sbctl(const char *args, struct ctl_command *, size_t n,
85 struct ovsdb_idl *);
86
87 int
88 main(int argc, char *argv[])
89 {
90 struct ovsdb_idl *idl;
91 struct ctl_command *commands;
92 struct shash local_options;
93 unsigned int seqno;
94 size_t n_commands;
95 char *args;
96
97 set_program_name(argv[0]);
98 fatal_ignore_sigpipe();
99 vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
100 vlog_set_levels_from_string_assert("reconnect:warn");
101 sbrec_init();
102
103 sbctl_cmd_init();
104
105 /* Log our arguments. This is often valuable for debugging systems. */
106 args = process_escape_args(argv);
107 VLOG(ctl_might_write_to_db(argv) ? VLL_INFO : VLL_DBG, "Called as %s", args);
108
109 /* Parse command line. */
110 shash_init(&local_options);
111 parse_options(argc, argv, &local_options);
112 commands = ctl_parse_commands(argc - optind, argv + optind, &local_options,
113 &n_commands);
114
115 if (timeout) {
116 time_alarm(timeout);
117 }
118
119 /* Initialize IDL. */
120 idl = the_idl = ovsdb_idl_create(db, &sbrec_idl_class, false, false);
121 run_prerequisites(commands, n_commands, idl);
122
123 /* Execute the commands.
124 *
125 * 'seqno' is the database sequence number for which we last tried to
126 * execute our transaction. There's no point in trying to commit more than
127 * once for any given sequence number, because if the transaction fails
128 * it's because the database changed and we need to obtain an up-to-date
129 * view of the database before we try the transaction again. */
130 seqno = ovsdb_idl_get_seqno(idl);
131 for (;;) {
132 ovsdb_idl_run(idl);
133 if (!ovsdb_idl_is_alive(idl)) {
134 int retval = ovsdb_idl_get_last_error(idl);
135 ctl_fatal("%s: database connection failed (%s)",
136 db, ovs_retval_to_string(retval));
137 }
138
139 if (seqno != ovsdb_idl_get_seqno(idl)) {
140 seqno = ovsdb_idl_get_seqno(idl);
141 if (do_sbctl(args, commands, n_commands, idl)) {
142 free(args);
143 exit(EXIT_SUCCESS);
144 }
145 }
146
147 if (seqno == ovsdb_idl_get_seqno(idl)) {
148 ovsdb_idl_wait(idl);
149 poll_block();
150 }
151 }
152 }
153
154 static const char *
155 sbctl_default_db(void)
156 {
157 static char *def;
158 if (!def) {
159 def = getenv("OVN_SB_DB");
160 if (!def) {
161 def = xasprintf("unix:%s/ovnsb_db.sock", ovs_rundir());
162 }
163 }
164 return def;
165 }
166
167 static void
168 parse_options(int argc, char *argv[], struct shash *local_options)
169 {
170 enum {
171 OPT_DB = UCHAR_MAX + 1,
172 OPT_ONELINE,
173 OPT_NO_SYSLOG,
174 OPT_DRY_RUN,
175 OPT_PEER_CA_CERT,
176 OPT_LOCAL,
177 OPT_COMMANDS,
178 OPT_OPTIONS,
179 VLOG_OPTION_ENUMS,
180 TABLE_OPTION_ENUMS
181 };
182 static const struct option global_long_options[] = {
183 {"db", required_argument, NULL, OPT_DB},
184 {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
185 {"dry-run", no_argument, NULL, OPT_DRY_RUN},
186 {"oneline", no_argument, NULL, OPT_ONELINE},
187 {"timeout", required_argument, NULL, 't'},
188 {"help", no_argument, NULL, 'h'},
189 {"commands", no_argument, NULL, OPT_COMMANDS},
190 {"options", no_argument, NULL, OPT_OPTIONS},
191 {"version", no_argument, NULL, 'V'},
192 VLOG_LONG_OPTIONS,
193 STREAM_SSL_LONG_OPTIONS,
194 TABLE_LONG_OPTIONS,
195 {NULL, 0, NULL, 0},
196 };
197 const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
198 char *tmp, *short_options;
199
200 struct option *options;
201 size_t allocated_options;
202 size_t n_options;
203 size_t i;
204
205 tmp = ovs_cmdl_long_options_to_short_options(global_long_options);
206 short_options = xasprintf("+%s", tmp);
207 free(tmp);
208
209 /* We want to parse both global and command-specific options here, but
210 * getopt_long() isn't too convenient for the job. We copy our global
211 * options into a dynamic array, then append all of the command-specific
212 * options. */
213 options = xmemdup(global_long_options, sizeof global_long_options);
214 allocated_options = ARRAY_SIZE(global_long_options);
215 n_options = n_global_long_options;
216 ctl_add_cmd_options(&options, &n_options, &allocated_options, OPT_LOCAL);
217 table_style.format = TF_LIST;
218
219 for (;;) {
220 int idx;
221 int c;
222
223 c = getopt_long(argc, argv, short_options, options, &idx);
224 if (c == -1) {
225 break;
226 }
227
228 switch (c) {
229 case OPT_DB:
230 db = optarg;
231 break;
232
233 case OPT_ONELINE:
234 oneline = true;
235 break;
236
237 case OPT_NO_SYSLOG:
238 vlog_set_levels(&this_module, VLF_SYSLOG, VLL_WARN);
239 break;
240
241 case OPT_DRY_RUN:
242 dry_run = true;
243 break;
244
245 case OPT_LOCAL:
246 if (shash_find(local_options, options[idx].name)) {
247 ctl_fatal("'%s' option specified multiple times",
248 options[idx].name);
249 }
250 shash_add_nocopy(local_options,
251 xasprintf("--%s", options[idx].name),
252 nullable_xstrdup(optarg));
253 break;
254
255 case 'h':
256 usage();
257
258 case OPT_COMMANDS:
259 ctl_print_commands();
260
261 case OPT_OPTIONS:
262 ctl_print_options(global_long_options);
263
264 case 'V':
265 ovs_print_version(0, 0);
266 printf("DB Schema %s\n", sbrec_get_db_version());
267 exit(EXIT_SUCCESS);
268
269 case 't':
270 timeout = strtoul(optarg, NULL, 10);
271 if (timeout < 0) {
272 ctl_fatal("value %s on -t or --timeout is invalid", optarg);
273 }
274 break;
275
276 VLOG_OPTION_HANDLERS
277 TABLE_OPTION_HANDLERS(&table_style)
278 STREAM_SSL_OPTION_HANDLERS
279
280 case '?':
281 exit(EXIT_FAILURE);
282
283 default:
284 abort();
285 }
286 }
287 free(short_options);
288
289 if (!db) {
290 db = sbctl_default_db();
291 }
292
293 for (i = n_global_long_options; options[i].name; i++) {
294 free(CONST_CAST(char *, options[i].name));
295 }
296 free(options);
297 }
298
299 static void
300 usage(void)
301 {
302 printf("\
303 %s: OVN southbound DB management utility\n\
304 \n\
305 For debugging and testing only, not for use in production.\n\
306 \n\
307 usage: %s [OPTIONS] COMMAND [ARG...]\n\
308 \n\
309 General commands:\n\
310 show print overview of database contents\n\
311 \n\
312 Chassis commands:\n\
313 chassis-add CHASSIS ENCAP-TYPE ENCAP-IP create a new chassis named\n\
314 CHASSIS with ENCAP-TYPE tunnels\n\
315 and ENCAP-IP\n\
316 chassis-del CHASSIS delete CHASSIS and all of its encaps\n\
317 and gateway_ports\n\
318 \n\
319 Port binding commands:\n\
320 lport-bind LPORT CHASSIS bind logical port LPORT to CHASSIS\n\
321 lport-unbind LPORT reset the port binding of logical port LPORT\n\
322 \n\
323 Logical flow commands:\n\
324 lflow-list [DATAPATH] List logical flows for all or a single datapath\n\
325 dump-flows [DATAPATH] Alias for lflow-list\n\
326 \n\
327 %s\
328 \n\
329 Options:\n\
330 --db=DATABASE connect to DATABASE\n\
331 (default: %s)\n\
332 -t, --timeout=SECS wait at most SECS seconds\n\
333 --dry-run do not commit changes to database\n\
334 --oneline print exactly one line of output per command\n",
335 program_name, program_name, ctl_get_db_cmd_usage(), sbctl_default_db());
336 vlog_usage();
337 printf("\
338 --no-syslog equivalent to --verbose=sbctl:syslog:warn\n");
339 printf("\n\
340 Other options:\n\
341 -h, --help display this help message\n\
342 -V, --version display version information\n");
343 stream_usage("database", true, true, false);
344 exit(EXIT_SUCCESS);
345 }
346
347 \f
348 /* ovs-sbctl specific context. Inherits the 'struct ctl_context' as base. */
349 struct sbctl_context {
350 struct ctl_context base;
351
352 /* A cache of the contents of the database.
353 *
354 * A command that needs to use any of this information must first call
355 * sbctl_context_populate_cache(). A command that changes anything that
356 * could invalidate the cache must either call
357 * sbctl_context_invalidate_cache() or manually update the cache to
358 * maintain its correctness. */
359 bool cache_valid;
360 /* Maps from chassis name to struct sbctl_chassis. */
361 struct shash chassis;
362 /* Maps from lport name to struct sbctl_port_binding. */
363 struct shash port_bindings;
364 };
365
366 /* Casts 'base' into 'struct sbctl_context'. */
367 static struct sbctl_context *
368 sbctl_context_cast(struct ctl_context *base)
369 {
370 return CONTAINER_OF(base, struct sbctl_context, base);
371 }
372
373 struct sbctl_chassis {
374 const struct sbrec_chassis *ch_cfg;
375 };
376
377 struct sbctl_port_binding {
378 const struct sbrec_port_binding *bd_cfg;
379 };
380
381 static void
382 sbctl_context_invalidate_cache(struct ctl_context *ctx)
383 {
384 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
385
386 if (!sbctl_ctx->cache_valid) {
387 return;
388 }
389 sbctl_ctx->cache_valid = false;
390 shash_destroy_free_data(&sbctl_ctx->chassis);
391 shash_destroy_free_data(&sbctl_ctx->port_bindings);
392 }
393
394 static void
395 sbctl_context_populate_cache(struct ctl_context *ctx)
396 {
397 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
398 const struct sbrec_chassis *chassis_rec;
399 const struct sbrec_port_binding *port_binding_rec;
400 struct sset chassis, port_bindings;
401
402 if (sbctl_ctx->cache_valid) {
403 /* Cache is already populated. */
404 return;
405 }
406 sbctl_ctx->cache_valid = true;
407 shash_init(&sbctl_ctx->chassis);
408 shash_init(&sbctl_ctx->port_bindings);
409 sset_init(&chassis);
410 SBREC_CHASSIS_FOR_EACH(chassis_rec, ctx->idl) {
411 struct sbctl_chassis *ch;
412
413 if (!sset_add(&chassis, chassis_rec->name)) {
414 VLOG_WARN("database contains duplicate chassis name (%s)",
415 chassis_rec->name);
416 continue;
417 }
418
419 ch = xmalloc(sizeof *ch);
420 ch->ch_cfg = chassis_rec;
421 shash_add(&sbctl_ctx->chassis, chassis_rec->name, ch);
422 }
423 sset_destroy(&chassis);
424
425 sset_init(&port_bindings);
426 SBREC_PORT_BINDING_FOR_EACH(port_binding_rec, ctx->idl) {
427 struct sbctl_port_binding *bd;
428
429 if (!sset_add(&port_bindings, port_binding_rec->logical_port)) {
430 VLOG_WARN("database contains duplicate port binding for logical "
431 "port (%s)",
432 port_binding_rec->logical_port);
433 continue;
434 }
435
436 bd = xmalloc(sizeof *bd);
437 bd->bd_cfg = port_binding_rec;
438 shash_add(&sbctl_ctx->port_bindings, port_binding_rec->logical_port,
439 bd);
440 }
441 sset_destroy(&port_bindings);
442 }
443
444 static void
445 check_conflicts(struct sbctl_context *sbctl_ctx, const char *name,
446 char *msg)
447 {
448 if (shash_find(&sbctl_ctx->chassis, name)) {
449 ctl_fatal("%s because a chassis named %s already exists",
450 msg, name);
451 }
452 free(msg);
453 }
454
455 static struct sbctl_chassis *
456 find_chassis(struct sbctl_context *sbctl_ctx, const char *name,
457 bool must_exist)
458 {
459 struct sbctl_chassis *sbctl_ch;
460
461 ovs_assert(sbctl_ctx->cache_valid);
462
463 sbctl_ch = shash_find_data(&sbctl_ctx->chassis, name);
464 if (must_exist && !sbctl_ch) {
465 ctl_fatal("no chassis named %s", name);
466 }
467
468 return sbctl_ch;
469 }
470
471 static struct sbctl_port_binding *
472 find_port_binding(struct sbctl_context *sbctl_ctx, const char *name,
473 bool must_exist)
474 {
475 struct sbctl_port_binding *bd;
476
477 ovs_assert(sbctl_ctx->cache_valid);
478
479 bd = shash_find_data(&sbctl_ctx->port_bindings, name);
480 if (must_exist && !bd) {
481 ctl_fatal("no port named %s", name);
482 }
483
484 return bd;
485 }
486
487 static void
488 pre_get_info(struct ctl_context *ctx)
489 {
490 ovsdb_idl_add_column(ctx->idl, &sbrec_chassis_col_name);
491 ovsdb_idl_add_column(ctx->idl, &sbrec_chassis_col_encaps);
492
493 ovsdb_idl_add_column(ctx->idl, &sbrec_encap_col_type);
494 ovsdb_idl_add_column(ctx->idl, &sbrec_encap_col_ip);
495
496 ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_logical_port);
497 ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_chassis);
498
499 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_logical_datapath);
500 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_pipeline);
501 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_actions);
502 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_priority);
503 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_table_id);
504 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_match);
505 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_external_ids);
506 }
507
508 static struct cmd_show_table cmd_show_tables[] = {
509 {&sbrec_table_chassis,
510 &sbrec_chassis_col_name,
511 {&sbrec_chassis_col_hostname,
512 &sbrec_chassis_col_encaps,
513 NULL},
514 {&sbrec_table_port_binding,
515 &sbrec_port_binding_col_logical_port,
516 &sbrec_port_binding_col_chassis}},
517
518 {&sbrec_table_encap,
519 &sbrec_encap_col_type,
520 {&sbrec_encap_col_ip,
521 &sbrec_encap_col_options,
522 NULL},
523 {NULL, NULL, NULL}},
524
525 {NULL, NULL, {NULL, NULL, NULL}, {NULL, NULL, NULL}},
526 };
527
528 static void
529 cmd_chassis_add(struct ctl_context *ctx)
530 {
531 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
532 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
533 const char *ch_name, *encap_types, *encap_ip;
534
535 ch_name = ctx->argv[1];
536 encap_types = ctx->argv[2];
537 encap_ip = ctx->argv[3];
538
539 sbctl_context_populate_cache(ctx);
540 if (may_exist) {
541 struct sbctl_chassis *sbctl_ch;
542
543 sbctl_ch = find_chassis(sbctl_ctx, ch_name, false);
544 if (sbctl_ch) {
545 return;
546 }
547 }
548 check_conflicts(sbctl_ctx, ch_name,
549 xasprintf("cannot create a chassis named %s", ch_name));
550
551 char *tokstr = xstrdup(encap_types);
552 char *token, *save_ptr = NULL;
553 struct sset encap_set = SSET_INITIALIZER(&encap_set);
554 for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL;
555 token = strtok_r(NULL, ",", &save_ptr)) {
556 sset_add(&encap_set, token);
557 }
558 free(tokstr);
559
560 size_t n_encaps = sset_count(&encap_set);
561 struct sbrec_encap **encaps = xmalloc(n_encaps * sizeof *encaps);
562 const char *encap_type;
563 int i = 0;
564 SSET_FOR_EACH (encap_type, &encap_set){
565 encaps[i] = sbrec_encap_insert(ctx->txn);
566
567 sbrec_encap_set_type(encaps[i], encap_type);
568 sbrec_encap_set_ip(encaps[i], encap_ip);
569 i++;
570 }
571 sset_destroy(&encap_set);
572
573 struct sbrec_chassis *ch = sbrec_chassis_insert(ctx->txn);
574 sbrec_chassis_set_name(ch, ch_name);
575 sbrec_chassis_set_encaps(ch, encaps, n_encaps);
576 free(encaps);
577
578 sbctl_context_invalidate_cache(ctx);
579 }
580
581 static void
582 cmd_chassis_del(struct ctl_context *ctx)
583 {
584 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
585 bool must_exist = !shash_find(&ctx->options, "--if-exists");
586 struct sbctl_chassis *sbctl_ch;
587
588 sbctl_context_populate_cache(ctx);
589 sbctl_ch = find_chassis(sbctl_ctx, ctx->argv[1], must_exist);
590 if (sbctl_ch) {
591 if (sbctl_ch->ch_cfg) {
592 size_t i;
593
594 for (i = 0; i < sbctl_ch->ch_cfg->n_encaps; i++) {
595 sbrec_encap_delete(sbctl_ch->ch_cfg->encaps[i]);
596 }
597 sbrec_chassis_delete(sbctl_ch->ch_cfg);
598 }
599 shash_find_and_delete(&sbctl_ctx->chassis, ctx->argv[1]);
600 free(sbctl_ch);
601 }
602 }
603
604 static void
605 cmd_lport_bind(struct ctl_context *ctx)
606 {
607 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
608 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
609 struct sbctl_chassis *sbctl_ch;
610 struct sbctl_port_binding *sbctl_bd;
611 char *lport_name, *ch_name;
612
613 /* port_binding must exist, chassis must exist! */
614 lport_name = ctx->argv[1];
615 ch_name = ctx->argv[2];
616
617 sbctl_context_populate_cache(ctx);
618 sbctl_bd = find_port_binding(sbctl_ctx, lport_name, true);
619 sbctl_ch = find_chassis(sbctl_ctx, ch_name, true);
620
621 if (sbctl_bd->bd_cfg->chassis) {
622 if (may_exist && sbctl_bd->bd_cfg->chassis == sbctl_ch->ch_cfg) {
623 return;
624 } else {
625 ctl_fatal("lport (%s) has already been binded to chassis (%s)",
626 lport_name, sbctl_bd->bd_cfg->chassis->name);
627 }
628 }
629 sbrec_port_binding_set_chassis(sbctl_bd->bd_cfg, sbctl_ch->ch_cfg);
630 sbctl_context_invalidate_cache(ctx);
631 }
632
633 static void
634 cmd_lport_unbind(struct ctl_context *ctx)
635 {
636 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
637 bool must_exist = !shash_find(&ctx->options, "--if-exists");
638 struct sbctl_port_binding *sbctl_bd;
639 char *lport_name;
640
641 lport_name = ctx->argv[1];
642 sbctl_context_populate_cache(ctx);
643 sbctl_bd = find_port_binding(sbctl_ctx, lport_name, must_exist);
644 if (sbctl_bd) {
645 sbrec_port_binding_set_chassis(sbctl_bd->bd_cfg, NULL);
646 }
647 }
648
649 enum {
650 PL_INGRESS,
651 PL_EGRESS,
652 };
653
654 /* Help ensure we catch any future pipeline values */
655 static int
656 pipeline_encode(const char *pl)
657 {
658 if (!strcmp(pl, "ingress")) {
659 return PL_INGRESS;
660 } else if (!strcmp(pl, "egress")) {
661 return PL_EGRESS;
662 }
663
664 OVS_NOT_REACHED();
665 }
666
667 static int
668 lflow_cmp(const void *lf1_, const void *lf2_)
669 {
670 const struct sbrec_logical_flow *const *lf1p = lf1_;
671 const struct sbrec_logical_flow *const *lf2p = lf2_;
672 const struct sbrec_logical_flow *lf1 = *lf1p;
673 const struct sbrec_logical_flow *lf2 = *lf2p;
674
675 int pl1 = pipeline_encode(lf1->pipeline);
676 int pl2 = pipeline_encode(lf2->pipeline);
677
678 #define CMP(expr) \
679 do { \
680 int res; \
681 res = (expr); \
682 if (res) { \
683 return res; \
684 } \
685 } while (0)
686
687 CMP(uuid_compare_3way(&lf1->logical_datapath->header_.uuid,
688 &lf2->logical_datapath->header_.uuid));
689 CMP(pl1 - pl2);
690 CMP(lf1->table_id > lf2->table_id ? 1 :
691 (lf1->table_id < lf2->table_id ? -1 : 0));
692 CMP(lf1->priority > lf2->priority ? -1 :
693 (lf1->priority < lf2->priority ? 1 : 0));
694 CMP(strcmp(lf1->match, lf2->match));
695
696 #undef CMP
697
698 return 0;
699 }
700
701 static void
702 cmd_lflow_list(struct ctl_context *ctx)
703 {
704 const char *datapath = ctx->argc == 2 ? ctx->argv[1] : NULL;
705 struct uuid datapath_uuid = { .parts = { 0, }};
706 const struct sbrec_logical_flow **lflows;
707 const struct sbrec_logical_flow *lflow;
708 size_t n_flows = 0, n_capacity = 64;
709
710 if (datapath && !uuid_from_string(&datapath_uuid, datapath)) {
711 VLOG_ERR("Invalid format of datapath UUID");
712 return;
713 }
714
715 lflows = xmalloc(sizeof *lflows * n_capacity);
716 SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->idl) {
717 if (n_flows == n_capacity) {
718 lflows = x2nrealloc(lflows, &n_capacity, sizeof *lflows);
719 }
720 lflows[n_flows] = lflow;
721 n_flows++;
722 }
723
724 qsort(lflows, n_flows, sizeof *lflows, lflow_cmp);
725
726 const char *cur_pipeline = "";
727 size_t i;
728 for (i = 0; i < n_flows; i++) {
729 lflow = lflows[i];
730 if (datapath && !uuid_equals(&datapath_uuid,
731 &lflow->logical_datapath->header_.uuid)) {
732 continue;
733 }
734 if (strcmp(cur_pipeline, lflow->pipeline)) {
735 printf("Datapath: " UUID_FMT " Pipeline: %s\n",
736 UUID_ARGS(&lflow->logical_datapath->header_.uuid),
737 lflow->pipeline);
738 cur_pipeline = lflow->pipeline;
739 }
740
741 const char *table_name = smap_get(&lflow->external_ids, "stage-name");
742 printf(" table=%" PRId64 "(%16s), priority=%5" PRId64
743 ", match=(%s), action=(%s)\n",
744 lflow->table_id, table_name ? table_name : "",
745 lflow->priority, lflow->match, lflow->actions);
746 }
747
748 free(lflows);
749 }
750
751 \f
752 static const struct ctl_table_class tables[] = {
753 {&sbrec_table_chassis,
754 {{&sbrec_table_chassis, &sbrec_chassis_col_name, NULL},
755 {NULL, NULL, NULL}}},
756
757 {&sbrec_table_encap,
758 {{NULL, NULL, NULL},
759 {NULL, NULL, NULL}}},
760
761 {&sbrec_table_logical_flow,
762 {{&sbrec_table_logical_flow, NULL,
763 &sbrec_logical_flow_col_logical_datapath},
764 {NULL, NULL, NULL}}},
765
766 {&sbrec_table_multicast_group,
767 {{NULL, NULL, NULL},
768 {NULL, NULL, NULL}}},
769
770 {&sbrec_table_datapath_binding,
771 {{NULL, NULL, NULL},
772 {NULL, NULL, NULL}}},
773
774 {&sbrec_table_port_binding,
775 {{&sbrec_table_port_binding, &sbrec_port_binding_col_logical_port, NULL},
776 {NULL, NULL, NULL}}},
777
778 {&sbrec_table_mac_binding,
779 {{&sbrec_table_mac_binding, &sbrec_mac_binding_col_logical_port, NULL},
780 {NULL, NULL, NULL}}},
781
782 {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
783 };
784
785 \f
786 static void
787 sbctl_context_init_command(struct sbctl_context *sbctl_ctx,
788 struct ctl_command *command)
789 {
790 ctl_context_init_command(&sbctl_ctx->base, command);
791 }
792
793 static void
794 sbctl_context_init(struct sbctl_context *sbctl_ctx,
795 struct ctl_command *command, struct ovsdb_idl *idl,
796 struct ovsdb_idl_txn *txn,
797 struct ovsdb_symbol_table *symtab)
798 {
799 ctl_context_init(&sbctl_ctx->base, command, idl, txn, symtab,
800 sbctl_context_invalidate_cache);
801 sbctl_ctx->cache_valid = false;
802 }
803
804 static void
805 sbctl_context_done_command(struct sbctl_context *sbctl_ctx,
806 struct ctl_command *command)
807 {
808 ctl_context_done_command(&sbctl_ctx->base, command);
809 }
810
811 static void
812 sbctl_context_done(struct sbctl_context *sbctl_ctx,
813 struct ctl_command *command)
814 {
815 ctl_context_done(&sbctl_ctx->base, command);
816 }
817
818 static void
819 run_prerequisites(struct ctl_command *commands, size_t n_commands,
820 struct ovsdb_idl *idl)
821 {
822 struct ctl_command *c;
823
824 for (c = commands; c < &commands[n_commands]; c++) {
825 if (c->syntax->prerequisites) {
826 struct sbctl_context sbctl_ctx;
827
828 ds_init(&c->output);
829 c->table = NULL;
830
831 sbctl_context_init(&sbctl_ctx, c, idl, NULL, NULL);
832 (c->syntax->prerequisites)(&sbctl_ctx.base);
833 sbctl_context_done(&sbctl_ctx, c);
834
835 ovs_assert(!c->output.string);
836 ovs_assert(!c->table);
837 }
838 }
839 }
840
841 static bool
842 do_sbctl(const char *args, struct ctl_command *commands, size_t n_commands,
843 struct ovsdb_idl *idl)
844 {
845 struct ovsdb_idl_txn *txn;
846 enum ovsdb_idl_txn_status status;
847 struct ovsdb_symbol_table *symtab;
848 struct sbctl_context sbctl_ctx;
849 struct ctl_command *c;
850 struct shash_node *node;
851 char *error = NULL;
852
853 txn = the_idl_txn = ovsdb_idl_txn_create(idl);
854 if (dry_run) {
855 ovsdb_idl_txn_set_dry_run(txn);
856 }
857
858 ovsdb_idl_txn_add_comment(txn, "ovs-sbctl: %s", args);
859
860 symtab = ovsdb_symbol_table_create();
861 for (c = commands; c < &commands[n_commands]; c++) {
862 ds_init(&c->output);
863 c->table = NULL;
864 }
865 sbctl_context_init(&sbctl_ctx, NULL, idl, txn, symtab);
866 for (c = commands; c < &commands[n_commands]; c++) {
867 sbctl_context_init_command(&sbctl_ctx, c);
868 if (c->syntax->run) {
869 (c->syntax->run)(&sbctl_ctx.base);
870 }
871 sbctl_context_done_command(&sbctl_ctx, c);
872
873 if (sbctl_ctx.base.try_again) {
874 sbctl_context_done(&sbctl_ctx, NULL);
875 goto try_again;
876 }
877 }
878 sbctl_context_done(&sbctl_ctx, NULL);
879
880 SHASH_FOR_EACH (node, &symtab->sh) {
881 struct ovsdb_symbol *symbol = node->data;
882 if (!symbol->created) {
883 ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
884 "with \"-- --id=%s create ...\")",
885 node->name, node->name);
886 }
887 if (!symbol->strong_ref) {
888 if (!symbol->weak_ref) {
889 VLOG_WARN("row id \"%s\" was created but no reference to it "
890 "was inserted, so it will not actually appear in "
891 "the database", node->name);
892 } else {
893 VLOG_WARN("row id \"%s\" was created but only a weak "
894 "reference to it was inserted, so it will not "
895 "actually appear in the database", node->name);
896 }
897 }
898 }
899
900 status = ovsdb_idl_txn_commit_block(txn);
901 if (status == TXN_UNCHANGED || status == TXN_SUCCESS) {
902 for (c = commands; c < &commands[n_commands]; c++) {
903 if (c->syntax->postprocess) {
904 sbctl_context_init(&sbctl_ctx, c, idl, txn, symtab);
905 (c->syntax->postprocess)(&sbctl_ctx.base);
906 sbctl_context_done(&sbctl_ctx, c);
907 }
908 }
909 }
910 error = xstrdup(ovsdb_idl_txn_get_error(txn));
911
912 switch (status) {
913 case TXN_UNCOMMITTED:
914 case TXN_INCOMPLETE:
915 OVS_NOT_REACHED();
916
917 case TXN_ABORTED:
918 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
919 ctl_fatal("transaction aborted");
920
921 case TXN_UNCHANGED:
922 case TXN_SUCCESS:
923 break;
924
925 case TXN_TRY_AGAIN:
926 goto try_again;
927
928 case TXN_ERROR:
929 ctl_fatal("transaction error: %s", error);
930
931 case TXN_NOT_LOCKED:
932 /* Should not happen--we never call ovsdb_idl_set_lock(). */
933 ctl_fatal("database not locked");
934
935 default:
936 OVS_NOT_REACHED();
937 }
938 free(error);
939
940 ovsdb_symbol_table_destroy(symtab);
941
942 for (c = commands; c < &commands[n_commands]; c++) {
943 struct ds *ds = &c->output;
944
945 if (c->table) {
946 table_print(c->table, &table_style);
947 } else if (oneline) {
948 size_t j;
949
950 ds_chomp(ds, '\n');
951 for (j = 0; j < ds->length; j++) {
952 int ch = ds->string[j];
953 switch (ch) {
954 case '\n':
955 fputs("\\n", stdout);
956 break;
957
958 case '\\':
959 fputs("\\\\", stdout);
960 break;
961
962 default:
963 putchar(ch);
964 }
965 }
966 putchar('\n');
967 } else {
968 fputs(ds_cstr(ds), stdout);
969 }
970 ds_destroy(&c->output);
971 table_destroy(c->table);
972 free(c->table);
973
974 shash_destroy_free_data(&c->options);
975 }
976 free(commands);
977 ovsdb_idl_txn_destroy(txn);
978 ovsdb_idl_destroy(idl);
979
980 return true;
981
982 try_again:
983 /* Our transaction needs to be rerun, or a prerequisite was not met. Free
984 * resources and return so that the caller can try again. */
985 if (txn) {
986 ovsdb_idl_txn_abort(txn);
987 ovsdb_idl_txn_destroy(txn);
988 the_idl_txn = NULL;
989 }
990 ovsdb_symbol_table_destroy(symtab);
991 for (c = commands; c < &commands[n_commands]; c++) {
992 ds_destroy(&c->output);
993 table_destroy(c->table);
994 free(c->table);
995 }
996 free(error);
997 return false;
998 }
999
1000 /* Frees the current transaction and the underlying IDL and then calls
1001 * exit(status).
1002 *
1003 * Freeing the transaction and the IDL is not strictly necessary, but it makes
1004 * for a clean memory leak report from valgrind in the normal case. That makes
1005 * it easier to notice real memory leaks. */
1006 static void
1007 sbctl_exit(int status)
1008 {
1009 if (the_idl_txn) {
1010 ovsdb_idl_txn_abort(the_idl_txn);
1011 ovsdb_idl_txn_destroy(the_idl_txn);
1012 }
1013 ovsdb_idl_destroy(the_idl);
1014 exit(status);
1015 }
1016
1017 static const struct ctl_command_syntax sbctl_commands[] = {
1018 /* Chassis commands. */
1019 {"chassis-add", 3, 3, "CHASSIS ENCAP-TYPE ENCAP-IP", pre_get_info,
1020 cmd_chassis_add, NULL, "--may-exist", RW},
1021 {"chassis-del", 1, 1, "CHASSIS", pre_get_info, cmd_chassis_del, NULL,
1022 "--if-exists", RW},
1023
1024 /* Port binding commands. */
1025 {"lport-bind", 2, 2, "LPORT CHASSIS", pre_get_info, cmd_lport_bind, NULL,
1026 "--may-exist", RW},
1027 {"lport-unbind", 1, 1, "LPORT", pre_get_info, cmd_lport_unbind, NULL,
1028 "--if-exists", RW},
1029
1030 /* Logical flow commands */
1031 {"lflow-list", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL,
1032 "", RO},
1033 {"dump-flows", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL,
1034 "", RO}, /* Friendly alias for lflow-list */
1035
1036 /* SSL commands (To Be Added). */
1037
1038 {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
1039 };
1040
1041 /* Registers sbctl and common db commands. */
1042 static void
1043 sbctl_cmd_init(void)
1044 {
1045 ctl_init(tables, cmd_show_tables, sbctl_exit);
1046 ctl_register_commands(sbctl_commands);
1047 }