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