From: Ben Pfaff Date: Tue, 16 Jun 2015 15:38:46 +0000 (-0700) Subject: ovs-sim: New utility for multi-node OVS and OVN simulation. X-Git-Tag: v2.5.0~1049 X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fovs.git;a=commitdiff_plain;h=6901639bc8a84ac9204a03d466f977562dabdf3e ovs-sim: New utility for multi-node OVS and OVN simulation. Please see the examples in ovs-sim(1) for some examples of how this can be useful. Signed-off-by: Ben Pfaff --- diff --git a/Makefile.am b/Makefile.am index fc623e6de..178e82c01 100644 --- a/Makefile.am +++ b/Makefile.am @@ -173,6 +173,7 @@ SUFFIXES += .in -e 's,[@]sysconfdir[@],$(sysconfdir),g' \ -e 's,[@]bindir[@],$(bindir),g' \ -e 's,[@]sbindir[@],$(sbindir),g' \ + -e 's,[@]abs_builddir[@],$(abs_builddir),g' \ -e 's,[@]abs_top_srcdir[@],$(abs_top_srcdir),g' \ > $@.tmp @if head -n 1 $@.tmp | grep '#!' > /dev/null; then \ diff --git a/NEWS b/NEWS index a3eeed52b..6fb43fac7 100644 --- a/NEWS +++ b/NEWS @@ -103,6 +103,8 @@ Post-v2.3.0 openvswitch.ko but built and loaded automatically as individual kernel modules (vport-*.ko). - Support for STT tunneling. + - ovs-sim: New developer tool for simulating multiple OVS instances. + See ovs-sim(1) for more information. v2.3.0 - 14 Aug 2014 diff --git a/utilities/automake.mk b/utilities/automake.mk index 6083b4b68..3b43cb412 100644 --- a/utilities/automake.mk +++ b/utilities/automake.mk @@ -30,6 +30,10 @@ check_SCRIPTS += \ utilities/ovs-appctl-bashcomp.bash \ utilities/ovs-vsctl-bashcomp.bash +EXTRA_DIST += utilities/ovs-sim.in utilities/ovs-sim.1.xml +man_MANS += utilities/ovs-sim.1 +noinst_SCRIPTS += utilities/ovs-sim + utilities/ovs-lib: $(top_builddir)/config.status docs += utilities/ovs-command-bashcomp.INSTALL.md diff --git a/utilities/ovs-sim.1.xml b/utilities/ovs-sim.1.xml new file mode 100644 index 000000000..cedf66138 --- /dev/null +++ b/utilities/ovs-sim.1.xml @@ -0,0 +1,323 @@ + + +

Name

+

ovs-sim -- Open vSwitch simulator environment

+ +

Synopsis

+

ovs-sim [option]... [script]...

+ +

Description

+

+ ovs-sim provides a convenient environment for running one or + more Open vSwitch instances and related software in a sandboxed + simulation environment. +

+ +

+ To use ovs-sim, first build Open vSwitch, then invoke it + directly from the build directory, e.g.: +

+ +
+git clone https://github.com/openvswitch/ovs.git
+cd ovs
+./configure
+make
+utilities/ovs-sim
+    
+ +

+ When invoked in the most ordinary way as shown above, + ovs-sim does the following: +

+ +
    +
  1. + Creates a directory sandbox as a subdirectory of the + current directory (first destroying such a directory if it already + exists) and cds into that directory. +
  2. + +
  3. + Installs all of the Open vSwitch manpages into a man + subdirectory of sandbox and adjusts the MANPATH + environment variable so that man and other manpage viewers + can find them. +
  4. + +
  5. +

    + Creates a simulated Open vSwitch named main and sets it + up as the default target for OVS commands, as if the following + ovs-sim commands had been run: +

    + +
    +          sim_add main
    +          as main
    +        
    + +

    + See Commands, below, for an explanation. +

    +
  6. + +
  7. + Runs any scripts specified on the command line (see + Options below). The scripts can use arbitrary Bash + syntax, plus the additional commands described under + Commands, below. +
  8. + +
  9. + If no scripts were specified, or if or + was specified, invokes an interactive + Bash subshell. The user can use arbitrary Bash commands, plus the + additional commands described under Commands, below. +
  10. +
+ +

+ ovs-sim and the sandbox environment that it creates does not + require superuser or other special privileges. Generally, it should not + be run with such privileges. +

+ +

Options

+ +

+ ovs-sim accepts the following options and arguments: +

+ +
+
script
+
+ Runs script, which should be a Bash script, within a + subshell after initializing. If multiple script arguments + are given, then they are run in the order given. If any + script exits with a nonzero exit code, then + ovs-sim exits immediately with the same exit code. +
+ +
+
+
+ By default, if any script is specified, ovs-sim + exits as soon as the scripts finish executing. With this option, or if + no scripts are specified, ovs-sim instead starts an + interactive Bash session. +
+
+ +

Commands

+ +

+ Scripts and interactive usage may use the following commands implemented + by ovs-sim. They are implemented as Bash shell functions + exported to subshells. +

+ +

Basic Commands

+ +

+ These are the basic commands for working with sandboxed Open vSwitch + instances. +

+ +
+
sim_add sandbox
+
+

+ Starts a new simulated Open vSwitch instance named + sandbox. Files related to the instance, such as logs, + databases, sockets, and pidfiles, are created in a subdirectory also + named sandbox. Afterward, the as command + (see below) can be used to run Open vSwitch utilities in the context + of the new sandbox. +

+ +

+ The new sandbox starts out without any bridges. Use + ovs-vsctl in the context of the new sandbox to create a + bridge, e.g.: +

+ +
+sim_add hv0           # Create sandbox hv0.  
+as hv0                # Set hv0 as default sandbox.
+ovs-vsctl add-br br0  # Add bridge br0 inside hv0.
+        
+ +

+ The Open vSwitch instances that sim_add create enable + ``dummy'' devices. This means that bridges and interfaces can be + created with type dummy to indicate that they should be + totally simulated, without any reference to system entities. In + fact, ovs-sim also configures Open vSwitch so that the + default system type of bridges and interfaces are + replaced by dummy devices. Other types of devices, + however, retain their usual functions, which means that, e.g., + vxlan tunnels still act as tunnels (see + README-native-tunneling.md). +

+
+ +
as sandbox
+
+

+ Sets sandbox as the default simulation target for Open + vSwitch commands (e.g. ovs-vsctl, + ovs-ofctl, ovs-appctl). +

+ +

+ This command updates the beginning of the shell prompt to indicate + the new default target. +

+
+ +
as sandbox command arg...
+
+ Runs the given command with sandbox as the + simulation target, e.g. as hv0 ovs-vsctl add-br br0 runs + ovs-vsctl add-br br0 within sandbox hv0. + The default target is unchanged. +
+
+ +

Interconnection Network Commands

+ +

+ When multiple sandboxed Open vSwitch instances exist, one will inevitably + want to connect them together. These commands allow for that. + Conceptually, an interconnection network is a switch that + ovs-sim makes it easy to plug into other switches in other + sandboxed Open vSwitch instances. Interconnection networks are + implemented as bridges in the main switch that + ovs-sim creates by default, so to use interconnection + networks please avoid working with main directly. +

+ +
+
net_add network
+
+ Creates a new interconnection network named network. +
+ +
net_attach network bridge
+
+ Adds a new port to bridge in the default sandbox (as set + with as) and plugs it into the network + interconnection network. network must already have been + created by a previous invocation of net_add. The default + sandbox must not be main. +
+
+ +

OVN Commands

+ +

+ These commands interact with OVN, the Open Virtual Network. +

+ +
+
ovn_start
+
+ Creates and initializes the central OVN databases (both + ovn-sb(5) and ovn-nb) and starts an instance + of ovsdb-server for each one. Also starts an instance of + ovn-northd. +
+ +
ovn_attach network bridge ip [masklen]
+
+ First, this command attaches bridge to interconnection + network network, just like net_attach + network bridge. Second, it configures + (simulated) IP address ip (with network mask length + masklen, which defaults to 24) on bridge. + Finally, it configures the Open vSwitch database to work with OVN and + starts ovn-controller. +
+
+ +

Examples

+ +

+ The following creates a pair of Open vSwitch instances + hv0 and hv1, adds a port named + vif0 or vif1, respectively, to each + one, and then connects the two through an interconnection + network n1: +

+ +
+net_add n1
+for i in 0 1; do
+    sim_add hv$i
+    as hv$i ovs-vsctl add-br br0 -- add-port br0 vif$i
+    as hv$i net_attach n1 br0
+done
+    
+ +

+ Here's an extended version that also starts OVN: +

+ +
+ovn_start
+ovn-nbctl lswitch-add lsw0
+
+net_add n1
+for i in 0 1; do
+    sim_add hv$i
+    as hv$i
+    ovs-vsctl add-br br-phys
+    ovn_attach n1 br-phys 192.168.0.`expr $i + 1`
+    ovs-vsctl add-port br-int vif$i -- set Interface vif$i external-ids:iface-id=lp$i
+    ovn-nbctl lport-add lsw0 lp$i
+    ovn-nbctl lport-set-macs lp$i f0:00:00:00:00:0$i
+done
+    
+ +

+ Here's a primitive OVN ``scale test'' (adjust the scale by + changing n in the first line : +

+ +
+n=200; export n
+ovn_start
+net_add n1
+ovn-nbctl lswitch-add br0
+for i in `seq $n`; do
+    (sim_add hv$i
+    as hv$i
+    ovs-vsctl add-br br-phys
+    y=$(expr $i / 256)
+    x=$(expr $i % 256)
+    ovn_attach n1 br-phys 192.168.$y.$x
+    ovs-vsctl add-port br-int vif$i -- set Interface vif$i external-ids:iface-id=lp$i) &
+    case $i in
+    	 *50|*00) echo $i; wait ;;
+    esac
+done
+wait
+for i in `seq $n`; do
+    yy=$(printf %02x $(expr $i / 256))
+    xx=$(printf $02x $(expr $i % 256))
+    ovn-nbctl lport-add br0 lp$i
+    ovn-nbctl lport-set-macs lp$i f0:00:00:00:$yy:$xx
+done
+    
+ +

+ When the scale test has finished initializing, you can watch the + logical ports come up with a command like this: +

+ +
+watch 'for i in `seq $n`; do if test `ovn-nbctl lport-get-up lp$i` != up; then echo $i; fi; done'
+    
+ +
diff --git a/utilities/ovs-sim.in b/utilities/ovs-sim.in new file mode 100755 index 000000000..f77b5d1df --- /dev/null +++ b/utilities/ovs-sim.in @@ -0,0 +1,355 @@ +#! /usr/bin/env bash +# +# Copyright (c) 2013, 2015 Nicira, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +sim_builddir='@abs_builddir@'; export sim_builddir +sim_srcdir='@abs_top_srcdir@'; export sim_srcdir +interactive=false +scripts= + +for option; do + case $option in + -h|--help) + cat <&2 + exit 1 + ;; + *) + case $option in + /*) ;; + *) option=`pwd`/$option ;; + esac + scripts="$scripts $option" + ;; + esac + shift +done + +if test -z "$scripts"; then + interactive=: +fi + +# Check that we've got proper builddir and srcdir. +if test ! -e "$sim_builddir"/vswitchd/ovs-vswitchd; then + echo "$sim_builddir/vswitchd/ovs-vswitchd does not exist (need to run \"make\"?)" >&2 + exit 1 +fi +if test ! -e "$sim_srcdir"/WHY-OVS.md; then + echo "$sim_srcdir/WHY-OVS.md does not exist" >&2 + exit 1 +fi + +# Put built tools early in $PATH. +PATH=$sim_builddir/ovsdb:$sim_builddir/vswitchd:$sim_builddir/utilities:$PATH +PATH=$sim_builddir/ovn:$sim_srcdir/ovn:$sim_builddir/ovn/controller:$sim_builddir/ovn/northd:$PATH +export PATH + +rm -rf sandbox +mkdir sandbox +cd sandbox +sim_base=`pwd`; export sim_base + +trap_signals() { + for signal in 0 1 2 3 13 14 15; do + trap " + set +e + cd '$sim_base' && (kill \`cat */*.pid\`) >/dev/null 2>&1 + trap - $signal + kill -$signal $$" $signal + done +} +export -f trap_signals +trap_signals + +sim_setvars() { + sandbox=$1 + OVS_RUNDIR=$sim_base/$1; export OVS_RUNDIR + OVS_LOGDIR=$sim_base/$1; export OVS_LOGDIR + OVS_DBDIR=$sim_base/$1; export OVS_DBDIR + OVS_SYSCONFDIR=$sim_base/$1; export OVS_SYSCONFDIR + PS1="|$1: $sim_PS1" +} +export -f sim_setvars + +as() { + case $# in + 0) + echo >&2 "$FUNCNAME: missing arguments (use --help for help)" + return 1 + ;; + 1) + if test "$1" != --help; then + sim_setvars $1 + else + cat <&2 "$FUNCNAME: missing argument (use --help for help)" + return 1 + fi + + set X $1; shift + if test $# != 1; then + echo >&2 "$FUNCNAME: sandbox name must be a single word" + return 1 + fi + + if test -e "$sim_base/$1"; then + echo >&2 "$1 already exists" + return 1 + fi + + # Create sandbox. + mkdir "$sim_base"/$1 || return 1 + + daemon_opts="--detach --no-chdir --pidfile -vconsole:off --log-file" + + # Create database and start ovsdb-server. + touch $sim_base/$1/.conf.db.~lock~ + as $1 ovsdb-tool create $sim_base/$1/conf.db "$sim_srcdir/vswitchd/vswitch.ovsschema" + as $1 ovsdb-server $daemon_opts --remote=punix:"$sim_base"/$1/db.sock + + # Initialize database. + as $1 ovs-vsctl --no-wait -- init + + # Start ovs-vswitchd. + as $1 ovs-vswitchd $daemon_opts --enable-dummy=system -vvconn -vnetdev_dummy +} +export -f sim_add + +net_add() { + if test "$1" == --help; then + cat <&2 "$FUNCNAME: missing argument (use --help for help)" + return 1 + fi + + as main ovs-vsctl add-br "$1" +} +export -f net_add + +net_attach() { + if test "$1" == --help; then + cat <&2 "$FUNCNAME: wrong number of arguments (use --help for help)" + return 1 + fi + if test $sandbox = main; then + echo >&2 "$FUNCNAME: can only attach interconnection networks to sandboxes other than main" + return 1 + fi + + local net=$1 bridge=$2 + + port=${sandbox}_$bridge + as main ovs-vsctl \ + -- add-port $net "$port" \ + -- set Interface "$port" options:pstream="punix:$sim_base/main/$port.sock" options:rxq_pcap="$sim_base/main/$port-rx.pcap" options:tx_pcap="$sim_base/main/$port-tx.pcap" options:header=extended + + ovs-vsctl \ + -- set Interface $bridge options:tx_pcap="$sim_base/$sandbox/$bridge-tx.pcap" options:rxq_pcap="$sim_base/$sandbox/$bridge-rx.pcap" \ + -- add-port $bridge ${bridge}_$net \ + -- set Interface ${bridge}_$net options:stream="unix:$sim_base/main/$port.sock" options:rxq_pcap="$sim_base/$sandbox/${bridge}_$net-rx.pcap" options:tx_pcap="$sim_base/$sandbox/${bridge}_$net-tx.pcap" options:header=extended +} +export -f net_attach + +ovn_start() { + if test "$1" == --help; then + cat <&2 "$FUNCNAME: no arguments accepted (use --help for help)" + return 1 + fi + + if test -d ovn-sb || test -d ovn-nb; then + echo >&2 "OVN already started" + exit 1 + fi + + daemon_opts="--detach --no-chdir --pidfile -vconsole:off --log-file" + for db in ovn-sb ovn-nb; do + mkdir "$sim_base"/$db + touch "$sim_base"/$db/.$db.db.~lock~ + as $db ovsdb-tool create "$sim_base"/$db/$db.db "$sim_srcdir"/ovn/$db.ovsschema + as $db ovsdb-server $daemon_opts --remote=punix:"$sim_base"/$db/$db.sock "$sim_base"/$db/$db.db + done + + OVN_NB_DB=unix:$sim_base/ovn-nb/ovn-nb.sock; export OVN_NB_DB + + mkdir "$sim_base"/northd + as northd ovn-northd $daemon_opts \ + --ovnnb-db=unix:"$sim_base"/ovn-nb/ovn-nb.sock \ + --ovnsb-db=unix:"$sim_base"/ovn-sb/ovn-sb.sock +} +export -f ovn_start + +ovn_attach() { + if test "$1" == --help; then + cat <&2 "$FUNCNAME: wrong number of arguments (use --help for help)" + return 1 + fi + + local net=$1 bridge=$2 ip=$3 masklen=${4-24} + net_attach $net $bridge || return $? + + ovs-appctl netdev-dummy/ip4addr $bridge $ip/$masklen >/dev/null + ovs-appctl ovs/route/add $ip/$masklen $bridge > /dev/null + ovs-vsctl \ + -- set Open_vSwitch . external-ids:system-id=$sandbox \ + -- set Open_vSwitch . external-ids:ovn-remote=unix:$sim_base/ovn-sb/ovn-sb.sock \ + -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \ + -- set Open_vSwitch . external-ids:ovn-encap-ip=$ip\ + -- add-br br-int \ + -- set bridge br-int fail-mode=secure other-config:disable-in-band=true + ovn-controller --detach --no-chdir --pidfile -vconsole:off --log-file +} +export -f ovn_attach + +# Easy access to OVS manpages. +mkdir $sim_base/man +mandir=`cd $sim_base/man && pwd` +(cd "$sim_builddir" && ${MAKE-make} install-man mandir=$mandir >/dev/null) +MANPATH=$mandir:; export MANPATH + +export scripts +export interactive +rc=' + if [ -f /etc/bashrc ]; then + . /etc/bashrc + fi + if [ -f ~/.bashrc ]; then + . ~/.bashrc + fi + + trap_signals + sim_PS1=$PS1 + sim_add main + as main + + for script in $scripts; do + . $script || exit $? + done + + $interactive || exit 0 + + cat <