aboutsummaryrefslogtreecommitdiff
path: root/utilities
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2011-10-17 11:24:37 -0700
committerBen Pfaff <blp@nicira.com>2011-10-24 12:23:28 -0700
commit10500639d5756986a587116ca1b8b42764f5ace2 (patch)
treef20d2409615181cd70fe3ba0596d2896ce1f8e66 /utilities
parent4be00e48e29f84e9b08e590ac2e3adbc9d99273f (diff)
ovs-dpctl: Add new "set-if" command.
I have found this useful for testing tunnel configuration.
Diffstat (limited to 'utilities')
-rw-r--r--utilities/ovs-dpctl.8.in13
-rw-r--r--utilities/ovs-dpctl.c101
2 files changed, 111 insertions, 3 deletions
diff --git a/utilities/ovs-dpctl.8.in b/utilities/ovs-dpctl.8.in
index ee124484..bf7f97f6 100644
--- a/utilities/ovs-dpctl.8.in
+++ b/utilities/ovs-dpctl.8.in
@@ -34,11 +34,12 @@ default provider \fBsystem\fR is assumed.
The following commands manage datapaths.
.
.TP
-\fBadd\-dp \fIdp\fR [\fInetdev\fR...]
+\fBadd\-dp \fIdp\fR [\fInetdev\fR[\fB,\fIoption\fR]...]
Creates datapath \fIdp\fR, with a local port also named \fIdp\fR.
This will fail if a network device \fIdp\fR already exists.
.IP
-If \fInetdev\fRs are specified, \fBovs\-dpctl\fR adds them to the datapath.
+If \fInetdev\fRs are specified, \fBovs\-dpctl\fR adds them to the
+new datapath, just as if \fBadd\-if\fR was specified.
.
.TP
\fBdel\-dp \fIdp\fR
@@ -68,6 +69,14 @@ Adds an arbitrary key-value option to the port's configuration.
\fBovs\-vswitchd.conf.db\fR(5) documents the available port types and
options.
.
+.IP "\fBset\-if \fIdp port\fR[\fB,\fIoption\fR]..."
+Reconfigures each \fIport\fR in \fIdp\fR as specified. An
+\fIoption\fR of the form \fIkey\fB=\fIvalue\fR adds the specified
+key-value option to the port or overrides an existing key's value. An
+\fIoption\fR of the form \fIkey\fB=\fR, that is, without a value,
+deletes the key-value named \fIkey\fR. The type of a port cannot be
+changed, so \fBtype=\fItype\fR is only allowed if \fItype\fR is the
+port's existing type.
.TP
\fBdel\-if \fIdp netdev\fR...
Removes each \fInetdev\fR from the list of network devices datapath
diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c
index d78fb317..499d4945 100644
--- a/utilities/ovs-dpctl.c
+++ b/utilities/ovs-dpctl.c
@@ -131,12 +131,16 @@ usage(void)
" add-dp DP [IFACE...] add new datapath DP (with IFACEs)\n"
" del-dp DP delete local datapath DP\n"
" add-if DP IFACE... add each IFACE as a port on DP\n"
+ " set-if DP IFACE... reconfigure each IFACE within DP\n"
" del-if DP IFACE... delete each IFACE from DP\n"
" dump-dps display names of all datapaths\n"
" show show basic info on all datapaths\n"
" show DP... show basic info on each DP\n"
" dump-flows DP display flows in DP\n"
- " del-flows DP delete all flows from DP\n",
+ " del-flows DP delete all flows from DP\n"
+ "Each IFACE on add-dp, add-if, and set-if may be followed by\n"
+ "comma-separated options. See ovs-dpctl(8) for syntax, or the\n"
+ "Interface table in ovs-vswitchd.conf.db(5) for an options list.\n",
program_name, program_name);
vlog_usage();
printf("\nOther options:\n"
@@ -234,6 +238,7 @@ do_add_if(int argc OVS_UNUSED, char *argv[])
if (!name) {
ovs_error(0, "%s is not a valid network device name", argv[i]);
+ failure = true;
continue;
}
@@ -287,6 +292,99 @@ next:
}
}
+static void
+do_set_if(int argc, char *argv[])
+{
+ bool failure = false;
+ struct dpif *dpif;
+ int i;
+
+ run(parsed_dpif_open(argv[1], false, &dpif), "opening datapath");
+ for (i = 2; i < argc; i++) {
+ struct netdev *netdev = NULL;
+ struct dpif_port dpif_port;
+ char *save_ptr = NULL;
+ char *type = NULL;
+ const char *name;
+ struct shash args;
+ char *option;
+ int error;
+
+ name = strtok_r(argv[i], ",", &save_ptr);
+ if (!name) {
+ ovs_error(0, "%s is not a valid network device name", argv[i]);
+ failure = true;
+ continue;
+ }
+
+ /* Get the port's type from the datapath. */
+ error = dpif_port_query_by_name(dpif, name, &dpif_port);
+ if (error) {
+ ovs_error(error, "%s: failed to query port in %s", name, argv[1]);
+ goto next;
+ }
+ type = xstrdup(dpif_port.type);
+ dpif_port_destroy(&dpif_port);
+
+ /* Retrieve its existing configuration. */
+ error = netdev_open(name, type, &netdev);
+ if (error) {
+ ovs_error(error, "%s: failed to open network device", name);
+ goto next;
+ }
+
+ shash_init(&args);
+ error = netdev_get_config(netdev, &args);
+ if (error) {
+ ovs_error(error, "%s: failed to fetch configuration", name);
+ goto next;
+ }
+
+ /* Parse changes to configuration. */
+ while ((option = strtok_r(NULL, ",", &save_ptr)) != NULL) {
+ char *save_ptr_2 = NULL;
+ char *key, *value;
+
+ key = strtok_r(option, "=", &save_ptr_2);
+ value = strtok_r(NULL, "", &save_ptr_2);
+ if (!value) {
+ value = "";
+ }
+
+ if (!strcmp(key, "type")) {
+ if (strcmp(value, type)) {
+ ovs_error(0, "%s: can't change type from %s to %s",
+ name, type, value);
+ failure = true;
+ }
+ } else if (value[0] == '\0') {
+ free(shash_find_and_delete(&args, key));
+ } else {
+ free(shash_replace(&args, key, xstrdup(value)));
+ }
+ }
+
+ /* Update configuration. */
+ error = netdev_set_config(netdev, &args);
+ smap_destroy(&args);
+ if (error) {
+ ovs_error(error, "%s: failed to configure network device", name);
+ goto next;
+ }
+
+next:
+ free(type);
+ netdev_close(netdev);
+ if (error) {
+ failure = true;
+ }
+ }
+ dpif_close(dpif);
+ if (failure) {
+ exit(EXIT_FAILURE);
+ }
+}
+
static bool
get_port_number(struct dpif *dpif, const char *name, uint16_t *port)
{
@@ -600,6 +698,7 @@ static const struct command all_commands[] = {
{ "del-dp", 1, 1, do_del_dp },
{ "add-if", 2, INT_MAX, do_add_if },
{ "del-if", 2, INT_MAX, do_del_if },
+ { "set-if", 2, INT_MAX, do_set_if },
{ "dump-dps", 0, 0, do_dump_dps },
{ "show", 0, INT_MAX, do_show },
{ "dump-flows", 1, 1, do_dump_flows },