2 * Copyright (c) 2009 Nicira Networks.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
28 #include "command-line.h"
31 #include "dynamic-string.h"
32 #include "ovsdb-idl.h"
33 #include "poll-loop.h"
35 #include "vswitchd/vswitch-idl.h"
40 #define THIS_MODULE VLM_vsctl
42 /* --db: The database server to contact. */
43 static const char *db;
45 /* --oneline: Write each command's output as a single line? */
48 static char *default_db(void);
49 static void usage(void) NO_RETURN;
50 static void parse_options(int argc, char *argv[]);
52 static void check_vsctl_command(int argc, char *argv[]);
53 static void do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl);
56 main(int argc, char *argv[])
58 struct ovsdb_idl *idl;
61 int start, n_commands;
65 set_program_name(argv[0]);
66 signal(SIGPIPE, SIG_IGN);
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);
73 /* Log our arguments. This is often valuable for debugging systems. */
75 for (i = 1; i < argc; i++) {
76 ds_put_format(&args, " %s", argv[i]);
78 VLOG_INFO("Called as%s", ds_cstr(&args));
81 /* Do basic command syntax checking. */
83 for (start = i = optind; i <= argc; i++) {
84 if (i == argc || !strcmp(argv[i], "--")) {
86 check_vsctl_command(i - start, &argv[start]);
93 ovs_fatal(0, "missing command name (use --help for help)");
96 /* Now execut the commands. */
97 idl = ovsdb_idl_create(db, &ovsrec_idl_class);
98 seqno = ovsdb_idl_get_seqno(idl);
101 unsigned int new_seqno;
104 new_seqno = ovsdb_idl_get_seqno(idl);
105 if (new_seqno != seqno) {
107 ovs_fatal(0, "too many database inconsistency failures");
109 do_vsctl(argc - optind, argv + optind, idl);
119 parse_options(int argc, char *argv[])
122 OPT_DB = UCHAR_MAX + 1,
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'},
139 c = getopt_long(argc, argv, "+v::hV", long_options, NULL);
154 vlog_set_levels(VLM_vsctl, VLF_SYSLOG, VLL_WARN);
161 OVS_PRINT_VERSION(0, 0);
165 vlog_set_verbosity(optarg);
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"
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"
193 "delete BRIDGE and all of its ports\n"
195 "print the names of all the bridges\n"
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 printf("\nPort commands:\n"
203 " list-ports BRIDGE "
204 "print the names of all the ports on BRIDGE\n"
205 " add-port BRIDGE PORT "
206 "add network device PORT to BRIDGE\n"
207 " add-bond BRIDGE PORT IFACE... "
208 "add new bonded port PORT in BRIDGE from IFACES\n"
209 " del-port [BRIDGE] PORT "
210 "delete PORT (which may be bonded) from BRIDGE\n"
212 "print name of bridge that contains PORT\n"
213 "A bond is considered to be a single port.\n");
214 printf("\nInterface commands (a bond consists of multiple interfaces):\n"
215 " list-ifaces BRIDGE "
216 "print the names of all the interfaces on BRIDGE\n"
217 " iface-to-br IFACE "
218 "print name of bridge that contains IFACE\n");
219 printf("\nOptions:\n"
221 "connect to DATABASE\n"
225 "print exactly one line of output per command\n",
228 printf("\nOther options:\n"
230 "display this help message\n"
232 "display version information\n");
241 def = xasprintf("unix:%s/ovsdb-server", ovs_rundir);
246 struct vsctl_bridge {
247 struct ovsrec_bridge *br_cfg;
249 struct vsctl_bridge *parent;
254 struct ovsrec_port *port_cfg;
255 struct vsctl_bridge *bridge;
259 struct ovsrec_interface *iface_cfg;
260 struct vsctl_port *port;
264 struct shash bridges;
269 static struct ovsdb_idl_txn *
270 txn_from_openvswitch(const struct ovsrec_open_vswitch *ovs)
272 return ovsdb_idl_txn_get(&ovs->header_);
275 static struct vsctl_bridge *
276 add_bridge(struct vsctl_info *b,
277 struct ovsrec_bridge *br_cfg, const char *name,
278 struct vsctl_bridge *parent, int vlan)
280 struct vsctl_bridge *br = xmalloc(sizeof *br);
282 br->name = xstrdup(name);
285 shash_add(&b->bridges, br->name, br);
290 port_is_fake_bridge(const struct ovsrec_port *port_cfg)
292 return (port_cfg->fake_bridge
294 && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095);
297 static struct vsctl_bridge *
298 find_vlan_bridge(struct vsctl_info *info,
299 struct vsctl_bridge *parent, int vlan)
301 struct shash_node *node;
303 SHASH_FOR_EACH (node, &info->bridges) {
304 struct vsctl_bridge *br = node->data;
305 if (br->parent == parent && br->vlan == vlan) {
314 free_info(struct vsctl_info *info)
316 struct shash_node *node;
318 SHASH_FOR_EACH (node, &info->bridges) {
319 struct vsctl_bridge *bridge = node->data;
323 shash_destroy(&info->bridges);
325 SHASH_FOR_EACH (node, &info->ports) {
326 struct vsctl_port *port = node->data;
329 shash_destroy(&info->ports);
331 SHASH_FOR_EACH (node, &info->ifaces) {
332 struct vsctl_iface *iface = node->data;
335 shash_destroy(&info->ifaces);
339 get_info(const struct ovsrec_open_vswitch *ovs, struct vsctl_info *info)
341 struct shash bridges, ports;
344 shash_init(&info->bridges);
345 shash_init(&info->ports);
346 shash_init(&info->ifaces);
348 shash_init(&bridges);
350 for (i = 0; i < ovs->n_bridges; i++) {
351 struct ovsrec_bridge *br_cfg = ovs->bridges[i];
352 struct vsctl_bridge *br;
355 if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
356 VLOG_WARN("%s: database contains duplicate bridge name",
360 br = add_bridge(info, br_cfg, br_cfg->name, NULL, 0);
365 for (j = 0; j < br_cfg->n_ports; j++) {
366 struct ovsrec_port *port_cfg = br_cfg->ports[j];
368 if (!shash_add_once(&ports, port_cfg->name, NULL)) {
369 VLOG_WARN("%s: database contains duplicate port name",
374 if (port_is_fake_bridge(port_cfg)
375 && shash_add_once(&bridges, port_cfg->name, NULL)) {
376 add_bridge(info, NULL, port_cfg->name, br, *port_cfg->tag);
380 shash_destroy(&bridges);
381 shash_destroy(&ports);
383 shash_init(&bridges);
385 for (i = 0; i < ovs->n_bridges; i++) {
386 struct ovsrec_bridge *br_cfg = ovs->bridges[i];
387 struct vsctl_bridge *br;
390 if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
393 br = shash_find_data(&info->bridges, br_cfg->name);
394 for (j = 0; j < br_cfg->n_ports; j++) {
395 struct ovsrec_port *port_cfg = br_cfg->ports[j];
396 struct vsctl_port *port;
399 if (!shash_add_once(&ports, port_cfg->name, NULL)) {
403 if (port_is_fake_bridge(port_cfg)
404 && !shash_add_once(&bridges, port_cfg->name, NULL)) {
408 port = xmalloc(sizeof *port);
409 port->port_cfg = port_cfg;
411 && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095) {
412 port->bridge = find_vlan_bridge(info, br, *port_cfg->tag);
419 shash_add(&info->ports, port_cfg->name, port);
421 for (k = 0; k < port_cfg->n_interfaces; k++) {
422 struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
423 struct vsctl_iface *iface;
425 if (shash_find(&info->ifaces, iface_cfg->name)) {
426 VLOG_WARN("%s: database contains duplicate interface name",
431 iface = xmalloc(sizeof *iface);
432 iface->iface_cfg = iface_cfg;
434 shash_add(&info->ifaces, iface_cfg->name, iface);
438 shash_destroy(&bridges);
439 shash_destroy(&ports);
443 check_conflicts(struct vsctl_info *info, const char *name,
446 struct vsctl_iface *iface;
447 struct vsctl_port *port;
449 if (shash_find(&info->bridges, name)) {
450 ovs_fatal(0, "%s because a bridge named %s already exists", msg, name);
453 port = shash_find_data(&info->ports, name);
455 ovs_fatal(0, "%s because a port named %s already exists on bridge %s",
456 msg, name, port->bridge->name);
459 iface = shash_find_data(&info->ifaces, name);
461 ovs_fatal(0, "%s because an interface named %s already exists "
462 "on bridge %s", msg, name, iface->port->bridge->name);
468 static struct vsctl_bridge *
469 find_bridge(struct vsctl_info *info, const char *name)
471 struct vsctl_bridge *br = shash_find_data(&info->bridges, name);
473 ovs_fatal(0, "no bridge named %s", name);
478 static struct vsctl_port *
479 find_port(struct vsctl_info *info, const char *name)
481 struct vsctl_port *port = shash_find_data(&info->ports, name);
482 if (!port || !strcmp(name, port->bridge->name)) {
483 ovs_fatal(0, "no port named %s", name);
488 static struct vsctl_iface *
489 find_iface(struct vsctl_info *info, const char *name)
491 struct vsctl_iface *iface = shash_find_data(&info->ifaces, name);
492 if (!iface || !strcmp(name, iface->port->bridge->name)) {
493 ovs_fatal(0, "no interface named %s", name);
499 bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
501 struct ovsrec_port **ports;
504 ports = xmalloc(sizeof *br->ports * (br->n_ports + 1));
505 for (i = 0; i < br->n_ports; i++) {
506 ports[i] = br->ports[i];
508 ports[br->n_ports] = port;
509 ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
514 bridge_delete_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
516 struct ovsrec_port **ports;
519 ports = xmalloc(sizeof *br->ports * br->n_ports);
520 for (i = n = 0; i < br->n_ports; i++) {
521 if (br->ports[i] != port) {
522 ports[n++] = br->ports[i];
525 ovsrec_bridge_set_ports(br, ports, n);
530 ovs_insert_bridge(const struct ovsrec_open_vswitch *ovs,
531 struct ovsrec_bridge *bridge)
533 struct ovsrec_bridge **bridges;
536 bridges = xmalloc(sizeof *ovs->bridges * (ovs->n_bridges + 1));
537 for (i = 0; i < ovs->n_bridges; i++) {
538 bridges[i] = ovs->bridges[i];
540 bridges[ovs->n_bridges] = bridge;
541 ovsrec_open_vswitch_set_bridges(ovs, bridges, ovs->n_bridges + 1);
546 ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
547 struct ovsrec_bridge *bridge)
549 struct ovsrec_bridge **bridges;
552 bridges = xmalloc(sizeof *ovs->bridges * ovs->n_bridges);
553 for (i = n = 0; i < ovs->n_bridges; i++) {
554 if (ovs->bridges[i] != bridge) {
555 bridges[n++] = ovs->bridges[i];
558 ovsrec_open_vswitch_set_bridges(ovs, bridges, n);
563 cmd_add_br(int argc, char *argv[], const struct ovsrec_open_vswitch *ovs,
564 struct ds *output UNUSED)
566 const char *br_name = argv[1];
567 struct vsctl_info info;
569 get_info(ovs, &info);
570 check_conflicts(&info, br_name,
571 xasprintf("cannot create a bridge named %s", br_name));
574 struct ovsrec_bridge *br;
575 struct ovsrec_port *port;
576 struct ovsrec_interface *iface;
578 iface = ovsrec_interface_insert(txn_from_openvswitch(ovs));
579 ovsrec_interface_set_name(iface, br_name);
581 port = ovsrec_port_insert(txn_from_openvswitch(ovs));
582 ovsrec_port_set_name(port, br_name);
583 ovsrec_port_set_interfaces(port, &iface, 1);
585 br = ovsrec_bridge_insert(txn_from_openvswitch(ovs));
586 ovsrec_bridge_set_name(br, br_name);
587 ovsrec_bridge_set_ports(br, &port, 1);
589 ovs_insert_bridge(ovs, br);
590 } else if (argc == 3) {
591 ovs_fatal(0, "'%s' comamnd takes exactly 1 or 3 arguments", argv[0]);
592 } else if (argc == 4) {
593 const char *parent_name = argv[2];
594 int vlan = atoi(argv[3]);
595 struct ovsrec_bridge *br;
596 struct vsctl_bridge *parent;
597 struct ovsrec_port *port;
598 struct ovsrec_interface *iface;
601 if (vlan < 1 || vlan > 4095) {
602 ovs_fatal(0, "%s: vlan must be between 1 and 4095", argv[0]);
605 parent = shash_find_data(&info.bridges, parent_name);
606 if (parent && parent->vlan) {
607 ovs_fatal(0, "cannot create brdige with fake bridge as parent");
610 ovs_fatal(0, "parent bridge %s does not exist", parent_name);
614 iface = ovsrec_interface_insert(txn_from_openvswitch(ovs));
615 ovsrec_interface_set_name(iface, br_name);
616 ovsrec_interface_set_type(iface, "internal");
618 port = ovsrec_port_insert(txn_from_openvswitch(ovs));
619 ovsrec_port_set_name(port, br_name);
620 ovsrec_port_set_interfaces(port, &iface, 1);
621 ovsrec_port_set_fake_bridge(port, true);
622 ovsrec_port_set_tag(port, &tag, 1);
624 bridge_insert_port(br, port);
633 del_port(struct vsctl_info *info, struct vsctl_port *port)
635 struct shash_node *node;
637 SHASH_FOR_EACH (node, &info->ifaces) {
638 struct vsctl_iface *iface = node->data;
639 if (iface->port == port) {
640 ovsrec_interface_delete(iface->iface_cfg);
643 ovsrec_port_delete(port->port_cfg);
645 bridge_delete_port((port->bridge->parent
646 ? port->bridge->parent->br_cfg
647 : port->bridge->br_cfg), port->port_cfg);
651 cmd_del_br(int argc UNUSED, char *argv[],
652 const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
654 struct shash_node *node;
655 struct vsctl_info info;
656 struct vsctl_bridge *bridge;
658 get_info(ovs, &info);
659 bridge = find_bridge(&info, argv[1]);
660 SHASH_FOR_EACH (node, &info.ports) {
661 struct vsctl_port *port = node->data;
662 if (port->bridge == bridge
663 || !strcmp(port->port_cfg->name, bridge->name)) {
664 del_port(&info, port);
667 if (bridge->br_cfg) {
668 ovsrec_bridge_delete(bridge->br_cfg);
669 ovs_delete_bridge(ovs, bridge->br_cfg);
675 output_sorted(struct svec *svec, struct ds *output)
681 SVEC_FOR_EACH (i, name, svec) {
682 ds_put_format(output, "%s\n", name);
687 cmd_list_br(int argc UNUSED, char *argv[] UNUSED,
688 const struct ovsrec_open_vswitch *ovs, struct ds *output)
690 struct shash_node *node;
691 struct vsctl_info info;
694 get_info(ovs, &info);
697 SHASH_FOR_EACH (node, &info.bridges) {
698 struct vsctl_bridge *br = node->data;
699 svec_add(&bridges, br->name);
701 output_sorted(&bridges, output);
702 svec_destroy(&bridges);
708 cmd_br_exists(int argc UNUSED, char *argv[],
709 const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
711 struct vsctl_info info;
713 get_info(ovs, &info);
714 if (!shash_find_data(&info.bridges, argv[1])) {
721 cmd_list_ports(int argc UNUSED, char *argv[],
722 const struct ovsrec_open_vswitch *ovs, struct ds *output)
724 struct vsctl_bridge *br;
725 struct shash_node *node;
726 struct vsctl_info info;
729 get_info(ovs, &info);
730 br = find_bridge(&info, argv[1]);
733 SHASH_FOR_EACH (node, &info.ports) {
734 struct vsctl_port *port = node->data;
736 if (strcmp(port->port_cfg->name, br->name) && br == port->bridge) {
737 svec_add(&ports, port->port_cfg->name);
740 output_sorted(&ports, output);
741 svec_destroy(&ports);
747 add_port(const struct ovsrec_open_vswitch *ovs,
748 const char *br_name, const char *port_name,
749 char *iface_names[], int n_ifaces)
751 struct vsctl_info info;
752 struct vsctl_bridge *bridge;
753 struct ovsrec_interface **ifaces;
754 struct ovsrec_port *port;
757 get_info(ovs, &info);
758 check_conflicts(&info, port_name,
759 xasprintf("cannot create a port named %s", port_name));
760 /* XXX need to check for conflicts on interfaces too */
761 bridge = find_bridge(&info, br_name);
763 ifaces = xmalloc(n_ifaces * sizeof *ifaces);
764 for (i = 0; i < n_ifaces; i++) {
765 ifaces[i] = ovsrec_interface_insert(txn_from_openvswitch(ovs));
766 ovsrec_interface_set_name(ifaces[i], iface_names[i]);
769 port = ovsrec_port_insert(txn_from_openvswitch(ovs));
770 ovsrec_port_set_name(port, port_name);
771 ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
773 int64_t tag = bridge->vlan;
774 ovsrec_port_set_tag(port, &tag, 1);
777 bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
778 : bridge->br_cfg), port);
784 cmd_add_port(int argc UNUSED, char *argv[],
785 const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
787 add_port(ovs, argv[1], argv[2], &argv[2], 1);
791 cmd_add_bond(int argc, char *argv[],
792 const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
794 add_port(ovs, argv[1], argv[2], &argv[3], argc - 3);
798 cmd_del_port(int argc, char *argv[],
799 const struct ovsrec_open_vswitch *ovs, struct ds *output UNUSED)
801 struct vsctl_info info;
803 get_info(ovs, &info);
805 struct vsctl_port *port = find_port(&info, argv[1]);
806 del_port(&info, port);
807 } else if (argc == 3) {
808 struct vsctl_bridge *bridge = find_bridge(&info, argv[1]);
809 struct vsctl_port *port = find_port(&info, argv[2]);
811 if (port->bridge == bridge) {
812 del_port(&info, port);
813 } else if (port->bridge->parent == bridge) {
814 ovs_fatal(0, "bridge %s does not have a port %s (although its "
815 "parent bridge %s does)",
816 argv[1], argv[2], bridge->parent->name);
818 ovs_fatal(0, "bridge %s does not have a port %s",
826 cmd_port_to_br(int argc UNUSED, char *argv[],
827 const struct ovsrec_open_vswitch *ovs, struct ds *output)
829 struct vsctl_port *port;
830 struct vsctl_info info;
832 get_info(ovs, &info);
833 port = find_port(&info, argv[1]);
834 ds_put_format(output, "%s\n", port->bridge->name);
839 cmd_br_to_vlan(int argc UNUSED, char *argv[],
840 const struct ovsrec_open_vswitch *ovs, struct ds *output)
842 struct vsctl_bridge *bridge;
843 struct vsctl_info info;
845 get_info(ovs, &info);
846 bridge = find_bridge(&info, argv[1]);
847 ds_put_format(output, "%d\n", bridge->vlan);
852 cmd_br_to_parent(int argc UNUSED, char *argv[],
853 const struct ovsrec_open_vswitch *ovs, struct ds *output)
855 struct vsctl_bridge *bridge;
856 struct vsctl_info info;
858 get_info(ovs, &info);
859 bridge = find_bridge(&info, argv[1]);
860 if (bridge->parent) {
861 bridge = bridge->parent;
863 ds_put_format(output, "%s\n", bridge->name);
868 cmd_list_ifaces(int argc UNUSED, char *argv[],
869 const struct ovsrec_open_vswitch *ovs, struct ds *output)
871 struct vsctl_bridge *br;
872 struct shash_node *node;
873 struct vsctl_info info;
876 get_info(ovs, &info);
877 br = find_bridge(&info, argv[1]);
880 SHASH_FOR_EACH (node, &info.ifaces) {
881 struct vsctl_iface *iface = node->data;
883 if (strcmp(iface->iface_cfg->name, br->name)
884 && br == iface->port->bridge) {
885 svec_add(&ifaces, iface->iface_cfg->name);
888 output_sorted(&ifaces, output);
889 svec_destroy(&ifaces);
895 cmd_iface_to_br(int argc UNUSED, char *argv[],
896 const struct ovsrec_open_vswitch *ovs, struct ds *output)
898 struct vsctl_iface *iface;
899 struct vsctl_info info;
901 get_info(ovs, &info);
902 iface = find_iface(&info, argv[1]);
903 ds_put_format(output, "%s\n", iface->port->bridge->name);
907 typedef void vsctl_handler_func(int argc, char *argv[],
908 const struct ovsrec_open_vswitch *,
911 struct vsctl_command {
915 vsctl_handler_func *handler;
918 static void run_vsctl_command(int argc, char *argv[],
919 const struct ovsrec_open_vswitch *ovs,
923 do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
925 struct ovsdb_idl_txn *txn;
926 const struct ovsrec_open_vswitch *ovs;
927 enum ovsdb_idl_txn_status status;
932 ovs = ovsrec_open_vswitch_first(idl);
934 /* XXX it would be more user-friendly to create a record ourselves
935 * (while verifying that the table is empty before doing so). */
936 ovs_fatal(0, "%s: database does not contain any Open vSwitch "
937 "configuration", db);
940 txn = ovsdb_idl_txn_create(idl);
941 output = xmalloc(argc * sizeof *output);
943 for (start = i = 0; i <= argc; i++) {
944 if (i == argc || !strcmp(argv[i], "--")) {
946 ds_init(&output[n_output]);
947 run_vsctl_command(i - start, &argv[start], ovs,
948 &output[n_output++]);
954 while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
959 ovsdb_idl_txn_destroy(txn);
966 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
967 ovs_fatal(0, "transaction aborted");
973 for (i = 0; i < n_output; i++) {
974 ds_destroy(&output[i]);
979 ovs_fatal(0, "transaction error");
985 for (i = 0; i < n_output; i++) {
986 struct ds *ds = &output[i];
991 for (j = 0; j < ds->length; j++) {
992 int c = ds->string[j];
995 fputs("\\n", stdout);
999 fputs("\\\\", stdout);
1008 fputs(ds_cstr(ds), stdout);
1014 static vsctl_handler_func *
1015 get_vsctl_handler(int argc, char *argv[])
1017 static const struct vsctl_command all_commands[] = {
1018 {"add-br", 1, 3, cmd_add_br},
1019 {"del-br", 1, 1, cmd_del_br},
1020 {"list-br", 0, 0, cmd_list_br},
1021 {"br-exists", 1, 1, cmd_br_exists},
1022 {"list-ports", 1, 1, cmd_list_ports},
1023 {"add-port", 2, 2, cmd_add_port},
1024 {"add-bond", 4, INT_MAX, cmd_add_bond},
1025 {"del-port", 1, 2, cmd_del_port},
1026 {"port-to-br", 1, 1, cmd_port_to_br},
1027 {"br-to-vlan", 1, 1, cmd_br_to_vlan},
1028 {"br-to-parent", 1, 1, cmd_br_to_parent},
1029 {"list-ifaces", 1, 1, cmd_list_ifaces},
1030 {"iface-to-br", 1, 1, cmd_iface_to_br},
1033 const struct vsctl_command *p;
1036 for (p = all_commands; p < &all_commands[ARRAY_SIZE(all_commands)]; p++) {
1037 if (!strcmp(p->name, argv[0])) {
1038 int n_arg = argc - 1;
1039 if (n_arg < p->min_args) {
1040 ovs_fatal(0, "'%s' command requires at least %d arguments",
1041 p->name, p->min_args);
1042 } else if (n_arg > p->max_args) {
1043 ovs_fatal(0, "'%s' command takes at most %d arguments",
1044 p->name, p->max_args);
1051 ovs_fatal(0, "unknown command '%s'; use --help for help", argv[0]);
1055 check_vsctl_command(int argc, char *argv[])
1057 get_vsctl_handler(argc, argv);
1061 run_vsctl_command(int argc, char *argv[],
1062 const struct ovsrec_open_vswitch *ovs, struct ds *output)
1064 get_vsctl_handler(argc, argv)(argc, argv, ovs, output);