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, bool fake_iface,
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);
1028 ovsrec_port_set_bond_fake_iface(port, fake_iface);
1032 int64_t tag = bridge->vlan;
1033 ovsrec_port_set_tag(port, &tag, 1);
1036 bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
1037 : bridge->br_cfg), port);
1043 cmd_add_port(struct vsctl_context *ctx)
1045 add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], false, &ctx->argv[2], 1);
1049 cmd_add_bond(struct vsctl_context *ctx)
1051 bool fake_iface = shash_find(&ctx->options, "--fake-iface");
1053 add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], fake_iface,
1054 &ctx->argv[3], ctx->argc - 3);
1058 cmd_del_port(struct vsctl_context *ctx)
1060 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1061 struct vsctl_info info;
1063 get_info(ctx->ovs, &info);
1064 if (ctx->argc == 2) {
1065 struct vsctl_port *port = find_port(&info, ctx->argv[1], must_exist);
1067 del_port(&info, port);
1069 } else if (ctx->argc == 3) {
1070 struct vsctl_bridge *bridge = find_bridge(&info, ctx->argv[1], true);
1071 struct vsctl_port *port = find_port(&info, ctx->argv[2], must_exist);
1074 if (port->bridge == bridge) {
1075 del_port(&info, port);
1076 } else if (port->bridge->parent == bridge) {
1077 vsctl_fatal("bridge %s does not have a port %s (although its "
1078 "parent bridge %s does)",
1079 ctx->argv[1], ctx->argv[2], bridge->parent->name);
1081 vsctl_fatal("bridge %s does not have a port %s",
1082 ctx->argv[1], ctx->argv[2]);
1090 cmd_port_to_br(struct vsctl_context *ctx)
1092 struct vsctl_port *port;
1093 struct vsctl_info info;
1095 get_info(ctx->ovs, &info);
1096 port = find_port(&info, ctx->argv[1], true);
1097 ds_put_format(&ctx->output, "%s\n", port->bridge->name);
1102 cmd_port_set_external_id(struct vsctl_context *ctx)
1104 struct vsctl_info info;
1105 struct vsctl_port *port;
1106 char **keys, **values;
1109 get_info(ctx->ovs, &info);
1110 port = find_port(&info, ctx->argv[1], true);
1111 set_external_id(port->port_cfg->key_external_ids,
1112 port->port_cfg->value_external_ids,
1113 port->port_cfg->n_external_ids,
1114 ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1115 &keys, &values, &n);
1116 ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
1124 cmd_port_get_external_id(struct vsctl_context *ctx)
1126 struct vsctl_info info;
1127 struct vsctl_port *port;
1129 get_info(ctx->ovs, &info);
1130 port = find_port(&info, ctx->argv[1], true);
1131 get_external_id(port->port_cfg->key_external_ids,
1132 port->port_cfg->value_external_ids,
1133 port->port_cfg->n_external_ids,
1134 "", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1139 cmd_br_to_vlan(struct vsctl_context *ctx)
1141 struct vsctl_bridge *bridge;
1142 struct vsctl_info info;
1144 get_info(ctx->ovs, &info);
1145 bridge = find_bridge(&info, ctx->argv[1], true);
1146 ds_put_format(&ctx->output, "%d\n", bridge->vlan);
1151 cmd_br_to_parent(struct vsctl_context *ctx)
1153 struct vsctl_bridge *bridge;
1154 struct vsctl_info info;
1156 get_info(ctx->ovs, &info);
1157 bridge = find_bridge(&info, ctx->argv[1], true);
1158 if (bridge->parent) {
1159 bridge = bridge->parent;
1161 ds_put_format(&ctx->output, "%s\n", bridge->name);
1166 cmd_list_ifaces(struct vsctl_context *ctx)
1168 struct vsctl_bridge *br;
1169 struct shash_node *node;
1170 struct vsctl_info info;
1173 get_info(ctx->ovs, &info);
1174 br = find_bridge(&info, ctx->argv[1], true);
1177 SHASH_FOR_EACH (node, &info.ifaces) {
1178 struct vsctl_iface *iface = node->data;
1180 if (strcmp(iface->iface_cfg->name, br->name)
1181 && br == iface->port->bridge) {
1182 svec_add(&ifaces, iface->iface_cfg->name);
1185 output_sorted(&ifaces, &ctx->output);
1186 svec_destroy(&ifaces);
1192 cmd_iface_to_br(struct vsctl_context *ctx)
1194 struct vsctl_iface *iface;
1195 struct vsctl_info info;
1197 get_info(ctx->ovs, &info);
1198 iface = find_iface(&info, ctx->argv[1], true);
1199 ds_put_format(&ctx->output, "%s\n", iface->port->bridge->name);
1204 cmd_iface_set_external_id(struct vsctl_context *ctx)
1206 struct vsctl_info info;
1207 struct vsctl_iface *iface;
1208 char **keys, **values;
1211 get_info(ctx->ovs, &info);
1212 iface = find_iface(&info, ctx->argv[1], true);
1213 set_external_id(iface->iface_cfg->key_external_ids,
1214 iface->iface_cfg->value_external_ids,
1215 iface->iface_cfg->n_external_ids,
1216 ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1217 &keys, &values, &n);
1218 ovsrec_interface_set_external_ids(iface->iface_cfg, keys, values, n);
1226 cmd_iface_get_external_id(struct vsctl_context *ctx)
1228 struct vsctl_info info;
1229 struct vsctl_iface *iface;
1231 get_info(ctx->ovs, &info);
1232 iface = find_iface(&info, ctx->argv[1], true);
1233 get_external_id(iface->iface_cfg->key_external_ids,
1234 iface->iface_cfg->value_external_ids,
1235 iface->iface_cfg->n_external_ids,
1236 "", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1241 cmd_get_controller(struct vsctl_context *ctx)
1243 struct vsctl_info info;
1245 get_info(ctx->ovs, &info);
1247 if (ctx->argc == 1) {
1248 /* Return the controller from the "Open_vSwitch" table */
1250 ds_put_format(&ctx->output, "%s\n", info.ctrl->target);
1253 /* Return the controller for a particular bridge. */
1254 struct vsctl_bridge *br = find_bridge(&info, ctx->argv[1], true);
1256 /* If no controller is explicitly defined for the requested
1257 * bridge, fallback to the "Open_vSwitch" table's controller. */
1259 ds_put_format(&ctx->output, "%s\n", br->ctrl->target);
1260 } else if (info.ctrl) {
1261 ds_put_format(&ctx->output, "%s\n", info.ctrl->target);
1269 cmd_del_controller(struct vsctl_context *ctx)
1271 struct vsctl_info info;
1273 get_info(ctx->ovs, &info);
1275 if (ctx->argc == 1) {
1277 ovsrec_controller_delete(info.ctrl);
1278 ovsrec_open_vswitch_set_controller(ctx->ovs, NULL);
1281 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1284 ovsrec_controller_delete(br->ctrl);
1285 ovsrec_bridge_set_controller(br->br_cfg, NULL);
1293 cmd_set_controller(struct vsctl_context *ctx)
1295 struct vsctl_info info;
1296 struct ovsrec_controller *ctrl;
1298 get_info(ctx->ovs, &info);
1300 if (ctx->argc == 2) {
1301 /* Set the controller in the "Open_vSwitch" table. */
1303 ovsrec_controller_delete(info.ctrl);
1305 ctrl = ovsrec_controller_insert(txn_from_openvswitch(ctx->ovs));
1306 ovsrec_controller_set_target(ctrl, ctx->argv[1]);
1307 ovsrec_open_vswitch_set_controller(ctx->ovs, ctrl);
1309 /* Set the controller for a particular bridge. */
1310 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1313 ovsrec_controller_delete(br->ctrl);
1315 ctrl = ovsrec_controller_insert(txn_from_openvswitch(ctx->ovs));
1316 ovsrec_controller_set_target(ctrl, ctx->argv[2]);
1317 ovsrec_bridge_set_controller(br->br_cfg, ctrl);
1324 cmd_get_fail_mode(struct vsctl_context *ctx)
1326 struct vsctl_info info;
1327 const char *fail_mode = NULL;
1329 get_info(ctx->ovs, &info);
1331 if (ctx->argc == 1) {
1332 /* Return the fail-mode from the "Open_vSwitch" table */
1333 if (info.ctrl && info.ctrl->fail_mode) {
1334 fail_mode = info.ctrl->fail_mode;
1337 /* Return the fail-mode for a particular bridge. */
1338 struct vsctl_bridge *br = find_bridge(&info, ctx->argv[1], true);
1340 /* If no controller or fail-mode is explicitly defined for the
1341 * requested bridge, fallback to the "Open_vSwitch" table's
1343 if (br->ctrl && br->ctrl->fail_mode) {
1344 fail_mode = br->ctrl->fail_mode;
1345 } else if (info.ctrl && info.ctrl->fail_mode) {
1346 fail_mode = info.ctrl->fail_mode;
1350 if (fail_mode && strlen(fail_mode)) {
1351 ds_put_format(&ctx->output, "%s\n", fail_mode);
1358 cmd_del_fail_mode(struct vsctl_context *ctx)
1360 struct vsctl_info info;
1362 get_info(ctx->ovs, &info);
1364 if (ctx->argc == 1) {
1365 if (info.ctrl && info.ctrl->fail_mode) {
1366 ovsrec_controller_set_fail_mode(info.ctrl, NULL);
1369 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1371 if (br->ctrl && br->ctrl->fail_mode) {
1372 ovsrec_controller_set_fail_mode(br->ctrl, NULL);
1380 cmd_set_fail_mode(struct vsctl_context *ctx)
1382 struct vsctl_info info;
1383 const char *fail_mode;
1385 get_info(ctx->ovs, &info);
1387 fail_mode = (ctx->argc == 2) ? ctx->argv[1] : ctx->argv[2];
1389 if (strcmp(fail_mode, "standalone") && strcmp(fail_mode, "secure")) {
1390 vsctl_fatal("fail-mode must be \"standalone\" or \"secure\"");
1393 if (ctx->argc == 2) {
1394 /* Set the fail-mode in the "Open_vSwitch" table. */
1396 vsctl_fatal("no controller declared");
1398 ovsrec_controller_set_fail_mode(info.ctrl, fail_mode);
1400 struct vsctl_bridge *br = find_real_bridge(&info, ctx->argv[1], true);
1403 vsctl_fatal("no controller declared for %s", br->name);
1405 ovsrec_controller_set_fail_mode(br->ctrl, fail_mode);
1412 cmd_get_ssl(struct vsctl_context *ctx)
1414 struct ovsrec_ssl *ssl = ctx->ovs->ssl;
1417 ds_put_format(&ctx->output, "Private key: %s\n", ssl->private_key);
1418 ds_put_format(&ctx->output, "Certificate: %s\n", ssl->certificate);
1419 ds_put_format(&ctx->output, "CA Certificate: %s\n", ssl->ca_cert);
1420 ds_put_format(&ctx->output, "Bootstrap: %s\n",
1421 ssl->bootstrap_ca_cert ? "true" : "false");
1426 cmd_del_ssl(struct vsctl_context *ctx)
1428 struct ovsrec_ssl *ssl = ctx->ovs->ssl;
1431 ovsrec_ssl_delete(ssl);
1432 ovsrec_open_vswitch_set_ssl(ctx->ovs, NULL);
1437 cmd_set_ssl(struct vsctl_context *ctx)
1439 bool bootstrap = shash_find(&ctx->options, "--bootstrap");
1440 struct ovsrec_ssl *ssl = ctx->ovs->ssl;
1443 ovsrec_ssl_delete(ssl);
1445 ssl = ovsrec_ssl_insert(txn_from_openvswitch(ctx->ovs));
1447 ovsrec_ssl_set_private_key(ssl, ctx->argv[1]);
1448 ovsrec_ssl_set_certificate(ssl, ctx->argv[2]);
1449 ovsrec_ssl_set_ca_cert(ssl, ctx->argv[3]);
1451 ovsrec_ssl_set_bootstrap_ca_cert(ssl, bootstrap);
1453 ovsrec_open_vswitch_set_ssl(ctx->ovs, ssl);
1456 typedef void vsctl_handler_func(struct vsctl_context *);
1458 struct vsctl_command {
1462 vsctl_handler_func *handler;
1463 const char *options;
1466 static void run_vsctl_command(int argc, char *argv[],
1467 const struct ovsrec_open_vswitch *ovs,
1470 static struct json *
1471 where_uuid_equals(const struct uuid *uuid)
1474 json_array_create_1(
1475 json_array_create_3(
1476 json_string_create("_uuid"),
1477 json_string_create("=="),
1478 json_array_create_2(
1479 json_string_create("uuid"),
1480 json_string_create_nocopy(
1481 xasprintf(UUID_FMT, UUID_ARGS(uuid))))));
1485 do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
1487 struct ovsdb_idl_txn *txn;
1488 const struct ovsrec_open_vswitch *ovs;
1489 enum ovsdb_idl_txn_status status;
1490 struct ds comment, *output;
1495 txn = ovsdb_idl_txn_create(idl);
1497 ovsdb_idl_txn_set_dry_run(txn);
1501 ds_put_cstr(&comment, "ovs-vsctl:");
1502 for (i = 0; i < argc; i++) {
1503 ds_put_format(&comment, " %s", argv[i]);
1505 ovsdb_idl_txn_add_comment(txn, ds_cstr(&comment));
1506 ds_destroy(&comment);
1508 ovs = ovsrec_open_vswitch_first(idl);
1510 /* XXX add verification that table is empty */
1511 ovs = ovsrec_open_vswitch_insert(txn);
1514 if (wait_for_reload) {
1515 struct json *where = where_uuid_equals(&ovs->header_.uuid);
1516 ovsdb_idl_txn_increment(txn, "Open_vSwitch", "next_cfg",
1518 json_destroy(where);
1521 output = xmalloc(argc * sizeof *output);
1523 for (start = i = 0; i <= argc; i++) {
1524 if (i == argc || !strcmp(argv[i], "--")) {
1526 ds_init(&output[n_output]);
1527 run_vsctl_command(i - start, &argv[start], ovs,
1528 &output[n_output++]);
1534 while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
1536 ovsdb_idl_wait(idl);
1537 ovsdb_idl_txn_wait(txn);
1540 if (wait_for_reload && status == TXN_SUCCESS) {
1541 next_cfg = ovsdb_idl_txn_get_increment_new_value(txn);
1543 ovsdb_idl_txn_destroy(txn);
1546 case TXN_INCOMPLETE:
1550 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
1551 vsctl_fatal("transaction aborted");
1558 for (i = 0; i < n_output; i++) {
1559 ds_destroy(&output[i]);
1564 vsctl_fatal("transaction error");
1570 for (i = 0; i < n_output; i++) {
1571 struct ds *ds = &output[i];
1576 for (j = 0; j < ds->length; j++) {
1577 int c = ds->string[j];
1580 fputs("\\n", stdout);
1584 fputs("\\\\", stdout);
1593 fputs(ds_cstr(ds), stdout);
1597 if (wait_for_reload && status != TXN_UNCHANGED) {
1599 const struct ovsrec_open_vswitch *ovs;
1602 OVSREC_OPEN_VSWITCH_FOR_EACH (ovs, idl) {
1603 if (ovs->cur_cfg >= next_cfg) {
1607 ovsdb_idl_wait(idl);
1616 static vsctl_handler_func *
1617 get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx)
1619 static const struct vsctl_command all_commands[] = {
1620 /* Open vSwitch commands. */
1621 {"init", 0, 0, cmd_init, ""},
1623 /* Bridge commands. */
1624 {"add-br", 1, 3, cmd_add_br, ""},
1625 {"del-br", 1, 1, cmd_del_br, "--if-exists"},
1626 {"list-br", 0, 0, cmd_list_br, ""},
1627 {"br-exists", 1, 1, cmd_br_exists, ""},
1628 {"br-to-vlan", 1, 1, cmd_br_to_vlan, ""},
1629 {"br-to-parent", 1, 1, cmd_br_to_parent, ""},
1630 {"br-set-external-id", 2, 3, cmd_br_set_external_id, ""},
1631 {"br-get-external-id", 1, 2, cmd_br_get_external_id, ""},
1633 /* Port commands. */
1634 {"list-ports", 1, 1, cmd_list_ports, ""},
1635 {"add-port", 2, 2, cmd_add_port, ""},
1636 {"add-bond", 4, INT_MAX, cmd_add_bond, "--fake-iface"},
1637 {"del-port", 1, 2, cmd_del_port, "--if-exists"},
1638 {"port-to-br", 1, 1, cmd_port_to_br, ""},
1639 {"port-set-external-id", 2, 3, cmd_port_set_external_id, ""},
1640 {"port-get-external-id", 1, 2, cmd_port_get_external_id, ""},
1642 /* Interface commands. */
1643 {"list-ifaces", 1, 1, cmd_list_ifaces, ""},
1644 {"iface-to-br", 1, 1, cmd_iface_to_br, ""},
1645 {"iface-set-external-id", 2, 3, cmd_iface_set_external_id, ""},
1646 {"iface-get-external-id", 1, 2, cmd_iface_get_external_id, ""},
1648 /* Controller commands. */
1649 {"get-controller", 0, 1, cmd_get_controller, ""},
1650 {"del-controller", 0, 1, cmd_del_controller, ""},
1651 {"set-controller", 1, 2, cmd_set_controller, ""},
1652 {"get-fail-mode", 0, 1, cmd_get_fail_mode, ""},
1653 {"del-fail-mode", 0, 1, cmd_del_fail_mode, ""},
1654 {"set-fail-mode", 1, 2, cmd_set_fail_mode, ""},
1657 {"get-ssl", 0, 0, cmd_get_ssl, ""},
1658 {"del-ssl", 0, 0, cmd_del_ssl, ""},
1659 {"set-ssl", 3, 3, cmd_set_ssl, "--bootstrap"},
1662 const struct vsctl_command *p;
1665 shash_init(&ctx->options);
1666 for (i = 0; i < argc; i++) {
1667 if (argv[i][0] != '-') {
1670 if (!shash_add_once(&ctx->options, argv[i], NULL)) {
1671 vsctl_fatal("'%s' option specified multiple times", argv[i]);
1675 vsctl_fatal("missing command name");
1678 for (p = all_commands; p < &all_commands[ARRAY_SIZE(all_commands)]; p++) {
1679 if (!strcmp(p->name, argv[i])) {
1680 struct shash_node *node;
1683 SHASH_FOR_EACH (node, &ctx->options) {
1684 const char *s = strstr(p->options, node->name);
1685 int end = s ? s[strlen(node->name)] : EOF;
1686 if (end != ',' && end != ' ' && end != '\0') {
1687 vsctl_fatal("'%s' command has no '%s' option",
1688 argv[i], node->name);
1692 n_arg = argc - i - 1;
1693 if (n_arg < p->min_args) {
1694 vsctl_fatal("'%s' command requires at least %d arguments",
1695 p->name, p->min_args);
1696 } else if (n_arg > p->max_args) {
1697 vsctl_fatal("'%s' command takes at most %d arguments",
1698 p->name, p->max_args);
1700 ctx->argc = n_arg + 1;
1701 ctx->argv = &argv[i];
1707 vsctl_fatal("unknown command '%s'; use --help for help", argv[i]);
1711 check_vsctl_command(int argc, char *argv[])
1713 struct vsctl_context ctx;
1715 get_vsctl_handler(argc, argv, &ctx);
1716 shash_destroy(&ctx.options);
1720 run_vsctl_command(int argc, char *argv[],
1721 const struct ovsrec_open_vswitch *ovs, struct ds *output)
1723 vsctl_handler_func *function;
1724 struct vsctl_context ctx;
1726 function = get_vsctl_handler(argc, argv, &ctx);
1728 ds_init(&ctx.output);
1730 *output = ctx.output;
1731 shash_destroy(&ctx.options);