ovs-vsctl: Make functions to find entities more flexible.
[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 (!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 (!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     struct shash_node *node;
694     struct vsctl_info info;
695     struct vsctl_bridge *bridge;
696
697     get_info(ctx->ovs, &info);
698     bridge = find_bridge(&info, ctx->argv[1], true);
699     SHASH_FOR_EACH (node, &info.ports) {
700         struct vsctl_port *port = node->data;
701         if (port->bridge == bridge
702             || !strcmp(port->port_cfg->name, bridge->name)) {
703             del_port(&info, port);
704         }
705     }
706     if (bridge->br_cfg) {
707         ovsrec_bridge_delete(bridge->br_cfg);
708         ovs_delete_bridge(ctx->ovs, bridge->br_cfg);
709     }
710     free_info(&info);
711 }
712
713 static void
714 output_sorted(struct svec *svec, struct ds *output)
715 {
716     const char *name;
717     size_t i;
718
719     svec_sort(svec);
720     SVEC_FOR_EACH (i, name, svec) {
721         ds_put_format(output, "%s\n", name);
722     }
723 }
724
725 static void
726 cmd_list_br(struct vsctl_context *ctx)
727 {
728     struct shash_node *node;
729     struct vsctl_info info;
730     struct svec bridges;
731
732     get_info(ctx->ovs, &info);
733
734     svec_init(&bridges);
735     SHASH_FOR_EACH (node, &info.bridges) {
736         struct vsctl_bridge *br = node->data;
737         svec_add(&bridges, br->name);
738     }
739     output_sorted(&bridges, &ctx->output);
740     svec_destroy(&bridges);
741
742     free_info(&info);
743 }
744
745 static void
746 cmd_br_exists(struct vsctl_context *ctx)
747 {
748     struct vsctl_info info;
749
750     get_info(ctx->ovs, &info);
751     if (!find_bridge(&info, ctx->argv[1], false)) {
752         exit(2);
753     }
754     free_info(&info);
755 }
756
757 /* Returns true if 'b_prefix' (of length 'b_prefix_len') concatenated with 'b'
758  * equals 'a', false otherwise. */
759 static bool
760 key_matches(const char *a,
761             const char *b_prefix, size_t b_prefix_len, const char *b)
762 {
763     return !strncmp(a, b_prefix, b_prefix_len) && !strcmp(a + b_prefix_len, b);
764 }
765
766 static void
767 set_external_id(char **old_keys, char **old_values, size_t old_n,
768                 char *key, char *value,
769                 char ***new_keysp, char ***new_valuesp, size_t *new_np)
770 {
771     char **new_keys;
772     char **new_values;
773     size_t new_n;
774     size_t i;
775
776     new_keys = xmalloc(sizeof *new_keys * (old_n + 1));
777     new_values = xmalloc(sizeof *new_values * (old_n + 1));
778     new_n = 0;
779     for (i = 0; i < old_n; i++) {
780         if (strcmp(key, old_keys[i])) {
781             new_keys[new_n] = old_keys[i];
782             new_values[new_n] = old_values[i];
783             new_n++;
784         }
785     }
786     if (value) {
787         new_keys[new_n] = key;
788         new_values[new_n] = value;
789         new_n++;
790     }
791     *new_keysp = new_keys;
792     *new_valuesp = new_values;
793     *new_np = new_n;
794 }
795
796 static void
797 cmd_br_set_external_id(struct vsctl_context *ctx)
798 {
799     struct vsctl_info info;
800     struct vsctl_bridge *bridge;
801     char **keys, **values;
802     size_t n;
803
804     get_info(ctx->ovs, &info);
805     bridge = find_bridge(&info, ctx->argv[1], true);
806     if (bridge->br_cfg) {
807         set_external_id(bridge->br_cfg->key_external_ids,
808                         bridge->br_cfg->value_external_ids,
809                         bridge->br_cfg->n_external_ids,
810                         ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
811                         &keys, &values, &n);
812         ovsrec_bridge_set_external_ids(bridge->br_cfg, keys, values, n);
813     } else {
814         char *key = xasprintf("fake-bridge-%s", ctx->argv[2]);
815         struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
816         set_external_id(port->port_cfg->key_external_ids,
817                         port->port_cfg->value_external_ids,
818                         port->port_cfg->n_external_ids,
819                         key, ctx->argc >= 4 ? ctx->argv[3] : NULL,
820                         &keys, &values, &n);
821         ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
822         free(key);
823     }
824     free(keys);
825     free(values);
826
827     free_info(&info);
828 }
829
830 static void
831 get_external_id(char **keys, char **values, size_t n,
832                 const char *prefix, const char *key,
833                 struct ds *output)
834 {
835     size_t prefix_len = strlen(prefix);
836     struct svec svec;
837     size_t i;
838
839     svec_init(&svec);
840     for (i = 0; i < n; i++) {
841         if (!key && !strncmp(keys[i], prefix, prefix_len)) {
842             svec_add_nocopy(&svec, xasprintf("%s=%s",
843                                              keys[i] + prefix_len, values[i]));
844         } else if (key_matches(keys[i], prefix, prefix_len, key)) {
845             svec_add(&svec, values[i]);
846             break;
847         }
848     }
849     output_sorted(&svec, output);
850     svec_destroy(&svec);
851 }
852
853 static void
854 cmd_br_get_external_id(struct vsctl_context *ctx)
855 {
856     struct vsctl_info info;
857     struct vsctl_bridge *bridge;
858
859     get_info(ctx->ovs, &info);
860     bridge = find_bridge(&info, ctx->argv[1], true);
861     if (bridge->br_cfg) {
862         get_external_id(bridge->br_cfg->key_external_ids,
863                         bridge->br_cfg->value_external_ids,
864                         bridge->br_cfg->n_external_ids,
865                         "", ctx->argc >= 3 ? ctx->argv[2] : NULL,
866                         &ctx->output);
867     } else {
868         struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
869         get_external_id(port->port_cfg->key_external_ids,
870                         port->port_cfg->value_external_ids,
871                         port->port_cfg->n_external_ids,
872                         "fake-bridge-", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
873     }
874     free_info(&info);
875 }
876
877
878 static void
879 cmd_list_ports(struct vsctl_context *ctx)
880 {
881     struct vsctl_bridge *br;
882     struct shash_node *node;
883     struct vsctl_info info;
884     struct svec ports;
885
886     get_info(ctx->ovs, &info);
887     br = find_bridge(&info, ctx->argv[1], true);
888
889     svec_init(&ports);
890     SHASH_FOR_EACH (node, &info.ports) {
891         struct vsctl_port *port = node->data;
892
893         if (strcmp(port->port_cfg->name, br->name) && br == port->bridge) {
894             svec_add(&ports, port->port_cfg->name);
895         }
896     }
897     output_sorted(&ports, &ctx->output);
898     svec_destroy(&ports);
899
900     free_info(&info);
901 }
902
903 static void
904 add_port(const struct ovsrec_open_vswitch *ovs,
905          const char *br_name, const char *port_name,
906          char *iface_names[], int n_ifaces)
907 {
908     struct vsctl_info info;
909     struct vsctl_bridge *bridge;
910     struct ovsrec_interface **ifaces;
911     struct ovsrec_port *port;
912     size_t i;
913
914     get_info(ovs, &info);
915     check_conflicts(&info, port_name,
916                     xasprintf("cannot create a port named %s", port_name));
917     /* XXX need to check for conflicts on interfaces too */
918     bridge = find_bridge(&info, br_name, true);
919
920     ifaces = xmalloc(n_ifaces * sizeof *ifaces);
921     for (i = 0; i < n_ifaces; i++) {
922         ifaces[i] = ovsrec_interface_insert(txn_from_openvswitch(ovs));
923         ovsrec_interface_set_name(ifaces[i], iface_names[i]);
924     }
925
926     port = ovsrec_port_insert(txn_from_openvswitch(ovs));
927     ovsrec_port_set_name(port, port_name);
928     ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
929     free(ifaces);
930
931     if (bridge->vlan) {
932         int64_t tag = bridge->vlan;
933         ovsrec_port_set_tag(port, &tag, 1);
934     }
935
936     bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
937                         : bridge->br_cfg), port);
938
939     free_info(&info);
940 }
941
942 static void
943 cmd_add_port(struct vsctl_context *ctx)
944 {
945     add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[2], 1);
946 }
947
948 static void
949 cmd_add_bond(struct vsctl_context *ctx)
950 {
951     add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[3], ctx->argc - 3);
952 }
953
954 static void
955 cmd_del_port(struct vsctl_context *ctx)
956 {
957     struct vsctl_info info;
958
959     get_info(ctx->ovs, &info);
960     if (ctx->argc == 2) {
961         struct vsctl_port *port = find_port(&info, ctx->argv[1], true);
962         del_port(&info, port);
963     } else if (ctx->argc == 3) {
964         struct vsctl_bridge *bridge = find_bridge(&info, ctx->argv[1], true);
965         struct vsctl_port *port = find_port(&info, ctx->argv[2], true);
966
967         if (port->bridge == bridge) {
968             del_port(&info, port);
969         } else if (port->bridge->parent == bridge) {
970             ovs_fatal(0, "bridge %s does not have a port %s (although its "
971                       "parent bridge %s does)",
972                       ctx->argv[1], ctx->argv[2], bridge->parent->name);
973         } else {
974             ovs_fatal(0, "bridge %s does not have a port %s",
975                       ctx->argv[1], ctx->argv[2]);
976         }
977     }
978     free_info(&info);
979 }
980
981 static void
982 cmd_port_to_br(struct vsctl_context *ctx)
983 {
984     struct vsctl_port *port;
985     struct vsctl_info info;
986
987     get_info(ctx->ovs, &info);
988     port = find_port(&info, ctx->argv[1], true);
989     ds_put_format(&ctx->output, "%s\n", port->bridge->name);
990     free_info(&info);
991 }
992
993 static void
994 cmd_port_set_external_id(struct vsctl_context *ctx)
995 {
996     struct vsctl_info info;
997     struct vsctl_port *port;
998     char **keys, **values;
999     size_t n;
1000
1001     get_info(ctx->ovs, &info);
1002     port = find_port(&info, ctx->argv[1], true);
1003     set_external_id(port->port_cfg->key_external_ids,
1004                     port->port_cfg->value_external_ids,
1005                     port->port_cfg->n_external_ids,
1006                     ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1007                     &keys, &values, &n);
1008     ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
1009     free(keys);
1010     free(values);
1011
1012     free_info(&info);
1013 }
1014
1015 static void
1016 cmd_port_get_external_id(struct vsctl_context *ctx)
1017 {
1018     struct vsctl_info info;
1019     struct vsctl_port *port;
1020
1021     get_info(ctx->ovs, &info);
1022     port = find_port(&info, ctx->argv[1], true);
1023     get_external_id(port->port_cfg->key_external_ids,
1024                     port->port_cfg->value_external_ids,
1025                     port->port_cfg->n_external_ids,
1026                     "",  ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1027     free_info(&info);
1028 }
1029
1030 static void
1031 cmd_br_to_vlan(struct vsctl_context *ctx)
1032 {
1033     struct vsctl_bridge *bridge;
1034     struct vsctl_info info;
1035
1036     get_info(ctx->ovs, &info);
1037     bridge = find_bridge(&info, ctx->argv[1], true);
1038     ds_put_format(&ctx->output, "%d\n", bridge->vlan);
1039     free_info(&info);
1040 }
1041
1042 static void
1043 cmd_br_to_parent(struct vsctl_context *ctx)
1044 {
1045     struct vsctl_bridge *bridge;
1046     struct vsctl_info info;
1047
1048     get_info(ctx->ovs, &info);
1049     bridge = find_bridge(&info, ctx->argv[1], true);
1050     if (bridge->parent) {
1051         bridge = bridge->parent;
1052     }
1053     ds_put_format(&ctx->output, "%s\n", bridge->name);
1054     free_info(&info);
1055 }
1056
1057 static void
1058 cmd_list_ifaces(struct vsctl_context *ctx)
1059 {
1060     struct vsctl_bridge *br;
1061     struct shash_node *node;
1062     struct vsctl_info info;
1063     struct svec ifaces;
1064
1065     get_info(ctx->ovs, &info);
1066     br = find_bridge(&info, ctx->argv[1], true);
1067
1068     svec_init(&ifaces);
1069     SHASH_FOR_EACH (node, &info.ifaces) {
1070         struct vsctl_iface *iface = node->data;
1071
1072         if (strcmp(iface->iface_cfg->name, br->name)
1073             && br == iface->port->bridge) {
1074             svec_add(&ifaces, iface->iface_cfg->name);
1075         }
1076     }
1077     output_sorted(&ifaces, &ctx->output);
1078     svec_destroy(&ifaces);
1079
1080     free_info(&info);
1081 }
1082
1083 static void
1084 cmd_iface_to_br(struct vsctl_context *ctx)
1085 {
1086     struct vsctl_iface *iface;
1087     struct vsctl_info info;
1088
1089     get_info(ctx->ovs, &info);
1090     iface = find_iface(&info, ctx->argv[1], true);
1091     ds_put_format(&ctx->output, "%s\n", iface->port->bridge->name);
1092     free_info(&info);
1093 }
1094
1095 static void
1096 cmd_iface_set_external_id(struct vsctl_context *ctx)
1097 {
1098     struct vsctl_info info;
1099     struct vsctl_iface *iface;
1100     char **keys, **values;
1101     size_t n;
1102
1103     get_info(ctx->ovs, &info);
1104     iface = find_iface(&info, ctx->argv[1], true);
1105     set_external_id(iface->iface_cfg->key_external_ids,
1106                     iface->iface_cfg->value_external_ids,
1107                     iface->iface_cfg->n_external_ids,
1108                     ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1109                     &keys, &values, &n);
1110     ovsrec_interface_set_external_ids(iface->iface_cfg, keys, values, n);
1111     free(keys);
1112     free(values);
1113
1114     free_info(&info);
1115 }
1116
1117 static void
1118 cmd_iface_get_external_id(struct vsctl_context *ctx)
1119 {
1120     struct vsctl_info info;
1121     struct vsctl_iface *iface;
1122
1123     get_info(ctx->ovs, &info);
1124     iface = find_iface(&info, ctx->argv[1], true);
1125     get_external_id(iface->iface_cfg->key_external_ids,
1126                     iface->iface_cfg->value_external_ids,
1127                     iface->iface_cfg->n_external_ids,
1128                     "",  ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1129     free_info(&info);
1130 }
1131 \f
1132 typedef void vsctl_handler_func(struct vsctl_context *);
1133
1134 struct vsctl_command {
1135     const char *name;
1136     int min_args;
1137     int max_args;
1138     vsctl_handler_func *handler;
1139     const char *options;
1140 };
1141
1142 static void run_vsctl_command(int argc, char *argv[],
1143                               const struct ovsrec_open_vswitch *ovs,
1144                               struct ds *output);
1145
1146 static void
1147 do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
1148 {
1149     struct ovsdb_idl_txn *txn;
1150     const struct ovsrec_open_vswitch *ovs;
1151     enum ovsdb_idl_txn_status status;
1152     struct ds *output;
1153     int n_output;
1154     int i, start;
1155
1156     ovs = ovsrec_open_vswitch_first(idl);
1157     if (!ovs) {
1158         /* XXX it would be more user-friendly to create a record ourselves
1159          * (while verifying that the table is empty before doing so). */
1160         ovs_fatal(0, "%s: database does not contain any Open vSwitch "
1161                   "configuration", db);
1162     }
1163
1164     txn = ovsdb_idl_txn_create(idl);
1165     output = xmalloc(argc * sizeof *output);
1166     n_output = 0;
1167     for (start = i = 0; i <= argc; i++) {
1168         if (i == argc || !strcmp(argv[i], "--")) {
1169             if (i > start) {
1170                 ds_init(&output[n_output]);
1171                 run_vsctl_command(i - start, &argv[start], ovs,
1172                                   &output[n_output++]);
1173             }
1174             start = i + 1;
1175         }
1176     }
1177
1178     while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
1179         ovsdb_idl_run(idl);
1180         ovsdb_idl_wait(idl);
1181         ovsdb_idl_txn_wait(txn);
1182         poll_block();
1183     }
1184     ovsdb_idl_txn_destroy(txn);
1185
1186     switch (status) {
1187     case TXN_INCOMPLETE:
1188         NOT_REACHED();
1189
1190     case TXN_ABORTED:
1191         /* Should not happen--we never call ovsdb_idl_txn_abort(). */
1192         ovs_fatal(0, "transaction aborted");
1193
1194     case TXN_SUCCESS:
1195         break;
1196
1197     case TXN_TRY_AGAIN:
1198         for (i = 0; i < n_output; i++) {
1199             ds_destroy(&output[i]);
1200         }
1201         return;
1202
1203     case TXN_ERROR:
1204         ovs_fatal(0, "transaction error");
1205
1206     default:
1207         NOT_REACHED();
1208     }
1209
1210     for (i = 0; i < n_output; i++) {
1211         struct ds *ds = &output[i];
1212         if (oneline) {
1213             size_t j;
1214
1215             ds_chomp(ds, '\n');
1216             for (j = 0; j < ds->length; j++) {
1217                 int c = ds->string[j];
1218                 switch (c) {
1219                 case '\n':
1220                     fputs("\\n", stdout);
1221                     break;
1222
1223                 case '\\':
1224                     fputs("\\\\", stdout);
1225                     break;
1226
1227                 default:
1228                     putchar(c);
1229                 }
1230             }
1231             putchar('\n');
1232         } else {
1233             fputs(ds_cstr(ds), stdout);
1234         }
1235     }
1236     exit(EXIT_SUCCESS);
1237 }
1238
1239 static vsctl_handler_func *
1240 get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx)
1241 {
1242     static const struct vsctl_command all_commands[] = {
1243         /* Bridge commands. */
1244         {"add-br", 1, 3, cmd_add_br, ""},
1245         {"del-br", 1, 1, cmd_del_br, ""},
1246         {"list-br", 0, 0, cmd_list_br, ""},
1247         {"br-exists", 1, 1, cmd_br_exists, ""},
1248         {"br-to-vlan", 1, 1, cmd_br_to_vlan, ""},
1249         {"br-to-parent", 1, 1, cmd_br_to_parent, ""},
1250         {"br-set-external-id", 2, 3, cmd_br_set_external_id, ""},
1251         {"br-get-external-id", 1, 2, cmd_br_get_external_id, ""},
1252
1253         /* Port commands. */
1254         {"list-ports", 1, 1, cmd_list_ports, ""},
1255         {"add-port", 2, 2, cmd_add_port, ""},
1256         {"add-bond", 4, INT_MAX, cmd_add_bond, ""},
1257         {"del-port", 1, 2, cmd_del_port, ""},
1258         {"port-to-br", 1, 1, cmd_port_to_br, ""},
1259         {"port-set-external-id", 2, 3, cmd_port_set_external_id, ""},
1260         {"port-get-external-id", 1, 2, cmd_port_get_external_id, ""},
1261
1262         /* Interface commands. */
1263         {"list-ifaces", 1, 1, cmd_list_ifaces, ""},
1264         {"iface-to-br", 1, 1, cmd_iface_to_br, ""},
1265         {"iface-set-external-id", 2, 3, cmd_iface_set_external_id, ""},
1266         {"iface-get-external-id", 1, 2, cmd_iface_get_external_id, ""},
1267     };
1268
1269     const struct vsctl_command *p;
1270     int i;
1271
1272     shash_init(&ctx->options);
1273     for (i = 0; i < argc; i++) {
1274         if (argv[i][0] != '-') {
1275             break;
1276         }
1277         if (!shash_add_once(&ctx->options, argv[i], NULL)) {
1278             ovs_fatal(0, "'%s' option specified multiple times", argv[i]);
1279         }
1280     }
1281     if (i == argc) {
1282         ovs_fatal(0, "missing command name");
1283     }
1284
1285     for (p = all_commands; p < &all_commands[ARRAY_SIZE(all_commands)]; p++) {
1286         if (!strcmp(p->name, argv[i])) {
1287             struct shash_node *node;
1288             int n_arg;
1289
1290             SHASH_FOR_EACH (node, &ctx->options) {
1291                 const char *s = strstr(p->options, node->name);
1292                 int end = s ? s[strlen(node->name)] : EOF;
1293                 if (end != ',' && end != ' ' && end != '\0') {
1294                     ovs_fatal(0, "'%s' command has no '%s' option",
1295                               argv[i], node->name);
1296                 }
1297             }
1298
1299             n_arg = argc - i - 1;
1300             if (n_arg < p->min_args) {
1301                 ovs_fatal(0, "'%s' command requires at least %d arguments",
1302                           p->name, p->min_args);
1303             } else if (n_arg > p->max_args) {
1304                 ovs_fatal(0, "'%s' command takes at most %d arguments",
1305                           p->name, p->max_args);
1306             } else {
1307                 ctx->argc = n_arg + 1;
1308                 ctx->argv = &argv[i];
1309                 return p->handler;
1310             }
1311         }
1312     }
1313
1314     ovs_fatal(0, "unknown command '%s'; use --help for help", argv[0]);
1315 }
1316
1317 static void
1318 check_vsctl_command(int argc, char *argv[])
1319 {
1320     struct vsctl_context ctx;
1321
1322     get_vsctl_handler(argc, argv, &ctx);
1323     shash_destroy(&ctx.options);
1324 }
1325
1326 static void
1327 run_vsctl_command(int argc, char *argv[],
1328                   const struct ovsrec_open_vswitch *ovs, struct ds *output)
1329 {
1330     vsctl_handler_func *function;
1331     struct vsctl_context ctx;
1332
1333     function = get_vsctl_handler(argc, argv, &ctx);
1334     ctx.ovs = ovs;
1335     ds_init(&ctx.output);
1336     function(&ctx);
1337     *output = ctx.output;
1338     shash_destroy(&ctx.options);
1339 }