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