#! /bin/sh
-# Copyright (C) 2009, 2010, 2011 Nicira Networks, Inc.
+# Copyright (C) 2009, 2010, 2011, 2012 Nicira, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
*/*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;;
*) dir0=./ ;;
esac
-. "$dir0/ovs-lib.sh" || exit 1
+. "$dir0/ovs-lib" || exit 1
for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do
case :$PATH: in
## start ##
## ----- ##
-insert_modules_if_required () {
- # If openvswitch_mod is already loaded then we're done.
- test -e /sys/module/openvswitch_mod && return 0
+insert_openvswitch_mod_if_required () {
+ # If openvswitch is already loaded then we're done.
+ test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
+ return 0
- # Load openvswitch_mod. If that's successful then we're done.
- action "Inserting openvswitch module" modprobe openvswitch_mod && return 0
+ # Load openvswitch. If that's successful then we're done.
+ action "Inserting openvswitch module" modprobe openvswitch && return 0
# If the bridge module is loaded, then that might be blocking
- # openvswitch_mod. Try to unload it, if there are no bridges.
+ # openvswitch. Try to unload it, if there are no bridges.
test -e /sys/module/bridge || return 1
bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
if test "$bridges" != "*"; then
fi
action "removing bridge module" rmmod bridge || return 1
- # Try loading openvswitch_mod again.
- action "Inserting openvswitch module" modprobe openvswitch_mod
+ # Try loading openvswitch again.
+ action "Inserting openvswitch module" modprobe openvswitch
+}
+
+insert_brcompat_mod_if_required () {
+ if test -e /sys/module/bridge; then
+ log_warning_msg "bridge module is loaded, not loading brcompat"
+ return 1
+ fi
+ test -e /sys/module/brcompat -o -e /sys/module/brcompat_mod && return 0
+ action "Inserting brcompat module" modprobe brcompat
+}
+
+insert_mod_if_required () {
+ insert_openvswitch_mod_if_required || return 1
+ if test X"$BRCOMPAT" = Xyes; then
+ if insert_brcompat_mod_if_required; then
+ :
+ else
+ log_warning_msg "could not load brcompat module, disabling bridge compatibility"
+ BRCOMPAT=no
+ fi
+ fi
}
ovs_vsctl () {
}
ovsdb_tool () {
- ovsdb-tool -vANY:console:emer "$@"
+ ovsdb-tool -vconsole:off "$@"
+}
+
+create_db () {
+ action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
}
upgrade_db () {
if test ! -e "$DB_FILE"; then
log_warning_msg "$DB_FILE does not exist"
install -d -m 755 -o root -g root `dirname $DB_FILE`
-
- action "Creating empty database $DB_FILE" true
- ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
+ create_db
elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then
# Back up the old version.
version=`ovsdb_tool db-version "$DB_FILE"`
cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'`
- cp "$DB_FILE" "$DB_FILE.backup$version-$cksum"
+ backup=$DB_FILE.backup$version-$cksum
+ action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1
# Compact database. This is important if the old schema did not enable
# garbage collection (i.e. if it did not have any tables with "isRoot":
# does) would cause the record to be dropped by the first transaction,
# then the second transaction would cause a referential integrity
# failure (for a strong reference).
- ovsdb_tool compact "$DB_FILE"
+ #
+ # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't
+ # understand some feature of the schema used in the OVSDB version that
+ # we're downgrading from, so we don't give up on error.
+ action "Compacting database" ovsdb_tool compact "$DB_FILE"
# Upgrade or downgrade schema.
- ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"
+ if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
+ :
+ else
+ log_warning_msg "Schema conversion failed, using empty database instead"
+ rm -f "$DB_FILE"
+ create_db
+ fi
fi
}
action "Configuring Open vSwitch system IDs" "$@" $extra_ids
}
-start () {
+check_force_cores () {
if test X"$FORCE_COREFILES" = Xyes; then
ulimit -Sc 67108864
fi
+}
- insert_modules_if_required || return 1
+start_ovsdb () {
+ check_force_cores
if daemon_is_running ovsdb-server; then
- log_success_msg "ovsdb-server is already running"
+ log_success_msg "ovsdb-server is already running"
else
- # Create initial database or upgrade database schema.
- upgrade_db || return 1
-
- # Start ovsdb-server.
- set ovsdb-server "$DB_FILE"
- set "$@" -vANY:CONSOLE:EMER -vANY:SYSLOG:ERR -vANY:FILE:INFO
- set "$@" --remote=punix:"$DB_SOCK"
- set "$@" --remote=db:Open_vSwitch,manager_options
- set "$@" --private-key=db:SSL,private_key
- set "$@" --certificate=db:SSL,certificate
- set "$@" --bootstrap-ca-cert=db:SSL,ca_cert
- start_daemon "$OVSDB_SERVER_PRIORITY" "$@" || return 1
-
- # Initialize database settings.
- ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
- || return 1
- set_system_ids || return 1
- if test X"$DELETE_BRIDGES" = Xyes; then
+ # Create initial database or upgrade database schema.
+ upgrade_db || return 1
+
+ # Start ovsdb-server.
+ set ovsdb-server "$DB_FILE"
+ for db in $EXTRA_DBS; do
+ case $db in
+ /*) ;;
+ *) db=$dbdir/$db ;;
+ esac
+
+ if test ! -f "$db"; then
+ log_warning_msg "$db (from \$EXTRA_DBS) does not exist."
+ elif ovsdb-tool db-version "$db" >/dev/null; then
+ set "$@" "$db"
+ else
+ log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
+ fi
+ done
+ set "$@" -vconsole:emer -vsyslog:err -vfile:info
+ set "$@" --remote=punix:"$DB_SOCK"
+ set "$@" --remote=db:Open_vSwitch,Open_vSwitch,manager_options
+ set "$@" --private-key=db:Open_vSwitch,SSL,private_key
+ set "$@" --certificate=db:Open_vSwitch,SSL,certificate
+ set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert
+ start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
+ || return 1
+
+ # Initialize database settings.
+ ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
+ || return 1
+ set_system_ids || return 1
+ if test X"$DELETE_BRIDGES" = Xyes; then
for bridge in `ovs_vsctl list-br`; do
- ovs_vsctl del-br $bridge
+ ovs_vsctl del-br $bridge
done
- fi
+ fi
fi
+}
+
+start_forwarding () {
+ check_force_cores
+
+ insert_mod_if_required || return 1
if daemon_is_running ovs-vswitchd; then
- log_success_msg "ovs-vswitchd is already running"
+ log_success_msg "ovs-vswitchd is already running"
else
- # Increase the limit on the number of open file descriptors since
- # ovs-vswitchd needs a few per bridge
- ulimit -n 4096
-
- # Start ovs-vswitchd.
- set ovs-vswitchd unix:"$DB_SOCK"
- set "$@" -vANY:CONSOLE:EMER -vANY:SYSLOG:ERR -vANY:FILE:INFO
- if test X"$MLOCKALL" != Xno; then
- set "$@" --mlockall
- fi
- start_daemon "$VSWITCHD_PRIORITY" "$@"
+ # Increase the limit on the number of open file descriptors.
+ # ovs-vswitchd needs 16 per datapath, plus a few extra, so this
+ # should allow for 256 (or more) bridges.
+ ulimit -n 5000
+
+ # Start ovs-vswitchd.
+ set ovs-vswitchd unix:"$DB_SOCK"
+ set "$@" -vconsole:emer -vsyslog:err -vfile:info
+ if test X"$MLOCKALL" != Xno; then
+ set "$@" --mlockall
+ fi
+ start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
+ fi
+
+ if daemon_is_running ovs-brcompatd; then
+ log_success_msg "ovs-brcompatd is already running"
+ elif test X"$BRCOMPAT" = Xyes; then
+ set ovs-brcompatd
+ set "$@" -vconsole:emer -vsyslog:err -vfile:info
+ start_daemon "$OVS_BRCOMPATD_PRIORITY" "$OVS_BRCOMPATD_WRAPPER" "$@"
fi
}
## stop ##
## ---- ##
-stop () {
- stop_daemon ovs-vswitchd
+stop_ovsdb () {
stop_daemon ovsdb-server
}
+stop_forwarding () {
+ stop_daemon ovs-brcompatd
+ stop_daemon ovs-vswitchd
+}
+
## ----------------- ##
## force-reload-kmod ##
## ----------------- ##
# But ignore interfaces that don't really exist.
for d in `(ovs_vsctl --bare \
-- --columns=name find Interface type=internal \
- -- list-br) | sort -u`
+ -- list-br) | sort -u`
do
if test -e "/sys/class/net/$d"; then
- printf "%s " "$d"
- fi
+ printf "%s " "$d"
+ fi
done
}
+save_flows () {
+ if set X `ovs_vsctl list-br`; then
+ shift
+ if "$datadir/scripts/ovs-save" save-flows "$@" > "$script_flows"; then
+ chmod +x "$script_flows"
+ return 0
+ fi
+ fi
+ script_flows=
+ return 1
+}
+
save_interfaces () {
- "$datadir/scripts/ovs-save" $ifaces > "$script"
+ "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
+ > "${script_interfaces}"
+}
+
+restore_flows () {
+ [ -n "${script_flows}" ] && \
+ action "Restoring saved flows" "${script_flows}"
}
force_reload_kmod () {
ifaces=`internal_interfaces`
action "Detected internal interfaces: $ifaces" true
- stop
+ script_interfaces=`mktemp`
+ script_flows=`mktemp`
+ trap 'rm -f "${script_interfaces}" "${script_flows}" ' 0 1 2 13 15
+
+ action "Saving flows" save_flows
- script=`mktemp`
- if action "Save interface configuration to $script" save_interfaces; then
+ # Restart the database first, since a large database may take a
+ # while to load, and we want to minimize forwarding disruption.
+ stop_ovsdb
+ start_ovsdb
+
+ stop_forwarding
+
+ if action "Saving interface configuration" save_interfaces; then
:
else
log_warning_msg "Failed to save configuration, not replacing kernel module"
- start
+ start_forwarding
exit 1
fi
- chmod +x "$script"
+ chmod +x "$script_interfaces"
for dp in `ovs-dpctl dump-dps`; do
- action "Removing datapath: $dp" "$dpctl" del-dp "$dp"
+ action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
done
+ # try both old and new names in case this is post upgrade
+ if test -e /sys/module/brcompat_mod; then
+ action "Removing brcompat module" rmmod brcompat_mod
+ elif test -e /sys/module/brcompat; then
+ action "Removing brcompat module" rmmod brcompat
+ fi
if test -e /sys/module/openvswitch_mod; then
action "Removing openvswitch module" rmmod openvswitch_mod
+ elif test -e /sys/module/openvswitch; then
+ action "Removing openvswitch module" rmmod openvswitch
+ fi
+
+ start_forwarding
+
+ restore_flows
+
+ action "Restoring interface configuration" "$script_interfaces"
+ rc=$?
+ if test $rc = 0; then
+ level=debug
+ else
+ level=err
fi
+ log="logger -p daemon.$level -t ovs-save"
+ $log "force-reload-kmod interface restore script exited with status $rc:"
+ $log -f "$script_interfaces"
- start
+ "$datadir/scripts/ovs-check-dead-ifs"
+}
+
+## ------- ##
+## restart ##
+## ------- ##
+
+restart () {
+ if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
+ script_flows=`mktemp`
+ trap 'rm -f "${script_flows}"' 0 1 2 13 15
+
+ action "Saving flows" save_flows
+ fi
+
+ # Restart the database first, since a large database may take a
+ # while to load, and we want to minimize forwarding disruption.
+ stop_ovsdb
+ start_ovsdb
+
+ stop_forwarding
+ start_forwarding
+
+ # Restore the saved flows. Do not return error if restore fails.
+ restore_flows || true
+}
+
+## --------------- ##
+## enable-protocol ##
+## --------------- ##
+
+enable_protocol () {
+ # Translate the protocol name to a number, because "iptables -n -L" prints
+ # some protocols by name (despite the -n) and therefore we need to look for
+ # both forms.
+ #
+ # (iptables -S output is more uniform but old iptables doesn't have it.)
+ protonum=`grep "^$PROTOCOL[ ]" /etc/protocols | awk '{print $2}'`
+ if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
+ log_failure_msg "unknown protocol $PROTOCOL"
+ return 1
+ fi
- action "Restore interface configuration from $script" "$script"
+ name=$PROTOCOL
+ match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
+ insert="iptables -I INPUT -p $PROTOCOL"
+ if test X"$DPORT" != X; then
+ name="$name to port $DPORT"
+ match="$match && /dpt:$DPORT/"
+ insert="$insert --dport $DPORT"
+ fi
+ if test X"$SPORT" != X; then
+ name="$name from port $SPORT"
+ match="$match && /spt:$SPORT/"
+ insert="$insert --sport $SPORT"
+ fi
+ insert="$insert -j ACCEPT"
+
+ if (iptables -n -L INPUT) >/dev/null 2>&1; then
+ if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
+ then
+ # There's already a rule for this protocol. Don't override it.
+ log_success_msg "iptables already has a rule for $name, not explicitly enabling"
+ else
+ action "Enabling $name with iptables" $insert
+ fi
+ elif (iptables --version) >/dev/null 2>&1; then
+ action "cannot list iptables rules, not adding a rule for $name"
+ else
+ action "iptables binary not installed, not adding a rule for $name"
+ fi
}
## ---- ##
SYSTEM_ID=
DELETE_BRIDGES=no
+ BRCOMPAT=no
DAEMON_CWD=/
FORCE_COREFILES=yes
MLOCKALL=yes
OVSDB_SERVER_PRIORITY=-10
OVS_VSWITCHD_PRIORITY=-10
+ OVS_BRCOMPATD_PRIORITY=-10
+ OVSDB_SERVER_WRAPPER=
+ OVS_VSWITCHD_WRAPPER=
+ OVS_BRCOMPATD_WRAPPER=
- DB_FILE=$etcdir/conf.db
+ DB_FILE=$dbdir/conf.db
DB_SOCK=$rundir/db.sock
DB_SCHEMA=$datadir/vswitch.ovsschema
+ EXTRA_DBS=
- if (lsb_release --id) >/dev/null 2>&1; then
+ PROTOCOL=gre
+ DPORT=
+ SPORT=
+
+ type_file=$etcdir/system-type.conf
+ version_file=$etcdir/system-version.conf
+
+ if test -e "$type_file" ; then
+ SYSTEM_TYPE=`cat $type_file`
+ SYSTEM_VERSION=`cat $version_file`
+ elif (lsb_release --id) >/dev/null 2>&1; then
SYSTEM_TYPE=`lsb_release --id -s`
system_release=`lsb_release --release -s`
system_codename=`lsb_release --codename -s`
Commands:
start start Open vSwitch daemons
stop stop Open vSwitch daemons
+ restart stop and start Open vSwitch daemons
status check whether Open vSwitch daemons are running
version print versions of Open vSwitch daemons
+ load-kmod insert modules if not already present
force-reload-kmod save OVS network device state, stop OVS, unload kernel
module, reload kernel module, start OVS, restore state
+ enable-protocol enable protocol specified in options with iptables
help display this help message
-One of the following options should be specified when starting Open vSwitch:
+One of the following options is required for "start", "restart" and "force-reload-kmod":
--system-id=UUID set specific ID to uniquely identify this system
--system-id=random use a random but persistent UUID to identify this system
-Other important options for starting Open vSwitch:
+Other important options for "start", "restart" and "force-reload-kmod":
--system-type=TYPE set system type (e.g. "XenServer")
--system-version=VERSION set system version (e.g. "5.6.100-39265p")
--external-id="key=value"
add given key-value pair to Open_vSwitch external-ids
--delete-bridges delete all bridges just before starting ovs-vswitchd
-Less important options for starting Open vSwitch:
- --daemon-cwd=DIR current working directory for OVS daemons (default: $DAEMON_CWD)
- --no-force-corefiles
- do not forcibly enable core dumps for OVS daemons
- --no-mlockall do not lock all of ovs-vswitchd into memory
- --ovsdb-server-priority=NICE
- set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
- --ovs-vswitchd-priority=NICE
- set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
+Less important options for "start", "restart" and "force-reload-kmod":
+ --daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD)
+ --no-force-corefiles do not force on core dumps for OVS daemons
+ --no-mlockall do not lock all of ovs-vswitchd into memory
+ --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
+ --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
+ --ovs-brcompatd-priority=NICE set ovs-brcompatd's niceness (default: $OVS_BRCOMPATD_PRIORITY)
+
+Debugging options for "start", "restart" and "force-reload-kmod":
+ --ovsdb-server-wrapper=WRAPPER
+ --ovs-vswitchd-wrapper=WRAPPER
+ --ovs-vswitchd-wrapper=WRAPPER
+ run specified daemon under WRAPPER (either 'valgrind' or 'strace')
+
+Options for "start", "restart", "force-reload-kmod", "load-kmod", "status", and "version":
+ --brcompat enable Linux bridge compatibility module and daemon
File location options:
--db-file=FILE database file name (default: $DB_FILE)
--db-sock=SOCKET JSON-RPC socket name (default: $DB_SOCK)
--db-schema=FILE database schema file name (default: $DB_SCHEMA)
+Options for "enable-protocol":
+ --protocol=PROTOCOL protocol to enable with iptables (default: gre)
+ --sport=PORT source port to match (for tcp or udp protocol)
+ --dport=PORT ddestination port to match (for tcp or udp protocol)
+
Other options:
-h, --help display this help message
-V, --version display version information
Default directories with "configure" option and environment variable override:
- logs: @LOGDIR@ (--log-dir, OVS_LOGDIR)
- pidfiles and sockets: @RUNDIR@ (--run-dir, OVS_RUNDIR)
+ logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
+ pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
+ conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
user binaries: @bindir@ (--bindir, OVS_BINDIR)
eval $var=\$value
}
+daemons () {
+ echo ovsdb-server ovs-vswitchd
+ if test X"$BRCOMPAT" = Xyes; then
+ echo ovs-brcompatd
+ fi
+}
+
set_defaults
extra_ids=
command=
usage
;;
-V | --version)
- echo "$0 (Open vSwitch) $VERSION$BUILDNR"
+ echo "$0 (Open vSwitch) $VERSION"
exit 0
;;
--external-id=*)
done
case $command in
start)
- start
+ start_ovsdb
+ start_forwarding
;;
stop)
- stop
+ stop_forwarding
+ stop_ovsdb
+ ;;
+ restart)
+ restart
;;
status)
- daemon_status ovsdb-server && daemon_status ovs-vswitchd
+ rc=0
+ for daemon in `daemons`; do
+ daemon_status $daemon || rc=$?
+ done
+ exit $rc
;;
version)
- ovsdb-server --version && ovs-vswitchd --version
+ for daemon in `daemons`; do
+ $daemon --version
+ done
;;
force-reload-kmod)
- force_reload_kmod
+ force_reload_kmod
+ ;;
+ load-kmod)
+ insert_mod_if_required
+ ;;
+ enable-protocol)
+ enable_protocol
;;
help)
usage
exit 1
;;
esac
-