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