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