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