vsctl: Start making it work with ovsdb.
[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 "vswitchd/vswitch-idl.h"
35 #include "timeval.h"
36 #include "util.h"
37
38 #include "vlog.h"
39 #define THIS_MODULE VLM_vsctl
40
41 /* --db: The database server to contact. */
42 static const char *db;
43
44 /* --oneline: Write each command's output as a single line? */
45 static bool oneline;
46
47 static char *default_db(void);
48 static void usage(void) NO_RETURN;
49 static void parse_options(int argc, char *argv[]);
50
51 static void do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl);
52
53 int
54 main(int argc, char *argv[])
55 {
56     struct ovsdb_idl *idl;
57     unsigned int seqno;
58     int trials;
59
60     set_program_name(argv[0]);
61     signal(SIGPIPE, SIG_IGN);
62     time_init();
63     vlog_init();
64     parse_options(argc, argv);
65
66     idl = ovsdb_idl_create(db, &ovsrec_idl_class);
67     seqno = ovsdb_idl_get_seqno(idl);
68     trials = 0;
69     for (;;) {
70         unsigned int new_seqno;
71
72         ovsdb_idl_run(idl);
73         new_seqno = ovsdb_idl_get_seqno(idl);
74         if (new_seqno != seqno) {
75             if (++trials > 5) {
76                 ovs_fatal(0, "too many database inconsistency failures");
77             }
78             do_vsctl(argc - optind, argv + optind, idl);
79             seqno = new_seqno;
80         }
81
82         ovsdb_idl_wait(idl);
83         poll_block();
84     }
85 }
86
87 static void
88 parse_options(int argc, char *argv[])
89 {
90     enum {
91         OPT_DB = UCHAR_MAX + 1,
92         OPT_ONELINE,
93     };
94     static struct option long_options[] = {
95         {"db", required_argument, 0, OPT_DB},
96         {"oneline", no_argument, 0, OPT_ONELINE},
97         {"verbose", optional_argument, 0, 'v'},
98         {"help", no_argument, 0, 'h'},
99         {"version", no_argument, 0, 'V'},
100         {0, 0, 0, 0},
101     };
102     char *short_options;
103
104     short_options = xasprintf ("+%s",
105                                long_options_to_short_options(long_options));
106     for (;;) {
107         int c;
108
109         c = getopt_long(argc, argv, short_options, long_options, NULL);
110         if (c == -1) {
111             break;
112         }
113
114         switch (c) {
115         case OPT_DB:
116             db = optarg;
117             break;
118
119         case OPT_ONELINE:
120             oneline = true;
121             break;
122
123         case 'h':
124             usage();
125
126         case 'V':
127             OVS_PRINT_VERSION(0, 0);
128             exit(EXIT_SUCCESS);
129
130         case 'v':
131             vlog_set_verbosity(optarg);
132             break;
133
134         case '?':
135             exit(EXIT_FAILURE);
136
137         default:
138             abort();
139         }
140     }
141     free(short_options);
142
143     if (!db) {
144         db = default_db();
145     }
146 }
147
148 static void
149 usage(void)
150 {
151     printf("%s: ovs-vswitchd management utility\n"
152            "usage: %s [OPTIONS] COMMAND [ARG...]\n",
153            program_name, program_name);
154     printf("\nBridge commands:\n"
155            "  add-br BRIDGE               "
156            "create a new bridge named BRIDGE\n"
157            "  add-br BRIDGE PARENT VLAN   "
158            "create new fake bridge BRIDGE in PARENT on VLAN\n"
159            "  del-br BRIDGE               "
160            "delete BRIDGE and all of its ports\n"
161            "  list-br                     "
162            "print the names of all the bridges\n"
163            "  br-exists BRIDGE            "
164            "test whether BRIDGE exists\n"
165            "  br-to-vlan BRIDGE           "
166            "print the VLAN which BRIDGE is on\n"
167            "  br-to-parent BRIDGE         "
168            "print the parent of BRIDGE\n");
169     printf("\nPort commands:\n"
170            "  list-ports BRIDGE           "
171            "print the names of all the ports on BRIDGE\n"
172            "  add-port BRIDGE PORT        "
173            "add network device PORT to BRIDGE\n"
174            "  add-bond BRIDGE PORT IFACE...  "
175            "add new bonded port PORT in BRIDGE from IFACES\n"
176            "  del-port [BRIDGE] PORT      "
177            "delete PORT (which may be bonded) from BRIDGE\n"
178            "  port-to-br PORT             "
179            "print name of bridge that contains PORT\n"
180            "A bond is considered to be a single port.\n");
181     printf("\nInterface commands (a bond consists of multiple interfaces):\n"
182            "  list-ifaces BRIDGE          "
183            "print the names of all the interfaces on BRIDGE\n"
184            "  iface-to-br IFACE           "
185            "print name of bridge that contains IFACE\n");
186     printf("\nOptions:\n"
187            "  --db=DATABASE               "
188            "connect to DATABASE\n"
189            "                              "
190            "(default: %s)\n"
191            "  --oneline                   "
192            "print exactly one line of output per command\n",
193            default_db());
194     vlog_usage();
195     printf("\nOther options:\n"
196            "  -h, --help                  "
197            "display this help message\n"
198            "  -V, --version               "
199            "display version information\n");
200     exit(EXIT_SUCCESS);
201 }
202
203 static char *
204 default_db(void)
205 {
206     static char *def;
207     if (!def) {
208         def = xasprintf("%s/ovsdb-server", ovs_rundir);
209     }
210     return def;
211 }
212 \f
213 struct vsctl_bridge {
214     struct ovsrec_bridge *br_cfg;
215     char *name;
216     struct vsctl_bridge *parent;
217     int vlan;
218 };
219
220 struct vsctl_port {
221     struct ovsrec_port *port_cfg;
222     struct vsctl_bridge *bridge;
223 };
224
225 struct vsctl_iface {
226     struct ovsrec_interface *iface_cfg;
227     struct vsctl_port *port;
228 };
229
230 struct vsctl_info {
231     struct shash bridges;
232     struct shash ports;
233     struct shash ifaces;
234 };
235
236 static struct ovsdb_idl_txn *
237 txn_from_openvswitch(const struct ovsrec_open_vswitch *ovs)
238 {
239     return ovsdb_idl_txn_get(&ovs->header_);
240 }
241
242 static struct vsctl_bridge *
243 add_bridge(struct vsctl_info *b,
244            struct ovsrec_bridge *br_cfg, const char *name,
245            struct vsctl_bridge *parent, int vlan)
246 {
247     struct vsctl_bridge *br = xmalloc(sizeof *br);
248     br->br_cfg = br_cfg;
249     br->name = xstrdup(name);
250     br->parent = parent;
251     br->vlan = vlan;
252     shash_add(&b->bridges, br->name, br);
253     return br;
254 }
255
256 static bool
257 port_is_fake_bridge(const struct ovsrec_port *port_cfg)
258 {
259     return (port_cfg->fake_bridge
260             && port_cfg->tag
261             && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095);
262 }
263
264 static struct vsctl_bridge *
265 find_vlan_bridge(struct vsctl_info *info,
266                  struct vsctl_bridge *parent, int vlan)
267 {
268     struct shash_node *node;
269
270     SHASH_FOR_EACH (node, &info->bridges) {
271         struct vsctl_bridge *br = node->data;
272         if (br->parent == parent && br->vlan == vlan) {
273             return br;
274         }
275     }
276
277     return NULL;
278 }
279
280 static void
281 free_info(struct vsctl_info *info)
282 {
283     struct shash_node *node;
284
285     SHASH_FOR_EACH (node, &info->bridges) {
286         struct vsctl_bridge *bridge = node->data;
287         free(bridge->name);
288         free(bridge);
289     }
290     shash_destroy(&info->bridges);
291
292     SHASH_FOR_EACH (node, &info->ports) {
293         struct vsctl_port *port = node->data;
294         free(port);
295     }
296     shash_destroy(&info->ports);
297
298     SHASH_FOR_EACH (node, &info->ifaces) {
299         struct vsctl_iface *iface = node->data;
300         free(iface);
301     }
302     shash_destroy(&info->ifaces);
303 }
304
305 static void
306 get_info(const struct ovsrec_open_vswitch *ovs, struct vsctl_info *info)
307 {
308     struct shash bridges, ports;
309     size_t i;
310
311     shash_init(&info->bridges);
312     shash_init(&info->ports);
313     shash_init(&info->ifaces);
314
315     shash_init(&bridges);
316     shash_init(&ports);
317     for (i = 0; i < ovs->n_bridges; i++) {
318         struct ovsrec_bridge *br_cfg = ovs->bridges[i];
319         struct vsctl_bridge *br;
320         size_t j;
321
322         if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
323             VLOG_WARN("%s: database contains duplicate bridge name",
324                       br_cfg->name);
325             continue;
326         }
327         br = add_bridge(info, br_cfg, br_cfg->name, NULL, 0);
328         if (!br) {
329             continue;
330         }
331
332         for (j = 0; j < br_cfg->n_ports; j++) {
333             struct ovsrec_port *port_cfg = br_cfg->ports[j];
334
335             if (!shash_add_once(&ports, port_cfg->name, NULL)) {
336                 VLOG_WARN("%s: database contains duplicate port name",
337                           port_cfg->name);
338                 continue;
339             }
340
341             if (port_is_fake_bridge(port_cfg)
342                 && shash_add_once(&bridges, br_cfg->name, NULL)) {
343                 add_bridge(info, NULL, port_cfg->name, br, *port_cfg->tag);
344             }
345         }
346     }
347     shash_destroy(&bridges);
348     shash_destroy(&ports);
349
350     shash_init(&bridges);
351     shash_init(&ports);
352     for (i = 0; i < ovs->n_bridges; i++) {
353         struct ovsrec_bridge *br_cfg = ovs->bridges[i];
354         struct vsctl_bridge *br;
355         size_t j;
356
357         if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
358             continue;
359         }
360         br = shash_find_data(&info->bridges, br_cfg->name);
361         for (j = 0; j < br_cfg->n_ports; j++) {
362             struct ovsrec_port *port_cfg = br_cfg->ports[j];
363             struct vsctl_port *port;
364             size_t k;
365
366             if (!shash_add_once(&ports, port_cfg->name, NULL)) {
367                 continue;
368             }
369
370             if (port_is_fake_bridge(port_cfg)
371                 && !shash_add_once(&bridges, br_cfg->name, NULL)) {
372                 continue;
373             }
374
375             port = xmalloc(sizeof *port);
376             port->port_cfg = port_cfg;
377             if (port_cfg->tag
378                 && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095) {
379                 port->bridge = find_vlan_bridge(info, br, *port_cfg->tag);
380                 if (!port->bridge) {
381                     port->bridge = br;
382                 }
383             } else {
384                 port->bridge = br;
385             }
386             shash_add(&info->ports, port_cfg->name, port);
387
388             for (k = 0; k < port_cfg->n_interfaces; k++) {
389                 struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
390                 struct vsctl_iface *iface;
391
392                 if (shash_find(&info->ifaces, iface_cfg->name)) {
393                     VLOG_WARN("%s: database contains duplicate interface name",
394                               iface_cfg->name);
395                     continue;
396                 }
397
398                 iface = xmalloc(sizeof *iface);
399                 iface->iface_cfg = iface_cfg;
400                 iface->port = port;
401             }
402         }
403     }
404     shash_destroy(&bridges);
405     shash_destroy(&ports);
406 }
407
408 static void
409 check_conflicts(struct vsctl_info *info, const char *name,
410                 char *msg)
411 {
412     struct vsctl_iface *iface;
413     struct vsctl_port *port;
414
415     if (shash_find(&info->bridges, name)) {
416         ovs_fatal(0, "%s because a bridge named %s already exists", msg, name);
417     }
418
419     port = shash_find_data(&info->ports, name);
420     if (port) {
421         ovs_fatal(0, "%s because a port named %s already exists on bridge %s",
422                   msg, name, port->bridge->name);
423     }
424
425     iface = shash_find_data(&info->ifaces, name);
426     if (iface) {
427         ovs_fatal(0, "%s because an interface named %s already exists "
428                   "on bridge %s", msg, name, iface->port->bridge->name);
429     }
430
431     free(msg);
432 }
433
434 static struct vsctl_bridge *
435 find_bridge(struct vsctl_info *info, const char *name)
436 {
437     struct vsctl_bridge *br = shash_find_data(&info->bridges, name);
438     if (!br) {
439         ovs_fatal(0, "no bridge named %s", name);
440     }
441     return br;
442 }
443
444 static struct vsctl_port *
445 find_port(struct vsctl_info *info, const char *name)
446 {
447     struct vsctl_port *port = shash_find_data(&info->ports, name);
448     if (!port || !strcmp(name, port->bridge->name)) {
449         ovs_fatal(0, "no port named %s", name);
450     }
451     return port;
452 }
453
454 static struct vsctl_iface *
455 find_iface(struct vsctl_info *info, const char *name)
456 {
457     struct vsctl_iface *iface = shash_find_data(&info->ifaces, name);
458     if (!iface) {
459         ovs_fatal(0, "no interface named %s", name);
460     }
461     return iface;
462 }
463
464 static void
465 bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
466 {
467     struct ovsrec_port **ports;
468     size_t i;
469
470     ports = xmalloc(sizeof *br->ports * (br->n_ports + 1));
471     for (i = 0; i < br->n_ports; i++) {
472         ports[i] = br->ports[i];
473     }
474     printf("bridge has %zu ports, adding 1\n", br->n_ports);
475     ports[br->n_ports] = port;
476     ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
477     free(ports);
478 }
479
480 static void
481 bridge_delete_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
482 {
483     struct ovsrec_port **ports;
484     size_t i, n;
485
486     ports = xmalloc(sizeof *br->ports * br->n_ports);
487     for (i = n = 0; i < br->n_ports; i++) {
488         if (br->ports[i] != port) {
489             ports[n++] = br->ports[i];
490         }
491     }
492     ovsrec_bridge_set_ports(br, ports, n);
493     free(ports);
494 }
495
496 static void
497 ovs_insert_bridge(const struct ovsrec_open_vswitch *ovs,
498                   struct ovsrec_bridge *bridge)
499 {
500     struct ovsrec_bridge **bridges;
501     size_t i;
502
503     bridges = xmalloc(sizeof *ovs->bridges * (ovs->n_bridges + 1));
504     for (i = 0; i < ovs->n_bridges; i++) {
505         bridges[i] = ovs->bridges[i];
506     }
507     bridges[ovs->n_bridges] = bridge;
508     ovsrec_open_vswitch_set_bridges(ovs, bridges, ovs->n_bridges + 1);
509     free(bridges);
510 }
511
512 static void
513 ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
514                   struct ovsrec_bridge *bridge)
515 {
516     struct ovsrec_bridge **bridges;
517     size_t i, n;
518
519     bridges = xmalloc(sizeof *ovs->bridges * ovs->n_bridges);
520     for (i = n = 0; i < ovs->n_bridges; i++) {
521         if (ovs->bridges[i] != bridge) {
522             bridges[n++] = ovs->bridges[i];
523         }
524     }
525     ovsrec_open_vswitch_set_bridges(ovs, bridges, n);
526     free(bridges);
527 }
528
529 static void
530 cmd_add_br(int argc, char *argv[], const struct ovsrec_open_vswitch *ovs,
531            struct ds *output UNUSED)
532 {
533     const char *br_name = argv[1];
534     struct vsctl_info info;
535
536     get_info(ovs, &info);
537     check_conflicts(&info, br_name,
538                     xasprintf("cannot create a bridge named %s", br_name));
539
540     if (argc == 2) {
541         struct ovsrec_bridge *br;
542         struct ovsrec_port *port;
543         struct ovsrec_interface *iface;
544
545         iface = ovsrec_interface_insert(txn_from_openvswitch(ovs));
546         ovsrec_interface_set_name(iface, br_name);
547
548         port = ovsrec_port_insert(txn_from_openvswitch(ovs));
549         ovsrec_port_set_name(port, br_name);
550         ovsrec_port_set_interfaces(port, &iface, 1);
551
552         br = ovsrec_bridge_insert(txn_from_openvswitch(ovs));
553         ovsrec_bridge_set_name(br, br_name);
554         ovsrec_bridge_set_ports(br, &port, 1);
555
556         ovs_insert_bridge(ovs, br);
557     } else if (argc == 3) {
558         ovs_fatal(0, "'%s' comamnd takes exactly 1 or 3 arguments", argv[0]);
559     } else if (argc >= 4) {
560         const char *parent_name = argv[2];
561         int vlan = atoi(argv[3]);
562         struct ovsrec_bridge *br;
563         struct vsctl_bridge *parent;
564         struct ovsrec_port *port;
565         struct ovsrec_interface *iface;
566         int64_t tag = vlan;
567
568         if (vlan < 1 || vlan > 4095) {
569             ovs_fatal(0, "%s: vlan must be between 1 and 4095", argv[0]);
570         }
571
572         parent = shash_find_data(&info.bridges, parent_name);
573         if (parent && parent->vlan) {
574             ovs_fatal(0, "cannot create brdige with fake bridge as parent");
575         }
576         if (!parent) {
577             ovs_fatal(0, "parent bridge %s does not exist", parent_name);
578         }
579         br = parent->br_cfg;
580
581         iface = ovsrec_interface_insert(txn_from_openvswitch(ovs));
582         ovsrec_interface_set_name(iface, br_name);
583         ovsrec_interface_set_type(iface, "internal");
584
585         port = ovsrec_port_insert(txn_from_openvswitch(ovs));
586         ovsrec_port_set_name(port, br_name);
587         ovsrec_port_set_interfaces(port, &iface, 1);
588         ovsrec_port_set_fake_bridge(port, true);
589         ovsrec_port_set_tag(port, &tag, 1);
590     } else {
591         NOT_REACHED();
592     }
593
594     free_info(&info);
595 }
596
597 static void
598 del_port(struct vsctl_info *info, struct vsctl_port *port)
599 {
600     struct shash_node *node;
601
602     SHASH_FOR_EACH (node, &info->ifaces) {
603         struct vsctl_iface *iface = node->data;
604         if (iface->port == port) {
605             ovsrec_interface_delete(iface->iface_cfg);
606         }
607     }
608     ovsrec_port_delete(port->port_cfg);
609
610     bridge_delete_port((port->bridge->parent
611                         ? port->bridge->parent->br_cfg
612                         : port->bridge->br_cfg), port->port_cfg);
613 }
614
615 static void
616 cmd_del_br(int argc UNUSED, char *argv[],
617            const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
618 {
619     struct shash_node *node;
620     struct vsctl_info info;
621     struct vsctl_bridge *bridge;
622
623     get_info(ovs, &info);
624     bridge = find_bridge(&info, argv[1]);
625     SHASH_FOR_EACH (node, &info.ports) {
626         struct vsctl_port *port = node->data;
627         if (port->bridge == bridge) {
628             del_port(&info, port);
629         }
630     }
631     if (bridge->br_cfg) {
632         ovsrec_bridge_delete(bridge->br_cfg);
633         ovs_delete_bridge(ovs, bridge->br_cfg);
634     }
635     free_info(&info);
636 }
637
638 static void
639 cmd_list_br(int argc UNUSED, char *argv[] UNUSED,
640             const struct ovsrec_open_vswitch *ovs, struct ds *output)
641 {
642     struct shash_node *node;
643     struct vsctl_info info;
644
645     get_info(ovs, &info);
646     SHASH_FOR_EACH (node, &info.bridges) {
647         struct vsctl_bridge *br = node->data;
648         ds_put_format(output, "%s\n", br->name);
649     }
650     free_info(&info);
651 }
652
653 static void
654 cmd_br_exists(int argc UNUSED, char *argv[],
655               const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
656 {
657     struct vsctl_info info;
658
659     get_info(ovs, &info);
660     if (!shash_find_data(&info.bridges, argv[1])) {
661         exit(2);
662     }
663     free_info(&info);
664 }
665
666 static void
667 cmd_list_ports(int argc UNUSED, char *argv[],
668                const struct ovsrec_open_vswitch *ovs, struct ds *output)
669 {
670     struct vsctl_bridge *br;
671     struct shash_node *node;
672     struct vsctl_info info;
673
674     get_info(ovs, &info);
675     br = find_bridge(&info, argv[1]);
676     SHASH_FOR_EACH (node, &info.ports) {
677         struct vsctl_port *port = node->data;
678
679         if (strcmp(port->port_cfg->name, br->name) && br == port->bridge) {
680             ds_put_format(output, "%s\n", port->port_cfg->name);
681         }
682     }
683     free_info(&info);
684 }
685
686 static void
687 add_port(const struct ovsrec_open_vswitch *ovs,
688          const char *br_name, const char *port_name,
689          char *iface_names[], int n_ifaces)
690 {
691     struct vsctl_info info;
692     struct vsctl_bridge *bridge;
693     struct ovsrec_interface **ifaces;
694     struct ovsrec_port *port;
695     size_t i;
696
697     get_info(ovs, &info);
698     check_conflicts(&info, port_name,
699                     xasprintf("cannot create a port named %s", port_name));
700     /* XXX need to check for conflicts on interfaces too */
701     bridge = find_bridge(&info, br_name);
702
703     ifaces = xmalloc(n_ifaces * sizeof *ifaces);
704     for (i = 0; i < n_ifaces; i++) {
705         ifaces[i] = ovsrec_interface_insert(txn_from_openvswitch(ovs));
706         ovsrec_interface_set_name(ifaces[i], iface_names[i]);
707     }
708
709     port = ovsrec_port_insert(txn_from_openvswitch(ovs));
710     ovsrec_port_set_name(port, port_name);
711     ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
712     if (bridge->vlan) {
713         int64_t tag = bridge->vlan;
714         ovsrec_port_set_tag(port, &tag, 1);
715     }
716
717     bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
718                         : bridge->br_cfg), port);
719
720     free_info(&info);
721 }
722
723 static void
724 cmd_add_port(int argc UNUSED, char *argv[],
725              const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
726 {
727     add_port(ovs, argv[1], argv[2], &argv[2], 1);
728 }
729
730 static void
731 cmd_add_bond(int argc, char *argv[],
732              const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
733 {
734     add_port(ovs, argv[1], argv[2], &argv[3], argc - 3);
735 }
736
737 static void
738 cmd_del_port(int argc, char *argv[],
739              const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
740 {
741     struct vsctl_info info;
742
743     get_info(ovs, &info);
744     if (argc == 2) {
745         struct vsctl_port *port = find_port(&info, argv[1]);
746         del_port(&info, port);
747     } else if (argc == 3) {
748         struct vsctl_bridge *bridge = find_bridge(&info, argv[1]);
749         struct vsctl_port *port = find_port(&info, argv[2]);
750
751         if (port->bridge == bridge) {
752             del_port(&info, port);
753         } else if (port->bridge->parent == bridge) {
754             ovs_fatal(0, "bridge %s does not have a port %s (although its "
755                       "parent bridge %s does)",
756                       argv[1], argv[2], bridge->parent->name);
757         } else {
758             ovs_fatal(0, "bridge %s does not have a port %s",
759                       argv[1], argv[2]);
760         }
761     }
762     free_info(&info);
763 }
764
765 static void
766 cmd_port_to_br(int argc UNUSED, char *argv[],
767                const struct ovsrec_open_vswitch *ovs, struct ds *output)
768 {
769     struct vsctl_port *port;
770     struct vsctl_info info;
771
772     get_info(ovs, &info);
773     port = find_port(&info, argv[1]);
774     ds_put_format(output, "%s\n", port->bridge->name);
775     free_info(&info);
776 }
777
778 static void
779 cmd_br_to_vlan(int argc UNUSED, char *argv[],
780                const struct ovsrec_open_vswitch *ovs, struct ds *output)
781 {
782     struct vsctl_bridge *bridge;
783     struct vsctl_info info;
784
785     get_info(ovs, &info);
786     bridge = find_bridge(&info, argv[1]);
787     ds_put_format(output, "%d\n", bridge->vlan);
788     free_info(&info);
789 }
790
791 static void
792 cmd_br_to_parent(int argc UNUSED, char *argv[],
793                  const struct ovsrec_open_vswitch *ovs, struct ds *output)
794 {
795     struct vsctl_bridge *bridge;
796     struct vsctl_info info;
797
798     get_info(ovs, &info);
799     bridge = find_bridge(&info, argv[1]);
800     if (bridge->parent) {
801         bridge = bridge->parent;
802     }
803     ds_put_format(output, "%s\n", bridge->name);
804     free_info(&info);
805 }
806
807 static void
808 cmd_list_ifaces(int argc UNUSED, char *argv[],
809                 const struct ovsrec_open_vswitch *ovs, struct ds *output)
810 {
811     struct vsctl_bridge *br;
812     struct shash_node *node;
813     struct vsctl_info info;
814
815     get_info(ovs, &info);
816     br = find_bridge(&info, argv[1]);
817     SHASH_FOR_EACH (node, &info.ifaces) {
818         struct vsctl_iface *iface = node->data;
819
820         if (br == iface->port->bridge) {
821             ds_put_format(output, "%s\n", iface->iface_cfg->name);
822         }
823     }
824     free_info(&info);
825 }
826
827 static void
828 cmd_iface_to_br(int argc UNUSED, char *argv[],
829                 const struct ovsrec_open_vswitch *ovs, struct ds *output)
830 {
831     struct vsctl_iface *iface;
832     struct vsctl_info info;
833
834     get_info(ovs, &info);
835     iface = find_iface(&info, argv[1]);
836     ds_put_format(output, "%s\n", iface->port->bridge->name);
837     free_info(&info);
838 }
839 \f
840 struct vsctl_command {
841     const char *name;
842     int min_args;
843     int max_args;
844     void (*handler)(int argc, char *argv[],
845                     const struct ovsrec_open_vswitch *ovs, struct ds *output);
846 };
847
848 static void run_vsctl_command(int argc, char *argv[],
849                               const struct ovsrec_open_vswitch *ovs,
850                               struct ds *output);
851
852 static void
853 do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
854 {
855     struct ovsdb_idl_txn *txn;
856     const struct ovsrec_open_vswitch *ovs;
857     enum ovsdb_idl_txn_status status;
858     struct ds *output;
859     int n_output;
860     int i, start;
861
862     ovs = ovsrec_open_vswitch_first(idl);
863     if (!ovs) {
864         /* XXX it would be more user-friendly to create a record ourselves
865          * (while verifying that the table is empty before doing so). */
866         ovs_fatal(0, "%s: database does not contain any Open vSwitch "
867                   "configuration", db);
868     }
869
870     txn = ovsdb_idl_txn_create(idl);
871     output = xmalloc(argc * sizeof *output);
872     n_output = 0;
873     for (start = i = 0; i < argc; i++) {
874         if (!strcmp(argv[i], "--")) {
875             if (i > start) {
876                 ds_init(&output[n_output]);
877                 run_vsctl_command(i - start, &argv[start], ovs,
878                                   &output[n_output++]);
879             }
880             start = i + 1;
881         }
882     }
883     if (i > start) {
884         ds_init(&output[n_output]);
885         run_vsctl_command(i - start, &argv[start], ovs, &output[n_output++]);
886     }
887
888     while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
889         ovsdb_idl_run(idl);
890         ovsdb_idl_wait(idl);
891         poll_block();
892     }
893     ovsdb_idl_txn_destroy(txn);
894
895     switch (status) {
896     case TXN_INCOMPLETE:
897         NOT_REACHED();
898
899     case TXN_ABORTED:
900         /* Should not happen--we never call ovsdb_idl_txn_abort(). */
901         ovs_fatal(0, "transaction aborted");
902
903     case TXN_SUCCESS:
904         break;
905
906     case TXN_TRY_AGAIN:
907         for (i = 0; i < n_output; i++) {
908             ds_destroy(&output[i]);
909         }
910         return;
911
912     case TXN_ERROR:
913         ovs_fatal(0, "transaction error");
914
915     default:
916         NOT_REACHED();
917     }
918
919     for (i = 0; i < n_output; i++) {
920         struct ds *ds = &output[i];
921         if (oneline) {
922             size_t j;
923
924             ds_chomp(ds, '\n');
925             for (j = 0; j < ds->length; j++) {
926                 int c = ds->string[j];
927                 switch (c) {
928                 case '\n':
929                     fputs("\\n", stdout);
930                     break;
931
932                 case '\\':
933                     fputs("\\\\", stdout);
934                     break;
935
936                 default:
937                     putchar(c);
938                 }
939             }
940             putchar('\n');
941         } else {
942             fputs(ds_cstr(ds), stdout);
943         }
944     }
945     exit(EXIT_SUCCESS);
946 }
947
948 static void
949 run_vsctl_command(int argc, char *argv[],
950                   const struct ovsrec_open_vswitch *ovs, struct ds *output)
951 {
952     static const struct vsctl_command all_commands[] = {
953         {"add-br", 1, 3, cmd_add_br},
954         {"del-br", 1, 1, cmd_del_br},
955         {"list-br", 0, 0, cmd_list_br},
956         {"br-exists", 1, 1, cmd_br_exists},
957         {"list-ports", 1, 1, cmd_list_ports},
958         {"add-port", 2, 2, cmd_add_port},
959         {"add-bond", 4, INT_MAX, cmd_add_bond},
960         {"del-port", 1, 2, cmd_del_port},
961         {"port-to-br", 1, 1, cmd_port_to_br},
962         {"br-to-vlan", 1, 1, cmd_br_to_vlan},
963         {"br-to-parent", 1, 1, cmd_br_to_parent},
964         {"list-ifaces", 1, 1, cmd_list_ifaces},
965         {"iface-to-br", 1, 1, cmd_iface_to_br},
966     };
967
968     const struct vsctl_command *p;
969
970     assert(argc > 0);
971     for (p = all_commands; p->name != NULL; p++) {
972         if (!strcmp(p->name, argv[0])) {
973             int n_arg = argc - 1;
974             if (n_arg < p->min_args) {
975                 ovs_fatal(0, "'%s' command requires at least %d arguments",
976                           p->name, p->min_args);
977             } else if (n_arg > p->max_args) {
978                 ovs_fatal(0, "'%s' command takes at most %d arguments",
979                           p->name, p->max_args);
980             } else {
981                 p->handler(argc, argv, ovs, output);
982                 return;
983             }
984         }
985     }
986
987     ovs_fatal(0, "unknown command '%s'; use --help for help", argv[0]);
988 }