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"
33 #include "ovsdb-idl.h"
34 #include "poll-loop.h"
36 #include "vswitchd/vswitch-idl.h"
41 #define THIS_MODULE VLM_vsctl
43 /* --db: The database server to contact. */
44 static const char *db;
46 /* --oneline: Write each command's output as a single line? */
49 /* --dry-run: Do not commit any changes. */
52 /* --no-wait: Wait for ovs-vswitchd to reload its configuration? */
53 static bool wait_for_reload = true;
55 /* --timeout: Time to wait for a connection to 'db'. */
56 static int timeout = 5;
58 static void vsctl_fatal(const char *, ...) PRINTF_FORMAT(1, 2) NO_RETURN;
59 static char *default_db(void);
60 static void usage(void) NO_RETURN;
61 static void parse_options(int argc, char *argv[]);
63 static void check_vsctl_command(int argc, char *argv[]);
64 static void do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl);
67 main(int argc, char *argv[])
69 struct ovsdb_idl *idl;
72 int start, n_commands;
76 set_program_name(argv[0]);
77 signal(SIGPIPE, SIG_IGN);
80 vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_WARN);
81 vlog_set_levels(VLM_reconnect, VLF_ANY_FACILITY, VLL_WARN);
82 parse_options(argc, argv);
88 /* Log our arguments. This is often valuable for debugging systems. */
90 for (i = 1; i < argc; i++) {
91 ds_put_format(&args, " %s", argv[i]);
93 VLOG_INFO("Called as%s", ds_cstr(&args));
96 /* Do basic command syntax checking. */
98 for (start = i = optind; i <= argc; i++) {
99 if (i == argc || !strcmp(argv[i], "--")) {
101 check_vsctl_command(i - start, &argv[start]);
108 vsctl_fatal("missing command name (use --help for help)");
111 /* Now execute the commands. */
112 idl = ovsdb_idl_create(db, &ovsrec_idl_class);
113 seqno = ovsdb_idl_get_seqno(idl);
116 unsigned int new_seqno;
119 new_seqno = ovsdb_idl_get_seqno(idl);
120 if (new_seqno != seqno) {
122 vsctl_fatal("too many database inconsistency failures");
124 do_vsctl(argc - optind, argv + optind, idl);
134 vsctl_fatal(const char *format, ...)
139 va_start(args, format);
140 message = xvasprintf(format, args);
143 vlog_set_levels(VLM_vsctl, VLF_CONSOLE, VLL_EMER);
144 VLOG_ERR("%s", message);
145 ovs_fatal(0, "%s", message);
149 parse_options(int argc, char *argv[])
152 OPT_DB = UCHAR_MAX + 1,
158 static struct option long_options[] = {
159 {"db", required_argument, 0, OPT_DB},
160 {"no-syslog", no_argument, 0, OPT_NO_SYSLOG},
161 {"no-wait", no_argument, 0, OPT_NO_WAIT},
162 {"dry-run", no_argument, 0, OPT_DRY_RUN},
163 {"oneline", no_argument, 0, OPT_ONELINE},
164 {"timeout", required_argument, 0, 't'},
165 {"verbose", optional_argument, 0, 'v'},
166 {"help", no_argument, 0, 'h'},
167 {"version", no_argument, 0, 'V'},
173 unsigned long int timeout;
176 c = getopt_long(argc, argv, "+v::hVt:", long_options, NULL);
191 vlog_set_levels(VLM_vsctl, VLF_SYSLOG, VLL_WARN);
195 wait_for_reload = false;
206 OVS_PRINT_VERSION(0, 0);
210 timeout = strtoul(optarg, NULL, 10);
212 ovs_fatal(0, "value %s on -t or --timeout is invalid",
218 vlog_set_verbosity(optarg);
237 printf("%s: ovs-vswitchd management utility\n"
238 "usage: %s [OPTIONS] COMMAND [ARG...]\n",
239 program_name, program_name);
240 printf("\nBridge commands:\n"
242 "create a new bridge named BRIDGE\n"
243 " add-br BRIDGE PARENT VLAN "
244 "create new fake bridge BRIDGE in PARENT on VLAN\n"
246 "delete BRIDGE and all of its ports\n"
248 "print the names of all the bridges\n"
250 "test whether BRIDGE exists\n"
251 " br-to-vlan BRIDGE "
252 "print the VLAN which BRIDGE is on\n"
253 " br-to-parent BRIDGE "
254 "print the parent of BRIDGE\n"
255 " br-set-external-id BRIDGE KEY VALUE"
256 " set KEY on BRIDGE to VALUE\n"
257 " br-set-external-id BRIDGE KEY"
258 " unset KEY on BRIDGE\n"
259 " br-get-external-id BRIDGE KEY"
260 " print value of KEY on BRIDGE\n"
261 " br-get-external-id BRIDGE"
262 " list key-value pairs on BRIDGE\n"
264 printf("\nPort commands:\n"
265 " list-ports BRIDGE "
266 "print the names of all the ports on BRIDGE\n"
267 " add-port BRIDGE PORT "
268 "add network device PORT to BRIDGE\n"
269 " add-bond BRIDGE PORT IFACE... "
270 "add new bonded port PORT in BRIDGE from IFACES\n"
271 " del-port [BRIDGE] PORT "
272 "delete PORT (which may be bonded) from BRIDGE\n"
274 "print name of bridge that contains PORT\n"
275 " port-set-external-id PORT KEY VALUE"
276 " set KEY on PORT to VALUE\n"
277 " port-set-external-id PORT KEY"
278 " unset KEY on PORT\n"
279 " port-get-external-id PORT KEY"
280 " print value of KEY on PORT\n"
281 " port-get-external-id PORT"
282 " list key-value pairs on PORT\n"
283 "A bond is considered to be a single port.\n"
285 printf("\nInterface commands (a bond consists of multiple interfaces):\n"
286 " list-ifaces BRIDGE "
287 "print the names of all the interfaces on BRIDGE\n"
288 " iface-to-br IFACE "
289 "print name of bridge that contains IFACE\n"
290 " iface-set-external-id IFACE KEY VALUE"
291 " set KEY on IFACE to VALUE\n"
292 " iface-set-external-id IFACE KEY"
293 " unset KEY on IFACE\n"
294 " iface-get-external-id IFACE KEY"
295 " print value of KEY on IFACE\n"
296 " iface-get-external-id IFACE"
297 " list key-value pairs on IFACE\n"
299 printf("\nController commands:\n"
300 " get-controller [BRIDGE] "
301 "print the controller for BRIDGE\n"
302 " del-controller [BRIDGE] "
303 "delete the controller for BRIDGE\n"
304 " set-controller [BRIDGE] TARGET "
305 "set the controller for BRIDGE to TARGET\n"
306 " get-fail-mode [BRIDGE] "
307 "print the fail-mode for BRIDGE\n"
308 " del-fail-mode [BRIDGE] "
309 "delete the fail-mode for BRIDGE\n"
310 " set-fail-mode [BRIDGE] MODE "
311 "set the fail-mode for BRIDGE to MODE\n"
313 printf("\nOptions:\n"
315 "connect to DATABASE\n"
319 "print exactly one line of output per command\n",
322 printf("\nOther options:\n"
324 "display this help message\n"
326 "display version information\n");
335 def = xasprintf("unix:%s/ovsdb-server", ovs_rundir);
340 struct vsctl_context {
343 const struct ovsrec_open_vswitch *ovs;
345 struct shash options;
348 struct vsctl_bridge {
349 struct ovsrec_bridge *br_cfg;
351 struct ovsrec_controller *ctrl;
352 struct vsctl_bridge *parent;
357 struct ovsrec_port *port_cfg;
358 struct vsctl_bridge *bridge;
362 struct ovsrec_interface *iface_cfg;
363 struct vsctl_port *port;
367 struct shash bridges;
370 struct ovsrec_controller *ctrl;
373 static struct ovsdb_idl_txn *
374 txn_from_openvswitch(const struct ovsrec_open_vswitch *ovs)
376 return ovsdb_idl_txn_get(&ovs->header_);
379 static struct vsctl_bridge *
380 add_bridge(struct vsctl_info *b,
381 struct ovsrec_bridge *br_cfg, const char *name,
382 struct vsctl_bridge *parent, int vlan)
384 struct vsctl_bridge *br = xmalloc(sizeof *br);
386 br->name = xstrdup(name);
389 br->ctrl = parent ? parent->br_cfg->controller : br_cfg->controller;
390 shash_add(&b->bridges, br->name, br);
395 port_is_fake_bridge(const struct ovsrec_port *port_cfg)
397 return (port_cfg->fake_bridge
399 && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095);
402 static struct vsctl_bridge *
403 find_vlan_bridge(struct vsctl_info *info,
404 struct vsctl_bridge *parent, int vlan)
406 struct shash_node *node;
408 SHASH_FOR_EACH (node, &info->bridges) {
409 struct vsctl_bridge *br = node->data;
410 if (br->parent == parent && br->vlan == vlan) {
419 free_info(struct vsctl_info *info)
421 struct shash_node *node;
423 SHASH_FOR_EACH (node, &info->bridges) {
424 struct vsctl_bridge *bridge = node->data;
428 shash_destroy(&info->bridges);
430 SHASH_FOR_EACH (node, &info->ports) {
431 struct vsctl_port *port = node->data;
434 shash_destroy(&info->ports);
436 SHASH_FOR_EACH (node, &info->ifaces) {
437 struct vsctl_iface *iface = node->data;
440 shash_destroy(&info->ifaces);
444 get_info(const struct ovsrec_open_vswitch *ovs, struct vsctl_info *info)
446 struct shash bridges, ports;
449 shash_init(&info->bridges);
450 shash_init(&info->ports);
451 shash_init(&info->ifaces);
453 info->ctrl = ovs->controller;
455 shash_init(&bridges);
457 for (i = 0; i < ovs->n_bridges; i++) {
458 struct ovsrec_bridge *br_cfg = ovs->bridges[i];
459 struct vsctl_bridge *br;
462 if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
463 VLOG_WARN("%s: database contains duplicate bridge name",
467 br = add_bridge(info, br_cfg, br_cfg->name, NULL, 0);
472 for (j = 0; j < br_cfg->n_ports; j++) {
473 struct ovsrec_port *port_cfg = br_cfg->ports[j];
475 if (!shash_add_once(&ports, port_cfg->name, NULL)) {
476 VLOG_WARN("%s: database contains duplicate port name",
481 if (port_is_fake_bridge(port_cfg)
482 && shash_add_once(&bridges, port_cfg->name, NULL)) {
483 add_bridge(info, NULL, port_cfg->name, br, *port_cfg->tag);
487 shash_destroy(&bridges);
488 shash_destroy(&ports);
490 shash_init(&bridges);
492 for (i = 0; i < ovs->n_bridges; i++) {
493 struct ovsrec_bridge *br_cfg = ovs->bridges[i];
494 struct vsctl_bridge *br;
497 if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
500 br = shash_find_data(&info->bridges, br_cfg->name);
501 for (j = 0; j < br_cfg->n_ports; j++) {
502 struct ovsrec_port *port_cfg = br_cfg->ports[j];
503 struct vsctl_port *port;
506 if (!shash_add_once(&ports, port_cfg->name, NULL)) {
510 if (port_is_fake_bridge(port_cfg)
511 && !shash_add_once(&bridges, port_cfg->name, NULL)) {
515 port = xmalloc(sizeof *port);
516 port->port_cfg = port_cfg;
518 && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095) {
519 port->bridge = find_vlan_bridge(info, br, *port_cfg->tag);
526 shash_add(&info->ports, port_cfg->name, port);
528 for (k = 0; k < port_cfg->n_interfaces; k++) {
529 struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
530 struct vsctl_iface *iface;
532 if (shash_find(&info->ifaces, iface_cfg->name)) {
533 VLOG_WARN("%s: database contains duplicate interface name",
538 iface = xmalloc(sizeof *iface);
539 iface->iface_cfg = iface_cfg;
541 shash_add(&info->ifaces, iface_cfg->name, iface);
545 shash_destroy(&bridges);
546 shash_destroy(&ports);
550 check_conflicts(struct vsctl_info *info, const char *name,
553 struct vsctl_iface *iface;
554 struct vsctl_port *port;
556 if (shash_find(&info->bridges, name)) {
557 vsctl_fatal("%s because a bridge named %s already exists",
561 port = shash_find_data(&info->ports, name);
563 vsctl_fatal("%s because a port named %s already exists on "
564 "bridge %s", msg, name, port->bridge->name);
567 iface = shash_find_data(&info->ifaces, name);
569 vsctl_fatal("%s because an interface named %s already exists "
570 "on bridge %s", msg, name, iface->port->bridge->name);
576 static struct vsctl_bridge *
577 find_bridge(struct vsctl_info *info, const char *name, bool must_exist)
579 struct vsctl_bridge *br = shash_find_data(&info->bridges, name);
580 if (must_exist && !br) {
581 vsctl_fatal("no bridge named %s", name);
586 static struct vsctl_bridge *
587 find_real_bridge(struct vsctl_info *info, const char *name, bool must_exist)
589 struct vsctl_bridge *br = find_bridge(info, name, must_exist);
590 if (br && br->parent) {
591 vsctl_fatal("%s is a fake bridge", name);
596 static struct vsctl_port *
597 find_port(struct vsctl_info *info, const char *name, bool must_exist)
599 struct vsctl_port *port = shash_find_data(&info->ports, name);
600 if (port && !strcmp(name, port->bridge->name)) {
603 if (must_exist && !port) {
604 vsctl_fatal("no port named %s", name);
609 static struct vsctl_iface *
610 find_iface(struct vsctl_info *info, const char *name, bool must_exist)
612 struct vsctl_iface *iface = shash_find_data(&info->ifaces, name);
613 if (iface && !strcmp(name, iface->port->bridge->name)) {
616 if (must_exist && !iface) {
617 vsctl_fatal("no interface named %s", name);
623 bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
625 struct ovsrec_port **ports;
628 ports = xmalloc(sizeof *br->ports * (br->n_ports + 1));
629 for (i = 0; i < br->n_ports; i++) {
630 ports[i] = br->ports[i];
632 ports[br->n_ports] = port;
633 ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
638 bridge_delete_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
640 struct ovsrec_port **ports;
643 ports = xmalloc(sizeof *br->ports * br->n_ports);
644 for (i = n = 0; i < br->n_ports; i++) {
645 if (br->ports[i] != port) {
646 ports[n++] = br->ports[i];
649 ovsrec_bridge_set_ports(br, ports, n);
654 ovs_insert_bridge(const struct ovsrec_open_vswitch *ovs,
655 struct ovsrec_bridge *bridge)
657 struct ovsrec_bridge **bridges;
660 bridges = xmalloc(sizeof *ovs->bridges * (ovs->n_bridges + 1));
661 for (i = 0; i < ovs->n_bridges; i++) {
662 bridges[i] = ovs->bridges[i];
664 bridges[ovs->n_bridges] = bridge;
665 ovsrec_open_vswitch_set_bridges(ovs, bridges, ovs->n_bridges + 1);
670 ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
671 struct ovsrec_bridge *bridge)
673 struct ovsrec_bridge **bridges;
676 bridges = xmalloc(sizeof *ovs->bridges * ovs->n_bridges);
677 for (i = n = 0; i < ovs->n_bridges; i++) {
678 if (ovs->bridges[i] != bridge) {
679 bridges[n++] = ovs->bridges[i];
682 ovsrec_open_vswitch_set_bridges(ovs, bridges, n);
687 cmd_init(struct vsctl_context *ctx UNUSED)
692 cmd_add_br(struct vsctl_context *ctx)
694 const char *br_name = ctx->argv[1];
695 struct vsctl_info info;
697 get_info(ctx->ovs, &info);
698 check_conflicts(&info, br_name,
699 xasprintf("cannot create a bridge named %s", br_name));
701 if (ctx->argc == 2) {
702 struct ovsrec_bridge *br;
703 struct ovsrec_port *port;
704 struct ovsrec_interface *iface;
706 iface = ovsrec_interface_insert(txn_from_openvswitch(ctx->ovs));
707 ovsrec_interface_set_name(iface, br_name);
709 port = ovsrec_port_insert(txn_from_openvswitch(ctx->ovs));
710 ovsrec_port_set_name(port, br_name);
711 ovsrec_port_set_interfaces(port, &iface, 1);
713 br = ovsrec_bridge_insert(txn_from_openvswitch(ctx->ovs));
714 ovsrec_bridge_set_name(br, br_name);
715 ovsrec_bridge_set_ports(br, &port, 1);
717 ovs_insert_bridge(ctx->ovs, br);
718 } else if (ctx->argc == 3) {
719 vsctl_fatal("'%s' command takes exactly 1 or 3 arguments",
721 } else if (ctx->argc == 4) {
722 const char *parent_name = ctx->argv[2];
723 int vlan = atoi(ctx->argv[3]);
724 struct ovsrec_bridge *br;
725 struct vsctl_bridge *parent;
726 struct ovsrec_port *port;
727 struct ovsrec_interface *iface;
730 if (vlan < 1 || vlan > 4095) {
731 vsctl_fatal("%s: vlan must be between 1 and 4095", ctx->argv[0]);
734 parent = find_bridge(&info, parent_name, false);
735 if (parent && parent->vlan) {
736 vsctl_fatal("cannot create bridge with fake bridge as parent");
739 vsctl_fatal("parent bridge %s does not exist", parent_name);
743 iface = ovsrec_interface_insert(txn_from_openvswitch(ctx->ovs));
744 ovsrec_interface_set_name(iface, br_name);
745 ovsrec_interface_set_type(iface, "internal");
747 port = ovsrec_port_insert(txn_from_openvswitch(ctx->ovs));
748 ovsrec_port_set_name(port, br_name);
749 ovsrec_port_set_interfaces(port, &iface, 1);
750 ovsrec_port_set_fake_bridge(port, true);
751 ovsrec_port_set_tag(port, &tag, 1);
753 bridge_insert_port(br, port);
762 del_port(struct vsctl_info *info, struct vsctl_port *port)
764 struct shash_node *node;
766 SHASH_FOR_EACH (node, &info->ifaces) {
767 struct vsctl_iface *iface = node->data;
768 if (iface->port == port) {
769 ovsrec_interface_delete(iface->iface_cfg);
772 ovsrec_port_delete(port->port_cfg);
774 bridge_delete_port((port->bridge->parent
775 ? port->bridge->parent->br_cfg
776 : port->bridge->br_cfg), port->port_cfg);
780 cmd_del_br(struct vsctl_context *ctx)
782 bool must_exist = !shash_find(&ctx->options, "--if-exists");
783 struct vsctl_bridge *bridge;
784 struct vsctl_info info;
786 get_info(ctx->ovs, &info);
787 bridge = find_bridge(&info, ctx->argv[1], must_exist);
789 struct shash_node *node;
791 SHASH_FOR_EACH (node, &info.ports) {
792 struct vsctl_port *port = node->data;
793 if (port->bridge == bridge
794 || !strcmp(port->port_cfg->name, bridge->name)) {
795 del_port(&info, port);
798 if (bridge->br_cfg) {
799 ovsrec_bridge_delete(bridge->br_cfg);
800 ovs_delete_bridge(ctx->ovs, bridge->br_cfg);
807 output_sorted(struct svec *svec, struct ds *output)
813 SVEC_FOR_EACH (i, name, svec) {
814 ds_put_format(output, "%s\n", name);
819 cmd_list_br(struct vsctl_context *ctx)
821 struct shash_node *node;
822 struct vsctl_info info;
825 get_info(ctx->ovs, &info);
828 SHASH_FOR_EACH (node, &info.bridges) {
829 struct vsctl_bridge *br = node->data;
830 svec_add(&bridges, br->name);
832 output_sorted(&bridges, &ctx->output);
833 svec_destroy(&bridges);
839 cmd_br_exists(struct vsctl_context *ctx)
841 struct vsctl_info info;
843 get_info(ctx->ovs, &info);
844 if (!find_bridge(&info, ctx->argv[1], false)) {
850 /* Returns true if 'b_prefix' (of length 'b_prefix_len') concatenated with 'b'
851 * equals 'a', false otherwise. */
853 key_matches(const char *a,
854 const char *b_prefix, size_t b_prefix_len, const char *b)
856 return !strncmp(a, b_prefix, b_prefix_len) && !strcmp(a + b_prefix_len, b);
860 set_external_id(char **old_keys, char **old_values, size_t old_n,
861 char *key, char *value,
862 char ***new_keysp, char ***new_valuesp, size_t *new_np)
869 new_keys = xmalloc(sizeof *new_keys * (old_n + 1));
870 new_values = xmalloc(sizeof *new_values * (old_n + 1));
872 for (i = 0; i < old_n; i++) {
873 if (strcmp(key, old_keys[i])) {
874 new_keys[new_n] = old_keys[i];
875 new_values[new_n] = old_values[i];
880 new_keys[new_n] = key;
881 new_values[new_n] = value;
884 *new_keysp = new_keys;
885 *new_valuesp = new_values;
890 cmd_br_set_external_id(struct vsctl_context *ctx)
892 struct vsctl_info info;
893 struct vsctl_bridge *bridge;
894 char **keys, **values;
897 get_info(ctx->ovs, &info);
898 bridge = find_bridge(&info, ctx->argv[1], true);
899 if (bridge->br_cfg) {
900 set_external_id(bridge->br_cfg->key_external_ids,
901 bridge->br_cfg->value_external_ids,
902 bridge->br_cfg->n_external_ids,
903 ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
905 ovsrec_bridge_set_external_ids(bridge->br_cfg, keys, values, n);
907 char *key = xasprintf("fake-bridge-%s", ctx->argv[2]);
908 struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
909 set_external_id(port->port_cfg->key_external_ids,
910 port->port_cfg->value_external_ids,
911 port->port_cfg->n_external_ids,
912 key, ctx->argc >= 4 ? ctx->argv[3] : NULL,
914 ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
924 get_external_id(char **keys, char **values, size_t n,
925 const char *prefix, const char *key,
928 size_t prefix_len = strlen(prefix);
933 for (i = 0; i < n; i++) {
934 if (!key && !strncmp(keys[i], prefix, prefix_len)) {
935 svec_add_nocopy(&svec, xasprintf("%s=%s",
936 keys[i] + prefix_len, values[i]));
937 } else if (key_matches(keys[i], prefix, prefix_len, key)) {
938 svec_add(&svec, values[i]);
942 output_sorted(&svec, output);
947 cmd_br_get_external_id(struct vsctl_context *ctx)
949 struct vsctl_info info;
950 struct vsctl_bridge *bridge;
952 get_info(ctx->ovs, &info);
953 bridge = find_bridge(&info, ctx->argv[1], true);
954 if (bridge->br_cfg) {
955 get_external_id(bridge->br_cfg->key_external_ids,
956 bridge->br_cfg->value_external_ids,
957 bridge->br_cfg->n_external_ids,
958 "", ctx->argc >= 3 ? ctx->argv[2] : NULL,
961 struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
962 get_external_id(port->port_cfg->key_external_ids,
963 port->port_cfg->value_external_ids,
964 port->port_cfg->n_external_ids,
965 "fake-bridge-", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
972 cmd_list_ports(struct vsctl_context *ctx)
974 struct vsctl_bridge *br;
975 struct shash_node *node;
976 struct vsctl_info info;
979 get_info(ctx->ovs, &info);
980 br = find_bridge(&info, ctx->argv[1], true);
983 SHASH_FOR_EACH (node, &info.ports) {
984 struct vsctl_port *port = node->data;
986 if (strcmp(port->port_cfg->name, br->name) && br == port->bridge) {
987 svec_add(&ports, port->port_cfg->name);
990 output_sorted(&ports, &ctx->output);
991 svec_destroy(&ports);
997 add_port(const struct ovsrec_open_vswitch *ovs,
998 const char *br_name, const char *port_name,
999 char *iface_names[], int n_ifaces)
1001 struct vsctl_info info;
1002 struct vsctl_bridge *bridge;
1003 struct ovsrec_interface **ifaces;
1004 struct ovsrec_port *port;
1007 get_info(ovs, &info);
1008 check_conflicts(&info, port_name,
1009 xasprintf("cannot create a port named %s", port_name));
1010 /* XXX need to check for conflicts on interfaces too */
1011 bridge = find_bridge(&info, br_name, true);
1013 ifaces = xmalloc(n_ifaces * sizeof *ifaces);
1014 for (i = 0; i < n_ifaces; i++) {
1015 ifaces[i] = ovsrec_interface_insert(txn_from_openvswitch(ovs));
1016 ovsrec_interface_set_name(ifaces[i], iface_names[i]);
1019 port = ovsrec_port_insert(txn_from_openvswitch(ovs));
1020 ovsrec_port_set_name(port, port_name);
1021 ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
1025 int64_t tag = bridge->vlan;
1026 ovsrec_port_set_tag(port, &tag, 1);
1029 bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
1030 : bridge->br_cfg), port);
1036 cmd_add_port(struct vsctl_context *ctx)
1038 add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[2], 1);
1042 cmd_add_bond(struct vsctl_context *ctx)
1044 add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[3], ctx->argc - 3);
1048 cmd_del_port(struct vsctl_context *ctx)
1050 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1051 struct vsctl_info info;
1053 get_info(ctx->ovs, &info);
1054 if (ctx->argc == 2) {
1055 struct vsctl_port *port = find_port(&info, ctx->argv[1], must_exist);
1057 del_port(&info, port);
1059 } else if (ctx->argc == 3) {
1060 struct vsctl_bridge *bridge = find_bridge(&info, ctx->argv[1], true);
1061 struct vsctl_port *port = find_port(&info, ctx->argv[2], must_exist);
1064 if (port->bridge == bridge) {
1065 del_port(&info, port);
1066 } else if (port->bridge->parent == bridge) {
1067 vsctl_fatal("bridge %s does not have a port %s (although its "
1068 "parent bridge %s does)",
1069 ctx->argv[1], ctx->argv[2], bridge->parent->name);
1071 vsctl_fatal("bridge %s does not have a port %s",
1072 ctx->argv[1], ctx->argv[2]);
1080 cmd_port_to_br(struct vsctl_context *ctx)
1082 struct vsctl_port *port;
1083 struct vsctl_info info;
1085 get_info(ctx->ovs, &info);
1086 port = find_port(&info, ctx->argv[1], true);
1087 ds_put_format(&ctx->output, "%s\n", port->bridge->name);
1092 cmd_port_set_external_id(struct vsctl_context *ctx)
1094 struct vsctl_info info;
1095 struct vsctl_port *port;
1096 char **keys, **values;
1099 get_info(ctx->ovs, &info);
1100 port = find_port(&info, ctx->argv[1], true);
1101 set_external_id(port->port_cfg->key_external_ids,
1102 port->port_cfg->value_external_ids,
1103 port->port_cfg->n_external_ids,
1104 ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1105 &keys, &values, &n);
1106 ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
1114 cmd_port_get_external_id(struct vsctl_context *ctx)
1116 struct vsctl_info info;
1117 struct vsctl_port *port;
1119 get_info(ctx->ovs, &info);
1120 port = find_port(&info, ctx->argv[1], true);
1121 get_external_id(port->port_cfg->key_external_ids,
1122 port->port_cfg->value_external_ids,
1123 port->port_cfg->n_external_ids,
1124 "", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1129 cmd_br_to_vlan(struct vsctl_context *ctx)
1131 struct vsctl_bridge *bridge;
1132 struct vsctl_info info;
1134 get_info(ctx->ovs, &info);
1135 bridge = find_bridge(&info, ctx->argv[1], true);
1136 ds_put_format(&ctx->output, "%d\n", bridge->vlan);
1141 cmd_br_to_parent(struct vsctl_context *ctx)
1143 struct vsctl_bridge *bridge;
1144 struct vsctl_info info;
1146 get_info(ctx->ovs, &info);
1147 bridge = find_bridge(&info, ctx->argv[1], true);
1148 if (bridge->parent) {
1149 bridge = bridge->parent;
1151 ds_put_format(&ctx->output, "%s\n", bridge->name);
1156 cmd_list_ifaces(struct vsctl_context *ctx)
1158 struct vsctl_bridge *br;
1159 struct shash_node *node;
1160 struct vsctl_info info;
1163 get_info(ctx->ovs, &info);
1164 br = find_bridge(&info, ctx->argv[1], true);
1167 SHASH_FOR_EACH (node, &info.ifaces) {
1168 struct vsctl_iface *iface = node->data;
1170 if (strcmp(iface->iface_cfg->name, br->name)
1171 && br == iface->port->bridge) {
1172 svec_add(&ifaces, iface->iface_cfg->name);
1175 output_sorted(&ifaces, &ctx->output);
1176 svec_destroy(&ifaces);
1182 cmd_iface_to_br(struct vsctl_context *ctx)
1184 struct vsctl_iface *iface;
1185 struct vsctl_info info;
1187 get_info(ctx->ovs, &info);
1188 iface = find_iface(&info, ctx->argv[1], true);
1189 ds_put_format(&ctx->output, "%s\n", iface->port->bridge->name);
1194 cmd_iface_set_external_id(struct vsctl_context *ctx)
1196 struct vsctl_info info;
1197 struct vsctl_iface *iface;
1198 char **keys, **values;
1201 get_info(ctx->ovs, &info);
1202 iface = find_iface(&info, ctx->argv[1], true);
1203 set_external_id(iface->iface_cfg->key_external_ids,
1204 iface->iface_cfg->value_external_ids,
1205 iface->iface_cfg->n_external_ids,
1206 ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1207 &keys, &values, &n);
1208 ovsrec_interface_set_external_ids(iface->iface_cfg, keys, values, n);
1216 cmd_iface_get_external_id(struct vsctl_context *ctx)
1218 struct vsctl_info info;
1219 struct vsctl_iface *iface;
1221 get_info(ctx->ovs, &info);
1222 iface = find_iface(&info, ctx->argv[1], true);
1223 get_external_id(iface->iface_cfg->key_external_ids,
1224 iface->iface_cfg->value_external_ids,
1225 iface->iface_cfg->n_external_ids,
1226 "", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1231 cmd_get_controller(struct vsctl_context *ctx)
1233 struct vsctl_info info;
1235 get_info(ctx->ovs, &info);
1237 if (ctx->argc == 1) {
1238 /* Return the controller from the "Open_vSwitch" table */
1240 ds_put_format(&ctx->output, "%s\n", info.ctrl->target);
1243 /* Return the controller for a particular bridge. */
1244 struct vsctl_bridge *br = find_bridge(&info, ctx->argv[1], true);
1246 /* If no controller is explicitly defined for the requested
1247 * bridge, fallback to the "Open_vSwitch" table's controller. */
1249 ds_put_format(&ctx->output, "%s\n", br->ctrl->target);
1250 } else if (info.ctrl) {
1251 ds_put_format(&ctx->output, "%s\n", info.ctrl->target);
1259 cmd_del_controller(struct vsctl_context *ctx)
1261 struct vsctl_info info;
1263 get_info(ctx->ovs, &info);
1265 if (ctx->argc == 1) {
1267 ovsrec_controller_delete(info.ctrl);
1268 ovsrec_open_vswitch_set_controller(ctx->ovs, NULL);
1271 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1274 ovsrec_controller_delete(br->ctrl);
1275 ovsrec_bridge_set_controller(br->br_cfg, NULL);
1283 cmd_set_controller(struct vsctl_context *ctx)
1285 struct vsctl_info info;
1286 struct ovsrec_controller *ctrl;
1288 get_info(ctx->ovs, &info);
1290 if (ctx->argc == 2) {
1291 /* Set the controller in the "Open_vSwitch" table. */
1293 ovsrec_controller_delete(info.ctrl);
1295 ctrl = ovsrec_controller_insert(txn_from_openvswitch(ctx->ovs));
1296 ovsrec_controller_set_target(ctrl, ctx->argv[1]);
1297 ovsrec_open_vswitch_set_controller(ctx->ovs, ctrl);
1299 /* Set the controller for a particular bridge. */
1300 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1303 ovsrec_controller_delete(br->ctrl);
1305 ctrl = ovsrec_controller_insert(txn_from_openvswitch(ctx->ovs));
1306 ovsrec_controller_set_target(ctrl, ctx->argv[2]);
1307 ovsrec_bridge_set_controller(br->br_cfg, ctrl);
1314 cmd_get_fail_mode(struct vsctl_context *ctx)
1316 struct vsctl_info info;
1317 const char *fail_mode = NULL;
1319 get_info(ctx->ovs, &info);
1321 if (ctx->argc == 1) {
1322 /* Return the fail-mode from the "Open_vSwitch" table */
1323 if (info.ctrl && info.ctrl->fail_mode) {
1324 fail_mode = info.ctrl->fail_mode;
1327 /* Return the fail-mode for a particular bridge. */
1328 struct vsctl_bridge *br = find_bridge(&info, ctx->argv[1], true);
1330 /* If no controller or fail-mode is explicitly defined for the
1331 * requested bridge, fallback to the "Open_vSwitch" table's
1333 if (br->ctrl && br->ctrl->fail_mode) {
1334 fail_mode = br->ctrl->fail_mode;
1335 } else if (info.ctrl && info.ctrl->fail_mode) {
1336 fail_mode = info.ctrl->fail_mode;
1340 if (fail_mode && strlen(fail_mode)) {
1341 ds_put_format(&ctx->output, "%s\n", info.ctrl->fail_mode);
1348 cmd_del_fail_mode(struct vsctl_context *ctx)
1350 struct vsctl_info info;
1352 get_info(ctx->ovs, &info);
1354 if (ctx->argc == 1) {
1355 if (info.ctrl && info.ctrl->fail_mode) {
1356 ovsrec_controller_set_fail_mode(info.ctrl, NULL);
1359 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1361 if (br->ctrl && br->ctrl->fail_mode) {
1362 ovsrec_controller_set_fail_mode(br->ctrl, NULL);
1370 cmd_set_fail_mode(struct vsctl_context *ctx)
1372 struct vsctl_info info;
1373 const char *fail_mode;
1375 get_info(ctx->ovs, &info);
1377 fail_mode = (ctx->argc == 2) ? ctx->argv[1] : ctx->argv[2];
1379 if (strcmp(fail_mode, "standalone") && strcmp(fail_mode, "secure")) {
1380 vsctl_fatal("fail-mode must be \"standalone\" or \"secure\"");
1383 if (ctx->argc == 2) {
1384 /* Set the fail-mode in the "Open_vSwitch" table. */
1386 vsctl_fatal("no controller declared");
1388 ovsrec_controller_set_fail_mode(info.ctrl, fail_mode);
1390 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1393 vsctl_fatal("no controller declared for %s", br->name);
1395 ovsrec_controller_set_fail_mode(br->ctrl, fail_mode);
1401 typedef void vsctl_handler_func(struct vsctl_context *);
1403 struct vsctl_command {
1407 vsctl_handler_func *handler;
1408 const char *options;
1411 static void run_vsctl_command(int argc, char *argv[],
1412 const struct ovsrec_open_vswitch *ovs,
1415 static struct json *
1416 where_uuid_equals(const struct uuid *uuid)
1419 json_array_create_1(
1420 json_array_create_3(
1421 json_string_create("_uuid"),
1422 json_string_create("=="),
1423 json_array_create_2(
1424 json_string_create("uuid"),
1425 json_string_create_nocopy(
1426 xasprintf(UUID_FMT, UUID_ARGS(uuid))))));
1430 do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
1432 struct ovsdb_idl_txn *txn;
1433 const struct ovsrec_open_vswitch *ovs;
1434 enum ovsdb_idl_txn_status status;
1435 struct ds comment, *output;
1440 txn = ovsdb_idl_txn_create(idl);
1442 ovsdb_idl_txn_set_dry_run(txn);
1446 ds_put_cstr(&comment, "ovs-vsctl:");
1447 for (i = 0; i < argc; i++) {
1448 ds_put_format(&comment, " %s", argv[i]);
1450 ovsdb_idl_txn_add_comment(txn, ds_cstr(&comment));
1451 ds_destroy(&comment);
1453 ovs = ovsrec_open_vswitch_first(idl);
1455 /* XXX add verification that table is empty */
1456 ovs = ovsrec_open_vswitch_insert(txn);
1459 if (wait_for_reload) {
1460 struct json *where = where_uuid_equals(&ovs->header_.uuid);
1461 ovsdb_idl_txn_increment(txn, "Open_vSwitch", "next_cfg",
1463 json_destroy(where);
1466 output = xmalloc(argc * sizeof *output);
1468 for (start = i = 0; i <= argc; i++) {
1469 if (i == argc || !strcmp(argv[i], "--")) {
1471 ds_init(&output[n_output]);
1472 run_vsctl_command(i - start, &argv[start], ovs,
1473 &output[n_output++]);
1479 while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
1481 ovsdb_idl_wait(idl);
1482 ovsdb_idl_txn_wait(txn);
1485 if (wait_for_reload && status == TXN_SUCCESS) {
1486 next_cfg = ovsdb_idl_txn_get_increment_new_value(txn);
1488 ovsdb_idl_txn_destroy(txn);
1491 case TXN_INCOMPLETE:
1495 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
1496 vsctl_fatal("transaction aborted");
1503 for (i = 0; i < n_output; i++) {
1504 ds_destroy(&output[i]);
1509 vsctl_fatal("transaction error");
1515 for (i = 0; i < n_output; i++) {
1516 struct ds *ds = &output[i];
1521 for (j = 0; j < ds->length; j++) {
1522 int c = ds->string[j];
1525 fputs("\\n", stdout);
1529 fputs("\\\\", stdout);
1538 fputs(ds_cstr(ds), stdout);
1542 if (wait_for_reload && status != TXN_UNCHANGED) {
1544 const struct ovsrec_open_vswitch *ovs;
1547 OVSREC_OPEN_VSWITCH_FOR_EACH (ovs, idl) {
1548 if (ovs->cur_cfg >= next_cfg) {
1552 ovsdb_idl_wait(idl);
1561 static vsctl_handler_func *
1562 get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx)
1564 static const struct vsctl_command all_commands[] = {
1565 /* Open vSwitch commands. */
1566 {"init", 0, 0, cmd_init, ""},
1568 /* Bridge commands. */
1569 {"add-br", 1, 3, cmd_add_br, ""},
1570 {"del-br", 1, 1, cmd_del_br, "--if-exists"},
1571 {"list-br", 0, 0, cmd_list_br, ""},
1572 {"br-exists", 1, 1, cmd_br_exists, ""},
1573 {"br-to-vlan", 1, 1, cmd_br_to_vlan, ""},
1574 {"br-to-parent", 1, 1, cmd_br_to_parent, ""},
1575 {"br-set-external-id", 2, 3, cmd_br_set_external_id, ""},
1576 {"br-get-external-id", 1, 2, cmd_br_get_external_id, ""},
1578 /* Port commands. */
1579 {"list-ports", 1, 1, cmd_list_ports, ""},
1580 {"add-port", 2, 2, cmd_add_port, ""},
1581 {"add-bond", 4, INT_MAX, cmd_add_bond, ""},
1582 {"del-port", 1, 2, cmd_del_port, "--if-exists"},
1583 {"port-to-br", 1, 1, cmd_port_to_br, ""},
1584 {"port-set-external-id", 2, 3, cmd_port_set_external_id, ""},
1585 {"port-get-external-id", 1, 2, cmd_port_get_external_id, ""},
1587 /* Interface commands. */
1588 {"list-ifaces", 1, 1, cmd_list_ifaces, ""},
1589 {"iface-to-br", 1, 1, cmd_iface_to_br, ""},
1590 {"iface-set-external-id", 2, 3, cmd_iface_set_external_id, ""},
1591 {"iface-get-external-id", 1, 2, cmd_iface_get_external_id, ""},
1593 /* Controller commands. */
1594 {"get-controller", 0, 1, cmd_get_controller, ""},
1595 {"del-controller", 0, 1, cmd_del_controller, ""},
1596 {"set-controller", 1, 2, cmd_set_controller, ""},
1597 {"get-fail-mode", 0, 1, cmd_get_fail_mode, ""},
1598 {"del-fail-mode", 0, 1, cmd_del_fail_mode, ""},
1599 {"set-fail-mode", 1, 2, cmd_set_fail_mode, ""},
1602 const struct vsctl_command *p;
1605 shash_init(&ctx->options);
1606 for (i = 0; i < argc; i++) {
1607 if (argv[i][0] != '-') {
1610 if (!shash_add_once(&ctx->options, argv[i], NULL)) {
1611 vsctl_fatal("'%s' option specified multiple times", argv[i]);
1615 vsctl_fatal("missing command name");
1618 for (p = all_commands; p < &all_commands[ARRAY_SIZE(all_commands)]; p++) {
1619 if (!strcmp(p->name, argv[i])) {
1620 struct shash_node *node;
1623 SHASH_FOR_EACH (node, &ctx->options) {
1624 const char *s = strstr(p->options, node->name);
1625 int end = s ? s[strlen(node->name)] : EOF;
1626 if (end != ',' && end != ' ' && end != '\0') {
1627 vsctl_fatal("'%s' command has no '%s' option",
1628 argv[i], node->name);
1632 n_arg = argc - i - 1;
1633 if (n_arg < p->min_args) {
1634 vsctl_fatal("'%s' command requires at least %d arguments",
1635 p->name, p->min_args);
1636 } else if (n_arg > p->max_args) {
1637 vsctl_fatal("'%s' command takes at most %d arguments",
1638 p->name, p->max_args);
1640 ctx->argc = n_arg + 1;
1641 ctx->argv = &argv[i];
1647 vsctl_fatal("unknown command '%s'; use --help for help", argv[i]);
1651 check_vsctl_command(int argc, char *argv[])
1653 struct vsctl_context ctx;
1655 get_vsctl_handler(argc, argv, &ctx);
1656 shash_destroy(&ctx.options);
1660 run_vsctl_command(int argc, char *argv[],
1661 const struct ovsrec_open_vswitch *ovs, struct ds *output)
1663 vsctl_handler_func *function;
1664 struct vsctl_context ctx;
1666 function = get_vsctl_handler(argc, argv, &ctx);
1668 ds_init(&ctx.output);
1670 *output = ctx.output;
1671 shash_destroy(&ctx.options);