summaryrefslogtreecommitdiff
path: root/utilities
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2010-02-09 11:03:14 -0800
committerBen Pfaff <blp@nicira.com>2010-02-09 11:05:19 -0800
commitaeee85aab0f50f0408672a3150a41caf0a89cc3d (patch)
tree158f6ce715cc0ff7049d0e4a20d0e25f74ccf725 /utilities
parente6e7ab87927c009bc0652ab57aa70b28e81b17c1 (diff)
downloadopenvswitch-aeee85aab0f50f0408672a3150a41caf0a89cc3d.tar.gz
ovs-vsctl: Add --may-exist option for add-br command.
This will be used in the XenServer interface-reconfigure script.
Diffstat (limited to 'utilities')
-rw-r--r--utilities/ovs-vsctl.8.in13
-rw-r--r--utilities/ovs-vsctl.c69
2 files changed, 64 insertions, 18 deletions
diff --git a/utilities/ovs-vsctl.8.in b/utilities/ovs-vsctl.8.in
index 81daf719d..723a3af0d 100644
--- a/utilities/ovs-vsctl.8.in
+++ b/utilities/ovs-vsctl.8.in
@@ -132,16 +132,25 @@ initialize the database without executing any other command.
.SS "Bridge Commands"
These commands examine and manipulate Open vSwitch bridges.
.
-.IP "\fBadd\-br \fIbridge\fR"
+.IP "[\fB\-\-may\-exist\fR] \fBadd\-br \fIbridge\fR"
Creates a new bridge named \fIbridge\fR. Initially the bridge will
have no ports (other than \fIbridge\fR itself).
+.IP
+Without \fB\-\-may\-exist\fR, attempting to create a bridge that
+exists is an error. With \fB\-\-may\-exist\fR, \fIbridge\fR may
+already exist (but it must be a real bridge, not a VLAN bridge).
.
-.IP "\fBadd\-br \fIbridge parent vlan\fR"
+.IP "[\fB\-\-may\-exist\fR] \fBadd\-br \fIbridge parent vlan\fR"
Creates a ``fake bridge'' named \fIbridge\fR within the existing Open
vSwitch bridge \fIparent\fR, which must already exist and must not
itself be a fake bridge. The new fake bridge will be on 802.1Q VLAN
\fIvlan\fR, which must be an integer between 1 and 4095. Initially
\fIbridge\fR will have no ports (other than \fIbridge\fR itself).
+.IP
+Without \fB\-\-may\-exist\fR, attempting to create a bridge that
+exists is an error. With \fB\-\-may\-exist\fR, \fIbridge\fR may
+already exist (but it must have the specified \fIvlan\fR and
+\fIparent\fR).
.
.IP "[\fB\-\-if\-exists\fR] \fBdel\-br \fIbridge\fR"
Deletes \fIbridge\fR and all of its ports. If \fIbridge\fR is a real
diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c
index 18f3fd645..98b7cea7c 100644
--- a/utilities/ovs-vsctl.c
+++ b/utilities/ovs-vsctl.c
@@ -807,17 +807,65 @@ cmd_init(struct vsctl_context *ctx UNUSED)
static void
cmd_add_br(struct vsctl_context *ctx)
{
+ bool may_exist = shash_find(&ctx->options, "--may-exist") != 0;
const char *br_name = ctx->argv[1];
+ const char *parent_name = ctx->argc > 2 ? ctx->argv[2] : NULL;
+ int vlan = ctx->argc > 3 ? atoi(ctx->argv[3]) : 0;
struct vsctl_info info;
+ br_name = ctx->argv[1];
+ if (ctx->argc == 2) {
+ parent_name = NULL;
+ vlan = 0;
+ } else if (ctx->argc == 4) {
+ parent_name = ctx->argv[2];
+ vlan = atoi(ctx->argv[3]);
+ if (vlan < 1 || vlan > 4095) {
+ vsctl_fatal("%s: vlan must be between 1 and 4095", ctx->argv[0]);
+ }
+ } else {
+ vsctl_fatal("'%s' command takes exactly 1 or 3 arguments",
+ ctx->argv[0]);
+ }
+
get_info(ctx->ovs, &info);
+ if (may_exist) {
+ struct vsctl_bridge *br;
+
+ br = find_bridge(&info, br_name, false);
+ if (br) {
+ if (!parent_name) {
+ if (br->parent) {
+ vsctl_fatal("\"--may-exist add-br %s\" but %s is "
+ "a VLAN bridge for VLAN %d",
+ br_name, br_name, br->vlan);
+ }
+ } else {
+ if (!br->parent) {
+ vsctl_fatal("\"--may-exist add-br %s %s %d\" but %s "
+ "is not a VLAN bridge",
+ br_name, parent_name, vlan, br_name);
+ } else if (strcmp(br->parent->name, parent_name)) {
+ vsctl_fatal("\"--may-exist add-br %s %s %d\" but %s "
+ "has the wrong parent %s",
+ br_name, parent_name, vlan,
+ br_name, br->parent->name);
+ } else if (br->vlan != vlan) {
+ vsctl_fatal("\"--may-exist add-br %s %s %d\" but %s "
+ "is a VLAN bridge for the wrong VLAN %d",
+ br_name, parent_name, vlan, br_name, br->vlan);
+ }
+ }
+ return;
+ }
+ }
check_conflicts(&info, br_name,
xasprintf("cannot create a bridge named %s", br_name));
- if (ctx->argc == 2) {
- struct ovsrec_bridge *br;
+ if (!parent_name) {
struct ovsrec_port *port;
struct ovsrec_interface *iface;
+ struct ovsrec_bridge *br;
iface = ovsrec_interface_insert(ctx->txn);
ovsrec_interface_set_name(iface, br_name);
@@ -831,22 +879,13 @@ cmd_add_br(struct vsctl_context *ctx)
ovsrec_bridge_set_ports(br, &port, 1);
ovs_insert_bridge(ctx->ovs, br);
- } else if (ctx->argc == 3) {
- vsctl_fatal("'%s' command takes exactly 1 or 3 arguments",
- ctx->argv[0]);
- } else if (ctx->argc == 4) {
- const char *parent_name = ctx->argv[2];
- int vlan = atoi(ctx->argv[3]);
- struct ovsrec_bridge *br;
+ } else {
struct vsctl_bridge *parent;
struct ovsrec_port *port;
struct ovsrec_interface *iface;
+ struct ovsrec_bridge *br;
int64_t tag = vlan;
- if (vlan < 1 || vlan > 4095) {
- vsctl_fatal("%s: vlan must be between 1 and 4095", ctx->argv[0]);
- }
-
parent = find_bridge(&info, parent_name, false);
if (parent && parent->vlan) {
vsctl_fatal("cannot create bridge with fake bridge as parent");
@@ -867,8 +906,6 @@ cmd_add_br(struct vsctl_context *ctx)
ovsrec_port_set_tag(port, &tag, 1);
bridge_insert_port(br, port);
- } else {
- NOT_REACHED();
}
free_info(&info);
@@ -2362,7 +2399,7 @@ static const struct vsctl_command_syntax all_commands[] = {
{"init", 0, 0, cmd_init, NULL, ""},
/* Bridge commands. */
- {"add-br", 1, 3, cmd_add_br, NULL, ""},
+ {"add-br", 1, 3, cmd_add_br, NULL, "--may-exist"},
{"del-br", 1, 1, cmd_del_br, NULL, "--if-exists"},
{"list-br", 0, 0, cmd_list_br, NULL, ""},
{"br-exists", 1, 1, cmd_br_exists, NULL, ""},