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