#! /bin/sh # # /etc/init.d/openvswitch-switch # # Written by Miquel van Smoorenburg . # Modified for Debian by Ian Murdock . # Further changes by Javier Fernandez-Sanguino # Modified for openvswitch-switch. # # Version: @(#)skeleton 1.9 26-Feb-2001 miquels@cistron.nl # ### BEGIN INIT INFO # Provides: openvswitch-switch # Required-Start: $network $named $remote_fs $syslog # Required-Stop: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Open vSwitch switch ### END INIT INFO PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/sbin/ovs-openflowd NAME=ovs-openflowd DESC=ovs-openflowd test -x $DAEMON || exit 0 NICIRA_OUI="002320" LOGDIR=/var/log/openvswitch PIDFILE=/var/run/$NAME.pid DHCLIENT_PIDFILE=/var/run/dhclient.of0.pid DODTIME=1 # Time to wait for the server to die, in seconds # If this value is set too low you might not # let some servers to die gracefully and # 'restart' will not work # Include ovs-openflowd defaults if available unset NETDEVS unset MODE unset SWITCH_IP unset CONTROLLER unset PRIVKEY unset CERT unset CACERT unset CACERT_MODE unset MGMT_VCONNS unset COMMANDS unset DAEMON_OPTS unset CORE_LIMIT unset DATAPATH_ID default=/etc/default/openvswitch-switch if [ -f $default ] ; then . $default fi set -e running_pid() { # Check if a given process pid's cmdline matches a given name pid=$1 name=$2 [ -z "$pid" ] && return 1 [ ! -d /proc/$pid ] && return 1 cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1` # Is this the expected child? case $cmd in $name|*/$name) return 0 ;; *) return 1 ;; esac } running() { # Check if the process is running looking at /proc # (works for all users) # No pidfile, probably no daemon present [ ! -f "$PIDFILE" ] && return 1 # Obtain the pid and check it against the binary name pid=`cat $PIDFILE` running_pid $pid $NAME || return 1 return 0 } force_stop() { # Forcefully kill the process [ ! -f "$PIDFILE" ] && return if running ; then kill -15 $pid # Is it really dead? [ -n "$DODTIME" ] && sleep "$DODTIME"s if running ; then kill -9 $pid [ -n "$DODTIME" ] && sleep "$DODTIME"s if running ; then echo "Cannot kill $NAME (pid=$pid)!" exit 1 fi fi fi rm -f $PIDFILE return 0 } must_succeed() { echo -n "$1: " shift if "$@"; then echo "success." else echo " ERROR." exit 1 fi } check_op() { echo -n "$1: " shift if "$@"; then echo "success." else echo " ERROR." fi } configure_ssl() { if (test "$CACERT_MODE" != secure && test "$CACERT_MODE" != bootstrap) \ || test ! -e "$PRIVKEY" || test ! -e "$CERT" \ || (test ! -e "$CACERT" && test "$CACERT_MODE" != bootstrap); then if test "$CACERT_MODE" != secure && test "$CACERT_MODE" != bootstrap then echo "CACERT_MODE is not set to 'secure' or 'bootstrap'" fi if test ! -e "$PRIVKEY"; then echo "$PRIVKEY: private key missing" >&2 fi if test ! -e "$CERT"; then echo "$CERT: certificate for private key missing" >&2 fi if test ! -e "$CACERT" && test "$CACERT_MODE" != bootstrap; then echo "$CACERT: CA certificate missing (and CA certificate bootstrapping not enabled)" >&2 fi echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2 if test "$MODE" = discovery; then echo "You may also delete or rename $PRIVKEY to disable SSL requirement" >&2 fi exit 1 fi SSL_OPTS="--private-key=$PRIVKEY --certificate=$CERT" if test ! -e "$CACERT" && test "$CACERT_MODE" = bootstrap; then SSL_OPTS="$SSL_OPTS --bootstrap-ca-cert=$CACERT" else SSL_OPTS="$SSL_OPTS --ca-cert=$CACERT" fi } check_int_var() { eval value=\$$1 if test -n "$value"; then if expr "X$value" : 'X[0-9][0-9]*$' > /dev/null 2>&1; then if test $value -lt $2; then echo "warning: The $1 option may not be set to a value below $2, treating as $2" >&2 eval $1=$2 fi else echo "warning: The $1 option must be set to a number, ignoring" >&2 unset $1 fi fi } check_new_option() { case $DAEMON_OPTS in *$1*) echo "warning: The $1 option in DAEMON_OPTS may now be set with the $2 variable in $default. The setting in DAEMON_OPTS will override the $2 variable, which will prevent the switch UI from configuring $1." >&2 ;; esac } case "$1" in start) if test -z "$NETDEVS"; then echo "$default: No network devices configured, switch disabled" >&2 echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2 exit 0 fi if test "$MODE" = discovery; then unset CONTROLLER elif test "$MODE" = in-band || test "$MODE" = out-of-band; then if test -z "$CONTROLLER"; then echo "$default: No controller configured and not configured for discovery, switch disabled" >&2 echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2 exit 0 fi else echo "$default: MODE must set to 'discovery', 'in-band', or 'out-of-band'" >&2 echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2 exit 1 fi : ${PRIVKEY:=/etc/openvswitch-switch/of0-privkey.pem} : ${CERT:=/etc/openvswitch-switch/of0-cert.pem} : ${CACERT:=/etc/openvswitch-switch/cacert.pem} case $CONTROLLER in '') # Discovery mode. if test -e "$PRIVKEY"; then configure_ssl fi ;; tcp:*) ;; ssl:*) configure_ssl ;; *) echo "$default: CONTROLLER must be in the form 'ssl:HOST[:PORT]' or 'tcp:HOST[:PORT]' when not in discovery mode" >&2 echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2 exit 1 esac case $DISCONNECTED_MODE in ''|switch|drop) ;; *) echo "$default: warning: DISCONNECTED_MODE is not 'switch' or 'drop'" >&2 ;; esac check_int_var RATE_LIMIT 100 check_int_var INACTIVITY_PROBE 5 check_int_var MAX_BACKOFF 1 check_new_option --fail DISCONNECTED_MODE check_new_option --stp STP check_new_option --rate-limit RATE_LIMIT check_new_option --inactivity INACTIVITY_PROBE check_new_option --max-backoff MAX_BACKOFF case $DAEMON_OPTS in *--rate-limit*) echo "$default: --rate-limit may now be set with RATE_LIMIT" >&2 esac echo -n "Loading openvswitch_mod: " if grep -q '^openvswitch_mod$' /proc/modules; then echo "already loaded, nothing to do." elif modprobe openvswitch_mod; then echo "success." else echo "ERROR." echo "openvswitch_mod has probably not been built for this kernel." if ! test -d /usr/share/doc/openvswitch-datapath-source; then echo "Install the openvswitch-datapath-source package, then read" echo "/usr/share/doc/openvswitch-datapath-source/README.Debian" else echo "For instructions, read" echo "/usr/share/doc/openvswitch-datapath-source/README.Debian" fi exit 1 fi for netdev in $NETDEVS; do check_op "Removing IP address from $netdev" ifconfig $netdev 0.0.0.0 done must_succeed "Creating datapath" ovs-dpctl add-dp of0 $NETDEVS xx='[0-9abcdefABCDEF][0-9abcdefABCDEF]' case $DATAPATH_ID in '') # Check if the DMI System UUID contains a Nicira mac address # that should be used for this datapath. The UUID is assumed # to be RFC 4122 compliant. DMIDECODE=`which dmidecode` if [ -n $DMIDECODE ]; then UUID_MAC=`$DMIDECODE -s system-uuid | cut -d'-' -f 5` case $UUID_MAC in $NICIRA_OUI*) ifconfig of0 down must_succeed "Setting of0 MAC address to $UUID_MAC" ifconfig of0 hw ether $UUID_MAC ifconfig of0 up ;; esac fi ;; $xx:$xx:$xx:$xx:$xx:$xx) ifconfig of0 down must_succeed "Setting of0 MAC address to $DATAPATH_ID" ifconfig of0 hw ether $DATAPATH_ID ifconfig of0 up ;; *) echo "DATAPATH_ID is not a valid MAC address in the form XX:XX:XX:XX:XX:XX, ignoring" >&2 ;; esac if test "$MODE" = in-band; then if test "$SWITCH_IP" = dhcp; then must_succeed "Temporarily disabling of0" ifconfig of0 down else COMMAND="ifconfig of0 $SWITCH_IP" if test -n "$SWITCH_NETMASK"; then COMMAND="$COMMAND netmask $SWITCH_NETMASK" fi must_succeed "Configuring of0: $COMMAND" $COMMAND if test -n "$SWITCH_GATEWAY"; then # This can fail because the route already exists, # so we don't insist that it succeed. COMMAND="route add default gw $SWITCH_GATEWAY" check_op "Adding default route: $COMMAND" $COMMAND fi fi else must_succeed "Disabling of0" ifconfig of0 down fi if test -n "$CORE_LIMIT"; then check_op "Setting core limit to $CORE_LIMIT" ulimit -c "$CORE_LIMIT" fi # Compose ovs-openflowd options. set -- set -- "$@" --verbose=ANY:console:emer --verbose=ANY:syslog:err set -- "$@" --log-file set -- "$@" --detach --pidfile=$PIDFILE for vconn in $MGMT_VCONNS; do set -- "$@" --listen="$vconn" done if test -n "$COMMANDS"; then set -- "$@" --command-acl="$COMMANDS" fi case $STP in yes) set -- "$@" --stp ;; no) set -- "$@" --no-stp ;; esac case $DISCONNECTED_MODE in switch) set -- "$@" --fail=open ;; drop) set -- "$@" --fail=closed ;; esac if test -n "$RATE_LIMIT"; then set -- "$@" --rate-limit=$RATE_LIMIT fi if test -n "$INACTIVITY_PROBE"; then set -- "$@" --inactivity-probe=$INACTIVITY_PROBE fi if test -n "$MAX_BACKOFF"; then set -- "$@" --max-backoff=$MAX_BACKOFF fi set -- "$@" $SSL_OPTS $DAEMON_OPTS if test "$MODE" = out-of-band; then set -- "$@" --out-of-band fi set -- "$@" of0 "$CONTROLLER" echo -n "Starting $DESC: " start-stop-daemon --start --quiet --pidfile $PIDFILE \ --exec $DAEMON -- "$@" if running; then echo "$NAME." else echo " ERROR." fi if test "$MODE" = in-band && test "$SWITCH_IP" = dhcp; then echo -n "Starting dhclient on of0: " start-stop-daemon --start --quiet --pidfile $DHCLIENT_PIDFILE \ --exec /sbin/dhclient -- -q -pf $DHCLIENT_PIDFILE of0 if running; then echo "dhclient." else echo " ERROR." fi fi ;; stop) if test -e /var/run/dhclient.of0.pid; then echo -n "Stopping dhclient on of0: " start-stop-daemon --stop --quiet --oknodo \ --pidfile $DHCLIENT_PIDFILE --exec /sbin/dhclient echo "dhclient." fi echo -n "Stopping $DESC: " start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE \ --exec $DAEMON echo "$NAME." check_op "Deleting datapath" ovs-dpctl del-dp of0 check_op "Unloading kernel module" modprobe -r openvswitch_mod ;; force-stop) echo -n "Forcefully stopping $DESC: " force_stop if ! running; then echo "$NAME." else echo " ERROR." fi ;; reload) ;; force-reload) start-stop-daemon --stop --test --quiet --pidfile \ $PIDFILE --exec $DAEMON \ && $0 restart \ || exit 0 ;; restart) $0 stop || true $0 start ;; status) echo -n "$NAME is " if running ; then echo "running" else echo " not running." exit 1 fi ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|force-reload|status|force-stop}" >&2 exit 1 ;; esac exit 0