ovs-vsctl: Print correct fail-mode
[sliver-openvswitch.git] / utilities / ovs-vsctl.c
1 /*
2  * Copyright (c) 2009 Nicira Networks.
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 <assert.h>
20 #include <errno.h>
21 #include <getopt.h>
22 #include <inttypes.h>
23 #include <signal.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "command-line.h"
29 #include "compiler.h"
30 #include "dirs.h"
31 #include "dynamic-string.h"
32 #include "json.h"
33 #include "ovsdb-idl.h"
34 #include "poll-loop.h"
35 #include "svec.h"
36 #include "vswitchd/vswitch-idl.h"
37 #include "timeval.h"
38 #include "util.h"
39
40 #include "vlog.h"
41 #define THIS_MODULE VLM_vsctl
42
43 /* --db: The database server to contact. */
44 static const char *db;
45
46 /* --oneline: Write each command's output as a single line? */
47 static bool oneline;
48
49 /* --dry-run: Do not commit any changes. */
50 static bool dry_run;
51
52 /* --no-wait: Wait for ovs-vswitchd to reload its configuration? */
53 static bool wait_for_reload = true;
54
55 /* --timeout: Time to wait for a connection to 'db'. */
56 static int timeout = 5;
57
58 static void vsctl_fatal(const char *, ...) PRINTF_FORMAT(1, 2) NO_RETURN;
59 static char *default_db(void);
60 static void usage(void) NO_RETURN;
61 static void parse_options(int argc, char *argv[]);
62
63 static void check_vsctl_command(int argc, char *argv[]);
64 static void do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl);
65
66 int
67 main(int argc, char *argv[])
68 {
69     struct ovsdb_idl *idl;
70     unsigned int seqno;
71     struct ds args;
72     int start, n_commands;
73     int trials;
74     int i;
75
76     set_program_name(argv[0]);
77     signal(SIGPIPE, SIG_IGN);
78     time_init();
79     vlog_init();
80     vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_WARN);
81     vlog_set_levels(VLM_reconnect, VLF_ANY_FACILITY, VLL_WARN);
82     parse_options(argc, argv);
83
84     if (timeout) {
85         time_alarm(timeout);
86     }
87
88     /* Log our arguments.  This is often valuable for debugging systems. */
89     ds_init(&args);
90     for (i = 1; i < argc; i++) {
91         ds_put_format(&args, " %s", argv[i]);
92     }
93     VLOG_INFO("Called as%s", ds_cstr(&args));
94     ds_destroy(&args);
95
96     /* Do basic command syntax checking. */
97     n_commands = 0;
98     for (start = i = optind; i <= argc; i++) {
99         if (i == argc || !strcmp(argv[i], "--")) {
100             if (i > start) {
101                 check_vsctl_command(i - start, &argv[start]);
102                 n_commands++;
103             }
104             start = i + 1;
105         }
106     }
107     if (!n_commands) {
108         vsctl_fatal("missing command name (use --help for help)");
109     }
110
111     /* Now execute the commands. */
112     idl = ovsdb_idl_create(db, &ovsrec_idl_class);
113     seqno = ovsdb_idl_get_seqno(idl);
114     trials = 0;
115     for (;;) {
116         unsigned int new_seqno;
117
118         ovsdb_idl_run(idl);
119         new_seqno = ovsdb_idl_get_seqno(idl);
120         if (new_seqno != seqno) {
121             if (++trials > 5) {
122                 vsctl_fatal("too many database inconsistency failures");
123             }
124             do_vsctl(argc - optind, argv + optind, idl);
125             seqno = new_seqno;
126         }
127
128         ovsdb_idl_wait(idl);
129         poll_block();
130     }
131 }
132
133 static void
134 vsctl_fatal(const char *format, ...)
135 {
136     char *message;
137     va_list args;
138
139     va_start(args, format);
140     message = xvasprintf(format, args);
141     va_end(args);
142
143     vlog_set_levels(VLM_vsctl, VLF_CONSOLE, VLL_EMER);
144     VLOG_ERR("%s", message);
145     ovs_fatal(0, "%s", message);
146 }
147
148 static void
149 parse_options(int argc, char *argv[])
150 {
151     enum {
152         OPT_DB = UCHAR_MAX + 1,
153         OPT_ONELINE,
154         OPT_NO_SYSLOG,
155         OPT_NO_WAIT,
156         OPT_DRY_RUN,
157         VLOG_OPTION_ENUMS
158     };
159     static struct option long_options[] = {
160         {"db", required_argument, 0, OPT_DB},
161         {"no-syslog", no_argument, 0, OPT_NO_SYSLOG},
162         {"no-wait", no_argument, 0, OPT_NO_WAIT},
163         {"dry-run", no_argument, 0, OPT_DRY_RUN},
164         {"oneline", no_argument, 0, OPT_ONELINE},
165         {"timeout", required_argument, 0, 't'},
166         {"help", no_argument, 0, 'h'},
167         {"version", no_argument, 0, 'V'},
168         VLOG_LONG_OPTIONS,
169         {0, 0, 0, 0},
170     };
171
172
173     for (;;) {
174         unsigned long int timeout;
175         int c;
176
177         c = getopt_long(argc, argv, "+v::hVt:", long_options, NULL);
178         if (c == -1) {
179             break;
180         }
181
182         switch (c) {
183         case OPT_DB:
184             db = optarg;
185             break;
186
187         case OPT_ONELINE:
188             oneline = true;
189             break;
190
191         case OPT_NO_SYSLOG:
192             vlog_set_levels(VLM_vsctl, VLF_SYSLOG, VLL_WARN);
193             break;
194
195         case OPT_NO_WAIT:
196             wait_for_reload = false;
197             break;
198
199         case OPT_DRY_RUN:
200             dry_run = true;
201             break;
202
203         case 'h':
204             usage();
205
206         case 'V':
207             OVS_PRINT_VERSION(0, 0);
208             exit(EXIT_SUCCESS);
209
210         case 't':
211             timeout = strtoul(optarg, NULL, 10);
212             if (timeout < 0) {
213                 ovs_fatal(0, "value %s on -t or --timeout is invalid",
214                           optarg);
215             }
216             break;
217
218         VLOG_OPTION_HANDLERS
219
220         case '?':
221             exit(EXIT_FAILURE);
222
223         default:
224             abort();
225         }
226     }
227
228     if (!db) {
229         db = default_db();
230     }
231 }
232
233 static void
234 usage(void)
235 {
236     printf("%s: ovs-vswitchd management utility\n"
237            "usage: %s [OPTIONS] COMMAND [ARG...]\n",
238            program_name, program_name);
239     printf("\nBridge commands:\n"
240            "  add-br BRIDGE               "
241            "create a new bridge named BRIDGE\n"
242            "  add-br BRIDGE PARENT VLAN   "
243            "create new fake bridge BRIDGE in PARENT on VLAN\n"
244            "  del-br BRIDGE               "
245            "delete BRIDGE and all of its ports\n"
246            "  list-br                     "
247            "print the names of all the bridges\n"
248            "  br-exists BRIDGE            "
249            "test whether BRIDGE exists\n"
250            "  br-to-vlan BRIDGE           "
251            "print the VLAN which BRIDGE is on\n"
252            "  br-to-parent BRIDGE         "
253            "print the parent of BRIDGE\n"
254            "  br-set-external-id BRIDGE KEY VALUE"
255            "  set KEY on BRIDGE to VALUE\n"
256            "  br-set-external-id BRIDGE KEY"
257            "  unset KEY on BRIDGE\n"
258            "  br-get-external-id BRIDGE KEY"
259            "  print value of KEY on BRIDGE\n"
260            "  br-get-external-id BRIDGE"
261            "  list key-value pairs on BRIDGE\n"
262         );
263     printf("\nPort commands:\n"
264            "  list-ports BRIDGE           "
265            "print the names of all the ports on BRIDGE\n"
266            "  add-port BRIDGE PORT        "
267            "add network device PORT to BRIDGE\n"
268            "  add-bond BRIDGE PORT IFACE...  "
269            "add new bonded port PORT in BRIDGE from IFACES\n"
270            "  del-port [BRIDGE] PORT      "
271            "delete PORT (which may be bonded) from BRIDGE\n"
272            "  port-to-br PORT             "
273            "print name of bridge that contains PORT\n"
274            "  port-set-external-id PORT KEY VALUE"
275            "  set KEY on PORT to VALUE\n"
276            "  port-set-external-id PORT KEY"
277            "  unset KEY on PORT\n"
278            "  port-get-external-id PORT KEY"
279            "  print value of KEY on PORT\n"
280            "  port-get-external-id PORT"
281            "  list key-value pairs on PORT\n"
282            "A bond is considered to be a single port.\n"
283         );
284     printf("\nInterface commands (a bond consists of multiple interfaces):\n"
285            "  list-ifaces BRIDGE          "
286            "print the names of all the interfaces on BRIDGE\n"
287            "  iface-to-br IFACE           "
288            "print name of bridge that contains IFACE\n"
289            "  iface-set-external-id IFACE KEY VALUE"
290            "  set KEY on IFACE to VALUE\n"
291            "  iface-set-external-id IFACE KEY"
292            "  unset KEY on IFACE\n"
293            "  iface-get-external-id IFACE KEY"
294            "  print value of KEY on IFACE\n"
295            "  iface-get-external-id IFACE"
296            "  list key-value pairs on IFACE\n"
297         );
298     printf("\nController commands:\n"
299            "  get-controller [BRIDGE]     "
300            "print the controller for BRIDGE\n"
301            "  del-controller [BRIDGE]     "
302            "delete the controller for BRIDGE\n"
303            "  set-controller [BRIDGE] TARGET  "
304            "set the controller for BRIDGE to TARGET\n"
305            "  get-fail-mode [BRIDGE]     "
306            "print the fail-mode for BRIDGE\n"
307            "  del-fail-mode [BRIDGE]     "
308            "delete the fail-mode for BRIDGE\n"
309            "  set-fail-mode [BRIDGE] MODE  "
310            "set the fail-mode for BRIDGE to MODE\n"
311         );
312     printf("\nSSL commands:\n"
313            "  get-ssl              "
314            "print the SSL configuration\n"
315            "  del-ssl              "
316            "delete the SSL configuration\n"
317            "  set-ssl PRIV-KEY CERT CA-CERT  "
318            "set the SSL configuration\n"
319         );
320     printf("\nOptions:\n"
321            "  --db=DATABASE               "
322            "connect to DATABASE\n"
323            "                              "
324            "(default: %s)\n"
325            "  --oneline                   "
326            "print exactly one line of output per command\n",
327            default_db());
328     vlog_usage();
329     printf("\nOther options:\n"
330            "  -h, --help                  "
331            "display this help message\n"
332            "  -V, --version               "
333            "display version information\n");
334     exit(EXIT_SUCCESS);
335 }
336
337 static char *
338 default_db(void)
339 {
340     static char *def;
341     if (!def) {
342         def = xasprintf("unix:%s/ovsdb-server", ovs_rundir);
343     }
344     return def;
345 }
346 \f
347 struct vsctl_context {
348     int argc;
349     char **argv;
350     const struct ovsrec_open_vswitch *ovs;
351     struct ds output;
352     struct shash options;
353 };
354
355 struct vsctl_bridge {
356     struct ovsrec_bridge *br_cfg;
357     char *name;
358     struct ovsrec_controller *ctrl;
359     struct vsctl_bridge *parent;
360     int vlan;
361 };
362
363 struct vsctl_port {
364     struct ovsrec_port *port_cfg;
365     struct vsctl_bridge *bridge;
366 };
367
368 struct vsctl_iface {
369     struct ovsrec_interface *iface_cfg;
370     struct vsctl_port *port;
371 };
372
373 struct vsctl_info {
374     struct shash bridges;
375     struct shash ports;
376     struct shash ifaces;
377     struct ovsrec_controller *ctrl;
378 };
379
380 static struct ovsdb_idl_txn *
381 txn_from_openvswitch(const struct ovsrec_open_vswitch *ovs)
382 {
383     return ovsdb_idl_txn_get(&ovs->header_);
384 }
385
386 static struct vsctl_bridge *
387 add_bridge(struct vsctl_info *b,
388            struct ovsrec_bridge *br_cfg, const char *name,
389            struct vsctl_bridge *parent, int vlan)
390 {
391     struct vsctl_bridge *br = xmalloc(sizeof *br);
392     br->br_cfg = br_cfg;
393     br->name = xstrdup(name);
394     br->parent = parent;
395     br->vlan = vlan;
396     br->ctrl = parent ? parent->br_cfg->controller : br_cfg->controller;
397     shash_add(&b->bridges, br->name, br);
398     return br;
399 }
400
401 static bool
402 port_is_fake_bridge(const struct ovsrec_port *port_cfg)
403 {
404     return (port_cfg->fake_bridge
405             && port_cfg->tag
406             && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095);
407 }
408
409 static struct vsctl_bridge *
410 find_vlan_bridge(struct vsctl_info *info,
411                  struct vsctl_bridge *parent, int vlan)
412 {
413     struct shash_node *node;
414
415     SHASH_FOR_EACH (node, &info->bridges) {
416         struct vsctl_bridge *br = node->data;
417         if (br->parent == parent && br->vlan == vlan) {
418             return br;
419         }
420     }
421
422     return NULL;
423 }
424
425 static void
426 free_info(struct vsctl_info *info)
427 {
428     struct shash_node *node;
429
430     SHASH_FOR_EACH (node, &info->bridges) {
431         struct vsctl_bridge *bridge = node->data;
432         free(bridge->name);
433         free(bridge);
434     }
435     shash_destroy(&info->bridges);
436
437     SHASH_FOR_EACH (node, &info->ports) {
438         struct vsctl_port *port = node->data;
439         free(port);
440     }
441     shash_destroy(&info->ports);
442
443     SHASH_FOR_EACH (node, &info->ifaces) {
444         struct vsctl_iface *iface = node->data;
445         free(iface);
446     }
447     shash_destroy(&info->ifaces);
448 }
449
450 static void
451 get_info(const struct ovsrec_open_vswitch *ovs, struct vsctl_info *info)
452 {
453     struct shash bridges, ports;
454     size_t i;
455
456     shash_init(&info->bridges);
457     shash_init(&info->ports);
458     shash_init(&info->ifaces);
459
460     info->ctrl = ovs->controller;
461
462     shash_init(&bridges);
463     shash_init(&ports);
464     for (i = 0; i < ovs->n_bridges; i++) {
465         struct ovsrec_bridge *br_cfg = ovs->bridges[i];
466         struct vsctl_bridge *br;
467         size_t j;
468
469         if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
470             VLOG_WARN("%s: database contains duplicate bridge name",
471                       br_cfg->name);
472             continue;
473         }
474         br = add_bridge(info, br_cfg, br_cfg->name, NULL, 0);
475         if (!br) {
476             continue;
477         }
478
479         for (j = 0; j < br_cfg->n_ports; j++) {
480             struct ovsrec_port *port_cfg = br_cfg->ports[j];
481
482             if (!shash_add_once(&ports, port_cfg->name, NULL)) {
483                 VLOG_WARN("%s: database contains duplicate port name",
484                           port_cfg->name);
485                 continue;
486             }
487
488             if (port_is_fake_bridge(port_cfg)
489                 && shash_add_once(&bridges, port_cfg->name, NULL)) {
490                 add_bridge(info, NULL, port_cfg->name, br, *port_cfg->tag);
491             }
492         }
493     }
494     shash_destroy(&bridges);
495     shash_destroy(&ports);
496
497     shash_init(&bridges);
498     shash_init(&ports);
499     for (i = 0; i < ovs->n_bridges; i++) {
500         struct ovsrec_bridge *br_cfg = ovs->bridges[i];
501         struct vsctl_bridge *br;
502         size_t j;
503
504         if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
505             continue;
506         }
507         br = shash_find_data(&info->bridges, br_cfg->name);
508         for (j = 0; j < br_cfg->n_ports; j++) {
509             struct ovsrec_port *port_cfg = br_cfg->ports[j];
510             struct vsctl_port *port;
511             size_t k;
512
513             if (!shash_add_once(&ports, port_cfg->name, NULL)) {
514                 continue;
515             }
516
517             if (port_is_fake_bridge(port_cfg)
518                 && !shash_add_once(&bridges, port_cfg->name, NULL)) {
519                 continue;
520             }
521
522             port = xmalloc(sizeof *port);
523             port->port_cfg = port_cfg;
524             if (port_cfg->tag
525                 && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095) {
526                 port->bridge = find_vlan_bridge(info, br, *port_cfg->tag);
527                 if (!port->bridge) {
528                     port->bridge = br;
529                 }
530             } else {
531                 port->bridge = br;
532             }
533             shash_add(&info->ports, port_cfg->name, port);
534
535             for (k = 0; k < port_cfg->n_interfaces; k++) {
536                 struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
537                 struct vsctl_iface *iface;
538
539                 if (shash_find(&info->ifaces, iface_cfg->name)) {
540                     VLOG_WARN("%s: database contains duplicate interface name",
541                               iface_cfg->name);
542                     continue;
543                 }
544
545                 iface = xmalloc(sizeof *iface);
546                 iface->iface_cfg = iface_cfg;
547                 iface->port = port;
548                 shash_add(&info->ifaces, iface_cfg->name, iface);
549             }
550         }
551     }
552     shash_destroy(&bridges);
553     shash_destroy(&ports);
554 }
555
556 static void
557 check_conflicts(struct vsctl_info *info, const char *name,
558                 char *msg)
559 {
560     struct vsctl_iface *iface;
561     struct vsctl_port *port;
562
563     if (shash_find(&info->bridges, name)) {
564         vsctl_fatal("%s because a bridge named %s already exists",
565                     msg, name);
566     }
567
568     port = shash_find_data(&info->ports, name);
569     if (port) {
570         vsctl_fatal("%s because a port named %s already exists on "
571                     "bridge %s", msg, name, port->bridge->name);
572     }
573
574     iface = shash_find_data(&info->ifaces, name);
575     if (iface) {
576         vsctl_fatal("%s because an interface named %s already exists "
577                     "on bridge %s", msg, name, iface->port->bridge->name);
578     }
579
580     free(msg);
581 }
582
583 static struct vsctl_bridge *
584 find_bridge(struct vsctl_info *info, const char *name, bool must_exist)
585 {
586     struct vsctl_bridge *br = shash_find_data(&info->bridges, name);
587     if (must_exist && !br) {
588         vsctl_fatal("no bridge named %s", name);
589     }
590     return br;
591 }
592
593 static struct vsctl_bridge *
594 find_real_bridge(struct vsctl_info *info, const char *name, bool must_exist)
595 {
596     struct vsctl_bridge *br = find_bridge(info, name, must_exist);
597     if (br && br->parent) {
598         vsctl_fatal("%s is a fake bridge", name);
599     }
600     return br;
601 }
602
603 static struct vsctl_port *
604 find_port(struct vsctl_info *info, const char *name, bool must_exist)
605 {
606     struct vsctl_port *port = shash_find_data(&info->ports, name);
607     if (port && !strcmp(name, port->bridge->name)) {
608         port = NULL;
609     }
610     if (must_exist && !port) {
611         vsctl_fatal("no port named %s", name);
612     }
613     return port;
614 }
615
616 static struct vsctl_iface *
617 find_iface(struct vsctl_info *info, const char *name, bool must_exist)
618 {
619     struct vsctl_iface *iface = shash_find_data(&info->ifaces, name);
620     if (iface && !strcmp(name, iface->port->bridge->name)) {
621         iface = NULL;
622     }
623     if (must_exist && !iface) {
624         vsctl_fatal("no interface named %s", name);
625     }
626     return iface;
627 }
628
629 static void
630 bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
631 {
632     struct ovsrec_port **ports;
633     size_t i;
634
635     ports = xmalloc(sizeof *br->ports * (br->n_ports + 1));
636     for (i = 0; i < br->n_ports; i++) {
637         ports[i] = br->ports[i];
638     }
639     ports[br->n_ports] = port;
640     ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
641     free(ports);
642 }
643
644 static void
645 bridge_delete_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
646 {
647     struct ovsrec_port **ports;
648     size_t i, n;
649
650     ports = xmalloc(sizeof *br->ports * br->n_ports);
651     for (i = n = 0; i < br->n_ports; i++) {
652         if (br->ports[i] != port) {
653             ports[n++] = br->ports[i];
654         }
655     }
656     ovsrec_bridge_set_ports(br, ports, n);
657     free(ports);
658 }
659
660 static void
661 ovs_insert_bridge(const struct ovsrec_open_vswitch *ovs,
662                   struct ovsrec_bridge *bridge)
663 {
664     struct ovsrec_bridge **bridges;
665     size_t i;
666
667     bridges = xmalloc(sizeof *ovs->bridges * (ovs->n_bridges + 1));
668     for (i = 0; i < ovs->n_bridges; i++) {
669         bridges[i] = ovs->bridges[i];
670     }
671     bridges[ovs->n_bridges] = bridge;
672     ovsrec_open_vswitch_set_bridges(ovs, bridges, ovs->n_bridges + 1);
673     free(bridges);
674 }
675
676 static void
677 ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
678                   struct ovsrec_bridge *bridge)
679 {
680     struct ovsrec_bridge **bridges;
681     size_t i, n;
682
683     bridges = xmalloc(sizeof *ovs->bridges * ovs->n_bridges);
684     for (i = n = 0; i < ovs->n_bridges; i++) {
685         if (ovs->bridges[i] != bridge) {
686             bridges[n++] = ovs->bridges[i];
687         }
688     }
689     ovsrec_open_vswitch_set_bridges(ovs, bridges, n);
690     free(bridges);
691 }
692
693 static void
694 cmd_init(struct vsctl_context *ctx UNUSED)
695 {
696 }
697
698 static void
699 cmd_add_br(struct vsctl_context *ctx)
700 {
701     const char *br_name = ctx->argv[1];
702     struct vsctl_info info;
703
704     get_info(ctx->ovs, &info);
705     check_conflicts(&info, br_name,
706                     xasprintf("cannot create a bridge named %s", br_name));
707
708     if (ctx->argc == 2) {
709         struct ovsrec_bridge *br;
710         struct ovsrec_port *port;
711         struct ovsrec_interface *iface;
712
713         iface = ovsrec_interface_insert(txn_from_openvswitch(ctx->ovs));
714         ovsrec_interface_set_name(iface, br_name);
715
716         port = ovsrec_port_insert(txn_from_openvswitch(ctx->ovs));
717         ovsrec_port_set_name(port, br_name);
718         ovsrec_port_set_interfaces(port, &iface, 1);
719
720         br = ovsrec_bridge_insert(txn_from_openvswitch(ctx->ovs));
721         ovsrec_bridge_set_name(br, br_name);
722         ovsrec_bridge_set_ports(br, &port, 1);
723
724         ovs_insert_bridge(ctx->ovs, br);
725     } else if (ctx->argc == 3) {
726         vsctl_fatal("'%s' command takes exactly 1 or 3 arguments",
727                     ctx->argv[0]);
728     } else if (ctx->argc == 4) {
729         const char *parent_name = ctx->argv[2];
730         int vlan = atoi(ctx->argv[3]);
731         struct ovsrec_bridge *br;
732         struct vsctl_bridge *parent;
733         struct ovsrec_port *port;
734         struct ovsrec_interface *iface;
735         int64_t tag = vlan;
736
737         if (vlan < 1 || vlan > 4095) {
738             vsctl_fatal("%s: vlan must be between 1 and 4095", ctx->argv[0]);
739         }
740
741         parent = find_bridge(&info, parent_name, false);
742         if (parent && parent->vlan) {
743             vsctl_fatal("cannot create bridge with fake bridge as parent");
744         }
745         if (!parent) {
746             vsctl_fatal("parent bridge %s does not exist", parent_name);
747         }
748         br = parent->br_cfg;
749
750         iface = ovsrec_interface_insert(txn_from_openvswitch(ctx->ovs));
751         ovsrec_interface_set_name(iface, br_name);
752         ovsrec_interface_set_type(iface, "internal");
753
754         port = ovsrec_port_insert(txn_from_openvswitch(ctx->ovs));
755         ovsrec_port_set_name(port, br_name);
756         ovsrec_port_set_interfaces(port, &iface, 1);
757         ovsrec_port_set_fake_bridge(port, true);
758         ovsrec_port_set_tag(port, &tag, 1);
759
760         bridge_insert_port(br, port);
761     } else {
762         NOT_REACHED();
763     }
764
765     free_info(&info);
766 }
767
768 static void
769 del_port(struct vsctl_info *info, struct vsctl_port *port)
770 {
771     struct shash_node *node;
772
773     SHASH_FOR_EACH (node, &info->ifaces) {
774         struct vsctl_iface *iface = node->data;
775         if (iface->port == port) {
776             ovsrec_interface_delete(iface->iface_cfg);
777         }
778     }
779     ovsrec_port_delete(port->port_cfg);
780
781     bridge_delete_port((port->bridge->parent
782                         ? port->bridge->parent->br_cfg
783                         : port->bridge->br_cfg), port->port_cfg);
784 }
785
786 static void
787 cmd_del_br(struct vsctl_context *ctx)
788 {
789     bool must_exist = !shash_find(&ctx->options, "--if-exists");
790     struct vsctl_bridge *bridge;
791     struct vsctl_info info;
792
793     get_info(ctx->ovs, &info);
794     bridge = find_bridge(&info, ctx->argv[1], must_exist);
795     if (bridge) {
796         struct shash_node *node;
797
798         SHASH_FOR_EACH (node, &info.ports) {
799             struct vsctl_port *port = node->data;
800             if (port->bridge == bridge
801                 || !strcmp(port->port_cfg->name, bridge->name)) {
802                 del_port(&info, port);
803             }
804         }
805         if (bridge->br_cfg) {
806             ovsrec_bridge_delete(bridge->br_cfg);
807             ovs_delete_bridge(ctx->ovs, bridge->br_cfg);
808         }
809     }
810     free_info(&info);
811 }
812
813 static void
814 output_sorted(struct svec *svec, struct ds *output)
815 {
816     const char *name;
817     size_t i;
818
819     svec_sort(svec);
820     SVEC_FOR_EACH (i, name, svec) {
821         ds_put_format(output, "%s\n", name);
822     }
823 }
824
825 static void
826 cmd_list_br(struct vsctl_context *ctx)
827 {
828     struct shash_node *node;
829     struct vsctl_info info;
830     struct svec bridges;
831
832     get_info(ctx->ovs, &info);
833
834     svec_init(&bridges);
835     SHASH_FOR_EACH (node, &info.bridges) {
836         struct vsctl_bridge *br = node->data;
837         svec_add(&bridges, br->name);
838     }
839     output_sorted(&bridges, &ctx->output);
840     svec_destroy(&bridges);
841
842     free_info(&info);
843 }
844
845 static void
846 cmd_br_exists(struct vsctl_context *ctx)
847 {
848     struct vsctl_info info;
849
850     get_info(ctx->ovs, &info);
851     if (!find_bridge(&info, ctx->argv[1], false)) {
852         exit(2);
853     }
854     free_info(&info);
855 }
856
857 /* Returns true if 'b_prefix' (of length 'b_prefix_len') concatenated with 'b'
858  * equals 'a', false otherwise. */
859 static bool
860 key_matches(const char *a,
861             const char *b_prefix, size_t b_prefix_len, const char *b)
862 {
863     return !strncmp(a, b_prefix, b_prefix_len) && !strcmp(a + b_prefix_len, b);
864 }
865
866 static void
867 set_external_id(char **old_keys, char **old_values, size_t old_n,
868                 char *key, char *value,
869                 char ***new_keysp, char ***new_valuesp, size_t *new_np)
870 {
871     char **new_keys;
872     char **new_values;
873     size_t new_n;
874     size_t i;
875
876     new_keys = xmalloc(sizeof *new_keys * (old_n + 1));
877     new_values = xmalloc(sizeof *new_values * (old_n + 1));
878     new_n = 0;
879     for (i = 0; i < old_n; i++) {
880         if (strcmp(key, old_keys[i])) {
881             new_keys[new_n] = old_keys[i];
882             new_values[new_n] = old_values[i];
883             new_n++;
884         }
885     }
886     if (value) {
887         new_keys[new_n] = key;
888         new_values[new_n] = value;
889         new_n++;
890     }
891     *new_keysp = new_keys;
892     *new_valuesp = new_values;
893     *new_np = new_n;
894 }
895
896 static void
897 cmd_br_set_external_id(struct vsctl_context *ctx)
898 {
899     struct vsctl_info info;
900     struct vsctl_bridge *bridge;
901     char **keys, **values;
902     size_t n;
903
904     get_info(ctx->ovs, &info);
905     bridge = find_bridge(&info, ctx->argv[1], true);
906     if (bridge->br_cfg) {
907         set_external_id(bridge->br_cfg->key_external_ids,
908                         bridge->br_cfg->value_external_ids,
909                         bridge->br_cfg->n_external_ids,
910                         ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
911                         &keys, &values, &n);
912         ovsrec_bridge_set_external_ids(bridge->br_cfg, keys, values, n);
913     } else {
914         char *key = xasprintf("fake-bridge-%s", ctx->argv[2]);
915         struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
916         set_external_id(port->port_cfg->key_external_ids,
917                         port->port_cfg->value_external_ids,
918                         port->port_cfg->n_external_ids,
919                         key, ctx->argc >= 4 ? ctx->argv[3] : NULL,
920                         &keys, &values, &n);
921         ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
922         free(key);
923     }
924     free(keys);
925     free(values);
926
927     free_info(&info);
928 }
929
930 static void
931 get_external_id(char **keys, char **values, size_t n,
932                 const char *prefix, const char *key,
933                 struct ds *output)
934 {
935     size_t prefix_len = strlen(prefix);
936     struct svec svec;
937     size_t i;
938
939     svec_init(&svec);
940     for (i = 0; i < n; i++) {
941         if (!key && !strncmp(keys[i], prefix, prefix_len)) {
942             svec_add_nocopy(&svec, xasprintf("%s=%s",
943                                              keys[i] + prefix_len, values[i]));
944         } else if (key_matches(keys[i], prefix, prefix_len, key)) {
945             svec_add(&svec, values[i]);
946             break;
947         }
948     }
949     output_sorted(&svec, output);
950     svec_destroy(&svec);
951 }
952
953 static void
954 cmd_br_get_external_id(struct vsctl_context *ctx)
955 {
956     struct vsctl_info info;
957     struct vsctl_bridge *bridge;
958
959     get_info(ctx->ovs, &info);
960     bridge = find_bridge(&info, ctx->argv[1], true);
961     if (bridge->br_cfg) {
962         get_external_id(bridge->br_cfg->key_external_ids,
963                         bridge->br_cfg->value_external_ids,
964                         bridge->br_cfg->n_external_ids,
965                         "", ctx->argc >= 3 ? ctx->argv[2] : NULL,
966                         &ctx->output);
967     } else {
968         struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
969         get_external_id(port->port_cfg->key_external_ids,
970                         port->port_cfg->value_external_ids,
971                         port->port_cfg->n_external_ids,
972                         "fake-bridge-", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
973     }
974     free_info(&info);
975 }
976
977
978 static void
979 cmd_list_ports(struct vsctl_context *ctx)
980 {
981     struct vsctl_bridge *br;
982     struct shash_node *node;
983     struct vsctl_info info;
984     struct svec ports;
985
986     get_info(ctx->ovs, &info);
987     br = find_bridge(&info, ctx->argv[1], true);
988
989     svec_init(&ports);
990     SHASH_FOR_EACH (node, &info.ports) {
991         struct vsctl_port *port = node->data;
992
993         if (strcmp(port->port_cfg->name, br->name) && br == port->bridge) {
994             svec_add(&ports, port->port_cfg->name);
995         }
996     }
997     output_sorted(&ports, &ctx->output);
998     svec_destroy(&ports);
999
1000     free_info(&info);
1001 }
1002
1003 static void
1004 add_port(const struct ovsrec_open_vswitch *ovs,
1005          const char *br_name, const char *port_name,
1006          char *iface_names[], int n_ifaces)
1007 {
1008     struct vsctl_info info;
1009     struct vsctl_bridge *bridge;
1010     struct ovsrec_interface **ifaces;
1011     struct ovsrec_port *port;
1012     size_t i;
1013
1014     get_info(ovs, &info);
1015     check_conflicts(&info, port_name,
1016                     xasprintf("cannot create a port named %s", port_name));
1017     /* XXX need to check for conflicts on interfaces too */
1018     bridge = find_bridge(&info, br_name, true);
1019
1020     ifaces = xmalloc(n_ifaces * sizeof *ifaces);
1021     for (i = 0; i < n_ifaces; i++) {
1022         ifaces[i] = ovsrec_interface_insert(txn_from_openvswitch(ovs));
1023         ovsrec_interface_set_name(ifaces[i], iface_names[i]);
1024     }
1025
1026     port = ovsrec_port_insert(txn_from_openvswitch(ovs));
1027     ovsrec_port_set_name(port, port_name);
1028     ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
1029     free(ifaces);
1030
1031     if (bridge->vlan) {
1032         int64_t tag = bridge->vlan;
1033         ovsrec_port_set_tag(port, &tag, 1);
1034     }
1035
1036     bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
1037                         : bridge->br_cfg), port);
1038
1039     free_info(&info);
1040 }
1041
1042 static void
1043 cmd_add_port(struct vsctl_context *ctx)
1044 {
1045     add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[2], 1);
1046 }
1047
1048 static void
1049 cmd_add_bond(struct vsctl_context *ctx)
1050 {
1051     add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[3], ctx->argc - 3);
1052 }
1053
1054 static void
1055 cmd_del_port(struct vsctl_context *ctx)
1056 {
1057     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1058     struct vsctl_info info;
1059
1060     get_info(ctx->ovs, &info);
1061     if (ctx->argc == 2) {
1062         struct vsctl_port *port = find_port(&info, ctx->argv[1], must_exist);
1063         if (port) {
1064             del_port(&info, port);
1065         }
1066     } else if (ctx->argc == 3) {
1067         struct vsctl_bridge *bridge = find_bridge(&info, ctx->argv[1], true);
1068         struct vsctl_port *port = find_port(&info, ctx->argv[2], must_exist);
1069
1070         if (port) {
1071             if (port->bridge == bridge) {
1072                 del_port(&info, port);
1073             } else if (port->bridge->parent == bridge) {
1074                 vsctl_fatal("bridge %s does not have a port %s (although its "
1075                             "parent bridge %s does)",
1076                             ctx->argv[1], ctx->argv[2], bridge->parent->name);
1077             } else {
1078                 vsctl_fatal("bridge %s does not have a port %s",
1079                             ctx->argv[1], ctx->argv[2]);
1080             }
1081         }
1082     }
1083     free_info(&info);
1084 }
1085
1086 static void
1087 cmd_port_to_br(struct vsctl_context *ctx)
1088 {
1089     struct vsctl_port *port;
1090     struct vsctl_info info;
1091
1092     get_info(ctx->ovs, &info);
1093     port = find_port(&info, ctx->argv[1], true);
1094     ds_put_format(&ctx->output, "%s\n", port->bridge->name);
1095     free_info(&info);
1096 }
1097
1098 static void
1099 cmd_port_set_external_id(struct vsctl_context *ctx)
1100 {
1101     struct vsctl_info info;
1102     struct vsctl_port *port;
1103     char **keys, **values;
1104     size_t n;
1105
1106     get_info(ctx->ovs, &info);
1107     port = find_port(&info, ctx->argv[1], true);
1108     set_external_id(port->port_cfg->key_external_ids,
1109                     port->port_cfg->value_external_ids,
1110                     port->port_cfg->n_external_ids,
1111                     ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1112                     &keys, &values, &n);
1113     ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
1114     free(keys);
1115     free(values);
1116
1117     free_info(&info);
1118 }
1119
1120 static void
1121 cmd_port_get_external_id(struct vsctl_context *ctx)
1122 {
1123     struct vsctl_info info;
1124     struct vsctl_port *port;
1125
1126     get_info(ctx->ovs, &info);
1127     port = find_port(&info, ctx->argv[1], true);
1128     get_external_id(port->port_cfg->key_external_ids,
1129                     port->port_cfg->value_external_ids,
1130                     port->port_cfg->n_external_ids,
1131                     "",  ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1132     free_info(&info);
1133 }
1134
1135 static void
1136 cmd_br_to_vlan(struct vsctl_context *ctx)
1137 {
1138     struct vsctl_bridge *bridge;
1139     struct vsctl_info info;
1140
1141     get_info(ctx->ovs, &info);
1142     bridge = find_bridge(&info, ctx->argv[1], true);
1143     ds_put_format(&ctx->output, "%d\n", bridge->vlan);
1144     free_info(&info);
1145 }
1146
1147 static void
1148 cmd_br_to_parent(struct vsctl_context *ctx)
1149 {
1150     struct vsctl_bridge *bridge;
1151     struct vsctl_info info;
1152
1153     get_info(ctx->ovs, &info);
1154     bridge = find_bridge(&info, ctx->argv[1], true);
1155     if (bridge->parent) {
1156         bridge = bridge->parent;
1157     }
1158     ds_put_format(&ctx->output, "%s\n", bridge->name);
1159     free_info(&info);
1160 }
1161
1162 static void
1163 cmd_list_ifaces(struct vsctl_context *ctx)
1164 {
1165     struct vsctl_bridge *br;
1166     struct shash_node *node;
1167     struct vsctl_info info;
1168     struct svec ifaces;
1169
1170     get_info(ctx->ovs, &info);
1171     br = find_bridge(&info, ctx->argv[1], true);
1172
1173     svec_init(&ifaces);
1174     SHASH_FOR_EACH (node, &info.ifaces) {
1175         struct vsctl_iface *iface = node->data;
1176
1177         if (strcmp(iface->iface_cfg->name, br->name)
1178             && br == iface->port->bridge) {
1179             svec_add(&ifaces, iface->iface_cfg->name);
1180         }
1181     }
1182     output_sorted(&ifaces, &ctx->output);
1183     svec_destroy(&ifaces);
1184
1185     free_info(&info);
1186 }
1187
1188 static void
1189 cmd_iface_to_br(struct vsctl_context *ctx)
1190 {
1191     struct vsctl_iface *iface;
1192     struct vsctl_info info;
1193
1194     get_info(ctx->ovs, &info);
1195     iface = find_iface(&info, ctx->argv[1], true);
1196     ds_put_format(&ctx->output, "%s\n", iface->port->bridge->name);
1197     free_info(&info);
1198 }
1199
1200 static void
1201 cmd_iface_set_external_id(struct vsctl_context *ctx)
1202 {
1203     struct vsctl_info info;
1204     struct vsctl_iface *iface;
1205     char **keys, **values;
1206     size_t n;
1207
1208     get_info(ctx->ovs, &info);
1209     iface = find_iface(&info, ctx->argv[1], true);
1210     set_external_id(iface->iface_cfg->key_external_ids,
1211                     iface->iface_cfg->value_external_ids,
1212                     iface->iface_cfg->n_external_ids,
1213                     ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1214                     &keys, &values, &n);
1215     ovsrec_interface_set_external_ids(iface->iface_cfg, keys, values, n);
1216     free(keys);
1217     free(values);
1218
1219     free_info(&info);
1220 }
1221
1222 static void
1223 cmd_iface_get_external_id(struct vsctl_context *ctx)
1224 {
1225     struct vsctl_info info;
1226     struct vsctl_iface *iface;
1227
1228     get_info(ctx->ovs, &info);
1229     iface = find_iface(&info, ctx->argv[1], true);
1230     get_external_id(iface->iface_cfg->key_external_ids,
1231                     iface->iface_cfg->value_external_ids,
1232                     iface->iface_cfg->n_external_ids,
1233                     "",  ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1234     free_info(&info);
1235 }
1236
1237 static void
1238 cmd_get_controller(struct vsctl_context *ctx)
1239 {
1240     struct vsctl_info info;
1241
1242     get_info(ctx->ovs, &info);
1243
1244     if (ctx->argc == 1) {
1245         /* Return the controller from the "Open_vSwitch" table */
1246         if (info.ctrl) {
1247             ds_put_format(&ctx->output, "%s\n", info.ctrl->target);
1248         }
1249     } else {
1250         /* Return the controller for a particular bridge. */
1251         struct vsctl_bridge *br = find_bridge(&info, ctx->argv[1], true);
1252
1253         /* If no controller is explicitly defined for the requested
1254          * bridge, fallback to the "Open_vSwitch" table's controller. */
1255         if (br->ctrl) {
1256             ds_put_format(&ctx->output, "%s\n", br->ctrl->target);
1257         } else if (info.ctrl) {
1258             ds_put_format(&ctx->output, "%s\n", info.ctrl->target);
1259         }
1260     }
1261
1262     free_info(&info);
1263 }
1264
1265 static void
1266 cmd_del_controller(struct vsctl_context *ctx)
1267 {
1268     struct vsctl_info info;
1269
1270     get_info(ctx->ovs, &info);
1271
1272     if (ctx->argc == 1) {
1273         if (info.ctrl) {
1274             ovsrec_controller_delete(info.ctrl);
1275             ovsrec_open_vswitch_set_controller(ctx->ovs, NULL);
1276         }
1277     } else {
1278         struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1279
1280         if (br->ctrl) {
1281             ovsrec_controller_delete(br->ctrl);
1282             ovsrec_bridge_set_controller(br->br_cfg, NULL);
1283         }
1284     }
1285
1286     free_info(&info);
1287 }
1288
1289 static void
1290 cmd_set_controller(struct vsctl_context *ctx)
1291 {
1292     struct vsctl_info info;
1293     struct ovsrec_controller *ctrl;
1294
1295     get_info(ctx->ovs, &info);
1296
1297     if (ctx->argc == 2) {
1298         /* Set the controller in the "Open_vSwitch" table. */
1299         if (info.ctrl) {
1300             ovsrec_controller_delete(info.ctrl);
1301         }
1302         ctrl = ovsrec_controller_insert(txn_from_openvswitch(ctx->ovs));
1303         ovsrec_controller_set_target(ctrl, ctx->argv[1]);
1304         ovsrec_open_vswitch_set_controller(ctx->ovs, ctrl);
1305     } else {
1306         /* Set the controller for a particular bridge. */
1307         struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1308
1309         if (br->ctrl) {
1310             ovsrec_controller_delete(br->ctrl);
1311         }
1312         ctrl = ovsrec_controller_insert(txn_from_openvswitch(ctx->ovs));
1313         ovsrec_controller_set_target(ctrl, ctx->argv[2]);
1314         ovsrec_bridge_set_controller(br->br_cfg, ctrl);
1315     }
1316
1317     free_info(&info);
1318 }
1319
1320 static void
1321 cmd_get_fail_mode(struct vsctl_context *ctx)
1322 {
1323     struct vsctl_info info;
1324     const char *fail_mode = NULL;
1325
1326     get_info(ctx->ovs, &info);
1327
1328     if (ctx->argc == 1) {
1329         /* Return the fail-mode from the "Open_vSwitch" table */
1330         if (info.ctrl && info.ctrl->fail_mode) {
1331             fail_mode = info.ctrl->fail_mode;
1332         }
1333     } else {
1334         /* Return the fail-mode for a particular bridge. */
1335         struct vsctl_bridge *br = find_bridge(&info, ctx->argv[1], true);
1336
1337         /* If no controller or fail-mode is explicitly defined for the 
1338          * requested bridge, fallback to the "Open_vSwitch" table's 
1339          * setting. */
1340         if (br->ctrl && br->ctrl->fail_mode) {
1341             fail_mode = br->ctrl->fail_mode;
1342         } else if (info.ctrl && info.ctrl->fail_mode) {
1343             fail_mode = info.ctrl->fail_mode;
1344         }
1345     }
1346
1347     if (fail_mode && strlen(fail_mode)) {
1348         ds_put_format(&ctx->output, "%s\n", fail_mode);
1349     }
1350
1351     free_info(&info);
1352 }
1353
1354 static void
1355 cmd_del_fail_mode(struct vsctl_context *ctx)
1356 {
1357     struct vsctl_info info;
1358
1359     get_info(ctx->ovs, &info);
1360
1361     if (ctx->argc == 1) {
1362         if (info.ctrl && info.ctrl->fail_mode) {
1363             ovsrec_controller_set_fail_mode(info.ctrl, NULL);
1364         }
1365     } else {
1366         struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1367
1368         if (br->ctrl && br->ctrl->fail_mode) {
1369             ovsrec_controller_set_fail_mode(br->ctrl, NULL);
1370         }
1371     }
1372
1373     free_info(&info);
1374 }
1375
1376 static void
1377 cmd_set_fail_mode(struct vsctl_context *ctx)
1378 {
1379     struct vsctl_info info;
1380     const char *fail_mode;
1381
1382     get_info(ctx->ovs, &info);
1383
1384     fail_mode = (ctx->argc == 2) ? ctx->argv[1] : ctx->argv[2];
1385
1386     if (strcmp(fail_mode, "standalone") && strcmp(fail_mode, "secure")) {
1387         vsctl_fatal("fail-mode must be \"standalone\" or \"secure\"");
1388     }
1389
1390     if (ctx->argc == 2) {
1391         /* Set the fail-mode in the "Open_vSwitch" table. */
1392         if (!info.ctrl) {
1393             vsctl_fatal("no controller declared");
1394         }
1395         ovsrec_controller_set_fail_mode(info.ctrl, fail_mode);
1396     } else {
1397         struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1398
1399         if (!br->ctrl) {
1400             vsctl_fatal("no controller declared for %s", br->name);
1401         }
1402         ovsrec_controller_set_fail_mode(br->ctrl, fail_mode);
1403     }
1404
1405     free_info(&info);
1406 }
1407
1408 static void
1409 cmd_get_ssl(struct vsctl_context *ctx)
1410 {
1411     struct ovsrec_ssl *ssl = ctx->ovs->ssl;
1412
1413     if (ssl) {
1414         ds_put_format(&ctx->output, "Private key: %s\n", ssl->private_key);
1415         ds_put_format(&ctx->output, "Certificate: %s\n", ssl->certificate);
1416         ds_put_format(&ctx->output, "CA Certificate: %s\n", ssl->ca_cert);
1417         ds_put_format(&ctx->output, "Bootstrap: %s\n",
1418                 ssl->bootstrap_ca_cert ? "true" : "false");
1419     }
1420 }
1421
1422 static void
1423 cmd_del_ssl(struct vsctl_context *ctx)
1424 {
1425     struct ovsrec_ssl *ssl = ctx->ovs->ssl;
1426
1427     if (ssl) {
1428         ovsrec_ssl_delete(ssl);
1429         ovsrec_open_vswitch_set_ssl(ctx->ovs, NULL);
1430     }
1431 }
1432
1433 static void
1434 cmd_set_ssl(struct vsctl_context *ctx)
1435 {
1436     bool bootstrap = shash_find(&ctx->options, "--bootstrap");
1437     struct ovsrec_ssl *ssl = ctx->ovs->ssl;
1438
1439     if (ssl) {
1440         ovsrec_ssl_delete(ssl);
1441     }
1442     ssl = ovsrec_ssl_insert(txn_from_openvswitch(ctx->ovs));
1443
1444     ovsrec_ssl_set_private_key(ssl, ctx->argv[1]);
1445     ovsrec_ssl_set_certificate(ssl, ctx->argv[2]);
1446     ovsrec_ssl_set_ca_cert(ssl, ctx->argv[3]);
1447
1448     ovsrec_ssl_set_bootstrap_ca_cert(ssl, bootstrap);
1449
1450     ovsrec_open_vswitch_set_ssl(ctx->ovs, ssl);
1451 }
1452 \f
1453 typedef void vsctl_handler_func(struct vsctl_context *);
1454
1455 struct vsctl_command {
1456     const char *name;
1457     int min_args;
1458     int max_args;
1459     vsctl_handler_func *handler;
1460     const char *options;
1461 };
1462
1463 static void run_vsctl_command(int argc, char *argv[],
1464                               const struct ovsrec_open_vswitch *ovs,
1465                               struct ds *output);
1466
1467 static struct json *
1468 where_uuid_equals(const struct uuid *uuid)
1469 {
1470     return
1471         json_array_create_1(
1472             json_array_create_3(
1473                 json_string_create("_uuid"),
1474                 json_string_create("=="),
1475                 json_array_create_2(
1476                     json_string_create("uuid"),
1477                     json_string_create_nocopy(
1478                         xasprintf(UUID_FMT, UUID_ARGS(uuid))))));
1479 }
1480
1481 static void
1482 do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
1483 {
1484     struct ovsdb_idl_txn *txn;
1485     const struct ovsrec_open_vswitch *ovs;
1486     enum ovsdb_idl_txn_status status;
1487     struct ds comment, *output;
1488     int64_t next_cfg;
1489     int n_output;
1490     int i, start;
1491
1492     txn = ovsdb_idl_txn_create(idl);
1493     if (dry_run) {
1494         ovsdb_idl_txn_set_dry_run(txn);
1495     }
1496
1497     ds_init(&comment);
1498     ds_put_cstr(&comment, "ovs-vsctl:");
1499     for (i = 0; i < argc; i++) {
1500         ds_put_format(&comment, " %s", argv[i]);
1501     }
1502     ovsdb_idl_txn_add_comment(txn, ds_cstr(&comment));
1503     ds_destroy(&comment);
1504
1505     ovs = ovsrec_open_vswitch_first(idl);
1506     if (!ovs) {
1507         /* XXX add verification that table is empty */
1508         ovs = ovsrec_open_vswitch_insert(txn);
1509     }
1510
1511     if (wait_for_reload) {
1512         struct json *where = where_uuid_equals(&ovs->header_.uuid);
1513         ovsdb_idl_txn_increment(txn, "Open_vSwitch", "next_cfg",
1514                                 where);
1515         json_destroy(where);
1516     }
1517
1518     output = xmalloc(argc * sizeof *output);
1519     n_output = 0;
1520     for (start = i = 0; i <= argc; i++) {
1521         if (i == argc || !strcmp(argv[i], "--")) {
1522             if (i > start) {
1523                 ds_init(&output[n_output]);
1524                 run_vsctl_command(i - start, &argv[start], ovs,
1525                                   &output[n_output++]);
1526             }
1527             start = i + 1;
1528         }
1529     }
1530
1531     while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
1532         ovsdb_idl_run(idl);
1533         ovsdb_idl_wait(idl);
1534         ovsdb_idl_txn_wait(txn);
1535         poll_block();
1536     }
1537     if (wait_for_reload && status == TXN_SUCCESS) {
1538         next_cfg = ovsdb_idl_txn_get_increment_new_value(txn);
1539     }
1540     ovsdb_idl_txn_destroy(txn);
1541
1542     switch (status) {
1543     case TXN_INCOMPLETE:
1544         NOT_REACHED();
1545
1546     case TXN_ABORTED:
1547         /* Should not happen--we never call ovsdb_idl_txn_abort(). */
1548         vsctl_fatal("transaction aborted");
1549
1550     case TXN_UNCHANGED:
1551     case TXN_SUCCESS:
1552         break;
1553
1554     case TXN_TRY_AGAIN:
1555         for (i = 0; i < n_output; i++) {
1556             ds_destroy(&output[i]);
1557         }
1558         return;
1559
1560     case TXN_ERROR:
1561         vsctl_fatal("transaction error");
1562
1563     default:
1564         NOT_REACHED();
1565     }
1566
1567     for (i = 0; i < n_output; i++) {
1568         struct ds *ds = &output[i];
1569         if (oneline) {
1570             size_t j;
1571
1572             ds_chomp(ds, '\n');
1573             for (j = 0; j < ds->length; j++) {
1574                 int c = ds->string[j];
1575                 switch (c) {
1576                 case '\n':
1577                     fputs("\\n", stdout);
1578                     break;
1579
1580                 case '\\':
1581                     fputs("\\\\", stdout);
1582                     break;
1583
1584                 default:
1585                     putchar(c);
1586                 }
1587             }
1588             putchar('\n');
1589         } else {
1590             fputs(ds_cstr(ds), stdout);
1591         }
1592     }
1593
1594     if (wait_for_reload && status != TXN_UNCHANGED) {
1595         for (;;) {
1596             const struct ovsrec_open_vswitch *ovs;
1597
1598             ovsdb_idl_run(idl);
1599             OVSREC_OPEN_VSWITCH_FOR_EACH (ovs, idl) {
1600                 if (ovs->cur_cfg >= next_cfg) {
1601                     goto done;
1602                 }
1603             }
1604             ovsdb_idl_wait(idl);
1605             poll_block();
1606         }
1607     done: ;
1608     }
1609
1610     exit(EXIT_SUCCESS);
1611 }
1612
1613 static vsctl_handler_func *
1614 get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx)
1615 {
1616     static const struct vsctl_command all_commands[] = {
1617         /* Open vSwitch commands. */
1618         {"init", 0, 0, cmd_init, ""},
1619
1620         /* Bridge commands. */
1621         {"add-br", 1, 3, cmd_add_br, ""},
1622         {"del-br", 1, 1, cmd_del_br, "--if-exists"},
1623         {"list-br", 0, 0, cmd_list_br, ""},
1624         {"br-exists", 1, 1, cmd_br_exists, ""},
1625         {"br-to-vlan", 1, 1, cmd_br_to_vlan, ""},
1626         {"br-to-parent", 1, 1, cmd_br_to_parent, ""},
1627         {"br-set-external-id", 2, 3, cmd_br_set_external_id, ""},
1628         {"br-get-external-id", 1, 2, cmd_br_get_external_id, ""},
1629
1630         /* Port commands. */
1631         {"list-ports", 1, 1, cmd_list_ports, ""},
1632         {"add-port", 2, 2, cmd_add_port, ""},
1633         {"add-bond", 4, INT_MAX, cmd_add_bond, ""},
1634         {"del-port", 1, 2, cmd_del_port, "--if-exists"},
1635         {"port-to-br", 1, 1, cmd_port_to_br, ""},
1636         {"port-set-external-id", 2, 3, cmd_port_set_external_id, ""},
1637         {"port-get-external-id", 1, 2, cmd_port_get_external_id, ""},
1638
1639         /* Interface commands. */
1640         {"list-ifaces", 1, 1, cmd_list_ifaces, ""},
1641         {"iface-to-br", 1, 1, cmd_iface_to_br, ""},
1642         {"iface-set-external-id", 2, 3, cmd_iface_set_external_id, ""},
1643         {"iface-get-external-id", 1, 2, cmd_iface_get_external_id, ""},
1644
1645         /* Controller commands. */
1646         {"get-controller", 0, 1, cmd_get_controller, ""},
1647         {"del-controller", 0, 1, cmd_del_controller, ""},
1648         {"set-controller", 1, 2, cmd_set_controller, ""},
1649         {"get-fail-mode", 0, 1, cmd_get_fail_mode, ""},
1650         {"del-fail-mode", 0, 1, cmd_del_fail_mode, ""},
1651         {"set-fail-mode", 1, 2, cmd_set_fail_mode, ""},
1652
1653         /* SSL commands. */
1654         {"get-ssl", 0, 0, cmd_get_ssl, ""},
1655         {"del-ssl", 0, 0, cmd_del_ssl, ""},
1656         {"set-ssl", 3, 3, cmd_set_ssl, "--bootstrap"},
1657     };
1658
1659     const struct vsctl_command *p;
1660     int i;
1661
1662     shash_init(&ctx->options);
1663     for (i = 0; i < argc; i++) {
1664         if (argv[i][0] != '-') {
1665             break;
1666         }
1667         if (!shash_add_once(&ctx->options, argv[i], NULL)) {
1668             vsctl_fatal("'%s' option specified multiple times", argv[i]);
1669         }
1670     }
1671     if (i == argc) {
1672         vsctl_fatal("missing command name");
1673     }
1674
1675     for (p = all_commands; p < &all_commands[ARRAY_SIZE(all_commands)]; p++) {
1676         if (!strcmp(p->name, argv[i])) {
1677             struct shash_node *node;
1678             int n_arg;
1679
1680             SHASH_FOR_EACH (node, &ctx->options) {
1681                 const char *s = strstr(p->options, node->name);
1682                 int end = s ? s[strlen(node->name)] : EOF;
1683                 if (end != ',' && end != ' ' && end != '\0') {
1684                     vsctl_fatal("'%s' command has no '%s' option",
1685                                 argv[i], node->name);
1686                 }
1687             }
1688
1689             n_arg = argc - i - 1;
1690             if (n_arg < p->min_args) {
1691                 vsctl_fatal("'%s' command requires at least %d arguments",
1692                             p->name, p->min_args);
1693             } else if (n_arg > p->max_args) {
1694                 vsctl_fatal("'%s' command takes at most %d arguments",
1695                             p->name, p->max_args);
1696             } else {
1697                 ctx->argc = n_arg + 1;
1698                 ctx->argv = &argv[i];
1699                 return p->handler;
1700             }
1701         }
1702     }
1703
1704     vsctl_fatal("unknown command '%s'; use --help for help", argv[i]);
1705 }
1706
1707 static void
1708 check_vsctl_command(int argc, char *argv[])
1709 {
1710     struct vsctl_context ctx;
1711
1712     get_vsctl_handler(argc, argv, &ctx);
1713     shash_destroy(&ctx.options);
1714 }
1715
1716 static void
1717 run_vsctl_command(int argc, char *argv[],
1718                   const struct ovsrec_open_vswitch *ovs, struct ds *output)
1719 {
1720     vsctl_handler_func *function;
1721     struct vsctl_context ctx;
1722
1723     function = get_vsctl_handler(argc, argv, &ctx);
1724     ctx.ovs = ovs;
1725     ds_init(&ctx.output);
1726     function(&ctx);
1727     *output = ctx.output;
1728     shash_destroy(&ctx.options);
1729 }