mirror of
https://github.com/openvswitch/ovs
synced 2025-09-01 06:45:17 +00:00
ovs-vsctl: Fix bugs.
The full ovs-vsctl test suite now passes.
This commit is contained in:
@@ -130,7 +130,9 @@ m4_define([CHECK_IFACES],
|
|||||||
[RUN_OVS_VSCTL([list-ifaces $1])],
|
[RUN_OVS_VSCTL([list-ifaces $1])],
|
||||||
[0],
|
[0],
|
||||||
[m4_foreach([iface], m4_cdr($@), [iface
|
[m4_foreach([iface], m4_cdr($@), [iface
|
||||||
])])
|
])],
|
||||||
|
[],
|
||||||
|
[OVS_VSCTL_CLEANUP])
|
||||||
AT_CHECK([RUN_OVS_VSCTL([iface-to-br $1])], [1], [],
|
AT_CHECK([RUN_OVS_VSCTL([iface-to-br $1])], [1], [],
|
||||||
[ovs-vsctl: no interface named $1
|
[ovs-vsctl: no interface named $1
|
||||||
],
|
],
|
||||||
@@ -192,7 +194,7 @@ AT_SETUP([add-br a, add-port a a1, add-port a a2])
|
|||||||
AT_KEYWORDS([ovs-vsctl])
|
AT_KEYWORDS([ovs-vsctl])
|
||||||
OVS_VSCTL_SETUP
|
OVS_VSCTL_SETUP
|
||||||
AT_CHECK([RUN_OVS_VSCTL(
|
AT_CHECK([RUN_OVS_VSCTL(
|
||||||
[add-br a],
|
[add-br a],
|
||||||
[add-port a a1],
|
[add-port a a1],
|
||||||
[add-port a a2])], [0], [], [], [OVS_VSCTL_CLEANUP])
|
[add-port a a2])], [0], [], [], [OVS_VSCTL_CLEANUP])
|
||||||
CHECK_BRIDGES([a, a, 0])
|
CHECK_BRIDGES([a, a, 0])
|
||||||
@@ -269,31 +271,23 @@ CHECK_PORTS([a])
|
|||||||
OVS_VSCTL_CLEANUP
|
OVS_VSCTL_CLEANUP
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
m4_define([ovs_vsctl_disabled_tests], [
|
|
||||||
dnl ----------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------
|
||||||
AT_BANNER([ovs-vsctl unit tests -- fake bridges])
|
AT_BANNER([ovs-vsctl unit tests -- fake bridges])
|
||||||
|
|
||||||
m4_define([SIMPLE_FAKE_CONF], [dnl
|
m4_define([OVS_VSCTL_SETUP_SIMPLE_FAKE_CONF],
|
||||||
bridge.xenbr0.port=eth0
|
[AT_CHECK(
|
||||||
bridge.xenbr0.port=eth0.9
|
[RUN_OVS_VSCTL(
|
||||||
bridge.xenbr0.port=xapi1
|
[add-br xenbr0],
|
||||||
bridge.xenbr0.port=xenbr0
|
[add-port xenbr0 eth0],
|
||||||
iface.xapi1.fake-bridge=true
|
[add-br xapi1 xenbr0 9],
|
||||||
iface.xapi1.internal=true
|
[add-port xapi1 eth0.9])],
|
||||||
vlan.eth0.9.tag=9
|
[0], [], [], [OVS_VSCTL_CLEANUP])])
|
||||||
vlan.xapi1.tag=9
|
|
||||||
])
|
|
||||||
|
|
||||||
AT_SETUP([simple fake bridge])
|
AT_SETUP([simple fake bridge])
|
||||||
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
||||||
OVS_VSCTL_SETUP
|
OVS_VSCTL_SETUP
|
||||||
AT_CHECK([RUN_OVS_VSCTL(
|
OVS_VSCTL_SETUP_SIMPLE_FAKE_CONF
|
||||||
[add-br xenbr0],
|
CHECK_BRIDGES([xapi1, xenbr0, 9], [xenbr0, xenbr0, 0])
|
||||||
[add-port xenbr0 eth0],
|
|
||||||
[add-br xapi1 xenbr0 9],
|
|
||||||
[add-port xapi1 eth0.9])])
|
|
||||||
AT_CHECK([cat conf], [0], [SIMPLE_FAKE_CONF])
|
|
||||||
CHECK_BRIDGES([xenbr0, xenbr0, 0], [xapi1, xenbr0, 9])
|
|
||||||
CHECK_PORTS([xenbr0], [eth0])
|
CHECK_PORTS([xenbr0], [eth0])
|
||||||
CHECK_IFACES([xenbr0], [eth0])
|
CHECK_IFACES([xenbr0], [eth0])
|
||||||
CHECK_PORTS([xapi1], [eth0.9])
|
CHECK_PORTS([xapi1], [eth0.9])
|
||||||
@@ -304,12 +298,8 @@ AT_CLEANUP
|
|||||||
AT_SETUP([simple fake bridge + del-br fake bridge])
|
AT_SETUP([simple fake bridge + del-br fake bridge])
|
||||||
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
||||||
OVS_VSCTL_SETUP
|
OVS_VSCTL_SETUP
|
||||||
AT_DATA([conf], [SIMPLE_FAKE_CONF])
|
OVS_VSCTL_SETUP_SIMPLE_FAKE_CONF
|
||||||
AT_CHECK([RUN_OVS_VSCTL([del-br xapi1])])
|
AT_CHECK([RUN_OVS_VSCTL([del-br xapi1])], [0], [], [], [OVS_VSCTL_CLEANUP])
|
||||||
AT_CHECK([cat conf], [0], [dnl
|
|
||||||
bridge.xenbr0.port=eth0
|
|
||||||
bridge.xenbr0.port=xenbr0
|
|
||||||
])
|
|
||||||
CHECK_BRIDGES([xenbr0, xenbr0, 0])
|
CHECK_BRIDGES([xenbr0, xenbr0, 0])
|
||||||
CHECK_PORTS([xenbr0], [eth0])
|
CHECK_PORTS([xenbr0], [eth0])
|
||||||
CHECK_IFACES([xenbr0], [eth0])
|
CHECK_IFACES([xenbr0], [eth0])
|
||||||
@@ -319,35 +309,25 @@ AT_CLEANUP
|
|||||||
AT_SETUP([simple fake bridge + del-br real bridge])
|
AT_SETUP([simple fake bridge + del-br real bridge])
|
||||||
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
||||||
OVS_VSCTL_SETUP
|
OVS_VSCTL_SETUP
|
||||||
AT_DATA([conf], [SIMPLE_FAKE_CONF])
|
OVS_VSCTL_SETUP_SIMPLE_FAKE_CONF
|
||||||
AT_CHECK([RUN_OVS_VSCTL([del-br xenbr0])])
|
AT_CHECK([RUN_OVS_VSCTL([del-br xenbr0])], [0], [], [], [OVS_VSCTL_CLEANUP])
|
||||||
AT_CHECK([cat conf], [0], [])
|
|
||||||
CHECK_BRIDGES
|
CHECK_BRIDGES
|
||||||
OVS_VSCTL_CLEANUP
|
OVS_VSCTL_CLEANUP
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
m4_define([BOND_FAKE_CONF], [dnl
|
m4_define([OVS_VSCTL_SETUP_BOND_FAKE_CONF],
|
||||||
bonding.bond0.slave=eth0
|
[AT_CHECK(
|
||||||
bonding.bond0.slave=eth1
|
[RUN_OVS_VSCTL(
|
||||||
bridge.xapi1.port=bond0
|
[add-br xapi1],
|
||||||
bridge.xapi1.port=bond0.11
|
[add-bond xapi1 bond0 eth0 eth1],
|
||||||
bridge.xapi1.port=xapi1
|
[add-br xapi2 xapi1 11],
|
||||||
bridge.xapi1.port=xapi2
|
[add-port xapi2 bond0.11])],
|
||||||
iface.xapi2.fake-bridge=true
|
[0], [], [], [OVS_VSCTL_CLEANUP])])
|
||||||
iface.xapi2.internal=true
|
|
||||||
vlan.bond0.11.tag=11
|
|
||||||
vlan.xapi2.tag=11
|
|
||||||
])
|
|
||||||
|
|
||||||
AT_SETUP([fake bridge on bond])
|
AT_SETUP([fake bridge on bond])
|
||||||
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
||||||
OVS_VSCTL_SETUP
|
OVS_VSCTL_SETUP
|
||||||
AT_CHECK([RUN_OVS_VSCTL(
|
OVS_VSCTL_SETUP_BOND_FAKE_CONF
|
||||||
[add-br xapi1],
|
|
||||||
[add-bond xapi1 bond0 eth0 eth1],
|
|
||||||
[add-br xapi2 xapi1 11],
|
|
||||||
[add-port xapi2 bond0.11])])
|
|
||||||
AT_CHECK([cat conf], [0], [BOND_FAKE_CONF])
|
|
||||||
CHECK_BRIDGES([xapi1, xapi1, 0], [xapi2, xapi1, 11])
|
CHECK_BRIDGES([xapi1, xapi1, 0], [xapi2, xapi1, 11])
|
||||||
CHECK_PORTS([xapi1], [bond0])
|
CHECK_PORTS([xapi1], [bond0])
|
||||||
CHECK_IFACES([xapi1], [eth0], [eth1])
|
CHECK_IFACES([xapi1], [eth0], [eth1])
|
||||||
@@ -359,9 +339,9 @@ AT_CLEANUP
|
|||||||
AT_SETUP([fake bridge on bond + del-br fake bridge])
|
AT_SETUP([fake bridge on bond + del-br fake bridge])
|
||||||
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
||||||
OVS_VSCTL_SETUP
|
OVS_VSCTL_SETUP
|
||||||
AT_DATA([conf], [BOND_FAKE_CONF])
|
OVS_VSCTL_SETUP_BOND_FAKE_CONF
|
||||||
AT_CHECK([RUN_OVS_VSCTL([--oneline del-br xapi2])], [0], [
|
AT_CHECK([RUN_OVS_VSCTL([--oneline del-br xapi2])], [0], [
|
||||||
])
|
], [], [OVS_VSCTL_CLEANUP])
|
||||||
CHECK_BRIDGES([xapi1, xapi1, 0])
|
CHECK_BRIDGES([xapi1, xapi1, 0])
|
||||||
CHECK_PORTS([xapi1], [bond0])
|
CHECK_PORTS([xapi1], [bond0])
|
||||||
CHECK_IFACES([xapi1], [eth0], [eth1])
|
CHECK_IFACES([xapi1], [eth0], [eth1])
|
||||||
@@ -370,9 +350,9 @@ AT_CLEANUP
|
|||||||
|
|
||||||
AT_SETUP([fake bridge on bond + del-br real bridge])
|
AT_SETUP([fake bridge on bond + del-br real bridge])
|
||||||
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
AT_KEYWORDS([ovs-vsctl fake-bridge])
|
||||||
AT_DATA([conf], [BOND_FAKE_CONF])
|
OVS_VSCTL_SETUP
|
||||||
|
OVS_VSCTL_SETUP_BOND_FAKE_CONF
|
||||||
AT_CHECK([RUN_OVS_VSCTL([del-br xapi1])])
|
AT_CHECK([RUN_OVS_VSCTL([del-br xapi1])])
|
||||||
CHECK_BRIDGES
|
CHECK_BRIDGES
|
||||||
OVS_VSCTL_CLEANUP
|
OVS_VSCTL_CLEANUP
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
])
|
|
||||||
|
@@ -15,20 +15,20 @@ ovs\-vsctl \- utility for querying and configuring \fBovs\-vswitchd\fR
|
|||||||
[\fB\-\-\fR \fIcommand \fR[\fIargs\fR\&...]]
|
[\fB\-\-\fR \fIcommand \fR[\fIargs\fR\&...]]
|
||||||
.
|
.
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBovs\-vsctl\fR program configures \fBovs\-vswitchd\fR(8), mainly
|
The \fBovs\-vsctl\fR program configures \fBovs\-vswitchd\fR(8) by
|
||||||
by providing a high\-level interface to editing its configuration file
|
providing a high\-level interface to editing its configuration
|
||||||
\fBovs\-vswitchd.conf\fR(5). This program is mainly intended for use
|
database. This program is mainly intended for use when
|
||||||
when \fBovs\-vswitchd\fR is running, but it can also be used when
|
\fBovs\-vswitchd\fR is running. If it is used when
|
||||||
\fBovs\-vswitchd\fR is not running. In the latter case configuration
|
\fBovs\-vswitchd\fR is not running, then \fB\-\-no\-wait\fR should be
|
||||||
changes will only take effect when \fBovs\-vswitchd\fR is started.
|
specified and configuration changes will only take effect when
|
||||||
|
\fBovs\-vswitchd\fR is started.
|
||||||
.PP
|
.PP
|
||||||
By default, each time \fBovs\-vsctl\fR runs, it examines and,
|
By default, each time \fBovs\-vsctl\fR runs, it connects to an
|
||||||
depending on the requested command or commands, possibly applies
|
\fBovsdb\-server\fR process that maintains an Open vSwitch
|
||||||
changes to an
|
configuration database. Using this connection, it queries and
|
||||||
\fBovs\-vswitchd.conf\fR file. Then, if it applied any changes and if
|
possibly applies changes to the database, depending on the supplied
|
||||||
\fBovs\-vswitchd\fR is running, it tells \fBovs\-vswitchd\fR to reload
|
commands. Then, if it applied any changes, it waits until
|
||||||
the modified configuration file and waits for the reload to complete
|
\fBovs\-vswitchd\fR has finished reconfiguring itself before it exits.
|
||||||
before exiting.
|
|
||||||
.
|
.
|
||||||
.SS "Linux VLAN Bridging Compatibility"
|
.SS "Linux VLAN Bridging Compatibility"
|
||||||
The \fBovs\-vsctl\fR program supports the model of a bridge
|
The \fBovs\-vsctl\fR program supports the model of a bridge
|
||||||
@@ -54,46 +54,34 @@ they are members.
|
|||||||
The following options affect the general outline of \fBovs\-vsctl\fR's
|
The following options affect the general outline of \fBovs\-vsctl\fR's
|
||||||
activities:
|
activities:
|
||||||
.
|
.
|
||||||
.IP "\fB\-c \fIfile\fR"
|
.IP "\fB\-\-db=\fIserver\fR"
|
||||||
.IQ "\fB\-\-config=\fIfile\fR"
|
Sets \fIserver\fR as the database server that \fBovs\-vsctl\fR
|
||||||
Sets the configuration file that \fBovs\-vsctl\fR reads and possibly
|
contacts to query or modify configuration. The default is
|
||||||
modifies. The default is \fB@localstatedir@/ovs\-vswitchd.conf\fR.
|
\fBunix:@RUNDIR@/ovsdb\-server\fR. \fIserver\fR must take one of the
|
||||||
|
following forms:
|
||||||
|
.RS
|
||||||
|
.IP "\fBtcp:\fIip\fB:\fIport\fR"
|
||||||
|
Connect to the given TCP \fIport\fR on \fIip\fR.
|
||||||
|
.IP "\fBunix:\fIfile\fR"
|
||||||
|
Connect to the Unix domain server socket named \fIfile\fR.
|
||||||
|
.RE
|
||||||
|
.IP "\fB\-\-no\-wait\fR"
|
||||||
|
Prevents \fBovs\-vsctl\fR from waiting for \fBovs\-vswitchd\fR to
|
||||||
|
reconfigure itself according to the the modified database. This
|
||||||
|
option should be used if \fBovs\-vswitchd\fR is not running;
|
||||||
|
otherwise, \fBovs-vsctl\fR will not exit until \fBovs-vswitchd\fR
|
||||||
|
starts.
|
||||||
.IP
|
.IP
|
||||||
If \fIfile\fR is specified as \fB\-\fR, then \fBovs\-vsctl\fR reads
|
This option has no effect if the commands specified do not change the
|
||||||
the configuration file from standard input and, for commands that
|
database.
|
||||||
modify the configuration, writes the new one to standard output. This
|
|
||||||
is useful for testing but it should not be used in production because
|
|
||||||
it bypasses the Open vSwitch configuration file locking protocol.
|
|
||||||
.
|
|
||||||
.IP "\fB\-t \fItarget\fR"
|
|
||||||
.IQ "\fB\-\-target=\fItarget\fR"
|
|
||||||
Configures how \fBovs\-vsctl\fR contacts \fBovs\-vswitchd\fR to
|
|
||||||
instruct it to reload its configuration file.
|
|
||||||
.IP
|
|
||||||
If \fItarget\fR begins with \fB/\fR it must name a Unix domain socket
|
|
||||||
on which \fBovs\-vswitchd\fR is listening for control channel
|
|
||||||
connections. By default, \fBovs\-vswitchd\fR listens on a Unix domain
|
|
||||||
socket named \fB@RUNDIR@/ovs\-vswitchd.\fIpid\fB.ctl\fR, where
|
|
||||||
\fIpid\fR is \fBovs\-vswitchd\fR's process ID.
|
|
||||||
.IP
|
|
||||||
Otherwise, \fBovs\-appctl\fR looks for a pidfile, that is, a file
|
|
||||||
whose contents are the process ID of a running process as a decimal
|
|
||||||
number, named \fB@RUNDIR@/\fItarget\fB.pid\fR. (The \fB\-\-pidfile\fR
|
|
||||||
option makes an Open vSwitch daemon create a pidfile.)
|
|
||||||
\fBovs\-appctl\fR reads the pidfile, then looks for a Unix socket
|
|
||||||
named \fB@RUNDIR@/\fItarget\fB.\fIpid\fB.ctl\fR, where \fIpid\fR is
|
|
||||||
replaced by the process ID read from \fItarget\fR, and uses that file
|
|
||||||
as if it had been specified directly as the target.
|
|
||||||
.IP
|
|
||||||
The default target is \fBovs\-vswitchd\fR.
|
|
||||||
.IP "\fB\-\-no\-reload\fR"
|
|
||||||
Prevents \fBovs\-vsctl\fR from telling \fBovs\-vswitchd\fR to reload
|
|
||||||
its configuration file.
|
|
||||||
.
|
.
|
||||||
.IP "\fB\-\-no\-syslog\fR"
|
.IP "\fB\-\-no\-syslog\fR"
|
||||||
By default, \fBovs\-vsctl\fR logs its arguments and the details of any
|
By default, \fBovs\-vsctl\fR logs its arguments and the details of any
|
||||||
changes that it makes to the system log. This option disables this
|
changes that it makes to the system log. This option disables this
|
||||||
logging.
|
logging.
|
||||||
|
.IP
|
||||||
|
This option is equivalent to \fB\-\-verbose=vvsctl:syslog:warn\fR.
|
||||||
|
.
|
||||||
.IP "\fB\-\-oneline\fR"
|
.IP "\fB\-\-oneline\fR"
|
||||||
Modifies the output format so that the output for each command is printed
|
Modifies the output format so that the output for each command is printed
|
||||||
on a single line. New-line characters that would otherwise separate
|
on a single line. New-line characters that would otherwise separate
|
||||||
@@ -101,6 +89,8 @@ lines are printed as \fB\\n\fR, and any instances of \fB\\\fR that
|
|||||||
would otherwise appear in the output are doubled.
|
would otherwise appear in the output are doubled.
|
||||||
Prints a blank line for each command that has no output.
|
Prints a blank line for each command that has no output.
|
||||||
.
|
.
|
||||||
|
.so lib/vlog.man
|
||||||
|
.
|
||||||
.SH COMMANDS
|
.SH COMMANDS
|
||||||
The commands implemented by \fBovs\-vsctl\fR are described in the
|
The commands implemented by \fBovs\-vsctl\fR are described in the
|
||||||
sections below.
|
sections below.
|
||||||
@@ -203,5 +193,5 @@ The \fIbridge\fR argument to \fBbr\-exists\fR specified the name of a
|
|||||||
bridge that does not exist.
|
bridge that does not exist.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.
|
.
|
||||||
.BR ovs\-vswitchd.conf (5),
|
.BR ovsdb\-server (1),
|
||||||
.BR ovs\-vswitchd (8).
|
.BR ovs\-vswitchd (8).
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include "dynamic-string.h"
|
#include "dynamic-string.h"
|
||||||
#include "ovsdb-idl.h"
|
#include "ovsdb-idl.h"
|
||||||
#include "poll-loop.h"
|
#include "poll-loop.h"
|
||||||
|
#include "svec.h"
|
||||||
#include "vswitchd/vswitch-idl.h"
|
#include "vswitchd/vswitch-idl.h"
|
||||||
#include "timeval.h"
|
#include "timeval.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -48,6 +49,7 @@ static char *default_db(void);
|
|||||||
static void usage(void) NO_RETURN;
|
static void usage(void) NO_RETURN;
|
||||||
static void parse_options(int argc, char *argv[]);
|
static void parse_options(int argc, char *argv[]);
|
||||||
|
|
||||||
|
static void check_vsctl_command(int argc, char *argv[]);
|
||||||
static void do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl);
|
static void do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl);
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -55,14 +57,43 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
struct ovsdb_idl *idl;
|
struct ovsdb_idl *idl;
|
||||||
unsigned int seqno;
|
unsigned int seqno;
|
||||||
|
struct ds args;
|
||||||
|
int start, n_commands;
|
||||||
int trials;
|
int trials;
|
||||||
|
int i;
|
||||||
|
|
||||||
set_program_name(argv[0]);
|
set_program_name(argv[0]);
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
time_init();
|
time_init();
|
||||||
vlog_init();
|
vlog_init();
|
||||||
|
vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_WARN);
|
||||||
|
vlog_set_levels(VLM_reconnect, VLF_ANY_FACILITY, VLL_WARN);
|
||||||
parse_options(argc, argv);
|
parse_options(argc, argv);
|
||||||
|
|
||||||
|
/* Log our arguments. This is often valuable for debugging systems. */
|
||||||
|
ds_init(&args);
|
||||||
|
for (i = 1; i < argc; i++) {
|
||||||
|
ds_put_format(&args, " %s", argv[i]);
|
||||||
|
}
|
||||||
|
VLOG_INFO("Called as%s", ds_cstr(&args));
|
||||||
|
ds_destroy(&args);
|
||||||
|
|
||||||
|
/* Do basic command syntax checking. */
|
||||||
|
n_commands = 0;
|
||||||
|
for (start = i = optind; i <= argc; i++) {
|
||||||
|
if (i == argc || !strcmp(argv[i], "--")) {
|
||||||
|
if (i > start) {
|
||||||
|
check_vsctl_command(i - start, &argv[start]);
|
||||||
|
n_commands++;
|
||||||
|
}
|
||||||
|
start = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!n_commands) {
|
||||||
|
ovs_fatal(0, "missing command name (use --help for help)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now execut the commands. */
|
||||||
idl = ovsdb_idl_create(db, &ovsrec_idl_class);
|
idl = ovsdb_idl_create(db, &ovsrec_idl_class);
|
||||||
seqno = ovsdb_idl_get_seqno(idl);
|
seqno = ovsdb_idl_get_seqno(idl);
|
||||||
trials = 0;
|
trials = 0;
|
||||||
@@ -90,23 +121,22 @@ parse_options(int argc, char *argv[])
|
|||||||
enum {
|
enum {
|
||||||
OPT_DB = UCHAR_MAX + 1,
|
OPT_DB = UCHAR_MAX + 1,
|
||||||
OPT_ONELINE,
|
OPT_ONELINE,
|
||||||
|
OPT_NO_SYSLOG
|
||||||
};
|
};
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"db", required_argument, 0, OPT_DB},
|
{"db", required_argument, 0, OPT_DB},
|
||||||
|
{"no-syslog", no_argument, 0, OPT_NO_SYSLOG},
|
||||||
{"oneline", no_argument, 0, OPT_ONELINE},
|
{"oneline", no_argument, 0, OPT_ONELINE},
|
||||||
{"verbose", optional_argument, 0, 'v'},
|
{"verbose", optional_argument, 0, 'v'},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"version", no_argument, 0, 'V'},
|
{"version", no_argument, 0, 'V'},
|
||||||
{0, 0, 0, 0},
|
{0, 0, 0, 0},
|
||||||
};
|
};
|
||||||
char *short_options;
|
|
||||||
|
|
||||||
short_options = xasprintf ("+%s",
|
|
||||||
long_options_to_short_options(long_options));
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
c = getopt_long(argc, argv, short_options, long_options, NULL);
|
c = getopt_long(argc, argv, "+v::hV", long_options, NULL);
|
||||||
if (c == -1) {
|
if (c == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -120,6 +150,10 @@ parse_options(int argc, char *argv[])
|
|||||||
oneline = true;
|
oneline = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_NO_SYSLOG:
|
||||||
|
vlog_set_levels(VLM_vsctl, VLF_SYSLOG, VLL_WARN);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
@@ -138,7 +172,6 @@ parse_options(int argc, char *argv[])
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(short_options);
|
|
||||||
|
|
||||||
if (!db) {
|
if (!db) {
|
||||||
db = default_db();
|
db = default_db();
|
||||||
@@ -205,7 +238,7 @@ default_db(void)
|
|||||||
{
|
{
|
||||||
static char *def;
|
static char *def;
|
||||||
if (!def) {
|
if (!def) {
|
||||||
def = xasprintf("%s/ovsdb-server", ovs_rundir);
|
def = xasprintf("unix:%s/ovsdb-server", ovs_rundir);
|
||||||
}
|
}
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
@@ -339,7 +372,7 @@ get_info(const struct ovsrec_open_vswitch *ovs, struct vsctl_info *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (port_is_fake_bridge(port_cfg)
|
if (port_is_fake_bridge(port_cfg)
|
||||||
&& shash_add_once(&bridges, br_cfg->name, NULL)) {
|
&& shash_add_once(&bridges, port_cfg->name, NULL)) {
|
||||||
add_bridge(info, NULL, port_cfg->name, br, *port_cfg->tag);
|
add_bridge(info, NULL, port_cfg->name, br, *port_cfg->tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,7 +401,7 @@ get_info(const struct ovsrec_open_vswitch *ovs, struct vsctl_info *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (port_is_fake_bridge(port_cfg)
|
if (port_is_fake_bridge(port_cfg)
|
||||||
&& !shash_add_once(&bridges, br_cfg->name, NULL)) {
|
&& !shash_add_once(&bridges, port_cfg->name, NULL)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,6 +431,7 @@ get_info(const struct ovsrec_open_vswitch *ovs, struct vsctl_info *info)
|
|||||||
iface = xmalloc(sizeof *iface);
|
iface = xmalloc(sizeof *iface);
|
||||||
iface->iface_cfg = iface_cfg;
|
iface->iface_cfg = iface_cfg;
|
||||||
iface->port = port;
|
iface->port = port;
|
||||||
|
shash_add(&info->ifaces, iface_cfg->name, iface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,7 +489,7 @@ static struct vsctl_iface *
|
|||||||
find_iface(struct vsctl_info *info, const char *name)
|
find_iface(struct vsctl_info *info, const char *name)
|
||||||
{
|
{
|
||||||
struct vsctl_iface *iface = shash_find_data(&info->ifaces, name);
|
struct vsctl_iface *iface = shash_find_data(&info->ifaces, name);
|
||||||
if (!iface) {
|
if (!iface || !strcmp(name, iface->port->bridge->name)) {
|
||||||
ovs_fatal(0, "no interface named %s", name);
|
ovs_fatal(0, "no interface named %s", name);
|
||||||
}
|
}
|
||||||
return iface;
|
return iface;
|
||||||
@@ -471,7 +505,6 @@ bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
|
|||||||
for (i = 0; i < br->n_ports; i++) {
|
for (i = 0; i < br->n_ports; i++) {
|
||||||
ports[i] = br->ports[i];
|
ports[i] = br->ports[i];
|
||||||
}
|
}
|
||||||
printf("bridge has %zu ports, adding 1\n", br->n_ports);
|
|
||||||
ports[br->n_ports] = port;
|
ports[br->n_ports] = port;
|
||||||
ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
|
ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
|
||||||
free(ports);
|
free(ports);
|
||||||
@@ -556,7 +589,7 @@ cmd_add_br(int argc, char *argv[], const struct ovsrec_open_vswitch *ovs,
|
|||||||
ovs_insert_bridge(ovs, br);
|
ovs_insert_bridge(ovs, br);
|
||||||
} else if (argc == 3) {
|
} else if (argc == 3) {
|
||||||
ovs_fatal(0, "'%s' comamnd takes exactly 1 or 3 arguments", argv[0]);
|
ovs_fatal(0, "'%s' comamnd takes exactly 1 or 3 arguments", argv[0]);
|
||||||
} else if (argc >= 4) {
|
} else if (argc == 4) {
|
||||||
const char *parent_name = argv[2];
|
const char *parent_name = argv[2];
|
||||||
int vlan = atoi(argv[3]);
|
int vlan = atoi(argv[3]);
|
||||||
struct ovsrec_bridge *br;
|
struct ovsrec_bridge *br;
|
||||||
@@ -587,6 +620,8 @@ cmd_add_br(int argc, char *argv[], const struct ovsrec_open_vswitch *ovs,
|
|||||||
ovsrec_port_set_interfaces(port, &iface, 1);
|
ovsrec_port_set_interfaces(port, &iface, 1);
|
||||||
ovsrec_port_set_fake_bridge(port, true);
|
ovsrec_port_set_fake_bridge(port, true);
|
||||||
ovsrec_port_set_tag(port, &tag, 1);
|
ovsrec_port_set_tag(port, &tag, 1);
|
||||||
|
|
||||||
|
bridge_insert_port(br, port);
|
||||||
} else {
|
} else {
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
@@ -624,7 +659,8 @@ cmd_del_br(int argc UNUSED, char *argv[],
|
|||||||
bridge = find_bridge(&info, argv[1]);
|
bridge = find_bridge(&info, argv[1]);
|
||||||
SHASH_FOR_EACH (node, &info.ports) {
|
SHASH_FOR_EACH (node, &info.ports) {
|
||||||
struct vsctl_port *port = node->data;
|
struct vsctl_port *port = node->data;
|
||||||
if (port->bridge == bridge) {
|
if (port->bridge == bridge
|
||||||
|
|| !strcmp(port->port_cfg->name, bridge->name)) {
|
||||||
del_port(&info, port);
|
del_port(&info, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -635,18 +671,36 @@ cmd_del_br(int argc UNUSED, char *argv[],
|
|||||||
free_info(&info);
|
free_info(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
output_sorted(struct svec *svec, struct ds *output)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
svec_sort(svec);
|
||||||
|
SVEC_FOR_EACH (i, name, svec) {
|
||||||
|
ds_put_format(output, "%s\n", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd_list_br(int argc UNUSED, char *argv[] UNUSED,
|
cmd_list_br(int argc UNUSED, char *argv[] UNUSED,
|
||||||
const struct ovsrec_open_vswitch *ovs, struct ds *output)
|
const struct ovsrec_open_vswitch *ovs, struct ds *output)
|
||||||
{
|
{
|
||||||
struct shash_node *node;
|
struct shash_node *node;
|
||||||
struct vsctl_info info;
|
struct vsctl_info info;
|
||||||
|
struct svec bridges;
|
||||||
|
|
||||||
get_info(ovs, &info);
|
get_info(ovs, &info);
|
||||||
|
|
||||||
|
svec_init(&bridges);
|
||||||
SHASH_FOR_EACH (node, &info.bridges) {
|
SHASH_FOR_EACH (node, &info.bridges) {
|
||||||
struct vsctl_bridge *br = node->data;
|
struct vsctl_bridge *br = node->data;
|
||||||
ds_put_format(output, "%s\n", br->name);
|
svec_add(&bridges, br->name);
|
||||||
}
|
}
|
||||||
|
output_sorted(&bridges, output);
|
||||||
|
svec_destroy(&bridges);
|
||||||
|
|
||||||
free_info(&info);
|
free_info(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,16 +724,22 @@ cmd_list_ports(int argc UNUSED, char *argv[],
|
|||||||
struct vsctl_bridge *br;
|
struct vsctl_bridge *br;
|
||||||
struct shash_node *node;
|
struct shash_node *node;
|
||||||
struct vsctl_info info;
|
struct vsctl_info info;
|
||||||
|
struct svec ports;
|
||||||
|
|
||||||
get_info(ovs, &info);
|
get_info(ovs, &info);
|
||||||
br = find_bridge(&info, argv[1]);
|
br = find_bridge(&info, argv[1]);
|
||||||
|
|
||||||
|
svec_init(&ports);
|
||||||
SHASH_FOR_EACH (node, &info.ports) {
|
SHASH_FOR_EACH (node, &info.ports) {
|
||||||
struct vsctl_port *port = node->data;
|
struct vsctl_port *port = node->data;
|
||||||
|
|
||||||
if (strcmp(port->port_cfg->name, br->name) && br == port->bridge) {
|
if (strcmp(port->port_cfg->name, br->name) && br == port->bridge) {
|
||||||
ds_put_format(output, "%s\n", port->port_cfg->name);
|
svec_add(&ports, port->port_cfg->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
output_sorted(&ports, output);
|
||||||
|
svec_destroy(&ports);
|
||||||
|
|
||||||
free_info(&info);
|
free_info(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,16 +871,23 @@ cmd_list_ifaces(int argc UNUSED, char *argv[],
|
|||||||
struct vsctl_bridge *br;
|
struct vsctl_bridge *br;
|
||||||
struct shash_node *node;
|
struct shash_node *node;
|
||||||
struct vsctl_info info;
|
struct vsctl_info info;
|
||||||
|
struct svec ifaces;
|
||||||
|
|
||||||
get_info(ovs, &info);
|
get_info(ovs, &info);
|
||||||
br = find_bridge(&info, argv[1]);
|
br = find_bridge(&info, argv[1]);
|
||||||
|
|
||||||
|
svec_init(&ifaces);
|
||||||
SHASH_FOR_EACH (node, &info.ifaces) {
|
SHASH_FOR_EACH (node, &info.ifaces) {
|
||||||
struct vsctl_iface *iface = node->data;
|
struct vsctl_iface *iface = node->data;
|
||||||
|
|
||||||
if (br == iface->port->bridge) {
|
if (strcmp(iface->iface_cfg->name, br->name)
|
||||||
ds_put_format(output, "%s\n", iface->iface_cfg->name);
|
&& br == iface->port->bridge) {
|
||||||
|
svec_add(&ifaces, iface->iface_cfg->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
output_sorted(&ifaces, output);
|
||||||
|
svec_destroy(&ifaces);
|
||||||
|
|
||||||
free_info(&info);
|
free_info(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -837,12 +904,15 @@ cmd_iface_to_br(int argc UNUSED, char *argv[],
|
|||||||
free_info(&info);
|
free_info(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef void vsctl_handler_func(int argc, char *argv[],
|
||||||
|
const struct ovsrec_open_vswitch *,
|
||||||
|
struct ds *output);
|
||||||
|
|
||||||
struct vsctl_command {
|
struct vsctl_command {
|
||||||
const char *name;
|
const char *name;
|
||||||
int min_args;
|
int min_args;
|
||||||
int max_args;
|
int max_args;
|
||||||
void (*handler)(int argc, char *argv[],
|
vsctl_handler_func *handler;
|
||||||
const struct ovsrec_open_vswitch *ovs, struct ds *output);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void run_vsctl_command(int argc, char *argv[],
|
static void run_vsctl_command(int argc, char *argv[],
|
||||||
@@ -870,8 +940,8 @@ do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
|
|||||||
txn = ovsdb_idl_txn_create(idl);
|
txn = ovsdb_idl_txn_create(idl);
|
||||||
output = xmalloc(argc * sizeof *output);
|
output = xmalloc(argc * sizeof *output);
|
||||||
n_output = 0;
|
n_output = 0;
|
||||||
for (start = i = 0; i < argc; i++) {
|
for (start = i = 0; i <= argc; i++) {
|
||||||
if (!strcmp(argv[i], "--")) {
|
if (i == argc || !strcmp(argv[i], "--")) {
|
||||||
if (i > start) {
|
if (i > start) {
|
||||||
ds_init(&output[n_output]);
|
ds_init(&output[n_output]);
|
||||||
run_vsctl_command(i - start, &argv[start], ovs,
|
run_vsctl_command(i - start, &argv[start], ovs,
|
||||||
@@ -880,10 +950,6 @@ do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
|
|||||||
start = i + 1;
|
start = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i > start) {
|
|
||||||
ds_init(&output[n_output]);
|
|
||||||
run_vsctl_command(i - start, &argv[start], ovs, &output[n_output++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
|
while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
|
||||||
ovsdb_idl_run(idl);
|
ovsdb_idl_run(idl);
|
||||||
@@ -945,9 +1011,8 @@ do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
|
|||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static vsctl_handler_func *
|
||||||
run_vsctl_command(int argc, char *argv[],
|
get_vsctl_handler(int argc, char *argv[])
|
||||||
const struct ovsrec_open_vswitch *ovs, struct ds *output)
|
|
||||||
{
|
{
|
||||||
static const struct vsctl_command all_commands[] = {
|
static const struct vsctl_command all_commands[] = {
|
||||||
{"add-br", 1, 3, cmd_add_br},
|
{"add-br", 1, 3, cmd_add_br},
|
||||||
@@ -968,7 +1033,7 @@ run_vsctl_command(int argc, char *argv[],
|
|||||||
const struct vsctl_command *p;
|
const struct vsctl_command *p;
|
||||||
|
|
||||||
assert(argc > 0);
|
assert(argc > 0);
|
||||||
for (p = all_commands; p->name != NULL; p++) {
|
for (p = all_commands; p < &all_commands[ARRAY_SIZE(all_commands)]; p++) {
|
||||||
if (!strcmp(p->name, argv[0])) {
|
if (!strcmp(p->name, argv[0])) {
|
||||||
int n_arg = argc - 1;
|
int n_arg = argc - 1;
|
||||||
if (n_arg < p->min_args) {
|
if (n_arg < p->min_args) {
|
||||||
@@ -978,11 +1043,23 @@ run_vsctl_command(int argc, char *argv[],
|
|||||||
ovs_fatal(0, "'%s' command takes at most %d arguments",
|
ovs_fatal(0, "'%s' command takes at most %d arguments",
|
||||||
p->name, p->max_args);
|
p->name, p->max_args);
|
||||||
} else {
|
} else {
|
||||||
p->handler(argc, argv, ovs, output);
|
return p->handler;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ovs_fatal(0, "unknown command '%s'; use --help for help", argv[0]);
|
ovs_fatal(0, "unknown command '%s'; use --help for help", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_vsctl_command(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
get_vsctl_handler(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_vsctl_command(int argc, char *argv[],
|
||||||
|
const struct ovsrec_open_vswitch *ovs, struct ds *output)
|
||||||
|
{
|
||||||
|
get_vsctl_handler(argc, argv)(argc, argv, ovs, output);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user