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