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,
159 static struct option long_options[] = {
160 {"db", required_argument, 0, OPT_DB},
161 {"no-syslog", no_argument, 0, OPT_NO_SYSLOG},
162 {"no-wait", no_argument, 0, OPT_NO_WAIT},
163 {"dry-run", no_argument, 0, OPT_DRY_RUN},
164 {"oneline", no_argument, 0, OPT_ONELINE},
165 {"timeout", required_argument, 0, 't'},
166 {"help", no_argument, 0, 'h'},
167 {"version", no_argument, 0, 'V'},
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",
235 printf("%s: ovs-vswitchd management utility\n"
236 "usage: %s [OPTIONS] COMMAND [ARG...]\n",
237 program_name, program_name);
238 printf("\nBridge commands:\n"
240 "create a new bridge named BRIDGE\n"
241 " add-br BRIDGE PARENT VLAN "
242 "create new fake bridge BRIDGE in PARENT on VLAN\n"
244 "delete BRIDGE and all of its ports\n"
246 "print the names of all the bridges\n"
248 "test whether BRIDGE exists\n"
249 " br-to-vlan BRIDGE "
250 "print the VLAN which BRIDGE is on\n"
251 " br-to-parent BRIDGE "
252 "print the parent of BRIDGE\n"
253 " br-set-external-id BRIDGE KEY VALUE"
254 " set KEY on BRIDGE to VALUE\n"
255 " br-set-external-id BRIDGE KEY"
256 " unset KEY on BRIDGE\n"
257 " br-get-external-id BRIDGE KEY"
258 " print value of KEY on BRIDGE\n"
259 " br-get-external-id BRIDGE"
260 " list key-value pairs on BRIDGE\n"
262 printf("\nPort commands:\n"
263 " list-ports BRIDGE "
264 "print the names of all the ports on BRIDGE\n"
265 " add-port BRIDGE PORT "
266 "add network device PORT to BRIDGE\n"
267 " add-bond BRIDGE PORT IFACE... "
268 "add new bonded port PORT in BRIDGE from IFACES\n"
269 " del-port [BRIDGE] PORT "
270 "delete PORT (which may be bonded) from BRIDGE\n"
272 "print name of bridge that contains PORT\n"
273 " port-set-external-id PORT KEY VALUE"
274 " set KEY on PORT to VALUE\n"
275 " port-set-external-id PORT KEY"
276 " unset KEY on PORT\n"
277 " port-get-external-id PORT KEY"
278 " print value of KEY on PORT\n"
279 " port-get-external-id PORT"
280 " list key-value pairs on PORT\n"
281 "A bond is considered to be a single port.\n"
283 printf("\nInterface commands (a bond consists of multiple interfaces):\n"
284 " list-ifaces BRIDGE "
285 "print the names of all the interfaces on BRIDGE\n"
286 " iface-to-br IFACE "
287 "print name of bridge that contains IFACE\n"
288 " iface-set-external-id IFACE KEY VALUE"
289 " set KEY on IFACE to VALUE\n"
290 " iface-set-external-id IFACE KEY"
291 " unset KEY on IFACE\n"
292 " iface-get-external-id IFACE KEY"
293 " print value of KEY on IFACE\n"
294 " iface-get-external-id IFACE"
295 " list key-value pairs on IFACE\n"
297 printf("\nController commands:\n"
298 " get-controller [BRIDGE] "
299 "print the controller for BRIDGE\n"
300 " del-controller [BRIDGE] "
301 "delete the controller for BRIDGE\n"
302 " set-controller [BRIDGE] TARGET "
303 "set the controller for BRIDGE to TARGET\n"
304 " get-fail-mode [BRIDGE] "
305 "print the fail-mode for BRIDGE\n"
306 " del-fail-mode [BRIDGE] "
307 "delete the fail-mode for BRIDGE\n"
308 " set-fail-mode [BRIDGE] MODE "
309 "set the fail-mode for BRIDGE to MODE\n"
311 printf("\nSSL commands:\n"
313 "print the SSL configuration\n"
315 "delete the SSL configuration\n"
316 " set-ssl PRIV-KEY CERT CA-CERT "
317 "set the SSL configuration\n"
319 printf("\nOptions:\n"
321 "connect to DATABASE\n"
325 "print exactly one line of output per command\n",
328 printf("\nOther options:\n"
330 "display this help message\n"
332 "display version information\n");
341 def = xasprintf("unix:%s/ovsdb-server", ovs_rundir);
346 struct vsctl_context {
349 const struct ovsrec_open_vswitch *ovs;
351 struct shash options;
354 struct vsctl_bridge {
355 struct ovsrec_bridge *br_cfg;
357 struct ovsrec_controller *ctrl;
358 struct vsctl_bridge *parent;
363 struct ovsrec_port *port_cfg;
364 struct vsctl_bridge *bridge;
368 struct ovsrec_interface *iface_cfg;
369 struct vsctl_port *port;
373 struct shash bridges;
376 struct ovsrec_controller *ctrl;
379 static struct ovsdb_idl_txn *
380 txn_from_openvswitch(const struct ovsrec_open_vswitch *ovs)
382 return ovsdb_idl_txn_get(&ovs->header_);
385 static struct vsctl_bridge *
386 add_bridge(struct vsctl_info *b,
387 struct ovsrec_bridge *br_cfg, const char *name,
388 struct vsctl_bridge *parent, int vlan)
390 struct vsctl_bridge *br = xmalloc(sizeof *br);
392 br->name = xstrdup(name);
395 br->ctrl = parent ? parent->br_cfg->controller : br_cfg->controller;
396 shash_add(&b->bridges, br->name, br);
401 port_is_fake_bridge(const struct ovsrec_port *port_cfg)
403 return (port_cfg->fake_bridge
405 && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095);
408 static struct vsctl_bridge *
409 find_vlan_bridge(struct vsctl_info *info,
410 struct vsctl_bridge *parent, int vlan)
412 struct shash_node *node;
414 SHASH_FOR_EACH (node, &info->bridges) {
415 struct vsctl_bridge *br = node->data;
416 if (br->parent == parent && br->vlan == vlan) {
425 free_info(struct vsctl_info *info)
427 struct shash_node *node;
429 SHASH_FOR_EACH (node, &info->bridges) {
430 struct vsctl_bridge *bridge = node->data;
434 shash_destroy(&info->bridges);
436 SHASH_FOR_EACH (node, &info->ports) {
437 struct vsctl_port *port = node->data;
440 shash_destroy(&info->ports);
442 SHASH_FOR_EACH (node, &info->ifaces) {
443 struct vsctl_iface *iface = node->data;
446 shash_destroy(&info->ifaces);
450 get_info(const struct ovsrec_open_vswitch *ovs, struct vsctl_info *info)
452 struct shash bridges, ports;
455 shash_init(&info->bridges);
456 shash_init(&info->ports);
457 shash_init(&info->ifaces);
459 info->ctrl = ovs->controller;
461 shash_init(&bridges);
463 for (i = 0; i < ovs->n_bridges; i++) {
464 struct ovsrec_bridge *br_cfg = ovs->bridges[i];
465 struct vsctl_bridge *br;
468 if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
469 VLOG_WARN("%s: database contains duplicate bridge name",
473 br = add_bridge(info, br_cfg, br_cfg->name, NULL, 0);
478 for (j = 0; j < br_cfg->n_ports; j++) {
479 struct ovsrec_port *port_cfg = br_cfg->ports[j];
481 if (!shash_add_once(&ports, port_cfg->name, NULL)) {
482 VLOG_WARN("%s: database contains duplicate port name",
487 if (port_is_fake_bridge(port_cfg)
488 && shash_add_once(&bridges, port_cfg->name, NULL)) {
489 add_bridge(info, NULL, port_cfg->name, br, *port_cfg->tag);
493 shash_destroy(&bridges);
494 shash_destroy(&ports);
496 shash_init(&bridges);
498 for (i = 0; i < ovs->n_bridges; i++) {
499 struct ovsrec_bridge *br_cfg = ovs->bridges[i];
500 struct vsctl_bridge *br;
503 if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
506 br = shash_find_data(&info->bridges, br_cfg->name);
507 for (j = 0; j < br_cfg->n_ports; j++) {
508 struct ovsrec_port *port_cfg = br_cfg->ports[j];
509 struct vsctl_port *port;
512 if (!shash_add_once(&ports, port_cfg->name, NULL)) {
516 if (port_is_fake_bridge(port_cfg)
517 && !shash_add_once(&bridges, port_cfg->name, NULL)) {
521 port = xmalloc(sizeof *port);
522 port->port_cfg = port_cfg;
524 && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095) {
525 port->bridge = find_vlan_bridge(info, br, *port_cfg->tag);
532 shash_add(&info->ports, port_cfg->name, port);
534 for (k = 0; k < port_cfg->n_interfaces; k++) {
535 struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
536 struct vsctl_iface *iface;
538 if (shash_find(&info->ifaces, iface_cfg->name)) {
539 VLOG_WARN("%s: database contains duplicate interface name",
544 iface = xmalloc(sizeof *iface);
545 iface->iface_cfg = iface_cfg;
547 shash_add(&info->ifaces, iface_cfg->name, iface);
551 shash_destroy(&bridges);
552 shash_destroy(&ports);
556 check_conflicts(struct vsctl_info *info, const char *name,
559 struct vsctl_iface *iface;
560 struct vsctl_port *port;
562 if (shash_find(&info->bridges, name)) {
563 vsctl_fatal("%s because a bridge named %s already exists",
567 port = shash_find_data(&info->ports, name);
569 vsctl_fatal("%s because a port named %s already exists on "
570 "bridge %s", msg, name, port->bridge->name);
573 iface = shash_find_data(&info->ifaces, name);
575 vsctl_fatal("%s because an interface named %s already exists "
576 "on bridge %s", msg, name, iface->port->bridge->name);
582 static struct vsctl_bridge *
583 find_bridge(struct vsctl_info *info, const char *name, bool must_exist)
585 struct vsctl_bridge *br = shash_find_data(&info->bridges, name);
586 if (must_exist && !br) {
587 vsctl_fatal("no bridge named %s", name);
592 static struct vsctl_bridge *
593 find_real_bridge(struct vsctl_info *info, const char *name, bool must_exist)
595 struct vsctl_bridge *br = find_bridge(info, name, must_exist);
596 if (br && br->parent) {
597 vsctl_fatal("%s is a fake bridge", name);
602 static struct vsctl_port *
603 find_port(struct vsctl_info *info, const char *name, bool must_exist)
605 struct vsctl_port *port = shash_find_data(&info->ports, name);
606 if (port && !strcmp(name, port->bridge->name)) {
609 if (must_exist && !port) {
610 vsctl_fatal("no port named %s", name);
615 static struct vsctl_iface *
616 find_iface(struct vsctl_info *info, const char *name, bool must_exist)
618 struct vsctl_iface *iface = shash_find_data(&info->ifaces, name);
619 if (iface && !strcmp(name, iface->port->bridge->name)) {
622 if (must_exist && !iface) {
623 vsctl_fatal("no interface named %s", name);
629 bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
631 struct ovsrec_port **ports;
634 ports = xmalloc(sizeof *br->ports * (br->n_ports + 1));
635 for (i = 0; i < br->n_ports; i++) {
636 ports[i] = br->ports[i];
638 ports[br->n_ports] = port;
639 ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
644 bridge_delete_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
646 struct ovsrec_port **ports;
649 ports = xmalloc(sizeof *br->ports * br->n_ports);
650 for (i = n = 0; i < br->n_ports; i++) {
651 if (br->ports[i] != port) {
652 ports[n++] = br->ports[i];
655 ovsrec_bridge_set_ports(br, ports, n);
660 ovs_insert_bridge(const struct ovsrec_open_vswitch *ovs,
661 struct ovsrec_bridge *bridge)
663 struct ovsrec_bridge **bridges;
666 bridges = xmalloc(sizeof *ovs->bridges * (ovs->n_bridges + 1));
667 for (i = 0; i < ovs->n_bridges; i++) {
668 bridges[i] = ovs->bridges[i];
670 bridges[ovs->n_bridges] = bridge;
671 ovsrec_open_vswitch_set_bridges(ovs, bridges, ovs->n_bridges + 1);
676 ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
677 struct ovsrec_bridge *bridge)
679 struct ovsrec_bridge **bridges;
682 bridges = xmalloc(sizeof *ovs->bridges * ovs->n_bridges);
683 for (i = n = 0; i < ovs->n_bridges; i++) {
684 if (ovs->bridges[i] != bridge) {
685 bridges[n++] = ovs->bridges[i];
688 ovsrec_open_vswitch_set_bridges(ovs, bridges, n);
693 cmd_init(struct vsctl_context *ctx UNUSED)
698 cmd_add_br(struct vsctl_context *ctx)
700 const char *br_name = ctx->argv[1];
701 struct vsctl_info info;
703 get_info(ctx->ovs, &info);
704 check_conflicts(&info, br_name,
705 xasprintf("cannot create a bridge named %s", br_name));
707 if (ctx->argc == 2) {
708 struct ovsrec_bridge *br;
709 struct ovsrec_port *port;
710 struct ovsrec_interface *iface;
712 iface = ovsrec_interface_insert(txn_from_openvswitch(ctx->ovs));
713 ovsrec_interface_set_name(iface, br_name);
715 port = ovsrec_port_insert(txn_from_openvswitch(ctx->ovs));
716 ovsrec_port_set_name(port, br_name);
717 ovsrec_port_set_interfaces(port, &iface, 1);
719 br = ovsrec_bridge_insert(txn_from_openvswitch(ctx->ovs));
720 ovsrec_bridge_set_name(br, br_name);
721 ovsrec_bridge_set_ports(br, &port, 1);
723 ovs_insert_bridge(ctx->ovs, br);
724 } else if (ctx->argc == 3) {
725 vsctl_fatal("'%s' command takes exactly 1 or 3 arguments",
727 } else if (ctx->argc == 4) {
728 const char *parent_name = ctx->argv[2];
729 int vlan = atoi(ctx->argv[3]);
730 struct ovsrec_bridge *br;
731 struct vsctl_bridge *parent;
732 struct ovsrec_port *port;
733 struct ovsrec_interface *iface;
736 if (vlan < 1 || vlan > 4095) {
737 vsctl_fatal("%s: vlan must be between 1 and 4095", ctx->argv[0]);
740 parent = find_bridge(&info, parent_name, false);
741 if (parent && parent->vlan) {
742 vsctl_fatal("cannot create bridge with fake bridge as parent");
745 vsctl_fatal("parent bridge %s does not exist", parent_name);
749 iface = ovsrec_interface_insert(txn_from_openvswitch(ctx->ovs));
750 ovsrec_interface_set_name(iface, br_name);
751 ovsrec_interface_set_type(iface, "internal");
753 port = ovsrec_port_insert(txn_from_openvswitch(ctx->ovs));
754 ovsrec_port_set_name(port, br_name);
755 ovsrec_port_set_interfaces(port, &iface, 1);
756 ovsrec_port_set_fake_bridge(port, true);
757 ovsrec_port_set_tag(port, &tag, 1);
759 bridge_insert_port(br, port);
768 del_port(struct vsctl_info *info, struct vsctl_port *port)
770 struct shash_node *node;
772 SHASH_FOR_EACH (node, &info->ifaces) {
773 struct vsctl_iface *iface = node->data;
774 if (iface->port == port) {
775 ovsrec_interface_delete(iface->iface_cfg);
778 ovsrec_port_delete(port->port_cfg);
780 bridge_delete_port((port->bridge->parent
781 ? port->bridge->parent->br_cfg
782 : port->bridge->br_cfg), port->port_cfg);
786 cmd_del_br(struct vsctl_context *ctx)
788 bool must_exist = !shash_find(&ctx->options, "--if-exists");
789 struct vsctl_bridge *bridge;
790 struct vsctl_info info;
792 get_info(ctx->ovs, &info);
793 bridge = find_bridge(&info, ctx->argv[1], must_exist);
795 struct shash_node *node;
797 SHASH_FOR_EACH (node, &info.ports) {
798 struct vsctl_port *port = node->data;
799 if (port->bridge == bridge
800 || !strcmp(port->port_cfg->name, bridge->name)) {
801 del_port(&info, port);
804 if (bridge->br_cfg) {
805 ovsrec_bridge_delete(bridge->br_cfg);
806 ovs_delete_bridge(ctx->ovs, bridge->br_cfg);
813 output_sorted(struct svec *svec, struct ds *output)
819 SVEC_FOR_EACH (i, name, svec) {
820 ds_put_format(output, "%s\n", name);
825 cmd_list_br(struct vsctl_context *ctx)
827 struct shash_node *node;
828 struct vsctl_info info;
831 get_info(ctx->ovs, &info);
834 SHASH_FOR_EACH (node, &info.bridges) {
835 struct vsctl_bridge *br = node->data;
836 svec_add(&bridges, br->name);
838 output_sorted(&bridges, &ctx->output);
839 svec_destroy(&bridges);
845 cmd_br_exists(struct vsctl_context *ctx)
847 struct vsctl_info info;
849 get_info(ctx->ovs, &info);
850 if (!find_bridge(&info, ctx->argv[1], false)) {
856 /* Returns true if 'b_prefix' (of length 'b_prefix_len') concatenated with 'b'
857 * equals 'a', false otherwise. */
859 key_matches(const char *a,
860 const char *b_prefix, size_t b_prefix_len, const char *b)
862 return !strncmp(a, b_prefix, b_prefix_len) && !strcmp(a + b_prefix_len, b);
866 set_external_id(char **old_keys, char **old_values, size_t old_n,
867 char *key, char *value,
868 char ***new_keysp, char ***new_valuesp, size_t *new_np)
875 new_keys = xmalloc(sizeof *new_keys * (old_n + 1));
876 new_values = xmalloc(sizeof *new_values * (old_n + 1));
878 for (i = 0; i < old_n; i++) {
879 if (strcmp(key, old_keys[i])) {
880 new_keys[new_n] = old_keys[i];
881 new_values[new_n] = old_values[i];
886 new_keys[new_n] = key;
887 new_values[new_n] = value;
890 *new_keysp = new_keys;
891 *new_valuesp = new_values;
896 cmd_br_set_external_id(struct vsctl_context *ctx)
898 struct vsctl_info info;
899 struct vsctl_bridge *bridge;
900 char **keys, **values;
903 get_info(ctx->ovs, &info);
904 bridge = find_bridge(&info, ctx->argv[1], true);
905 if (bridge->br_cfg) {
906 set_external_id(bridge->br_cfg->key_external_ids,
907 bridge->br_cfg->value_external_ids,
908 bridge->br_cfg->n_external_ids,
909 ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
911 ovsrec_bridge_set_external_ids(bridge->br_cfg, keys, values, n);
913 char *key = xasprintf("fake-bridge-%s", ctx->argv[2]);
914 struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
915 set_external_id(port->port_cfg->key_external_ids,
916 port->port_cfg->value_external_ids,
917 port->port_cfg->n_external_ids,
918 key, ctx->argc >= 4 ? ctx->argv[3] : NULL,
920 ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
930 get_external_id(char **keys, char **values, size_t n,
931 const char *prefix, const char *key,
934 size_t prefix_len = strlen(prefix);
939 for (i = 0; i < n; i++) {
940 if (!key && !strncmp(keys[i], prefix, prefix_len)) {
941 svec_add_nocopy(&svec, xasprintf("%s=%s",
942 keys[i] + prefix_len, values[i]));
943 } else if (key_matches(keys[i], prefix, prefix_len, key)) {
944 svec_add(&svec, values[i]);
948 output_sorted(&svec, output);
953 cmd_br_get_external_id(struct vsctl_context *ctx)
955 struct vsctl_info info;
956 struct vsctl_bridge *bridge;
958 get_info(ctx->ovs, &info);
959 bridge = find_bridge(&info, ctx->argv[1], true);
960 if (bridge->br_cfg) {
961 get_external_id(bridge->br_cfg->key_external_ids,
962 bridge->br_cfg->value_external_ids,
963 bridge->br_cfg->n_external_ids,
964 "", ctx->argc >= 3 ? ctx->argv[2] : NULL,
967 struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
968 get_external_id(port->port_cfg->key_external_ids,
969 port->port_cfg->value_external_ids,
970 port->port_cfg->n_external_ids,
971 "fake-bridge-", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
978 cmd_list_ports(struct vsctl_context *ctx)
980 struct vsctl_bridge *br;
981 struct shash_node *node;
982 struct vsctl_info info;
985 get_info(ctx->ovs, &info);
986 br = find_bridge(&info, ctx->argv[1], true);
989 SHASH_FOR_EACH (node, &info.ports) {
990 struct vsctl_port *port = node->data;
992 if (strcmp(port->port_cfg->name, br->name) && br == port->bridge) {
993 svec_add(&ports, port->port_cfg->name);
996 output_sorted(&ports, &ctx->output);
997 svec_destroy(&ports);
1003 add_port(const struct ovsrec_open_vswitch *ovs,
1004 const char *br_name, const char *port_name,
1005 char *iface_names[], int n_ifaces)
1007 struct vsctl_info info;
1008 struct vsctl_bridge *bridge;
1009 struct ovsrec_interface **ifaces;
1010 struct ovsrec_port *port;
1013 get_info(ovs, &info);
1014 check_conflicts(&info, port_name,
1015 xasprintf("cannot create a port named %s", port_name));
1016 /* XXX need to check for conflicts on interfaces too */
1017 bridge = find_bridge(&info, br_name, true);
1019 ifaces = xmalloc(n_ifaces * sizeof *ifaces);
1020 for (i = 0; i < n_ifaces; i++) {
1021 ifaces[i] = ovsrec_interface_insert(txn_from_openvswitch(ovs));
1022 ovsrec_interface_set_name(ifaces[i], iface_names[i]);
1025 port = ovsrec_port_insert(txn_from_openvswitch(ovs));
1026 ovsrec_port_set_name(port, port_name);
1027 ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
1031 int64_t tag = bridge->vlan;
1032 ovsrec_port_set_tag(port, &tag, 1);
1035 bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
1036 : bridge->br_cfg), port);
1042 cmd_add_port(struct vsctl_context *ctx)
1044 add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[2], 1);
1048 cmd_add_bond(struct vsctl_context *ctx)
1050 add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[3], ctx->argc - 3);
1054 cmd_del_port(struct vsctl_context *ctx)
1056 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1057 struct vsctl_info info;
1059 get_info(ctx->ovs, &info);
1060 if (ctx->argc == 2) {
1061 struct vsctl_port *port = find_port(&info, ctx->argv[1], must_exist);
1063 del_port(&info, port);
1065 } else if (ctx->argc == 3) {
1066 struct vsctl_bridge *bridge = find_bridge(&info, ctx->argv[1], true);
1067 struct vsctl_port *port = find_port(&info, ctx->argv[2], must_exist);
1070 if (port->bridge == bridge) {
1071 del_port(&info, port);
1072 } else if (port->bridge->parent == bridge) {
1073 vsctl_fatal("bridge %s does not have a port %s (although its "
1074 "parent bridge %s does)",
1075 ctx->argv[1], ctx->argv[2], bridge->parent->name);
1077 vsctl_fatal("bridge %s does not have a port %s",
1078 ctx->argv[1], ctx->argv[2]);
1086 cmd_port_to_br(struct vsctl_context *ctx)
1088 struct vsctl_port *port;
1089 struct vsctl_info info;
1091 get_info(ctx->ovs, &info);
1092 port = find_port(&info, ctx->argv[1], true);
1093 ds_put_format(&ctx->output, "%s\n", port->bridge->name);
1098 cmd_port_set_external_id(struct vsctl_context *ctx)
1100 struct vsctl_info info;
1101 struct vsctl_port *port;
1102 char **keys, **values;
1105 get_info(ctx->ovs, &info);
1106 port = find_port(&info, ctx->argv[1], true);
1107 set_external_id(port->port_cfg->key_external_ids,
1108 port->port_cfg->value_external_ids,
1109 port->port_cfg->n_external_ids,
1110 ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1111 &keys, &values, &n);
1112 ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
1120 cmd_port_get_external_id(struct vsctl_context *ctx)
1122 struct vsctl_info info;
1123 struct vsctl_port *port;
1125 get_info(ctx->ovs, &info);
1126 port = find_port(&info, ctx->argv[1], true);
1127 get_external_id(port->port_cfg->key_external_ids,
1128 port->port_cfg->value_external_ids,
1129 port->port_cfg->n_external_ids,
1130 "", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1135 cmd_br_to_vlan(struct vsctl_context *ctx)
1137 struct vsctl_bridge *bridge;
1138 struct vsctl_info info;
1140 get_info(ctx->ovs, &info);
1141 bridge = find_bridge(&info, ctx->argv[1], true);
1142 ds_put_format(&ctx->output, "%d\n", bridge->vlan);
1147 cmd_br_to_parent(struct vsctl_context *ctx)
1149 struct vsctl_bridge *bridge;
1150 struct vsctl_info info;
1152 get_info(ctx->ovs, &info);
1153 bridge = find_bridge(&info, ctx->argv[1], true);
1154 if (bridge->parent) {
1155 bridge = bridge->parent;
1157 ds_put_format(&ctx->output, "%s\n", bridge->name);
1162 cmd_list_ifaces(struct vsctl_context *ctx)
1164 struct vsctl_bridge *br;
1165 struct shash_node *node;
1166 struct vsctl_info info;
1169 get_info(ctx->ovs, &info);
1170 br = find_bridge(&info, ctx->argv[1], true);
1173 SHASH_FOR_EACH (node, &info.ifaces) {
1174 struct vsctl_iface *iface = node->data;
1176 if (strcmp(iface->iface_cfg->name, br->name)
1177 && br == iface->port->bridge) {
1178 svec_add(&ifaces, iface->iface_cfg->name);
1181 output_sorted(&ifaces, &ctx->output);
1182 svec_destroy(&ifaces);
1188 cmd_iface_to_br(struct vsctl_context *ctx)
1190 struct vsctl_iface *iface;
1191 struct vsctl_info info;
1193 get_info(ctx->ovs, &info);
1194 iface = find_iface(&info, ctx->argv[1], true);
1195 ds_put_format(&ctx->output, "%s\n", iface->port->bridge->name);
1200 cmd_iface_set_external_id(struct vsctl_context *ctx)
1202 struct vsctl_info info;
1203 struct vsctl_iface *iface;
1204 char **keys, **values;
1207 get_info(ctx->ovs, &info);
1208 iface = find_iface(&info, ctx->argv[1], true);
1209 set_external_id(iface->iface_cfg->key_external_ids,
1210 iface->iface_cfg->value_external_ids,
1211 iface->iface_cfg->n_external_ids,
1212 ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1213 &keys, &values, &n);
1214 ovsrec_interface_set_external_ids(iface->iface_cfg, keys, values, n);
1222 cmd_iface_get_external_id(struct vsctl_context *ctx)
1224 struct vsctl_info info;
1225 struct vsctl_iface *iface;
1227 get_info(ctx->ovs, &info);
1228 iface = find_iface(&info, ctx->argv[1], true);
1229 get_external_id(iface->iface_cfg->key_external_ids,
1230 iface->iface_cfg->value_external_ids,
1231 iface->iface_cfg->n_external_ids,
1232 "", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1237 cmd_get_controller(struct vsctl_context *ctx)
1239 struct vsctl_info info;
1241 get_info(ctx->ovs, &info);
1243 if (ctx->argc == 1) {
1244 /* Return the controller from the "Open_vSwitch" table */
1246 ds_put_format(&ctx->output, "%s\n", info.ctrl->target);
1249 /* Return the controller for a particular bridge. */
1250 struct vsctl_bridge *br = find_bridge(&info, ctx->argv[1], true);
1252 /* If no controller is explicitly defined for the requested
1253 * bridge, fallback to the "Open_vSwitch" table's controller. */
1255 ds_put_format(&ctx->output, "%s\n", br->ctrl->target);
1256 } else if (info.ctrl) {
1257 ds_put_format(&ctx->output, "%s\n", info.ctrl->target);
1265 cmd_del_controller(struct vsctl_context *ctx)
1267 struct vsctl_info info;
1269 get_info(ctx->ovs, &info);
1271 if (ctx->argc == 1) {
1273 ovsrec_controller_delete(info.ctrl);
1274 ovsrec_open_vswitch_set_controller(ctx->ovs, NULL);
1277 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1280 ovsrec_controller_delete(br->ctrl);
1281 ovsrec_bridge_set_controller(br->br_cfg, NULL);
1289 cmd_set_controller(struct vsctl_context *ctx)
1291 struct vsctl_info info;
1292 struct ovsrec_controller *ctrl;
1294 get_info(ctx->ovs, &info);
1296 if (ctx->argc == 2) {
1297 /* Set the controller in the "Open_vSwitch" table. */
1299 ovsrec_controller_delete(info.ctrl);
1301 ctrl = ovsrec_controller_insert(txn_from_openvswitch(ctx->ovs));
1302 ovsrec_controller_set_target(ctrl, ctx->argv[1]);
1303 ovsrec_open_vswitch_set_controller(ctx->ovs, ctrl);
1305 /* Set the controller for a particular bridge. */
1306 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1309 ovsrec_controller_delete(br->ctrl);
1311 ctrl = ovsrec_controller_insert(txn_from_openvswitch(ctx->ovs));
1312 ovsrec_controller_set_target(ctrl, ctx->argv[2]);
1313 ovsrec_bridge_set_controller(br->br_cfg, ctrl);
1320 cmd_get_fail_mode(struct vsctl_context *ctx)
1322 struct vsctl_info info;
1323 const char *fail_mode = NULL;
1325 get_info(ctx->ovs, &info);
1327 if (ctx->argc == 1) {
1328 /* Return the fail-mode from the "Open_vSwitch" table */
1329 if (info.ctrl && info.ctrl->fail_mode) {
1330 fail_mode = info.ctrl->fail_mode;
1333 /* Return the fail-mode for a particular bridge. */
1334 struct vsctl_bridge *br = find_bridge(&info, ctx->argv[1], true);
1336 /* If no controller or fail-mode is explicitly defined for the
1337 * requested bridge, fallback to the "Open_vSwitch" table's
1339 if (br->ctrl && br->ctrl->fail_mode) {
1340 fail_mode = br->ctrl->fail_mode;
1341 } else if (info.ctrl && info.ctrl->fail_mode) {
1342 fail_mode = info.ctrl->fail_mode;
1346 if (fail_mode && strlen(fail_mode)) {
1347 ds_put_format(&ctx->output, "%s\n", fail_mode);
1354 cmd_del_fail_mode(struct vsctl_context *ctx)
1356 struct vsctl_info info;
1358 get_info(ctx->ovs, &info);
1360 if (ctx->argc == 1) {
1361 if (info.ctrl && info.ctrl->fail_mode) {
1362 ovsrec_controller_set_fail_mode(info.ctrl, NULL);
1365 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1367 if (br->ctrl && br->ctrl->fail_mode) {
1368 ovsrec_controller_set_fail_mode(br->ctrl, NULL);
1376 cmd_set_fail_mode(struct vsctl_context *ctx)
1378 struct vsctl_info info;
1379 const char *fail_mode;
1381 get_info(ctx->ovs, &info);
1383 fail_mode = (ctx->argc == 2) ? ctx->argv[1] : ctx->argv[2];
1385 if (strcmp(fail_mode, "standalone") && strcmp(fail_mode, "secure")) {
1386 vsctl_fatal("fail-mode must be \"standalone\" or \"secure\"");
1389 if (ctx->argc == 2) {
1390 /* Set the fail-mode in the "Open_vSwitch" table. */
1392 vsctl_fatal("no controller declared");
1394 ovsrec_controller_set_fail_mode(info.ctrl, fail_mode);
1396 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1399 vsctl_fatal("no controller declared for %s", br->name);
1401 ovsrec_controller_set_fail_mode(br->ctrl, fail_mode);
1408 cmd_get_ssl(struct vsctl_context *ctx)
1410 struct ovsrec_ssl *ssl = ctx->ovs->ssl;
1413 ds_put_format(&ctx->output, "Private key: %s\n", ssl->private_key);
1414 ds_put_format(&ctx->output, "Certificate: %s\n", ssl->certificate);
1415 ds_put_format(&ctx->output, "CA Certificate: %s\n", ssl->ca_cert);
1416 ds_put_format(&ctx->output, "Bootstrap: %s\n",
1417 ssl->bootstrap_ca_cert ? "true" : "false");
1422 cmd_del_ssl(struct vsctl_context *ctx)
1424 struct ovsrec_ssl *ssl = ctx->ovs->ssl;
1427 ovsrec_ssl_delete(ssl);
1428 ovsrec_open_vswitch_set_ssl(ctx->ovs, NULL);
1433 cmd_set_ssl(struct vsctl_context *ctx)
1435 bool bootstrap = shash_find(&ctx->options, "--bootstrap");
1436 struct ovsrec_ssl *ssl = ctx->ovs->ssl;
1439 ovsrec_ssl_delete(ssl);
1441 ssl = ovsrec_ssl_insert(txn_from_openvswitch(ctx->ovs));
1443 ovsrec_ssl_set_private_key(ssl, ctx->argv[1]);
1444 ovsrec_ssl_set_certificate(ssl, ctx->argv[2]);
1445 ovsrec_ssl_set_ca_cert(ssl, ctx->argv[3]);
1447 ovsrec_ssl_set_bootstrap_ca_cert(ssl, bootstrap);
1449 ovsrec_open_vswitch_set_ssl(ctx->ovs, ssl);
1452 typedef void vsctl_handler_func(struct vsctl_context *);
1454 struct vsctl_command {
1458 vsctl_handler_func *handler;
1459 const char *options;
1462 static void run_vsctl_command(int argc, char *argv[],
1463 const struct ovsrec_open_vswitch *ovs,
1466 static struct json *
1467 where_uuid_equals(const struct uuid *uuid)
1470 json_array_create_1(
1471 json_array_create_3(
1472 json_string_create("_uuid"),
1473 json_string_create("=="),
1474 json_array_create_2(
1475 json_string_create("uuid"),
1476 json_string_create_nocopy(
1477 xasprintf(UUID_FMT, UUID_ARGS(uuid))))));
1481 do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
1483 struct ovsdb_idl_txn *txn;
1484 const struct ovsrec_open_vswitch *ovs;
1485 enum ovsdb_idl_txn_status status;
1486 struct ds comment, *output;
1491 txn = ovsdb_idl_txn_create(idl);
1493 ovsdb_idl_txn_set_dry_run(txn);
1497 ds_put_cstr(&comment, "ovs-vsctl:");
1498 for (i = 0; i < argc; i++) {
1499 ds_put_format(&comment, " %s", argv[i]);
1501 ovsdb_idl_txn_add_comment(txn, ds_cstr(&comment));
1502 ds_destroy(&comment);
1504 ovs = ovsrec_open_vswitch_first(idl);
1506 /* XXX add verification that table is empty */
1507 ovs = ovsrec_open_vswitch_insert(txn);
1510 if (wait_for_reload) {
1511 struct json *where = where_uuid_equals(&ovs->header_.uuid);
1512 ovsdb_idl_txn_increment(txn, "Open_vSwitch", "next_cfg",
1514 json_destroy(where);
1517 output = xmalloc(argc * sizeof *output);
1519 for (start = i = 0; i <= argc; i++) {
1520 if (i == argc || !strcmp(argv[i], "--")) {
1522 ds_init(&output[n_output]);
1523 run_vsctl_command(i - start, &argv[start], ovs,
1524 &output[n_output++]);
1530 while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
1532 ovsdb_idl_wait(idl);
1533 ovsdb_idl_txn_wait(txn);
1536 if (wait_for_reload && status == TXN_SUCCESS) {
1537 next_cfg = ovsdb_idl_txn_get_increment_new_value(txn);
1539 ovsdb_idl_txn_destroy(txn);
1542 case TXN_INCOMPLETE:
1546 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
1547 vsctl_fatal("transaction aborted");
1554 for (i = 0; i < n_output; i++) {
1555 ds_destroy(&output[i]);
1560 vsctl_fatal("transaction error");
1566 for (i = 0; i < n_output; i++) {
1567 struct ds *ds = &output[i];
1572 for (j = 0; j < ds->length; j++) {
1573 int c = ds->string[j];
1576 fputs("\\n", stdout);
1580 fputs("\\\\", stdout);
1589 fputs(ds_cstr(ds), stdout);
1593 if (wait_for_reload && status != TXN_UNCHANGED) {
1595 const struct ovsrec_open_vswitch *ovs;
1598 OVSREC_OPEN_VSWITCH_FOR_EACH (ovs, idl) {
1599 if (ovs->cur_cfg >= next_cfg) {
1603 ovsdb_idl_wait(idl);
1612 static vsctl_handler_func *
1613 get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx)
1615 static const struct vsctl_command all_commands[] = {
1616 /* Open vSwitch commands. */
1617 {"init", 0, 0, cmd_init, ""},
1619 /* Bridge commands. */
1620 {"add-br", 1, 3, cmd_add_br, ""},
1621 {"del-br", 1, 1, cmd_del_br, "--if-exists"},
1622 {"list-br", 0, 0, cmd_list_br, ""},
1623 {"br-exists", 1, 1, cmd_br_exists, ""},
1624 {"br-to-vlan", 1, 1, cmd_br_to_vlan, ""},
1625 {"br-to-parent", 1, 1, cmd_br_to_parent, ""},
1626 {"br-set-external-id", 2, 3, cmd_br_set_external_id, ""},
1627 {"br-get-external-id", 1, 2, cmd_br_get_external_id, ""},
1629 /* Port commands. */
1630 {"list-ports", 1, 1, cmd_list_ports, ""},
1631 {"add-port", 2, 2, cmd_add_port, ""},
1632 {"add-bond", 4, INT_MAX, cmd_add_bond, ""},
1633 {"del-port", 1, 2, cmd_del_port, "--if-exists"},
1634 {"port-to-br", 1, 1, cmd_port_to_br, ""},
1635 {"port-set-external-id", 2, 3, cmd_port_set_external_id, ""},
1636 {"port-get-external-id", 1, 2, cmd_port_get_external_id, ""},
1638 /* Interface commands. */
1639 {"list-ifaces", 1, 1, cmd_list_ifaces, ""},
1640 {"iface-to-br", 1, 1, cmd_iface_to_br, ""},
1641 {"iface-set-external-id", 2, 3, cmd_iface_set_external_id, ""},
1642 {"iface-get-external-id", 1, 2, cmd_iface_get_external_id, ""},
1644 /* Controller commands. */
1645 {"get-controller", 0, 1, cmd_get_controller, ""},
1646 {"del-controller", 0, 1, cmd_del_controller, ""},
1647 {"set-controller", 1, 2, cmd_set_controller, ""},
1648 {"get-fail-mode", 0, 1, cmd_get_fail_mode, ""},
1649 {"del-fail-mode", 0, 1, cmd_del_fail_mode, ""},
1650 {"set-fail-mode", 1, 2, cmd_set_fail_mode, ""},
1653 {"get-ssl", 0, 0, cmd_get_ssl, ""},
1654 {"del-ssl", 0, 0, cmd_del_ssl, ""},
1655 {"set-ssl", 3, 3, cmd_set_ssl, "--bootstrap"},
1658 const struct vsctl_command *p;
1661 shash_init(&ctx->options);
1662 for (i = 0; i < argc; i++) {
1663 if (argv[i][0] != '-') {
1666 if (!shash_add_once(&ctx->options, argv[i], NULL)) {
1667 vsctl_fatal("'%s' option specified multiple times", argv[i]);
1671 vsctl_fatal("missing command name");
1674 for (p = all_commands; p < &all_commands[ARRAY_SIZE(all_commands)]; p++) {
1675 if (!strcmp(p->name, argv[i])) {
1676 struct shash_node *node;
1679 SHASH_FOR_EACH (node, &ctx->options) {
1680 const char *s = strstr(p->options, node->name);
1681 int end = s ? s[strlen(node->name)] : EOF;
1682 if (end != ',' && end != ' ' && end != '\0') {
1683 vsctl_fatal("'%s' command has no '%s' option",
1684 argv[i], node->name);
1688 n_arg = argc - i - 1;
1689 if (n_arg < p->min_args) {
1690 vsctl_fatal("'%s' command requires at least %d arguments",
1691 p->name, p->min_args);
1692 } else if (n_arg > p->max_args) {
1693 vsctl_fatal("'%s' command takes at most %d arguments",
1694 p->name, p->max_args);
1696 ctx->argc = n_arg + 1;
1697 ctx->argv = &argv[i];
1703 vsctl_fatal("unknown command '%s'; use --help for help", argv[i]);
1707 check_vsctl_command(int argc, char *argv[])
1709 struct vsctl_context ctx;
1711 get_vsctl_handler(argc, argv, &ctx);
1712 shash_destroy(&ctx.options);
1716 run_vsctl_command(int argc, char *argv[],
1717 const struct ovsrec_open_vswitch *ovs, struct ds *output)
1719 vsctl_handler_func *function;
1720 struct vsctl_context ctx;
1722 function = get_vsctl_handler(argc, argv, &ctx);
1724 ds_init(&ctx.output);
1726 *output = ctx.output;
1727 shash_destroy(&ctx.options);