]> git.proxmox.com Git - mirror_ovs.git/blob - utilities/ovs-vsctl.c
ovs-actions: New document describing OVS actions in detail.
[mirror_ovs.git] / utilities / ovs-vsctl.c
1 /*
2 * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 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
32 #include "command-line.h"
33 #include "compiler.h"
34 #include "dirs.h"
35 #include "openvswitch/dynamic-string.h"
36 #include "fatal-signal.h"
37 #include "hash.h"
38 #include "openvswitch/json.h"
39 #include "ovsdb-data.h"
40 #include "ovsdb-idl.h"
41 #include "openvswitch/poll-loop.h"
42 #include "process.h"
43 #include "stream.h"
44 #include "stream-ssl.h"
45 #include "smap.h"
46 #include "sset.h"
47 #include "svec.h"
48 #include "lib/vswitch-idl.h"
49 #include "table.h"
50 #include "timeval.h"
51 #include "util.h"
52 #include "openvswitch/vconn.h"
53 #include "openvswitch/vlog.h"
54
55 VLOG_DEFINE_THIS_MODULE(vsctl);
56
57 struct vsctl_context;
58
59 /* --db: The database server to contact. */
60 static const char *db;
61
62 /* --oneline: Write each command's output as a single line? */
63 static bool oneline;
64
65 /* --dry-run: Do not commit any changes. */
66 static bool dry_run;
67
68 /* --no-wait: Wait for ovs-vswitchd to reload its configuration? */
69 static bool wait_for_reload = true;
70
71 /* --timeout: Time to wait for a connection to 'db'. */
72 static unsigned int timeout;
73
74 /* --retry: If true, ovs-vsctl will retry connecting to the database forever.
75 * If false and --db says to use an active connection method (e.g. "unix:",
76 * "tcp:", "ssl:"), then ovs-vsctl will try to connect once and exit with an
77 * error if the database server cannot be contacted (e.g. ovsdb-server is not
78 * running).
79 *
80 * Regardless of this setting, --timeout always limits how long ovs-vsctl will
81 * wait. */
82 static bool retry;
83
84 /* Format for table output. */
85 static struct table_style table_style = TABLE_STYLE_DEFAULT;
86
87 static void vsctl_cmd_init(void);
88
89 /* The IDL we're using and the current transaction, if any.
90 * This is for use by vsctl_exit() only, to allow it to clean up.
91 * Other code should use its context arguments. */
92 static struct ovsdb_idl *the_idl;
93 static struct ovsdb_idl_txn *the_idl_txn;
94 OVS_NO_RETURN static void vsctl_exit(int status);
95
96 OVS_NO_RETURN static void usage(void);
97 static void parse_options(int argc, char *argv[], struct shash *local_options);
98 static void run_prerequisites(struct ctl_command[], size_t n_commands,
99 struct ovsdb_idl *);
100 static bool do_vsctl(const char *args, struct ctl_command *, size_t n,
101 struct ovsdb_idl *);
102
103 /* post_db_reload_check frame work is to allow ovs-vsctl to do additional
104 * checks after OVSDB transactions are successfully recorded and reload by
105 * ovs-vswitchd.
106 *
107 * For example, When a new interface is added to OVSDB, ovs-vswitchd will
108 * either store a positive values on successful implementing the new
109 * interface, or -1 on failure.
110 *
111 * Unless --no-wait command line option is specified,
112 * post_db_reload_do_checks() is called right after any configuration
113 * changes is picked up (i.e. reload) by ovs-vswitchd. Any error detected
114 * post OVSDB reload is reported as ovs-vsctl errors. OVS-vswitchd logs
115 * more detailed messages about those errors.
116 *
117 * Current implementation only check for Post OVSDB reload failures on new
118 * interface additions with 'add-br' and 'add-port' commands.
119 *
120 * post_db_reload_expect_iface()
121 *
122 * keep track of interfaces to be checked post OVSDB reload. */
123 static void post_db_reload_check_init(void);
124 static void post_db_reload_do_checks(const struct vsctl_context *);
125 static void post_db_reload_expect_iface(const struct ovsrec_interface *);
126
127 static struct uuid *neoteric_ifaces;
128 static size_t n_neoteric_ifaces;
129 static size_t allocated_neoteric_ifaces;
130
131 int
132 main(int argc, char *argv[])
133 {
134 struct ovsdb_idl *idl;
135 struct ctl_command *commands;
136 struct shash local_options;
137 unsigned int seqno;
138 size_t n_commands;
139
140 set_program_name(argv[0]);
141 fatal_ignore_sigpipe();
142 vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
143 vlog_set_levels_from_string_assert("reconnect:warn");
144
145 vsctl_cmd_init();
146
147 /* Parse command line. */
148 char *args = process_escape_args(argv);
149 shash_init(&local_options);
150 parse_options(argc, argv, &local_options);
151 char *error = ctl_parse_commands(argc - optind, argv + optind,
152 &local_options, &commands, &n_commands);
153 if (error) {
154 ctl_fatal("%s", error);
155 }
156 VLOG(ctl_might_write_to_db(commands, n_commands) ? VLL_INFO : VLL_DBG,
157 "Called as %s", args);
158
159 ctl_timeout_setup(timeout);
160
161 /* Initialize IDL. */
162 idl = the_idl = ovsdb_idl_create(db, &ovsrec_idl_class, false, retry);
163 run_prerequisites(commands, n_commands, idl);
164
165 /* Execute the commands.
166 *
167 * 'seqno' is the database sequence number for which we last tried to
168 * execute our transaction. There's no point in trying to commit more than
169 * once for any given sequence number, because if the transaction fails
170 * it's because the database changed and we need to obtain an up-to-date
171 * view of the database before we try the transaction again. */
172 seqno = ovsdb_idl_get_seqno(idl);
173 for (;;) {
174 ovsdb_idl_run(idl);
175 if (!ovsdb_idl_is_alive(idl)) {
176 int retval = ovsdb_idl_get_last_error(idl);
177 ctl_fatal("%s: database connection failed (%s)",
178 db, ovs_retval_to_string(retval));
179 }
180
181 if (seqno != ovsdb_idl_get_seqno(idl)) {
182 seqno = ovsdb_idl_get_seqno(idl);
183 if (do_vsctl(args, commands, n_commands, idl)) {
184 free(args);
185 exit(EXIT_SUCCESS);
186 }
187 }
188
189 if (seqno == ovsdb_idl_get_seqno(idl)) {
190 ovsdb_idl_wait(idl);
191 poll_block();
192 }
193 }
194 }
195
196 static void
197 parse_options(int argc, char *argv[], struct shash *local_options)
198 {
199 enum {
200 OPT_DB = UCHAR_MAX + 1,
201 OPT_ONELINE,
202 OPT_NO_SYSLOG,
203 OPT_NO_WAIT,
204 OPT_DRY_RUN,
205 OPT_BOOTSTRAP_CA_CERT,
206 OPT_PEER_CA_CERT,
207 OPT_LOCAL,
208 OPT_RETRY,
209 OPT_COMMANDS,
210 OPT_OPTIONS,
211 VLOG_OPTION_ENUMS,
212 TABLE_OPTION_ENUMS,
213 SSL_OPTION_ENUMS,
214 };
215 static const struct option global_long_options[] = {
216 {"db", required_argument, NULL, OPT_DB},
217 {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
218 {"no-wait", no_argument, NULL, OPT_NO_WAIT},
219 {"dry-run", no_argument, NULL, OPT_DRY_RUN},
220 {"oneline", no_argument, NULL, OPT_ONELINE},
221 {"timeout", required_argument, NULL, 't'},
222 {"retry", no_argument, NULL, OPT_RETRY},
223 {"help", no_argument, NULL, 'h'},
224 {"commands", no_argument, NULL, OPT_COMMANDS},
225 {"options", no_argument, NULL, OPT_OPTIONS},
226 {"version", no_argument, NULL, 'V'},
227 VLOG_LONG_OPTIONS,
228 TABLE_LONG_OPTIONS,
229 STREAM_SSL_LONG_OPTIONS,
230 {"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT},
231 {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
232 {NULL, 0, NULL, 0},
233 };
234 const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
235 char *tmp, *short_options;
236
237 struct option *options;
238 size_t allocated_options;
239 size_t n_options;
240 size_t i;
241
242 tmp = ovs_cmdl_long_options_to_short_options(global_long_options);
243 short_options = xasprintf("+%s", tmp);
244 free(tmp);
245
246 /* We want to parse both global and command-specific options here, but
247 * getopt_long() isn't too convenient for the job. We copy our global
248 * options into a dynamic array, then append all of the command-specific
249 * options. */
250 options = xmemdup(global_long_options, sizeof global_long_options);
251 allocated_options = ARRAY_SIZE(global_long_options);
252 n_options = n_global_long_options;
253 ctl_add_cmd_options(&options, &n_options, &allocated_options, OPT_LOCAL);
254
255 for (;;) {
256 int idx;
257 int c;
258
259 c = getopt_long(argc, argv, short_options, options, &idx);
260 if (c == -1) {
261 break;
262 }
263
264 switch (c) {
265 case OPT_DB:
266 db = optarg;
267 break;
268
269 case OPT_ONELINE:
270 oneline = true;
271 break;
272
273 case OPT_NO_SYSLOG:
274 vlog_set_levels(&this_module, VLF_SYSLOG, VLL_WARN);
275 break;
276
277 case OPT_NO_WAIT:
278 wait_for_reload = false;
279 break;
280
281 case OPT_DRY_RUN:
282 dry_run = true;
283 break;
284
285 case OPT_LOCAL:
286 if (shash_find(local_options, options[idx].name)) {
287 ctl_fatal("'%s' option specified multiple times",
288 options[idx].name);
289 }
290 shash_add_nocopy(local_options,
291 xasprintf("--%s", options[idx].name),
292 nullable_xstrdup(optarg));
293 break;
294
295 case 'h':
296 usage();
297
298 case OPT_COMMANDS:
299 ctl_print_commands();
300 /* fall through */
301
302 case OPT_OPTIONS:
303 ctl_print_options(global_long_options);
304 /* fall through */
305
306 case 'V':
307 ovs_print_version(0, 0);
308 printf("DB Schema %s\n", ovsrec_get_db_version());
309 exit(EXIT_SUCCESS);
310
311 case 't':
312 if (!str_to_uint(optarg, 10, &timeout) || !timeout) {
313 ctl_fatal("value %s on -t or --timeout is invalid", optarg);
314 }
315 break;
316
317 case OPT_RETRY:
318 retry = true;
319 break;
320
321 VLOG_OPTION_HANDLERS
322 TABLE_OPTION_HANDLERS(&table_style)
323
324 STREAM_SSL_OPTION_HANDLERS
325
326 case OPT_PEER_CA_CERT:
327 stream_ssl_set_peer_ca_cert_file(optarg);
328 break;
329
330 case OPT_BOOTSTRAP_CA_CERT:
331 stream_ssl_set_ca_cert_file(optarg, true);
332 break;
333
334 case '?':
335 exit(EXIT_FAILURE);
336
337 default:
338 abort();
339 }
340 }
341 free(short_options);
342
343 if (!db) {
344 db = ctl_default_db();
345 }
346
347 for (i = n_global_long_options; options[i].name; i++) {
348 free(CONST_CAST(char *, options[i].name));
349 }
350 free(options);
351 }
352
353 static void
354 usage(void)
355 {
356 printf("\
357 %s: ovs-vswitchd management utility\n\
358 usage: %s [OPTIONS] COMMAND [ARG...]\n\
359 \n\
360 Open vSwitch commands:\n\
361 init initialize database, if not yet initialized\n\
362 show print overview of database contents\n\
363 emer-reset reset configuration to clean state\n\
364 \n\
365 Bridge commands:\n\
366 add-br BRIDGE create a new bridge named BRIDGE\n\
367 add-br BRIDGE PARENT VLAN create new fake BRIDGE in PARENT on VLAN\n\
368 del-br BRIDGE delete BRIDGE and all of its ports\n\
369 list-br print the names of all the bridges\n\
370 br-exists BRIDGE exit 2 if BRIDGE does not exist\n\
371 br-to-vlan BRIDGE print the VLAN which BRIDGE is on\n\
372 br-to-parent BRIDGE print the parent of BRIDGE\n\
373 br-set-external-id BRIDGE KEY VALUE set KEY on BRIDGE to VALUE\n\
374 br-set-external-id BRIDGE KEY unset KEY on BRIDGE\n\
375 br-get-external-id BRIDGE KEY print value of KEY on BRIDGE\n\
376 br-get-external-id BRIDGE list key-value pairs on BRIDGE\n\
377 \n\
378 Port commands (a bond is considered to be a single port):\n\
379 list-ports BRIDGE print the names of all the ports on BRIDGE\n\
380 add-port BRIDGE PORT add network device PORT to BRIDGE\n\
381 add-bond BRIDGE PORT IFACE... add bonded port PORT in BRIDGE from IFACES\n\
382 del-port [BRIDGE] PORT delete PORT (which may be bonded) from BRIDGE\n\
383 port-to-br PORT print name of bridge that contains PORT\n\
384 \n\
385 Interface commands (a bond consists of multiple interfaces):\n\
386 list-ifaces BRIDGE print the names of all interfaces on BRIDGE\n\
387 iface-to-br IFACE print name of bridge that contains IFACE\n\
388 \n\
389 Controller commands:\n\
390 get-controller BRIDGE print the controllers for BRIDGE\n\
391 del-controller BRIDGE delete the controllers for BRIDGE\n\
392 [--inactivity-probe=MSECS]\n\
393 set-controller BRIDGE TARGET... set the controllers for BRIDGE\n\
394 get-fail-mode BRIDGE print the fail-mode for BRIDGE\n\
395 del-fail-mode BRIDGE delete the fail-mode for BRIDGE\n\
396 set-fail-mode BRIDGE MODE set the fail-mode for BRIDGE to MODE\n\
397 \n\
398 Manager commands:\n\
399 get-manager print the managers\n\
400 del-manager delete the managers\n\
401 [--inactivity-probe=MSECS]\n\
402 set-manager TARGET... set the list of managers to TARGET...\n\
403 \n\
404 SSL commands:\n\
405 get-ssl print the SSL configuration\n\
406 del-ssl delete the SSL configuration\n\
407 set-ssl PRIV-KEY CERT CA-CERT set the SSL configuration\n\
408 \n\
409 Auto Attach commands:\n\
410 add-aa-mapping BRIDGE I-SID VLAN add Auto Attach mapping to BRIDGE\n\
411 del-aa-mapping BRIDGE I-SID VLAN delete Auto Attach mapping VLAN from BRIDGE\n\
412 get-aa-mapping BRIDGE get Auto Attach mappings from BRIDGE\n\
413 \n\
414 Switch commands:\n\
415 emer-reset reset switch to known good state\n\
416 \n\
417 %s\
418 %s\
419 \n\
420 Options:\n\
421 --db=DATABASE connect to DATABASE\n\
422 (default: %s)\n\
423 --no-wait do not wait for ovs-vswitchd to reconfigure\n\
424 --retry keep trying to connect to server forever\n\
425 -t, --timeout=SECS wait at most SECS seconds for ovs-vswitchd\n\
426 --dry-run do not commit changes to database\n\
427 --oneline print exactly one line of output per command\n",
428 program_name, program_name, ctl_get_db_cmd_usage(),
429 ctl_list_db_tables_usage(), ctl_default_db());
430 table_usage();
431 vlog_usage();
432 printf("\
433 --no-syslog equivalent to --verbose=vsctl:syslog:warn\n");
434 stream_usage("database", true, true, true);
435 printf("\n\
436 Other options:\n\
437 -h, --help display this help message\n\
438 -V, --version display version information\n");
439 exit(EXIT_SUCCESS);
440 }
441
442 \f
443 /* ovs-vsctl specific context. Inherits the 'struct ctl_context' as base. */
444 struct vsctl_context {
445 struct ctl_context base;
446
447 /* Modifiable state. */
448 const struct ovsrec_open_vswitch *ovs;
449 bool verified_ports;
450
451 /* A cache of the contents of the database.
452 *
453 * A command that needs to use any of this information must first call
454 * vsctl_context_populate_cache(). A command that changes anything that
455 * could invalidate the cache must either call
456 * vsctl_context_invalidate_cache() or manually update the cache to
457 * maintain its correctness. */
458 bool cache_valid;
459 struct shash bridges; /* Maps from bridge name to struct vsctl_bridge. */
460 struct shash ports; /* Maps from port name to struct vsctl_port. */
461 struct shash ifaces; /* Maps from port name to struct vsctl_iface. */
462 };
463
464 struct vsctl_bridge {
465 struct ovsrec_bridge *br_cfg;
466 char *name;
467 struct ovs_list ports; /* Contains "struct vsctl_port"s. */
468
469 /* VLAN ("fake") bridge support.
470 *
471 * Use 'parent != NULL' to detect a fake bridge, because 'vlan' can be 0
472 * in either case. */
473 struct hmap children; /* VLAN bridges indexed by 'vlan'. */
474 struct hmap_node children_node; /* Node in parent's 'children' hmap. */
475 struct vsctl_bridge *parent; /* Real bridge, or NULL. */
476 int vlan; /* VLAN VID (0...4095), or 0. */
477 };
478
479 struct vsctl_port {
480 struct ovs_list ports_node; /* In struct vsctl_bridge's 'ports' list. */
481 struct ovs_list ifaces; /* Contains "struct vsctl_iface"s. */
482 struct ovsrec_port *port_cfg;
483 struct vsctl_bridge *bridge;
484 };
485
486 struct vsctl_iface {
487 struct ovs_list ifaces_node; /* In struct vsctl_port's 'ifaces' list. */
488 struct ovsrec_interface *iface_cfg;
489 struct vsctl_port *port;
490 };
491
492 /* Casts 'base' into 'struct vsctl_context'. */
493 static struct vsctl_context *
494 vsctl_context_cast(struct ctl_context *base)
495 {
496 return CONTAINER_OF(base, struct vsctl_context, base);
497 }
498
499 static struct vsctl_bridge *find_vlan_bridge(struct vsctl_bridge *parent,
500 int vlan);
501
502 static char *
503 vsctl_context_to_string(const struct ctl_context *ctx)
504 {
505 const struct shash_node *node;
506 struct svec words;
507 char *s;
508 int i;
509
510 svec_init(&words);
511 SHASH_FOR_EACH (node, &ctx->options) {
512 svec_add(&words, node->name);
513 }
514 for (i = 0; i < ctx->argc; i++) {
515 svec_add(&words, ctx->argv[i]);
516 }
517 svec_terminate(&words);
518
519 s = process_escape_args(words.names);
520
521 svec_destroy(&words);
522
523 return s;
524 }
525
526 static void
527 verify_ports(struct vsctl_context *vsctl_ctx)
528 {
529 if (!vsctl_ctx->verified_ports) {
530 const struct ovsrec_bridge *bridge;
531 const struct ovsrec_port *port;
532
533 ovsrec_open_vswitch_verify_bridges(vsctl_ctx->ovs);
534 OVSREC_BRIDGE_FOR_EACH (bridge, vsctl_ctx->base.idl) {
535 ovsrec_bridge_verify_ports(bridge);
536 }
537 OVSREC_PORT_FOR_EACH (port, vsctl_ctx->base.idl) {
538 ovsrec_port_verify_interfaces(port);
539 }
540
541 vsctl_ctx->verified_ports = true;
542 }
543 }
544
545 static struct vsctl_bridge *
546 add_bridge_to_cache(struct vsctl_context *vsctl_ctx,
547 struct ovsrec_bridge *br_cfg, const char *name,
548 struct vsctl_bridge *parent, int vlan)
549 {
550 struct vsctl_bridge *br = xmalloc(sizeof *br);
551 br->br_cfg = br_cfg;
552 br->name = xstrdup(name);
553 ovs_list_init(&br->ports);
554 br->parent = parent;
555 br->vlan = vlan;
556 hmap_init(&br->children);
557 if (parent) {
558 struct vsctl_bridge *conflict = find_vlan_bridge(parent, vlan);
559 if (conflict) {
560 VLOG_WARN("%s: bridge has multiple VLAN bridges (%s and %s) "
561 "for VLAN %d, but only one is allowed",
562 parent->name, name, conflict->name, vlan);
563 } else {
564 hmap_insert(&parent->children, &br->children_node,
565 hash_int(vlan, 0));
566 }
567 }
568 shash_add(&vsctl_ctx->bridges, br->name, br);
569 return br;
570 }
571
572 static void
573 ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
574 struct ovsrec_bridge *bridge)
575 {
576 struct ovsrec_bridge **bridges;
577 size_t i, n;
578
579 bridges = xmalloc(sizeof *ovs->bridges * ovs->n_bridges);
580 for (i = n = 0; i < ovs->n_bridges; i++) {
581 if (ovs->bridges[i] != bridge) {
582 bridges[n++] = ovs->bridges[i];
583 }
584 }
585 ovsrec_open_vswitch_set_bridges(ovs, bridges, n);
586 free(bridges);
587 }
588
589 static void
590 del_cached_bridge(struct vsctl_context *vsctl_ctx, struct vsctl_bridge *br)
591 {
592 ovs_assert(ovs_list_is_empty(&br->ports));
593 ovs_assert(hmap_is_empty(&br->children));
594 if (br->parent) {
595 hmap_remove(&br->parent->children, &br->children_node);
596 }
597 if (br->br_cfg) {
598 ovsrec_bridge_delete(br->br_cfg);
599 ovs_delete_bridge(vsctl_ctx->ovs, br->br_cfg);
600 }
601 shash_find_and_delete(&vsctl_ctx->bridges, br->name);
602 hmap_destroy(&br->children);
603 free(br->name);
604 free(br);
605 }
606
607 static bool
608 port_is_fake_bridge(const struct ovsrec_port *port_cfg)
609 {
610 return (port_cfg->fake_bridge
611 && port_cfg->tag
612 && *port_cfg->tag >= 0 && *port_cfg->tag <= 4095);
613 }
614
615 static struct vsctl_bridge *
616 find_vlan_bridge(struct vsctl_bridge *parent, int vlan)
617 {
618 struct vsctl_bridge *child;
619
620 HMAP_FOR_EACH_IN_BUCKET (child, children_node, hash_int(vlan, 0),
621 &parent->children) {
622 if (child->vlan == vlan) {
623 return child;
624 }
625 }
626
627 return NULL;
628 }
629
630 static struct vsctl_port *
631 add_port_to_cache(struct vsctl_context *vsctl_ctx, struct vsctl_bridge *parent,
632 struct ovsrec_port *port_cfg)
633 {
634 struct vsctl_port *port;
635
636 if (port_cfg->tag
637 && *port_cfg->tag >= 0 && *port_cfg->tag <= 4095) {
638 struct vsctl_bridge *vlan_bridge;
639
640 vlan_bridge = find_vlan_bridge(parent, *port_cfg->tag);
641 if (vlan_bridge) {
642 parent = vlan_bridge;
643 }
644 }
645
646 port = xmalloc(sizeof *port);
647 ovs_list_push_back(&parent->ports, &port->ports_node);
648 ovs_list_init(&port->ifaces);
649 port->port_cfg = port_cfg;
650 port->bridge = parent;
651 shash_add(&vsctl_ctx->ports, port_cfg->name, port);
652
653 return port;
654 }
655
656 static void
657 del_cached_port(struct vsctl_context *vsctl_ctx, struct vsctl_port *port)
658 {
659 ovs_assert(ovs_list_is_empty(&port->ifaces));
660 ovs_list_remove(&port->ports_node);
661 shash_find_and_delete(&vsctl_ctx->ports, port->port_cfg->name);
662 ovsrec_port_delete(port->port_cfg);
663 free(port);
664 }
665
666 static struct vsctl_iface *
667 add_iface_to_cache(struct vsctl_context *vsctl_ctx, struct vsctl_port *parent,
668 struct ovsrec_interface *iface_cfg)
669 {
670 struct vsctl_iface *iface;
671
672 iface = xmalloc(sizeof *iface);
673 ovs_list_push_back(&parent->ifaces, &iface->ifaces_node);
674 iface->iface_cfg = iface_cfg;
675 iface->port = parent;
676 shash_add(&vsctl_ctx->ifaces, iface_cfg->name, iface);
677
678 return iface;
679 }
680
681 static void
682 del_cached_iface(struct vsctl_context *vsctl_ctx, struct vsctl_iface *iface)
683 {
684 ovs_list_remove(&iface->ifaces_node);
685 shash_find_and_delete(&vsctl_ctx->ifaces, iface->iface_cfg->name);
686 ovsrec_interface_delete(iface->iface_cfg);
687 free(iface);
688 }
689
690 static void
691 vsctl_context_invalidate_cache(struct ctl_context *ctx)
692 {
693 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
694 struct shash_node *node;
695
696 if (!vsctl_ctx->cache_valid) {
697 return;
698 }
699 vsctl_ctx->cache_valid = false;
700
701 SHASH_FOR_EACH (node, &vsctl_ctx->bridges) {
702 struct vsctl_bridge *bridge = node->data;
703 hmap_destroy(&bridge->children);
704 free(bridge->name);
705 free(bridge);
706 }
707 shash_destroy(&vsctl_ctx->bridges);
708
709 shash_destroy_free_data(&vsctl_ctx->ports);
710 shash_destroy_free_data(&vsctl_ctx->ifaces);
711 }
712
713 static void
714 pre_get_info(struct ctl_context *ctx)
715 {
716 ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_bridges);
717
718 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_name);
719 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_controller);
720 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_fail_mode);
721 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_ports);
722
723 ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_name);
724 ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_fake_bridge);
725 ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_tag);
726 ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_interfaces);
727
728 ovsdb_idl_add_column(ctx->idl, &ovsrec_interface_col_name);
729
730 ovsdb_idl_add_column(ctx->idl, &ovsrec_interface_col_ofport);
731 ovsdb_idl_add_column(ctx->idl, &ovsrec_interface_col_error);
732 }
733
734 static void
735 vsctl_context_populate_cache(struct ctl_context *ctx)
736 {
737 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
738 const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs;
739 struct sset bridges, ports;
740 size_t i;
741
742 if (vsctl_ctx->cache_valid) {
743 /* Cache is already populated. */
744 return;
745 }
746 vsctl_ctx->cache_valid = true;
747 shash_init(&vsctl_ctx->bridges);
748 shash_init(&vsctl_ctx->ports);
749 shash_init(&vsctl_ctx->ifaces);
750
751 sset_init(&bridges);
752 sset_init(&ports);
753 for (i = 0; i < ovs->n_bridges; i++) {
754 struct ovsrec_bridge *br_cfg = ovs->bridges[i];
755 struct vsctl_bridge *br;
756 size_t j;
757
758 if (!sset_add(&bridges, br_cfg->name)) {
759 VLOG_WARN("%s: database contains duplicate bridge name",
760 br_cfg->name);
761 continue;
762 }
763 br = add_bridge_to_cache(vsctl_ctx, br_cfg, br_cfg->name, NULL, 0);
764
765 for (j = 0; j < br_cfg->n_ports; j++) {
766 struct ovsrec_port *port_cfg = br_cfg->ports[j];
767
768 if (!sset_add(&ports, port_cfg->name)) {
769 /* Duplicate port name. (We will warn about that later.) */
770 continue;
771 }
772
773 if (port_is_fake_bridge(port_cfg)
774 && sset_add(&bridges, port_cfg->name)) {
775 add_bridge_to_cache(vsctl_ctx, NULL, port_cfg->name, br,
776 *port_cfg->tag);
777 }
778 }
779 }
780 sset_destroy(&bridges);
781 sset_destroy(&ports);
782
783 sset_init(&bridges);
784 for (i = 0; i < ovs->n_bridges; i++) {
785 struct ovsrec_bridge *br_cfg = ovs->bridges[i];
786 struct vsctl_bridge *br;
787 size_t j;
788
789 if (!sset_add(&bridges, br_cfg->name)) {
790 continue;
791 }
792 br = shash_find_data(&vsctl_ctx->bridges, br_cfg->name);
793 for (j = 0; j < br_cfg->n_ports; j++) {
794 struct ovsrec_port *port_cfg = br_cfg->ports[j];
795 struct vsctl_port *port;
796 size_t k;
797
798 port = shash_find_data(&vsctl_ctx->ports, port_cfg->name);
799 if (port) {
800 if (port_cfg == port->port_cfg) {
801 VLOG_WARN("%s: port is in multiple bridges (%s and %s)",
802 port_cfg->name, br->name, port->bridge->name);
803 } else {
804 /* Log as an error because this violates the database's
805 * uniqueness constraints, so the database server shouldn't
806 * have allowed it. */
807 VLOG_ERR("%s: database contains duplicate port name",
808 port_cfg->name);
809 }
810 continue;
811 }
812
813 if (port_is_fake_bridge(port_cfg)
814 && !sset_add(&bridges, port_cfg->name)) {
815 continue;
816 }
817
818 port = add_port_to_cache(vsctl_ctx, br, port_cfg);
819 for (k = 0; k < port_cfg->n_interfaces; k++) {
820 struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
821 struct vsctl_iface *iface;
822
823 iface = shash_find_data(&vsctl_ctx->ifaces, iface_cfg->name);
824 if (iface) {
825 if (iface_cfg == iface->iface_cfg) {
826 VLOG_WARN("%s: interface is in multiple ports "
827 "(%s and %s)",
828 iface_cfg->name,
829 iface->port->port_cfg->name,
830 port->port_cfg->name);
831 } else {
832 /* Log as an error because this violates the database's
833 * uniqueness constraints, so the database server
834 * shouldn't have allowed it. */
835 VLOG_ERR("%s: database contains duplicate interface "
836 "name", iface_cfg->name);
837 }
838 continue;
839 }
840
841 add_iface_to_cache(vsctl_ctx, port, iface_cfg);
842 }
843 }
844 }
845 sset_destroy(&bridges);
846 }
847
848 static void
849 check_conflicts(struct vsctl_context *vsctl_ctx, const char *name,
850 char *msg)
851 {
852 struct vsctl_iface *iface;
853 struct vsctl_port *port;
854
855 verify_ports(vsctl_ctx);
856
857 if (shash_find(&vsctl_ctx->bridges, name)) {
858 ctl_fatal("%s because a bridge named %s already exists",
859 msg, name);
860 }
861
862 port = shash_find_data(&vsctl_ctx->ports, name);
863 if (port) {
864 ctl_fatal("%s because a port named %s already exists on "
865 "bridge %s", msg, name, port->bridge->name);
866 }
867
868 iface = shash_find_data(&vsctl_ctx->ifaces, name);
869 if (iface) {
870 ctl_fatal("%s because an interface named %s already exists "
871 "on bridge %s", msg, name, iface->port->bridge->name);
872 }
873
874 free(msg);
875 }
876
877 static struct vsctl_bridge *
878 find_bridge(struct vsctl_context *vsctl_ctx, const char *name, bool must_exist)
879 {
880 struct vsctl_bridge *br;
881
882 ovs_assert(vsctl_ctx->cache_valid);
883
884 br = shash_find_data(&vsctl_ctx->bridges, name);
885 if (must_exist && !br) {
886 ctl_fatal("no bridge named %s", name);
887 }
888 ovsrec_open_vswitch_verify_bridges(vsctl_ctx->ovs);
889 return br;
890 }
891
892 static struct vsctl_bridge *
893 find_real_bridge(struct vsctl_context *vsctl_ctx,
894 const char *name, bool must_exist)
895 {
896 struct vsctl_bridge *br = find_bridge(vsctl_ctx, name, must_exist);
897 if (br && br->parent) {
898 ctl_fatal("%s is a fake bridge", name);
899 }
900 return br;
901 }
902
903 static struct vsctl_port *
904 find_port(struct vsctl_context *vsctl_ctx, const char *name, bool must_exist)
905 {
906 struct vsctl_port *port;
907
908 ovs_assert(vsctl_ctx->cache_valid);
909
910 port = shash_find_data(&vsctl_ctx->ports, name);
911 if (port && !strcmp(name, port->bridge->name)) {
912 port = NULL;
913 }
914 if (must_exist && !port) {
915 ctl_fatal("no port named %s", name);
916 }
917 verify_ports(vsctl_ctx);
918 return port;
919 }
920
921 static struct vsctl_iface *
922 find_iface(struct vsctl_context *vsctl_ctx, const char *name, bool must_exist)
923 {
924 struct vsctl_iface *iface;
925
926 ovs_assert(vsctl_ctx->cache_valid);
927
928 iface = shash_find_data(&vsctl_ctx->ifaces, name);
929 if (iface && !strcmp(name, iface->port->bridge->name)) {
930 iface = NULL;
931 }
932 if (must_exist && !iface) {
933 ctl_fatal("no interface named %s", name);
934 }
935 verify_ports(vsctl_ctx);
936 return iface;
937 }
938
939 static void
940 bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
941 {
942 struct ovsrec_port **ports;
943 size_t i;
944
945 ports = xmalloc(sizeof *br->ports * (br->n_ports + 1));
946 for (i = 0; i < br->n_ports; i++) {
947 ports[i] = br->ports[i];
948 }
949 ports[br->n_ports] = port;
950 ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
951 free(ports);
952 }
953
954 static void
955 bridge_delete_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
956 {
957 struct ovsrec_port **ports;
958 size_t i, n;
959
960 ports = xmalloc(sizeof *br->ports * br->n_ports);
961 for (i = n = 0; i < br->n_ports; i++) {
962 if (br->ports[i] != port) {
963 ports[n++] = br->ports[i];
964 }
965 }
966 ovsrec_bridge_set_ports(br, ports, n);
967 free(ports);
968 }
969
970 static void
971 ovs_insert_bridge(const struct ovsrec_open_vswitch *ovs,
972 struct ovsrec_bridge *bridge)
973 {
974 struct ovsrec_bridge **bridges;
975 size_t i;
976
977 bridges = xmalloc(sizeof *ovs->bridges * (ovs->n_bridges + 1));
978 for (i = 0; i < ovs->n_bridges; i++) {
979 bridges[i] = ovs->bridges[i];
980 }
981 bridges[ovs->n_bridges] = bridge;
982 ovsrec_open_vswitch_set_bridges(ovs, bridges, ovs->n_bridges + 1);
983 free(bridges);
984 }
985
986 static void
987 cmd_init(struct ctl_context *ctx OVS_UNUSED)
988 {
989 }
990
991 static struct cmd_show_table cmd_show_tables[] = {
992 {&ovsrec_table_open_vswitch,
993 NULL,
994 {&ovsrec_open_vswitch_col_manager_options,
995 &ovsrec_open_vswitch_col_bridges,
996 &ovsrec_open_vswitch_col_ovs_version},
997 {NULL, NULL, NULL}
998 },
999
1000 {&ovsrec_table_bridge,
1001 &ovsrec_bridge_col_name,
1002 {&ovsrec_bridge_col_controller,
1003 &ovsrec_bridge_col_fail_mode,
1004 &ovsrec_bridge_col_ports},
1005 {NULL, NULL, NULL}
1006 },
1007
1008 {&ovsrec_table_port,
1009 &ovsrec_port_col_name,
1010 {&ovsrec_port_col_tag,
1011 &ovsrec_port_col_trunks,
1012 &ovsrec_port_col_interfaces},
1013 {NULL, NULL, NULL}
1014 },
1015
1016 {&ovsrec_table_interface,
1017 &ovsrec_interface_col_name,
1018 {&ovsrec_interface_col_type,
1019 &ovsrec_interface_col_options,
1020 &ovsrec_interface_col_error,
1021 &ovsrec_interface_col_bfd_status},
1022 {NULL, NULL, NULL}
1023 },
1024
1025 {&ovsrec_table_controller,
1026 &ovsrec_controller_col_target,
1027 {&ovsrec_controller_col_is_connected,
1028 NULL,
1029 NULL},
1030 {NULL, NULL, NULL}
1031 },
1032
1033 {&ovsrec_table_manager,
1034 &ovsrec_manager_col_target,
1035 {&ovsrec_manager_col_is_connected,
1036 NULL,
1037 NULL},
1038 {NULL, NULL, NULL}
1039 },
1040
1041 {NULL, NULL, {NULL, NULL, NULL}, {NULL, NULL, NULL}}
1042 };
1043
1044 static void
1045 pre_cmd_emer_reset(struct ctl_context *ctx)
1046 {
1047 ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_manager_options);
1048 ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
1049
1050 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_controller);
1051 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_fail_mode);
1052 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_mirrors);
1053 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_netflow);
1054 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_sflow);
1055 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_ipfix);
1056 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_flood_vlans);
1057 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_other_config);
1058
1059 ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_other_config);
1060
1061 ovsdb_idl_add_column(ctx->idl,
1062 &ovsrec_interface_col_ingress_policing_rate);
1063 ovsdb_idl_add_column(ctx->idl,
1064 &ovsrec_interface_col_ingress_policing_burst);
1065 }
1066
1067 static void
1068 cmd_emer_reset(struct ctl_context *ctx)
1069 {
1070 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1071 const struct ovsdb_idl *idl = ctx->idl;
1072 const struct ovsrec_bridge *br;
1073 const struct ovsrec_port *port;
1074 const struct ovsrec_interface *iface;
1075 const struct ovsrec_mirror *mirror, *next_mirror;
1076 const struct ovsrec_controller *ctrl, *next_ctrl;
1077 const struct ovsrec_manager *mgr, *next_mgr;
1078 const struct ovsrec_netflow *nf, *next_nf;
1079 const struct ovsrec_ssl *ssl, *next_ssl;
1080 const struct ovsrec_sflow *sflow, *next_sflow;
1081 const struct ovsrec_ipfix *ipfix, *next_ipfix;
1082 const struct ovsrec_flow_sample_collector_set *fscset, *next_fscset;
1083
1084 /* Reset the Open_vSwitch table. */
1085 ovsrec_open_vswitch_set_manager_options(vsctl_ctx->ovs, NULL, 0);
1086 ovsrec_open_vswitch_set_ssl(vsctl_ctx->ovs, NULL);
1087
1088 OVSREC_BRIDGE_FOR_EACH (br, idl) {
1089 const char *hwaddr;
1090
1091 ovsrec_bridge_set_controller(br, NULL, 0);
1092 ovsrec_bridge_set_fail_mode(br, NULL);
1093 ovsrec_bridge_set_mirrors(br, NULL, 0);
1094 ovsrec_bridge_set_netflow(br, NULL);
1095 ovsrec_bridge_set_sflow(br, NULL);
1096 ovsrec_bridge_set_ipfix(br, NULL);
1097 ovsrec_bridge_set_flood_vlans(br, NULL, 0);
1098
1099 /* We only want to save the "hwaddr" key from other_config. */
1100 hwaddr = smap_get(&br->other_config, "hwaddr");
1101 if (hwaddr) {
1102 const struct smap smap = SMAP_CONST1(&smap, "hwaddr", hwaddr);
1103 ovsrec_bridge_set_other_config(br, &smap);
1104 } else {
1105 ovsrec_bridge_set_other_config(br, NULL);
1106 }
1107 }
1108
1109 OVSREC_PORT_FOR_EACH (port, idl) {
1110 ovsrec_port_set_other_config(port, NULL);
1111 }
1112
1113 OVSREC_INTERFACE_FOR_EACH (iface, idl) {
1114 /* xxx What do we do about gre/patch devices created by mgr? */
1115
1116 ovsrec_interface_set_ingress_policing_rate(iface, 0);
1117 ovsrec_interface_set_ingress_policing_burst(iface, 0);
1118 }
1119
1120 OVSREC_MIRROR_FOR_EACH_SAFE (mirror, next_mirror, idl) {
1121 ovsrec_mirror_delete(mirror);
1122 }
1123
1124 OVSREC_CONTROLLER_FOR_EACH_SAFE (ctrl, next_ctrl, idl) {
1125 ovsrec_controller_delete(ctrl);
1126 }
1127
1128 OVSREC_MANAGER_FOR_EACH_SAFE (mgr, next_mgr, idl) {
1129 ovsrec_manager_delete(mgr);
1130 }
1131
1132 OVSREC_NETFLOW_FOR_EACH_SAFE (nf, next_nf, idl) {
1133 ovsrec_netflow_delete(nf);
1134 }
1135
1136 OVSREC_SSL_FOR_EACH_SAFE (ssl, next_ssl, idl) {
1137 ovsrec_ssl_delete(ssl);
1138 }
1139
1140 OVSREC_SFLOW_FOR_EACH_SAFE (sflow, next_sflow, idl) {
1141 ovsrec_sflow_delete(sflow);
1142 }
1143
1144 OVSREC_IPFIX_FOR_EACH_SAFE (ipfix, next_ipfix, idl) {
1145 ovsrec_ipfix_delete(ipfix);
1146 }
1147
1148 OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH_SAFE (fscset, next_fscset, idl) {
1149 ovsrec_flow_sample_collector_set_delete(fscset);
1150 }
1151
1152 vsctl_context_invalidate_cache(ctx);
1153 }
1154
1155 static void
1156 cmd_add_br(struct ctl_context *ctx)
1157 {
1158 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1159 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
1160 const char *br_name, *parent_name;
1161 struct ovsrec_interface *iface;
1162 int vlan;
1163
1164 br_name = ctx->argv[1];
1165 if (!br_name[0]) {
1166 ctl_fatal("bridge name must not be empty string");
1167 }
1168 if (ctx->argc == 2) {
1169 parent_name = NULL;
1170 vlan = 0;
1171 } else if (ctx->argc == 4) {
1172 parent_name = ctx->argv[2];
1173 vlan = atoi(ctx->argv[3]);
1174 if (vlan < 0 || vlan > 4095) {
1175 ctl_fatal("%s: vlan must be between 0 and 4095", ctx->argv[0]);
1176 }
1177 } else {
1178 ctl_fatal("'%s' command takes exactly 1 or 3 arguments",
1179 ctx->argv[0]);
1180 }
1181
1182 vsctl_context_populate_cache(ctx);
1183 if (may_exist) {
1184 struct vsctl_bridge *br;
1185
1186 br = find_bridge(vsctl_ctx, br_name, false);
1187 if (br) {
1188 if (!parent_name) {
1189 if (br->parent) {
1190 ctl_fatal("\"--may-exist add-br %s\" but %s is "
1191 "a VLAN bridge for VLAN %d",
1192 br_name, br_name, br->vlan);
1193 }
1194 } else {
1195 if (!br->parent) {
1196 ctl_fatal("\"--may-exist add-br %s %s %d\" but %s "
1197 "is not a VLAN bridge",
1198 br_name, parent_name, vlan, br_name);
1199 } else if (strcmp(br->parent->name, parent_name)) {
1200 ctl_fatal("\"--may-exist add-br %s %s %d\" but %s "
1201 "has the wrong parent %s",
1202 br_name, parent_name, vlan,
1203 br_name, br->parent->name);
1204 } else if (br->vlan != vlan) {
1205 ctl_fatal("\"--may-exist add-br %s %s %d\" but %s "
1206 "is a VLAN bridge for the wrong VLAN %d",
1207 br_name, parent_name, vlan, br_name, br->vlan);
1208 }
1209 }
1210 return;
1211 }
1212 }
1213 check_conflicts(vsctl_ctx, br_name,
1214 xasprintf("cannot create a bridge named %s", br_name));
1215
1216 if (!parent_name) {
1217 struct ovsrec_port *port;
1218 struct ovsrec_bridge *br;
1219
1220 iface = ovsrec_interface_insert(ctx->txn);
1221 ovsrec_interface_set_name(iface, br_name);
1222 ovsrec_interface_set_type(iface, "internal");
1223
1224 port = ovsrec_port_insert(ctx->txn);
1225 ovsrec_port_set_name(port, br_name);
1226 ovsrec_port_set_interfaces(port, &iface, 1);
1227
1228 br = ovsrec_bridge_insert(ctx->txn);
1229 ovsrec_bridge_set_name(br, br_name);
1230 ovsrec_bridge_set_ports(br, &port, 1);
1231
1232 ovs_insert_bridge(vsctl_ctx->ovs, br);
1233 } else {
1234 struct vsctl_bridge *conflict;
1235 struct vsctl_bridge *parent;
1236 struct ovsrec_port *port;
1237 struct ovsrec_bridge *br;
1238 int64_t tag = vlan;
1239
1240 parent = find_bridge(vsctl_ctx, parent_name, false);
1241 if (parent && parent->parent) {
1242 ctl_fatal("cannot create bridge with fake bridge as parent");
1243 }
1244 if (!parent) {
1245 ctl_fatal("parent bridge %s does not exist", parent_name);
1246 }
1247 conflict = find_vlan_bridge(parent, vlan);
1248 if (conflict) {
1249 ctl_fatal("bridge %s already has a child VLAN bridge %s "
1250 "on VLAN %d", parent_name, conflict->name, vlan);
1251 }
1252 br = parent->br_cfg;
1253
1254 iface = ovsrec_interface_insert(ctx->txn);
1255 ovsrec_interface_set_name(iface, br_name);
1256 ovsrec_interface_set_type(iface, "internal");
1257
1258 port = ovsrec_port_insert(ctx->txn);
1259 ovsrec_port_set_name(port, br_name);
1260 ovsrec_port_set_interfaces(port, &iface, 1);
1261 ovsrec_port_set_fake_bridge(port, true);
1262 ovsrec_port_set_tag(port, &tag, 1);
1263
1264 bridge_insert_port(br, port);
1265 }
1266
1267 post_db_reload_expect_iface(iface);
1268 vsctl_context_invalidate_cache(ctx);
1269 }
1270
1271 static void
1272 del_port(struct vsctl_context *vsctl_ctx, struct vsctl_port *port)
1273 {
1274 struct vsctl_iface *iface, *next_iface;
1275
1276 bridge_delete_port((port->bridge->parent
1277 ? port->bridge->parent->br_cfg
1278 : port->bridge->br_cfg), port->port_cfg);
1279
1280 LIST_FOR_EACH_SAFE (iface, next_iface, ifaces_node, &port->ifaces) {
1281 del_cached_iface(vsctl_ctx, iface);
1282 }
1283 del_cached_port(vsctl_ctx, port);
1284 }
1285
1286 static void
1287 del_bridge(struct vsctl_context *vsctl_ctx, struct vsctl_bridge *br)
1288 {
1289 struct vsctl_bridge *child, *next_child;
1290 struct vsctl_port *port, *next_port;
1291 const struct ovsrec_flow_sample_collector_set *fscset, *next_fscset;
1292
1293 HMAP_FOR_EACH_SAFE (child, next_child, children_node, &br->children) {
1294 del_bridge(vsctl_ctx, child);
1295 }
1296
1297 LIST_FOR_EACH_SAFE (port, next_port, ports_node, &br->ports) {
1298 del_port(vsctl_ctx, port);
1299 }
1300
1301 OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH_SAFE (fscset, next_fscset,
1302 vsctl_ctx->base.idl) {
1303 if (fscset->bridge == br->br_cfg) {
1304 ovsrec_flow_sample_collector_set_delete(fscset);
1305 }
1306 }
1307
1308 del_cached_bridge(vsctl_ctx, br);
1309 }
1310
1311 static void
1312 cmd_del_br(struct ctl_context *ctx)
1313 {
1314 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1315 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1316 struct vsctl_bridge *bridge;
1317
1318 vsctl_context_populate_cache(ctx);
1319 bridge = find_bridge(vsctl_ctx, ctx->argv[1], must_exist);
1320 if (bridge) {
1321 del_bridge(vsctl_ctx, bridge);
1322 }
1323 }
1324
1325 static void
1326 output_sorted(struct svec *svec, struct ds *output)
1327 {
1328 const char *name;
1329 size_t i;
1330
1331 svec_sort(svec);
1332 SVEC_FOR_EACH (i, name, svec) {
1333 ds_put_format(output, "%s\n", name);
1334 }
1335 }
1336
1337 static void
1338 cmd_list_br(struct ctl_context *ctx)
1339 {
1340 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1341 struct shash_node *node;
1342 struct svec bridges;
1343 bool real = shash_find(&ctx->options, "--real");
1344 bool fake = shash_find(&ctx->options, "--fake");
1345
1346 /* If neither fake nor real were requested, return both. */
1347 if (!real && !fake) {
1348 real = fake = true;
1349 }
1350
1351 vsctl_context_populate_cache(ctx);
1352
1353 svec_init(&bridges);
1354 SHASH_FOR_EACH (node, &vsctl_ctx->bridges) {
1355 struct vsctl_bridge *br = node->data;
1356
1357 if (br->parent ? fake : real) {
1358 svec_add(&bridges, br->name);
1359 }
1360 }
1361 output_sorted(&bridges, &ctx->output);
1362 svec_destroy(&bridges);
1363 }
1364
1365 static void
1366 cmd_br_exists(struct ctl_context *ctx)
1367 {
1368 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1369
1370 vsctl_context_populate_cache(ctx);
1371 if (!find_bridge(vsctl_ctx, ctx->argv[1], false)) {
1372 vsctl_exit(2);
1373 }
1374 }
1375
1376 static void
1377 set_external_id(struct smap *old, struct smap *new,
1378 char *key, char *value)
1379 {
1380 smap_clone(new, old);
1381
1382 if (value) {
1383 smap_replace(new, key, value);
1384 } else {
1385 smap_remove(new, key);
1386 }
1387 }
1388
1389 static void
1390 pre_cmd_br_set_external_id(struct ctl_context *ctx)
1391 {
1392 pre_get_info(ctx);
1393 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_external_ids);
1394 ovsdb_idl_add_column(ctx->idl, &ovsrec_port_col_external_ids);
1395 }
1396
1397 static void
1398 cmd_br_set_external_id(struct ctl_context *ctx)
1399 {
1400 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1401 struct vsctl_bridge *bridge;
1402 struct smap new;
1403
1404 vsctl_context_populate_cache(ctx);
1405 bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
1406 if (bridge->br_cfg) {
1407
1408 set_external_id(&bridge->br_cfg->external_ids, &new, ctx->argv[2],
1409 ctx->argc >= 4 ? ctx->argv[3] : NULL);
1410 ovsrec_bridge_verify_external_ids(bridge->br_cfg);
1411 ovsrec_bridge_set_external_ids(bridge->br_cfg, &new);
1412 } else {
1413 char *key = xasprintf("fake-bridge-%s", ctx->argv[2]);
1414 struct vsctl_port *port = shash_find_data(&vsctl_ctx->ports,
1415 ctx->argv[1]);
1416 set_external_id(&port->port_cfg->external_ids, &new,
1417 key, ctx->argc >= 4 ? ctx->argv[3] : NULL);
1418 ovsrec_port_verify_external_ids(port->port_cfg);
1419 ovsrec_port_set_external_ids(port->port_cfg, &new);
1420 free(key);
1421 }
1422 smap_destroy(&new);
1423 }
1424
1425 static void
1426 get_external_id(struct smap *smap, const char *prefix, const char *key,
1427 struct ds *output)
1428 {
1429 if (key) {
1430 char *prefix_key = xasprintf("%s%s", prefix, key);
1431 const char *value = smap_get(smap, prefix_key);
1432
1433 if (value) {
1434 ds_put_format(output, "%s\n", value);
1435 }
1436 free(prefix_key);
1437 } else {
1438 const struct smap_node **sorted = smap_sort(smap);
1439 size_t prefix_len = strlen(prefix);
1440 size_t i;
1441
1442 for (i = 0; i < smap_count(smap); i++) {
1443 const struct smap_node *node = sorted[i];
1444 if (!strncmp(node->key, prefix, prefix_len)) {
1445 ds_put_format(output, "%s=%s\n", node->key + prefix_len,
1446 node->value);
1447 }
1448 }
1449 free(sorted);
1450 }
1451 }
1452
1453 static void
1454 pre_cmd_br_get_external_id(struct ctl_context *ctx)
1455 {
1456 pre_cmd_br_set_external_id(ctx);
1457 }
1458
1459 static void
1460 cmd_br_get_external_id(struct ctl_context *ctx)
1461 {
1462 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1463 struct vsctl_bridge *bridge;
1464
1465 vsctl_context_populate_cache(ctx);
1466
1467 bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
1468 if (bridge->br_cfg) {
1469 ovsrec_bridge_verify_external_ids(bridge->br_cfg);
1470 get_external_id(&bridge->br_cfg->external_ids, "",
1471 ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1472 } else {
1473 struct vsctl_port *port = shash_find_data(&vsctl_ctx->ports,
1474 ctx->argv[1]);
1475 ovsrec_port_verify_external_ids(port->port_cfg);
1476 get_external_id(&port->port_cfg->external_ids, "fake-bridge-",
1477 ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1478 }
1479 }
1480
1481 static void
1482 cmd_list_ports(struct ctl_context *ctx)
1483 {
1484 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1485 struct vsctl_bridge *br;
1486 struct vsctl_port *port;
1487 struct svec ports;
1488
1489 vsctl_context_populate_cache(ctx);
1490 br = find_bridge(vsctl_ctx, ctx->argv[1], true);
1491 ovsrec_bridge_verify_ports(br->br_cfg ? br->br_cfg : br->parent->br_cfg);
1492
1493 svec_init(&ports);
1494 LIST_FOR_EACH (port, ports_node, &br->ports) {
1495 if (strcmp(port->port_cfg->name, br->name)) {
1496 svec_add(&ports, port->port_cfg->name);
1497 }
1498 }
1499 output_sorted(&ports, &ctx->output);
1500 svec_destroy(&ports);
1501 }
1502
1503 static void
1504 add_port(struct ctl_context *ctx,
1505 const char *br_name, const char *port_name,
1506 bool may_exist, bool fake_iface,
1507 char *iface_names[], int n_ifaces,
1508 char *settings[], int n_settings)
1509 {
1510 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1511 struct vsctl_bridge *bridge;
1512 struct ovsrec_interface **ifaces;
1513 struct ovsrec_port *port;
1514 size_t i;
1515
1516 if (!port_name[0]) {
1517 ctl_fatal("port name must not be empty string");
1518 }
1519 for (i = 0; i < n_ifaces; i++) {
1520 if (!iface_names[i][0]) {
1521 ctl_fatal("interface name must not be empty string");
1522 }
1523 }
1524
1525 vsctl_context_populate_cache(ctx);
1526 if (may_exist) {
1527 struct vsctl_port *vsctl_port;
1528
1529 vsctl_port = find_port(vsctl_ctx, port_name, false);
1530 if (vsctl_port) {
1531 struct svec want_names, have_names;
1532
1533 svec_init(&want_names);
1534 for (i = 0; i < n_ifaces; i++) {
1535 svec_add(&want_names, iface_names[i]);
1536 }
1537 svec_sort(&want_names);
1538
1539 svec_init(&have_names);
1540 for (i = 0; i < vsctl_port->port_cfg->n_interfaces; i++) {
1541 svec_add(&have_names,
1542 vsctl_port->port_cfg->interfaces[i]->name);
1543 }
1544 svec_sort(&have_names);
1545
1546 if (strcmp(vsctl_port->bridge->name, br_name)) {
1547 char *command = vsctl_context_to_string(ctx);
1548 ctl_fatal("\"%s\" but %s is actually attached to bridge %s",
1549 command, port_name, vsctl_port->bridge->name);
1550 }
1551
1552 if (!svec_equal(&want_names, &have_names)) {
1553 char *have_names_string = svec_join(&have_names, ", ", "");
1554 char *command = vsctl_context_to_string(ctx);
1555
1556 ctl_fatal("\"%s\" but %s actually has interface(s) %s",
1557 command, port_name, have_names_string);
1558 }
1559
1560 svec_destroy(&want_names);
1561 svec_destroy(&have_names);
1562
1563 return;
1564 }
1565 }
1566 check_conflicts(vsctl_ctx, port_name,
1567 xasprintf("cannot create a port named %s", port_name));
1568 for (i = 0; i < n_ifaces; i++) {
1569 check_conflicts(vsctl_ctx, iface_names[i],
1570 xasprintf("cannot create an interface named %s",
1571 iface_names[i]));
1572 }
1573 bridge = find_bridge(vsctl_ctx, br_name, true);
1574
1575 ifaces = xmalloc(n_ifaces * sizeof *ifaces);
1576 for (i = 0; i < n_ifaces; i++) {
1577 ifaces[i] = ovsrec_interface_insert(ctx->txn);
1578 ovsrec_interface_set_name(ifaces[i], iface_names[i]);
1579 post_db_reload_expect_iface(ifaces[i]);
1580 }
1581
1582 port = ovsrec_port_insert(ctx->txn);
1583 ovsrec_port_set_name(port, port_name);
1584 ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
1585 ovsrec_port_set_bond_fake_iface(port, fake_iface);
1586
1587 if (bridge->parent) {
1588 int64_t tag = bridge->vlan;
1589 ovsrec_port_set_tag(port, &tag, 1);
1590 }
1591
1592 for (i = 0; i < n_settings; i++) {
1593 char *error = ctl_set_column("Port", &port->header_, settings[i],
1594 ctx->symtab);
1595 if (error) {
1596 ctl_fatal("%s", error);
1597 }
1598 }
1599
1600 bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
1601 : bridge->br_cfg), port);
1602
1603 struct vsctl_port *vsctl_port = add_port_to_cache(vsctl_ctx, bridge, port);
1604 for (i = 0; i < n_ifaces; i++) {
1605 add_iface_to_cache(vsctl_ctx, vsctl_port, ifaces[i]);
1606 }
1607 free(ifaces);
1608 }
1609
1610 static void
1611 cmd_add_port(struct ctl_context *ctx)
1612 {
1613 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
1614
1615 add_port(ctx, ctx->argv[1], ctx->argv[2], may_exist, false,
1616 &ctx->argv[2], 1, &ctx->argv[3], ctx->argc - 3);
1617 }
1618
1619 static void
1620 cmd_add_bond(struct ctl_context *ctx)
1621 {
1622 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
1623 bool fake_iface = shash_find(&ctx->options, "--fake-iface");
1624 int n_ifaces;
1625 int i;
1626
1627 n_ifaces = ctx->argc - 3;
1628 for (i = 3; i < ctx->argc; i++) {
1629 if (strchr(ctx->argv[i], '=')) {
1630 n_ifaces = i - 3;
1631 break;
1632 }
1633 }
1634 if (n_ifaces < 2) {
1635 ctl_fatal("add-bond requires at least 2 interfaces, but only "
1636 "%d were specified", n_ifaces);
1637 }
1638
1639 add_port(ctx, ctx->argv[1], ctx->argv[2], may_exist, fake_iface,
1640 &ctx->argv[3], n_ifaces,
1641 &ctx->argv[n_ifaces + 3], ctx->argc - 3 - n_ifaces);
1642 }
1643
1644 static void
1645 cmd_add_bond_iface(struct ctl_context *ctx)
1646 {
1647 vsctl_context_populate_cache(ctx);
1648
1649 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1650 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
1651 struct vsctl_port *port = find_port(vsctl_ctx, ctx->argv[1], true);
1652
1653 const char *iface_name = ctx->argv[2];
1654 if (may_exist) {
1655 struct vsctl_iface *iface = find_iface(vsctl_ctx, iface_name, false);
1656 if (iface) {
1657 if (iface->port == port) {
1658 return;
1659 }
1660 char *command = vsctl_context_to_string(ctx);
1661 ctl_fatal("\"%s\" but %s is actually attached to port %s",
1662 command, iface_name, iface->port->port_cfg->name);
1663 }
1664 }
1665 check_conflicts(vsctl_ctx, iface_name,
1666 xasprintf("cannot create an interface named %s",
1667 iface_name));
1668
1669 struct ovsrec_interface *iface = ovsrec_interface_insert(ctx->txn);
1670 ovsrec_interface_set_name(iface, iface_name);
1671 ovsrec_port_update_interfaces_addvalue(port->port_cfg, iface);
1672 post_db_reload_expect_iface(iface);
1673 add_iface_to_cache(vsctl_ctx, port, iface);
1674 }
1675
1676 static void
1677 cmd_del_bond_iface(struct ctl_context *ctx)
1678 {
1679 vsctl_context_populate_cache(ctx);
1680
1681 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1682 const char *iface_name = ctx->argv[ctx->argc - 1];
1683 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1684 struct vsctl_iface *iface = find_iface(vsctl_ctx, iface_name, must_exist);
1685 if (!iface) {
1686 ovs_assert(!must_exist);
1687 return;
1688 }
1689
1690 const char *port_name = ctx->argc > 2 ? ctx->argv[1] : NULL;
1691 if (port_name) {
1692 struct vsctl_port *port = find_port(vsctl_ctx, port_name, true);
1693 if (iface->port != port) {
1694 ctl_fatal("port %s does not have an interface %s",
1695 port_name, iface_name);
1696 }
1697 }
1698
1699 if (ovs_list_is_short(&iface->port->ifaces)) {
1700 ctl_fatal("cannot delete last interface from port %s",
1701 iface->port->port_cfg->name);
1702 }
1703
1704 ovsrec_port_update_interfaces_delvalue(iface->port->port_cfg,
1705 iface->iface_cfg);
1706 del_cached_iface(vsctl_ctx, iface);
1707 }
1708
1709 static void
1710 cmd_del_port(struct ctl_context *ctx)
1711 {
1712 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1713 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1714 bool with_iface = shash_find(&ctx->options, "--with-iface") != NULL;
1715 const char *target = ctx->argv[ctx->argc - 1];
1716 struct vsctl_port *port;
1717
1718 vsctl_context_populate_cache(ctx);
1719 if (find_bridge(vsctl_ctx, target, false)) {
1720 if (must_exist) {
1721 ctl_fatal("cannot delete port %s because it is the local port "
1722 "for bridge %s (deleting this port requires deleting "
1723 "the entire bridge)", target, target);
1724 }
1725 port = NULL;
1726 } else if (!with_iface) {
1727 port = find_port(vsctl_ctx, target, must_exist);
1728 } else {
1729 struct vsctl_iface *iface;
1730
1731 port = find_port(vsctl_ctx, target, false);
1732 if (!port) {
1733 iface = find_iface(vsctl_ctx, target, false);
1734 if (iface) {
1735 port = iface->port;
1736 }
1737 }
1738 if (must_exist && !port) {
1739 ctl_fatal("no port or interface named %s", target);
1740 }
1741 }
1742
1743 if (port) {
1744 if (ctx->argc == 3) {
1745 struct vsctl_bridge *bridge;
1746
1747 bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
1748 if (port->bridge != bridge) {
1749 if (port->bridge->parent == bridge) {
1750 ctl_fatal("bridge %s does not have a port %s (although "
1751 "its child bridge %s does)",
1752 ctx->argv[1], ctx->argv[2],
1753 port->bridge->name);
1754 } else {
1755 ctl_fatal("bridge %s does not have a port %s",
1756 ctx->argv[1], ctx->argv[2]);
1757 }
1758 }
1759 }
1760
1761 del_port(vsctl_ctx, port);
1762 }
1763 }
1764
1765 static void
1766 cmd_port_to_br(struct ctl_context *ctx)
1767 {
1768 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1769 struct vsctl_port *port;
1770
1771 vsctl_context_populate_cache(ctx);
1772
1773 port = find_port(vsctl_ctx, ctx->argv[1], true);
1774 ds_put_format(&ctx->output, "%s\n", port->bridge->name);
1775 }
1776
1777 static void
1778 cmd_br_to_vlan(struct ctl_context *ctx)
1779 {
1780 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1781 struct vsctl_bridge *bridge;
1782
1783 vsctl_context_populate_cache(ctx);
1784
1785 bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
1786 ds_put_format(&ctx->output, "%d\n", bridge->vlan);
1787 }
1788
1789 static void
1790 cmd_br_to_parent(struct ctl_context *ctx)
1791 {
1792 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1793 struct vsctl_bridge *bridge;
1794
1795 vsctl_context_populate_cache(ctx);
1796
1797 bridge = find_bridge(vsctl_ctx, ctx->argv[1], true);
1798 if (bridge->parent) {
1799 bridge = bridge->parent;
1800 }
1801 ds_put_format(&ctx->output, "%s\n", bridge->name);
1802 }
1803
1804 static void
1805 cmd_list_ifaces(struct ctl_context *ctx)
1806 {
1807 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1808 struct vsctl_bridge *br;
1809 struct vsctl_port *port;
1810 struct svec ifaces;
1811
1812 vsctl_context_populate_cache(ctx);
1813
1814 br = find_bridge(vsctl_ctx, ctx->argv[1], true);
1815 verify_ports(vsctl_ctx);
1816
1817 svec_init(&ifaces);
1818 LIST_FOR_EACH (port, ports_node, &br->ports) {
1819 struct vsctl_iface *iface;
1820
1821 LIST_FOR_EACH (iface, ifaces_node, &port->ifaces) {
1822 if (strcmp(iface->iface_cfg->name, br->name)) {
1823 svec_add(&ifaces, iface->iface_cfg->name);
1824 }
1825 }
1826 }
1827 output_sorted(&ifaces, &ctx->output);
1828 svec_destroy(&ifaces);
1829 }
1830
1831 static void
1832 cmd_iface_to_br(struct ctl_context *ctx)
1833 {
1834 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1835 struct vsctl_iface *iface;
1836
1837 vsctl_context_populate_cache(ctx);
1838
1839 iface = find_iface(vsctl_ctx, ctx->argv[1], true);
1840 ds_put_format(&ctx->output, "%s\n", iface->port->bridge->name);
1841 }
1842
1843 static void
1844 verify_controllers(struct ovsrec_bridge *bridge)
1845 {
1846 size_t i;
1847
1848 ovsrec_bridge_verify_controller(bridge);
1849 for (i = 0; i < bridge->n_controller; i++) {
1850 ovsrec_controller_verify_target(bridge->controller[i]);
1851 }
1852 }
1853
1854 static void
1855 pre_controller(struct ctl_context *ctx)
1856 {
1857 pre_get_info(ctx);
1858
1859 ovsdb_idl_add_column(ctx->idl, &ovsrec_controller_col_target);
1860 ovsdb_idl_add_column(ctx->idl, &ovsrec_controller_col_inactivity_probe);
1861 }
1862
1863 static void
1864 cmd_get_controller(struct ctl_context *ctx)
1865 {
1866 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1867 struct vsctl_bridge *br;
1868 struct svec targets;
1869 size_t i;
1870
1871 vsctl_context_populate_cache(ctx);
1872
1873 br = find_bridge(vsctl_ctx, ctx->argv[1], true);
1874 if (br->parent) {
1875 br = br->parent;
1876 }
1877 verify_controllers(br->br_cfg);
1878
1879 /* Print the targets in sorted order for reproducibility. */
1880 svec_init(&targets);
1881 for (i = 0; i < br->br_cfg->n_controller; i++) {
1882 svec_add(&targets, br->br_cfg->controller[i]->target);
1883 }
1884
1885 svec_sort(&targets);
1886 for (i = 0; i < targets.n; i++) {
1887 ds_put_format(&ctx->output, "%s\n", targets.names[i]);
1888 }
1889 svec_destroy(&targets);
1890 }
1891
1892 static void
1893 delete_controllers(struct ovsrec_controller **controllers,
1894 size_t n_controllers)
1895 {
1896 size_t i;
1897
1898 for (i = 0; i < n_controllers; i++) {
1899 ovsrec_controller_delete(controllers[i]);
1900 }
1901 }
1902
1903 static void
1904 cmd_del_controller(struct ctl_context *ctx)
1905 {
1906 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1907 struct ovsrec_bridge *br;
1908
1909 vsctl_context_populate_cache(ctx);
1910
1911 br = find_real_bridge(vsctl_ctx, ctx->argv[1], true)->br_cfg;
1912 verify_controllers(br);
1913
1914 if (br->controller) {
1915 delete_controllers(br->controller, br->n_controller);
1916 ovsrec_bridge_set_controller(br, NULL, 0);
1917 }
1918 }
1919
1920 static struct ovsrec_controller **
1921 insert_controllers(struct ctl_context *ctx, char *targets[], size_t n)
1922 {
1923 struct ovsrec_controller **controllers;
1924 size_t i;
1925 const char *inactivity_probe = shash_find_data(&ctx->options,
1926 "--inactivity-probe");
1927
1928 controllers = xmalloc(n * sizeof *controllers);
1929 for (i = 0; i < n; i++) {
1930 if (vconn_verify_name(targets[i]) && pvconn_verify_name(targets[i])) {
1931 VLOG_WARN("target type \"%s\" is possibly erroneous", targets[i]);
1932 }
1933 controllers[i] = ovsrec_controller_insert(ctx->txn);
1934 ovsrec_controller_set_target(controllers[i], targets[i]);
1935 if (inactivity_probe) {
1936 int64_t msecs = atoll(inactivity_probe);
1937 ovsrec_controller_set_inactivity_probe(controllers[i], &msecs, 1);
1938 }
1939 }
1940
1941 return controllers;
1942 }
1943
1944 static void
1945 cmd_set_controller(struct ctl_context *ctx)
1946 {
1947 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1948 struct ovsrec_controller **controllers;
1949 struct ovsrec_bridge *br;
1950 size_t n;
1951
1952 vsctl_context_populate_cache(ctx);
1953
1954 br = find_real_bridge(vsctl_ctx, ctx->argv[1], true)->br_cfg;
1955 verify_controllers(br);
1956
1957 delete_controllers(br->controller, br->n_controller);
1958
1959 n = ctx->argc - 2;
1960 controllers = insert_controllers(ctx, &ctx->argv[2], n);
1961 ovsrec_bridge_set_controller(br, controllers, n);
1962 free(controllers);
1963 }
1964
1965 static void
1966 cmd_get_fail_mode(struct ctl_context *ctx)
1967 {
1968 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1969 struct vsctl_bridge *br;
1970 const char *fail_mode;
1971
1972 vsctl_context_populate_cache(ctx);
1973 br = find_bridge(vsctl_ctx, ctx->argv[1], true);
1974
1975 if (br->parent) {
1976 br = br->parent;
1977 }
1978 ovsrec_bridge_verify_fail_mode(br->br_cfg);
1979
1980 fail_mode = br->br_cfg->fail_mode;
1981 if (fail_mode && strlen(fail_mode)) {
1982 ds_put_format(&ctx->output, "%s\n", fail_mode);
1983 }
1984 }
1985
1986 static void
1987 cmd_del_fail_mode(struct ctl_context *ctx)
1988 {
1989 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
1990 struct vsctl_bridge *br;
1991
1992 vsctl_context_populate_cache(ctx);
1993
1994 br = find_real_bridge(vsctl_ctx, ctx->argv[1], true);
1995
1996 ovsrec_bridge_set_fail_mode(br->br_cfg, NULL);
1997 }
1998
1999 static void
2000 cmd_set_fail_mode(struct ctl_context *ctx)
2001 {
2002 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2003 struct vsctl_bridge *br;
2004 const char *fail_mode = ctx->argv[2];
2005
2006 vsctl_context_populate_cache(ctx);
2007
2008 br = find_real_bridge(vsctl_ctx, ctx->argv[1], true);
2009
2010 if (strcmp(fail_mode, "standalone") && strcmp(fail_mode, "secure")) {
2011 ctl_fatal("fail-mode must be \"standalone\" or \"secure\"");
2012 }
2013
2014 ovsrec_bridge_set_fail_mode(br->br_cfg, fail_mode);
2015 }
2016
2017 static void
2018 verify_managers(const struct ovsrec_open_vswitch *ovs)
2019 {
2020 size_t i;
2021
2022 ovsrec_open_vswitch_verify_manager_options(ovs);
2023
2024 for (i = 0; i < ovs->n_manager_options; ++i) {
2025 const struct ovsrec_manager *mgr = ovs->manager_options[i];
2026
2027 ovsrec_manager_verify_target(mgr);
2028 }
2029 }
2030
2031 static void
2032 pre_manager(struct ctl_context *ctx)
2033 {
2034 ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_manager_options);
2035 ovsdb_idl_add_column(ctx->idl, &ovsrec_manager_col_target);
2036 ovsdb_idl_add_column(ctx->idl, &ovsrec_manager_col_inactivity_probe);
2037 }
2038
2039 static void
2040 cmd_get_manager(struct ctl_context *ctx)
2041 {
2042 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2043 const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs;
2044 struct svec targets;
2045 size_t i;
2046
2047 verify_managers(ovs);
2048
2049 /* Print the targets in sorted order for reproducibility. */
2050 svec_init(&targets);
2051
2052 for (i = 0; i < ovs->n_manager_options; i++) {
2053 svec_add(&targets, ovs->manager_options[i]->target);
2054 }
2055
2056 svec_sort_unique(&targets);
2057 for (i = 0; i < targets.n; i++) {
2058 ds_put_format(&ctx->output, "%s\n", targets.names[i]);
2059 }
2060 svec_destroy(&targets);
2061 }
2062
2063 static void
2064 delete_managers(const struct ovsrec_open_vswitch *ovs)
2065 {
2066 size_t i;
2067
2068 /* Delete Manager rows pointed to by 'manager_options' column. */
2069 for (i = 0; i < ovs->n_manager_options; i++) {
2070 ovsrec_manager_delete(ovs->manager_options[i]);
2071 }
2072
2073 /* Delete 'Manager' row refs in 'manager_options' column. */
2074 ovsrec_open_vswitch_set_manager_options(ovs, NULL, 0);
2075 }
2076
2077 static void
2078 cmd_del_manager(struct ctl_context *ctx)
2079 {
2080 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2081 const struct ovsrec_open_vswitch *ovs = vsctl_ctx->ovs;
2082
2083 verify_managers(ovs);
2084 delete_managers(ovs);
2085 }
2086
2087 static void
2088 insert_managers(struct vsctl_context *vsctl_ctx, char *targets[], size_t n,
2089 struct shash *options)
2090 {
2091 struct ovsrec_manager **managers;
2092 size_t i;
2093 const char *inactivity_probe = shash_find_data(options,
2094 "--inactivity-probe");
2095
2096 /* Insert each manager in a new row in Manager table. */
2097 managers = xmalloc(n * sizeof *managers);
2098 for (i = 0; i < n; i++) {
2099 if (stream_verify_name(targets[i]) && pstream_verify_name(targets[i])) {
2100 VLOG_WARN("target type \"%s\" is possibly erroneous", targets[i]);
2101 }
2102 managers[i] = ovsrec_manager_insert(vsctl_ctx->base.txn);
2103 ovsrec_manager_set_target(managers[i], targets[i]);
2104 if (inactivity_probe) {
2105 int64_t msecs = atoll(inactivity_probe);
2106 ovsrec_manager_set_inactivity_probe(managers[i], &msecs, 1);
2107 }
2108 }
2109
2110 /* Store uuids of new Manager rows in 'manager_options' column. */
2111 ovsrec_open_vswitch_set_manager_options(vsctl_ctx->ovs, managers, n);
2112 free(managers);
2113 }
2114
2115 static void
2116 cmd_set_manager(struct ctl_context *ctx)
2117 {
2118 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2119 const size_t n = ctx->argc - 1;
2120
2121 verify_managers(vsctl_ctx->ovs);
2122 delete_managers(vsctl_ctx->ovs);
2123 insert_managers(vsctl_ctx, &ctx->argv[1], n, &ctx->options);
2124 }
2125
2126 static void
2127 pre_cmd_get_ssl(struct ctl_context *ctx)
2128 {
2129 ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
2130
2131 ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_private_key);
2132 ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_certificate);
2133 ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_ca_cert);
2134 ovsdb_idl_add_column(ctx->idl, &ovsrec_ssl_col_bootstrap_ca_cert);
2135 }
2136
2137 static void
2138 cmd_get_ssl(struct ctl_context *ctx)
2139 {
2140 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2141 struct ovsrec_ssl *ssl = vsctl_ctx->ovs->ssl;
2142
2143 ovsrec_open_vswitch_verify_ssl(vsctl_ctx->ovs);
2144 if (ssl) {
2145 ovsrec_ssl_verify_private_key(ssl);
2146 ovsrec_ssl_verify_certificate(ssl);
2147 ovsrec_ssl_verify_ca_cert(ssl);
2148 ovsrec_ssl_verify_bootstrap_ca_cert(ssl);
2149
2150 ds_put_format(&ctx->output, "Private key: %s\n", ssl->private_key);
2151 ds_put_format(&ctx->output, "Certificate: %s\n", ssl->certificate);
2152 ds_put_format(&ctx->output, "CA Certificate: %s\n", ssl->ca_cert);
2153 ds_put_format(&ctx->output, "Bootstrap: %s\n",
2154 ssl->bootstrap_ca_cert ? "true" : "false");
2155 }
2156 }
2157
2158 static void
2159 pre_cmd_del_ssl(struct ctl_context *ctx)
2160 {
2161 ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
2162 }
2163
2164 static void
2165 cmd_del_ssl(struct ctl_context *ctx)
2166 {
2167 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2168 struct ovsrec_ssl *ssl = vsctl_ctx->ovs->ssl;
2169
2170 if (ssl) {
2171 ovsrec_open_vswitch_verify_ssl(vsctl_ctx->ovs);
2172 ovsrec_ssl_delete(ssl);
2173 ovsrec_open_vswitch_set_ssl(vsctl_ctx->ovs, NULL);
2174 }
2175 }
2176
2177 static void
2178 pre_cmd_set_ssl(struct ctl_context *ctx)
2179 {
2180 ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
2181 }
2182
2183 static void
2184 cmd_set_ssl(struct ctl_context *ctx)
2185 {
2186 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2187 bool bootstrap = shash_find(&ctx->options, "--bootstrap");
2188 struct ovsrec_ssl *ssl = vsctl_ctx->ovs->ssl;
2189
2190 ovsrec_open_vswitch_verify_ssl(vsctl_ctx->ovs);
2191 if (ssl) {
2192 ovsrec_ssl_delete(ssl);
2193 }
2194 ssl = ovsrec_ssl_insert(ctx->txn);
2195
2196 ovsrec_ssl_set_private_key(ssl, ctx->argv[1]);
2197 ovsrec_ssl_set_certificate(ssl, ctx->argv[2]);
2198 ovsrec_ssl_set_ca_cert(ssl, ctx->argv[3]);
2199
2200 ovsrec_ssl_set_bootstrap_ca_cert(ssl, bootstrap);
2201
2202 ovsrec_open_vswitch_set_ssl(vsctl_ctx->ovs, ssl);
2203 }
2204
2205 static void
2206 autoattach_insert_mapping(struct ovsrec_autoattach *aa,
2207 int64_t isid,
2208 int64_t vlan)
2209 {
2210 int64_t *key_mappings, *value_mappings;
2211 size_t i;
2212
2213 key_mappings = xmalloc(sizeof *aa->key_mappings * (aa->n_mappings + 1));
2214 value_mappings = xmalloc(sizeof *aa->value_mappings * (aa->n_mappings + 1));
2215
2216 for (i = 0; i < aa->n_mappings; i++) {
2217 key_mappings[i] = aa->key_mappings[i];
2218 value_mappings[i] = aa->value_mappings[i];
2219 }
2220 key_mappings[aa->n_mappings] = isid;
2221 value_mappings[aa->n_mappings] = vlan;
2222
2223 ovsrec_autoattach_set_mappings(aa, key_mappings, value_mappings,
2224 aa->n_mappings + 1);
2225
2226 free(key_mappings);
2227 free(value_mappings);
2228 }
2229
2230 static void
2231 cmd_add_aa_mapping(struct ctl_context *ctx)
2232 {
2233 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2234 struct vsctl_bridge *br;
2235 int64_t isid, vlan;
2236 char *nptr = NULL;
2237
2238 isid = strtoull(ctx->argv[2], &nptr, 10);
2239 if (nptr == ctx->argv[2] || nptr == NULL) {
2240 ctl_fatal("Invalid argument %s", ctx->argv[2]);
2241 return;
2242 }
2243
2244 vlan = strtoull(ctx->argv[3], &nptr, 10);
2245 if (nptr == ctx->argv[3] || nptr == NULL) {
2246 ctl_fatal("Invalid argument %s", ctx->argv[3]);
2247 return;
2248 }
2249
2250 vsctl_context_populate_cache(ctx);
2251
2252 br = find_bridge(vsctl_ctx, ctx->argv[1], true);
2253 if (br->parent) {
2254 br = br->parent;
2255 }
2256
2257 if (br->br_cfg) {
2258 if (!br->br_cfg->auto_attach) {
2259 struct ovsrec_autoattach *aa = ovsrec_autoattach_insert(ctx->txn);
2260 ovsrec_bridge_set_auto_attach(br->br_cfg, aa);
2261 }
2262 autoattach_insert_mapping(br->br_cfg->auto_attach, isid, vlan);
2263 }
2264 }
2265
2266 static void
2267 del_aa_mapping(struct ovsrec_autoattach *aa,
2268 int64_t isid,
2269 int64_t vlan)
2270 {
2271 int64_t *key_mappings, *value_mappings;
2272 size_t i, n;
2273
2274 key_mappings = xmalloc(sizeof *aa->key_mappings * (aa->n_mappings));
2275 value_mappings = xmalloc(sizeof *value_mappings * (aa->n_mappings));
2276
2277 for (i = n = 0; i < aa->n_mappings; i++) {
2278 if (aa->key_mappings[i] != isid && aa->value_mappings[i] != vlan) {
2279 key_mappings[n] = aa->key_mappings[i];
2280 value_mappings[n++] = aa->value_mappings[i];
2281 }
2282 }
2283
2284 ovsrec_autoattach_set_mappings(aa, key_mappings, value_mappings, n);
2285
2286 free(key_mappings);
2287 free(value_mappings);
2288 }
2289
2290 static void
2291 cmd_del_aa_mapping(struct ctl_context *ctx)
2292 {
2293 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2294 struct vsctl_bridge *br;
2295 int64_t isid, vlan;
2296 char *nptr = NULL;
2297
2298 isid = strtoull(ctx->argv[2], &nptr, 10);
2299 if (nptr == ctx->argv[2] || nptr == NULL) {
2300 ctl_fatal("Invalid argument %s", ctx->argv[2]);
2301 return;
2302 }
2303
2304 vlan = strtoull(ctx->argv[3], &nptr, 10);
2305 if (nptr == ctx->argv[3] || nptr == NULL) {
2306 ctl_fatal("Invalid argument %s", ctx->argv[3]);
2307 return;
2308 }
2309
2310 vsctl_context_populate_cache(ctx);
2311
2312 br = find_bridge(vsctl_ctx, ctx->argv[1], true);
2313 if (br->parent) {
2314 br = br->parent;
2315 }
2316
2317 if (br->br_cfg && br->br_cfg->auto_attach &&
2318 br->br_cfg->auto_attach->key_mappings &&
2319 br->br_cfg->auto_attach->value_mappings) {
2320 size_t i;
2321
2322 for (i = 0; i < br->br_cfg->auto_attach->n_mappings; i++) {
2323 if (br->br_cfg->auto_attach->key_mappings[i] == isid &&
2324 br->br_cfg->auto_attach->value_mappings[i] == vlan) {
2325 del_aa_mapping(br->br_cfg->auto_attach, isid, vlan);
2326 break;
2327 }
2328 }
2329 }
2330 }
2331
2332 static void
2333 pre_aa_mapping(struct ctl_context *ctx)
2334 {
2335 pre_get_info(ctx);
2336
2337 ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_auto_attach);
2338 ovsdb_idl_add_column(ctx->idl, &ovsrec_autoattach_col_mappings);
2339 }
2340
2341 static void
2342 verify_auto_attach(struct ovsrec_bridge *bridge)
2343 {
2344 if (bridge) {
2345 ovsrec_bridge_verify_auto_attach(bridge);
2346
2347 if (bridge->auto_attach) {
2348 ovsrec_autoattach_verify_mappings(bridge->auto_attach);
2349 }
2350 }
2351 }
2352
2353 static void
2354 cmd_get_aa_mapping(struct ctl_context *ctx)
2355 {
2356 struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
2357 struct vsctl_bridge *br;
2358
2359 vsctl_context_populate_cache(ctx);
2360
2361 br = find_bridge(vsctl_ctx, ctx->argv[1], true);
2362 if (br->parent) {
2363 br = br->parent;
2364 }
2365
2366 verify_auto_attach(br->br_cfg);
2367
2368 if (br->br_cfg && br->br_cfg->auto_attach &&
2369 br->br_cfg->auto_attach->key_mappings &&
2370 br->br_cfg->auto_attach->value_mappings) {
2371 size_t i;
2372
2373 for (i = 0; i < br->br_cfg->auto_attach->n_mappings; i++) {
2374 ds_put_format(&ctx->output, "%"PRId64" %"PRId64"\n",
2375 br->br_cfg->auto_attach->key_mappings[i],
2376 br->br_cfg->auto_attach->value_mappings[i]);
2377 }
2378 }
2379 }
2380
2381 \f
2382 static const struct ctl_table_class tables[OVSREC_N_TABLES] = {
2383 [OVSREC_TABLE_BRIDGE].row_ids[0] = {&ovsrec_bridge_col_name, NULL, NULL},
2384
2385 [OVSREC_TABLE_CONTROLLER].row_ids[0]
2386 = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_controller},
2387
2388 [OVSREC_TABLE_INTERFACE].row_ids[0]
2389 = {&ovsrec_interface_col_name, NULL, NULL},
2390
2391 [OVSREC_TABLE_MIRROR].row_ids[0] = {&ovsrec_mirror_col_name, NULL, NULL},
2392
2393 [OVSREC_TABLE_MANAGER].row_ids[0]
2394 = {&ovsrec_manager_col_target, NULL, NULL},
2395
2396 [OVSREC_TABLE_NETFLOW].row_ids[0]
2397 = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_netflow},
2398
2399 [OVSREC_TABLE_PORT].row_ids[0] = {&ovsrec_port_col_name, NULL, NULL},
2400
2401 [OVSREC_TABLE_QOS].row_ids[0]
2402 = {&ovsrec_port_col_name, NULL, &ovsrec_port_col_qos},
2403
2404 [OVSREC_TABLE_SFLOW].row_ids[0]
2405 = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_sflow},
2406
2407 [OVSREC_TABLE_FLOW_TABLE].row_ids[0]
2408 = {&ovsrec_flow_table_col_name, NULL, NULL},
2409
2410 [OVSREC_TABLE_IPFIX].row_ids[0]
2411 = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_ipfix},
2412
2413 [OVSREC_TABLE_AUTOATTACH].row_ids[0]
2414 = {&ovsrec_bridge_col_name, NULL, &ovsrec_bridge_col_auto_attach},
2415
2416 [OVSREC_TABLE_FLOW_SAMPLE_COLLECTOR_SET].row_ids[0]
2417 = {&ovsrec_flow_sample_collector_set_col_id, NULL, NULL},
2418 };
2419
2420 static void
2421 post_db_reload_check_init(void)
2422 {
2423 n_neoteric_ifaces = 0;
2424 }
2425
2426 static void
2427 post_db_reload_expect_iface(const struct ovsrec_interface *iface)
2428 {
2429 if (n_neoteric_ifaces >= allocated_neoteric_ifaces) {
2430 neoteric_ifaces = x2nrealloc(neoteric_ifaces,
2431 &allocated_neoteric_ifaces,
2432 sizeof *neoteric_ifaces);
2433 }
2434 neoteric_ifaces[n_neoteric_ifaces++] = iface->header_.uuid;
2435 }
2436
2437 static void
2438 post_db_reload_do_checks(const struct vsctl_context *vsctl_ctx)
2439 {
2440 bool print_error = false;
2441 size_t i;
2442
2443 for (i = 0; i < n_neoteric_ifaces; i++) {
2444 const struct uuid *uuid;
2445
2446 uuid = ovsdb_idl_txn_get_insert_uuid(vsctl_ctx->base.txn,
2447 &neoteric_ifaces[i]);
2448 if (uuid) {
2449 const struct ovsrec_interface *iface;
2450
2451 iface = ovsrec_interface_get_for_uuid(vsctl_ctx->base.idl, uuid);
2452 if (iface && (!iface->ofport || *iface->ofport == -1)) {
2453 if (iface->error && *iface->error) {
2454 ovs_error(0, "Error detected while setting up '%s': %s. "
2455 "See ovs-vswitchd log for details.",
2456 iface->name, iface->error);
2457 } else {
2458 ovs_error(0, "Error detected while setting up '%s'. "
2459 "See ovs-vswitchd log for details.",
2460 iface->name);
2461 }
2462 print_error = true;
2463 }
2464 }
2465 }
2466
2467 if (print_error) {
2468 ovs_error(0, "The default log directory is \"%s\".", ovs_logdir());
2469 }
2470 }
2471
2472 \f
2473 static void
2474 vsctl_context_init_command(struct vsctl_context *vsctl_ctx,
2475 struct ctl_command *command)
2476 {
2477 ctl_context_init_command(&vsctl_ctx->base, command);
2478 vsctl_ctx->verified_ports = false;
2479 }
2480
2481 static void
2482 vsctl_context_init(struct vsctl_context *vsctl_ctx,
2483 struct ctl_command *command, struct ovsdb_idl *idl,
2484 struct ovsdb_idl_txn *txn,
2485 const struct ovsrec_open_vswitch *ovs,
2486 struct ovsdb_symbol_table *symtab)
2487 {
2488 ctl_context_init(&vsctl_ctx->base, command, idl, txn, symtab,
2489 vsctl_context_invalidate_cache);
2490 if (command) {
2491 vsctl_ctx->verified_ports = false;
2492 }
2493 vsctl_ctx->ovs = ovs;
2494 vsctl_ctx->cache_valid = false;
2495 }
2496
2497 static void
2498 vsctl_context_done_command(struct vsctl_context *vsctl_ctx,
2499 struct ctl_command *command)
2500 {
2501 ctl_context_done_command(&vsctl_ctx->base, command);
2502 }
2503
2504 static void
2505 vsctl_context_done(struct vsctl_context *vsctl_ctx,
2506 struct ctl_command *command)
2507 {
2508 ctl_context_done(&vsctl_ctx->base, command);
2509 }
2510
2511 static void
2512 run_prerequisites(struct ctl_command *commands, size_t n_commands,
2513 struct ovsdb_idl *idl)
2514 {
2515 struct ctl_command *c;
2516
2517 ovsdb_idl_add_table(idl, &ovsrec_table_open_vswitch);
2518 if (wait_for_reload) {
2519 ovsdb_idl_add_column(idl, &ovsrec_open_vswitch_col_cur_cfg);
2520 }
2521 for (c = commands; c < &commands[n_commands]; c++) {
2522 if (c->syntax->prerequisites) {
2523 struct vsctl_context vsctl_ctx;
2524
2525 ds_init(&c->output);
2526 c->table = NULL;
2527
2528 vsctl_context_init(&vsctl_ctx, c, idl, NULL, NULL, NULL);
2529 (c->syntax->prerequisites)(&vsctl_ctx.base);
2530 if (vsctl_ctx.base.error) {
2531 ctl_fatal("%s", vsctl_ctx.base.error);
2532 }
2533 vsctl_context_done(&vsctl_ctx, c);
2534
2535 ovs_assert(!c->output.string);
2536 ovs_assert(!c->table);
2537 }
2538 }
2539 }
2540
2541 static char *
2542 vsctl_parent_process_info(void)
2543 {
2544 #ifdef __linux__
2545 pid_t parent_pid;
2546 struct ds s;
2547
2548 parent_pid = getppid();
2549 ds_init(&s);
2550
2551 /* Retrive the command line of the parent process, except the init
2552 * process since /proc/0 does not exist. */
2553 if (parent_pid) {
2554 char *procfile;
2555 FILE *f;
2556
2557 procfile = xasprintf("/proc/%d/cmdline", parent_pid);
2558
2559 f = fopen(procfile, "r");
2560 free(procfile);
2561 if (f) {
2562 ds_get_line(&s, f);
2563 fclose(f);
2564 }
2565 } else {
2566 ds_put_cstr(&s, "init");
2567 }
2568
2569 ds_put_format(&s, " (pid %d)", parent_pid);
2570 return ds_steal_cstr(&s);
2571 #else
2572 return NULL;
2573 #endif
2574 }
2575
2576 static bool
2577 do_vsctl(const char *args, struct ctl_command *commands, size_t n_commands,
2578 struct ovsdb_idl *idl)
2579 {
2580 struct ovsdb_idl_txn *txn;
2581 const struct ovsrec_open_vswitch *ovs;
2582 enum ovsdb_idl_txn_status status;
2583 struct ovsdb_symbol_table *symtab;
2584 struct vsctl_context vsctl_ctx;
2585 struct ctl_command *c;
2586 struct shash_node *node;
2587 int64_t next_cfg = 0;
2588 char *ppid_info = NULL;
2589
2590 txn = the_idl_txn = ovsdb_idl_txn_create(idl);
2591 if (dry_run) {
2592 ovsdb_idl_txn_set_dry_run(txn);
2593 }
2594
2595 ppid_info = vsctl_parent_process_info();
2596 if (ppid_info) {
2597 ovsdb_idl_txn_add_comment(txn, "ovs-vsctl (invoked by %s): %s",
2598 ppid_info, args);
2599 free(ppid_info);
2600 } else {
2601 ovsdb_idl_txn_add_comment(txn, "ovs-vsctl: %s", args);
2602 }
2603
2604 ovs = ovsrec_open_vswitch_first(idl);
2605 if (!ovs) {
2606 /* XXX add verification that table is empty */
2607 ovs = ovsrec_open_vswitch_insert(txn);
2608 }
2609
2610 if (wait_for_reload) {
2611 ovsdb_idl_txn_increment(txn, &ovs->header_,
2612 &ovsrec_open_vswitch_col_next_cfg, false);
2613 }
2614
2615 post_db_reload_check_init();
2616 symtab = ovsdb_symbol_table_create();
2617 for (c = commands; c < &commands[n_commands]; c++) {
2618 ds_init(&c->output);
2619 c->table = NULL;
2620 }
2621 vsctl_context_init(&vsctl_ctx, NULL, idl, txn, ovs, symtab);
2622 for (c = commands; c < &commands[n_commands]; c++) {
2623 vsctl_context_init_command(&vsctl_ctx, c);
2624 if (c->syntax->run) {
2625 (c->syntax->run)(&vsctl_ctx.base);
2626 }
2627 if (vsctl_ctx.base.error) {
2628 ctl_fatal("%s", vsctl_ctx.base.error);
2629 }
2630 vsctl_context_done_command(&vsctl_ctx, c);
2631
2632 if (vsctl_ctx.base.try_again) {
2633 vsctl_context_done(&vsctl_ctx, NULL);
2634 goto try_again;
2635 }
2636 }
2637 vsctl_context_done(&vsctl_ctx, NULL);
2638
2639 SHASH_FOR_EACH (node, &symtab->sh) {
2640 struct ovsdb_symbol *symbol = node->data;
2641 if (!symbol->created) {
2642 ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
2643 "with \"-- --id=%s create ...\")",
2644 node->name, node->name);
2645 }
2646 if (!symbol->strong_ref) {
2647 if (!symbol->weak_ref) {
2648 VLOG_WARN("row id \"%s\" was created but no reference to it "
2649 "was inserted, so it will not actually appear in "
2650 "the database", node->name);
2651 } else {
2652 VLOG_WARN("row id \"%s\" was created but only a weak "
2653 "reference to it was inserted, so it will not "
2654 "actually appear in the database", node->name);
2655 }
2656 }
2657 }
2658
2659 status = ovsdb_idl_txn_commit_block(txn);
2660 if (wait_for_reload && status == TXN_SUCCESS) {
2661 next_cfg = ovsdb_idl_txn_get_increment_new_value(txn);
2662 }
2663 if (status == TXN_UNCHANGED || status == TXN_SUCCESS) {
2664 for (c = commands; c < &commands[n_commands]; c++) {
2665 if (c->syntax->postprocess) {
2666 vsctl_context_init(&vsctl_ctx, c, idl, txn, ovs, symtab);
2667 (c->syntax->postprocess)(&vsctl_ctx.base);
2668 if (vsctl_ctx.base.error) {
2669 ctl_fatal("%s", vsctl_ctx.base.error);
2670 }
2671 vsctl_context_done(&vsctl_ctx, c);
2672 }
2673 }
2674 }
2675
2676 switch (status) {
2677 case TXN_UNCOMMITTED:
2678 case TXN_INCOMPLETE:
2679 OVS_NOT_REACHED();
2680
2681 case TXN_ABORTED:
2682 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
2683 ctl_fatal("transaction aborted");
2684
2685 case TXN_UNCHANGED:
2686 case TXN_SUCCESS:
2687 break;
2688
2689 case TXN_TRY_AGAIN:
2690 goto try_again;
2691
2692 case TXN_ERROR:
2693 ctl_fatal("transaction error: %s", ovsdb_idl_txn_get_error(txn));
2694
2695 case TXN_NOT_LOCKED:
2696 /* Should not happen--we never call ovsdb_idl_set_lock(). */
2697 ctl_fatal("database not locked");
2698
2699 default:
2700 OVS_NOT_REACHED();
2701 }
2702
2703 ovsdb_symbol_table_destroy(symtab);
2704
2705 for (c = commands; c < &commands[n_commands]; c++) {
2706 struct ds *ds = &c->output;
2707
2708 if (c->table) {
2709 table_print(c->table, &table_style);
2710 } else if (oneline) {
2711 size_t j;
2712
2713 ds_chomp(ds, '\n');
2714 for (j = 0; j < ds->length; j++) {
2715 int ch = ds->string[j];
2716 switch (ch) {
2717 case '\n':
2718 fputs("\\n", stdout);
2719 break;
2720
2721 case '\\':
2722 fputs("\\\\", stdout);
2723 break;
2724
2725 default:
2726 putchar(ch);
2727 }
2728 }
2729 putchar('\n');
2730 } else {
2731 fputs(ds_cstr(ds), stdout);
2732 }
2733 ds_destroy(&c->output);
2734 table_destroy(c->table);
2735 free(c->table);
2736
2737 shash_destroy_free_data(&c->options);
2738 }
2739 free(commands);
2740
2741 if (wait_for_reload && status != TXN_UNCHANGED) {
2742 /* Even, if --retry flag was not specified, ovs-vsctl still
2743 * has to retry to establish OVSDB connection, if wait_for_reload
2744 * was set. Otherwise, ovs-vsctl would end up waiting forever
2745 * until cur_cfg would be updated. */
2746 ovsdb_idl_enable_reconnect(idl);
2747 for (;;) {
2748 ovsdb_idl_run(idl);
2749 OVSREC_OPEN_VSWITCH_FOR_EACH (ovs, idl) {
2750 if (ovs->cur_cfg >= next_cfg) {
2751 post_db_reload_do_checks(&vsctl_ctx);
2752 goto done;
2753 }
2754 }
2755 ovsdb_idl_wait(idl);
2756 poll_block();
2757 }
2758 done: ;
2759 }
2760 ovsdb_idl_txn_destroy(txn);
2761 ovsdb_idl_destroy(idl);
2762
2763 return true;
2764
2765 try_again:
2766 /* Our transaction needs to be rerun, or a prerequisite was not met. Free
2767 * resources and return so that the caller can try again. */
2768 ovsdb_idl_txn_abort(txn);
2769 ovsdb_idl_txn_destroy(txn);
2770 the_idl_txn = NULL;
2771
2772 ovsdb_symbol_table_destroy(symtab);
2773 for (c = commands; c < &commands[n_commands]; c++) {
2774 ds_destroy(&c->output);
2775 table_destroy(c->table);
2776 free(c->table);
2777 }
2778 return false;
2779 }
2780
2781 /* Frees the current transaction and the underlying IDL and then calls
2782 * exit(status).
2783 *
2784 * Freeing the transaction and the IDL is not strictly necessary, but it makes
2785 * for a clean memory leak report from valgrind in the normal case. That makes
2786 * it easier to notice real memory leaks. */
2787 static void
2788 vsctl_exit(int status)
2789 {
2790 if (the_idl_txn) {
2791 ovsdb_idl_txn_abort(the_idl_txn);
2792 ovsdb_idl_txn_destroy(the_idl_txn);
2793 }
2794 ovsdb_idl_destroy(the_idl);
2795 exit(status);
2796 }
2797
2798 /*
2799 * Developers who add new commands to the 'struct ctl_command_syntax' must
2800 * define the 'arguments' member of the struct. The following keywords are
2801 * available for composing the argument format:
2802 *
2803 * TABLE RECORD BRIDGE PARENT PORT
2804 * KEY VALUE ARG KEY=VALUE ?KEY=VALUE
2805 * IFACE SYSIFACE COLUMN COLUMN?:KEY COLUMN?:KEY=VALUE
2806 * MODE CA-CERT CERTIFICATE PRIVATE-KEY
2807 * TARGET NEW-* (e.g. NEW-PORT)
2808 *
2809 * For argument types not listed above, just uses 'ARG' as place holder.
2810 *
2811 * Encloses the keyword with '[]' if it is optional. Appends '...' to
2812 * keyword or enclosed keyword to indicate that the argument can be specified
2813 * multiple times.
2814 *
2815 * */
2816 static const struct ctl_command_syntax vsctl_commands[] = {
2817 /* Open vSwitch commands. */
2818 {"init", 0, 0, "", NULL, cmd_init, NULL, "", RW},
2819
2820 /* Bridge commands. */
2821 {"add-br", 1, 3, "NEW-BRIDGE [PARENT] [NEW-VLAN]", pre_get_info,
2822 cmd_add_br, NULL, "--may-exist", RW},
2823 {"del-br", 1, 1, "BRIDGE", pre_get_info, cmd_del_br,
2824 NULL, "--if-exists", RW},
2825 {"list-br", 0, 0, "", pre_get_info, cmd_list_br, NULL, "--real,--fake",
2826 RO},
2827 {"br-exists", 1, 1, "BRIDGE", pre_get_info, cmd_br_exists, NULL, "", RO},
2828 {"br-to-vlan", 1, 1, "BRIDGE", pre_get_info, cmd_br_to_vlan, NULL, "",
2829 RO},
2830 {"br-to-parent", 1, 1, "BRIDGE", pre_get_info, cmd_br_to_parent, NULL,
2831 "", RO},
2832 {"br-set-external-id", 2, 3, "BRIDGE KEY [VALUE]",
2833 pre_cmd_br_set_external_id, cmd_br_set_external_id, NULL, "", RW},
2834 {"br-get-external-id", 1, 2, "BRIDGE [KEY]", pre_cmd_br_get_external_id,
2835 cmd_br_get_external_id, NULL, "", RO},
2836
2837 /* Port commands. */
2838 {"list-ports", 1, 1, "BRIDGE", pre_get_info, cmd_list_ports, NULL, "",
2839 RO},
2840 {"add-port", 2, INT_MAX, "BRIDGE NEW-PORT [COLUMN[:KEY]=VALUE]...",
2841 pre_get_info, cmd_add_port, NULL, "--may-exist", RW},
2842 {"del-port", 1, 2, "[BRIDGE] PORT|IFACE", pre_get_info, cmd_del_port, NULL,
2843 "--if-exists,--with-iface", RW},
2844 {"port-to-br", 1, 1, "PORT", pre_get_info, cmd_port_to_br, NULL, "", RO},
2845
2846 /* Bond commands. */
2847 {"add-bond", 4, INT_MAX,
2848 "BRIDGE BOND IFACE... [COLUMN[:KEY]=VALUE]...", pre_get_info,
2849 cmd_add_bond, NULL, "--may-exist,--fake-iface", RW},
2850 {"add-bond-iface", 2, 2, "BOND IFACE", pre_get_info, cmd_add_bond_iface,
2851 NULL, "--may-exist", RW},
2852 {"del-bond-iface", 1, 2, "[BOND] IFACE", pre_get_info, cmd_del_bond_iface,
2853 NULL, "--if-exists", RW},
2854
2855 /* Interface commands. */
2856 {"list-ifaces", 1, 1, "BRIDGE", pre_get_info, cmd_list_ifaces, NULL, "",
2857 RO},
2858 {"iface-to-br", 1, 1, "IFACE", pre_get_info, cmd_iface_to_br, NULL, "",
2859 RO},
2860
2861 /* Controller commands. */
2862 {"get-controller", 1, 1, "BRIDGE", pre_controller, cmd_get_controller,
2863 NULL, "", RO},
2864 {"del-controller", 1, 1, "BRIDGE", pre_controller, cmd_del_controller,
2865 NULL, "", RW},
2866 {"set-controller", 1, INT_MAX, "BRIDGE TARGET...", pre_controller,
2867 cmd_set_controller, NULL, "--inactivity-probe=", RW},
2868 {"get-fail-mode", 1, 1, "BRIDGE", pre_get_info, cmd_get_fail_mode, NULL,
2869 "", RO},
2870 {"del-fail-mode", 1, 1, "BRIDGE", pre_get_info, cmd_del_fail_mode, NULL,
2871 "", RW},
2872 {"set-fail-mode", 2, 2, "BRIDGE MODE", pre_get_info, cmd_set_fail_mode,
2873 NULL, "", RW},
2874
2875 /* Manager commands. */
2876 {"get-manager", 0, 0, "", pre_manager, cmd_get_manager, NULL, "", RO},
2877 {"del-manager", 0, 0, "", pre_manager, cmd_del_manager, NULL, "", RW},
2878 {"set-manager", 1, INT_MAX, "TARGET...", pre_manager, cmd_set_manager,
2879 NULL, "--inactivity-probe=", RW},
2880
2881 /* SSL commands. */
2882 {"get-ssl", 0, 0, "", pre_cmd_get_ssl, cmd_get_ssl, NULL, "", RO},
2883 {"del-ssl", 0, 0, "", pre_cmd_del_ssl, cmd_del_ssl, NULL, "", RW},
2884 {"set-ssl", 3, 3, "PRIVATE-KEY CERTIFICATE CA-CERT", pre_cmd_set_ssl,
2885 cmd_set_ssl, NULL, "--bootstrap", RW},
2886
2887 /* Auto Attach commands. */
2888 {"add-aa-mapping", 3, 3, "BRIDGE ARG ARG", pre_aa_mapping, cmd_add_aa_mapping,
2889 NULL, "", RW},
2890 {"del-aa-mapping", 3, 3, "BRIDGE ARG ARG", pre_aa_mapping, cmd_del_aa_mapping,
2891 NULL, "", RW},
2892 {"get-aa-mapping", 1, 1, "BRIDGE", pre_aa_mapping, cmd_get_aa_mapping,
2893 NULL, "", RO},
2894
2895 /* Switch commands. */
2896 {"emer-reset", 0, 0, "", pre_cmd_emer_reset, cmd_emer_reset, NULL, "", RW},
2897
2898 {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
2899 };
2900
2901 /* Registers vsctl and common db commands. */
2902 static void
2903 vsctl_cmd_init(void)
2904 {
2905 ctl_init(&ovsrec_idl_class, ovsrec_table_classes, tables, cmd_show_tables,
2906 vsctl_exit);
2907 ctl_register_commands(vsctl_commands);
2908 }