Merge "citrix" branch into "master.
[sliver-openvswitch.git] / debian / openvswitch-switch.init
1 #! /bin/sh
2 #
3 # /etc/init.d/openvswitch-switch
4 #
5 # Written by Miquel van Smoorenburg <miquels@cistron.nl>.
6 # Modified for Debian by Ian Murdock <imurdock@gnu.ai.mit.edu>.
7 # Further changes by Javier Fernandez-Sanguino <jfs@debian.org>
8 # Modified for openvswitch-switch.
9 #
10 # Version:      @(#)skeleton  1.9  26-Feb-2001  miquels@cistron.nl
11 #
12 ### BEGIN INIT INFO
13 # Provides:          openvswitch-switch
14 # Required-Start:    $network $named $remote_fs $syslog
15 # Required-Stop:
16 # Default-Start:     2 3 4 5
17 # Default-Stop:      0 1 6
18 # Short-Description: Open vSwitch switch
19 ### END INIT INFO
20
21 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
22 DAEMON=/usr/sbin/ovs-openflowd
23 NAME=ovs-openflowd
24 DESC=ovs-openflowd
25
26 test -x $DAEMON || exit 0
27
28 NICIRA_OUI="002320"
29
30 LOGDIR=/var/log/openvswitch
31 PIDFILE=/var/run/$NAME.pid
32 DHCLIENT_PIDFILE=/var/run/dhclient.of0.pid
33 DODTIME=1                   # Time to wait for the server to die, in seconds
34                             # If this value is set too low you might not
35                             # let some servers to die gracefully and
36                             # 'restart' will not work
37
38 # Include ovs-openflowd defaults if available
39 unset NETDEVS
40 unset MODE
41 unset SWITCH_IP
42 unset CONTROLLER
43 unset PRIVKEY
44 unset CERT
45 unset CACERT
46 unset CACERT_MODE
47 unset MGMT_VCONNS
48 unset COMMANDS
49 unset DAEMON_OPTS
50 unset CORE_LIMIT
51 unset DATAPATH_ID
52 default=/etc/default/openvswitch-switch
53 if [ -f $default ] ; then
54         . $default
55 fi
56
57 set -e
58
59 running_pid()
60 {
61     # Check if a given process pid's cmdline matches a given name
62     pid=$1
63     name=$2
64     [ -z "$pid" ] && return 1 
65     [ ! -d /proc/$pid ] &&  return 1
66     cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1`
67     # Is this the expected child?
68     case $cmd in
69         $name|*/$name)
70             return 0
71             ;;
72         *)
73             return 1
74             ;;
75     esac
76 }
77
78 running()
79 {
80 # Check if the process is running looking at /proc
81 # (works for all users)
82
83     # No pidfile, probably no daemon present
84     [ ! -f "$PIDFILE" ] && return 1
85     # Obtain the pid and check it against the binary name
86     pid=`cat $PIDFILE`
87     running_pid $pid $NAME || return 1
88     return 0
89 }
90
91 force_stop() {
92 # Forcefully kill the process
93     [ ! -f "$PIDFILE" ] && return
94     if running ; then
95         kill -15 $pid
96         # Is it really dead?
97         [ -n "$DODTIME" ] && sleep "$DODTIME"s
98         if running ; then
99             kill -9 $pid
100             [ -n "$DODTIME" ] && sleep "$DODTIME"s
101             if running ; then
102                 echo "Cannot kill $NAME (pid=$pid)!"
103                 exit 1
104             fi
105         fi
106     fi
107     rm -f $PIDFILE
108     return 0
109 }
110
111 must_succeed() {
112     echo -n "$1: "
113     shift
114     if "$@"; then
115         echo "success."
116     else
117         echo " ERROR."
118         exit 1
119     fi
120 }
121
122 check_op() {
123     echo -n "$1: "
124     shift
125     if "$@"; then
126         echo "success."
127     else
128         echo " ERROR."
129     fi
130 }
131
132 configure_ssl() {
133     if (test "$CACERT_MODE" != secure && test "$CACERT_MODE" != bootstrap) \
134        || test ! -e "$PRIVKEY" || test ! -e "$CERT" \
135        || (test ! -e "$CACERT" && test "$CACERT_MODE" != bootstrap); then
136         if test "$CACERT_MODE" != secure && test "$CACERT_MODE" != bootstrap
137         then
138             echo "CACERT_MODE is not set to 'secure' or 'bootstrap'"
139         fi
140         if test ! -e "$PRIVKEY"; then
141             echo "$PRIVKEY: private key missing" >&2
142         fi
143         if test ! -e "$CERT"; then
144             echo "$CERT: certificate for private key missing" >&2
145         fi
146         if test ! -e "$CACERT" && test "$CACERT_MODE" != bootstrap; then
147             echo "$CACERT: CA certificate missing (and CA certificate bootstrapping not enabled)" >&2
148         fi
149         echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2
150         if test "$MODE" = discovery; then
151             echo "You may also delete or rename $PRIVKEY to disable SSL requirement" >&2
152         fi
153         exit 1
154     fi
155
156     SSL_OPTS="--private-key=$PRIVKEY --certificate=$CERT"
157     if test ! -e "$CACERT" && test "$CACERT_MODE" = bootstrap; then
158         SSL_OPTS="$SSL_OPTS --bootstrap-ca-cert=$CACERT"
159     else
160         SSL_OPTS="$SSL_OPTS --ca-cert=$CACERT"
161     fi
162 }
163
164 check_int_var() {
165     eval value=\$$1
166     if test -n "$value"; then
167         if expr "X$value" : 'X[0-9][0-9]*$' > /dev/null 2>&1; then
168             if test $value -lt $2; then
169                 echo "warning: The $1 option may not be set to a value below $2, treating as $2" >&2
170                 eval $1=$2
171             fi
172         else
173             echo "warning: The $1 option must be set to a number, ignoring" >&2
174             unset $1
175         fi
176     fi
177 }
178
179 check_new_option() {
180     case $DAEMON_OPTS in
181         *$1*)
182             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
183             ;;
184     esac
185 }
186
187 case "$1" in
188     start)
189         if test -z "$NETDEVS"; then
190             echo "$default: No network devices configured, switch disabled" >&2
191             echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2
192             exit 0
193         fi
194         if test "$MODE" = discovery; then
195             unset CONTROLLER
196         elif test "$MODE" = in-band || test "$MODE" = out-of-band; then
197             if test -z "$CONTROLLER"; then
198                 echo "$default: No controller configured and not configured for discovery, switch disabled" >&2
199                 echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2
200                 exit 0
201             fi
202         else
203             echo "$default: MODE must set to 'discovery', 'in-band', or 'out-of-band'" >&2
204             echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2
205             exit 1
206         fi
207         : ${PRIVKEY:=/etc/openvswitch-switch/of0-privkey.pem}
208         : ${CERT:=/etc/openvswitch-switch/of0-cert.pem}
209         : ${CACERT:=/etc/openvswitch-switch/cacert.pem}
210         case $CONTROLLER in
211             '')
212                 # Discovery mode.
213                 if test -e "$PRIVKEY"; then
214                     configure_ssl
215                 fi
216                 ;;
217             tcp:*)
218                 ;;
219             ssl:*)
220                 configure_ssl
221                 ;;
222             *)
223                 echo "$default: CONTROLLER must be in the form 'ssl:IP[:PORT]' or 'tcp:IP[:PORT]' when not in discovery mode" >&2
224                 echo "Run ovs-switch-setup (in the openvswitch-switch-config package) or edit /etc/default/openvswitch-switch to configure" >&2
225                 exit 1
226         esac
227         case $DISCONNECTED_MODE in
228             ''|switch|drop) ;; 
229             *) echo "$default: warning: DISCONNECTED_MODE is not 'switch' or 'drop'" >&2 ;;
230         esac
231
232         check_int_var RATE_LIMIT 100
233         check_int_var INACTIVITY_PROBE 5
234         check_int_var MAX_BACKOFF 1
235
236         check_new_option --fail DISCONNECTED_MODE
237         check_new_option --stp STP
238         check_new_option --rate-limit RATE_LIMIT
239         check_new_option --inactivity INACTIVITY_PROBE
240         check_new_option --max-backoff MAX_BACKOFF
241         case $DAEMON_OPTS in
242             *--rate-limit*)
243                 echo "$default: --rate-limit may now be set with RATE_LIMIT" >&2
244         esac
245
246         echo -n "Loading openvswitch_mod: "
247         if grep -q '^openvswitch_mod$' /proc/modules; then
248             echo "already loaded, nothing to do."
249         elif modprobe openvswitch_mod; then
250             echo "success."
251         else
252             echo "ERROR."
253             echo "openvswitch_mod has probably not been built for this kernel."
254             if ! test -d /usr/share/doc/openvswitch-datapath-source; then
255                 echo "Install the openvswitch-datapath-source package, then read"
256                 echo "/usr/share/doc/openvswitch-datapath-source/README.Debian"
257             else
258                 echo "For instructions, read"
259                 echo "/usr/share/doc/openvswitch-datapath-source/README.Debian"
260             fi
261             exit 1
262         fi
263
264         for netdev in $NETDEVS; do
265             check_op "Removing IP address from $netdev" ifconfig $netdev 0.0.0.0
266         done
267
268         must_succeed "Creating datapath" ovs-dpctl add-dp of0 $NETDEVS
269
270         xx='[0-9abcdefABCDEF][0-9abcdefABCDEF]'
271         case $DATAPATH_ID in
272             '')
273                 # Check if the DMI System UUID contains a Nicira mac address
274                 # that should be used for this datapath.  The UUID is assumed 
275                 # to be RFC 4122 compliant.
276                 DMIDECODE=`which dmidecode`
277                 if [ -n $DMIDECODE ]; then
278                     UUID_MAC=`$DMIDECODE -s system-uuid | cut -d'-' -f 5`
279                     case $UUID_MAC in
280                         $NICIRA_OUI*)
281                             ifconfig of0 down
282                             must_succeed "Setting of0 MAC address to $UUID_MAC" ifconfig of0 hw ether $UUID_MAC
283                             ifconfig of0 up
284                             ;;
285                     esac
286                 fi  
287                 ;;
288             $xx:$xx:$xx:$xx:$xx:$xx)
289                 ifconfig of0 down
290                 must_succeed "Setting of0 MAC address to $DATAPATH_ID" ifconfig of0 hw ether $DATAPATH_ID
291                 ifconfig of0 up
292                 ;;
293             *)
294                 echo "DATAPATH_ID is not a valid MAC address in the form XX:XX:XX:XX:XX:XX, ignoring" >&2
295                 ;;
296         esac
297
298         if test "$MODE" = in-band; then
299             if test "$SWITCH_IP" = dhcp; then
300                 must_succeed "Temporarily disabling of0" ifconfig of0 down
301             else
302                 COMMAND="ifconfig of0 $SWITCH_IP"
303                 if test -n "$SWITCH_NETMASK"; then
304                     COMMAND="$COMMAND netmask $SWITCH_NETMASK"
305                 fi
306                 must_succeed "Configuring of0: $COMMAND" $COMMAND
307                 if test -n "$SWITCH_GATEWAY"; then
308                     # This can fail because the route already exists,
309                     # so we don't insist that it succeed.
310                     COMMAND="route add default gw $SWITCH_GATEWAY"
311                     check_op "Adding default route: $COMMAND" $COMMAND
312                 fi
313             fi
314         else
315             must_succeed "Disabling of0" ifconfig of0 down
316         fi
317
318         if test -n "$CORE_LIMIT"; then
319             check_op "Setting core limit to $CORE_LIMIT" ulimit -c "$CORE_LIMIT"
320         fi
321
322         # Compose ovs-openflowd options.
323         set --
324         set -- "$@" --verbose=ANY:console:emer --verbose=ANY:syslog:err
325         set -- "$@" --log-file
326         set -- "$@" --detach --pidfile=$PIDFILE
327         for vconn in $MGMT_VCONNS; do
328             set -- "$@" --listen="$vconn"
329         done
330         if test -n "$COMMANDS"; then
331             set -- "$@" --command-acl="$COMMANDS"
332         fi
333         case $STP in
334             yes) set -- "$@" --stp ;;
335             no) set -- "$@" --no-stp ;;
336         esac
337         case $DISCONNECTED_MODE in
338             switch) set -- "$@" --fail=open ;;
339             drop) set -- "$@" --fail=closed ;;
340         esac
341         if test -n "$RATE_LIMIT"; then
342             set -- "$@" --rate-limit=$RATE_LIMIT
343         fi
344         if test -n "$INACTIVITY_PROBE"; then
345             set -- "$@" --inactivity-probe=$INACTIVITY_PROBE
346         fi
347         if test -n "$MAX_BACKOFF"; then
348             set -- "$@" --max-backoff=$MAX_BACKOFF
349         fi
350         set -- "$@" $SSL_OPTS $DAEMON_OPTS
351         if test "$MODE" = out-of-band; then
352             set -- "$@" --out-of-band
353         fi
354         set -- "$@" of0 "$CONTROLLER"
355         echo -n "Starting $DESC: "
356         start-stop-daemon --start --quiet --pidfile $PIDFILE \
357             --exec $DAEMON -- "$@"
358         if running; then
359             echo "$NAME."
360         else
361             echo " ERROR."
362         fi
363
364         if test "$MODE" = in-band && test "$SWITCH_IP" = dhcp; then
365             echo -n "Starting dhclient on of0: "
366             start-stop-daemon --start --quiet --pidfile $DHCLIENT_PIDFILE \
367                 --exec /sbin/dhclient -- -q -pf $DHCLIENT_PIDFILE of0
368             if running; then
369                 echo "dhclient."
370             else
371                 echo " ERROR."
372             fi
373         fi
374         ;;
375     stop)
376         if test -e /var/run/dhclient.of0.pid; then
377             echo -n "Stopping dhclient on of0: "
378             start-stop-daemon --stop --quiet --oknodo \
379                 --pidfile $DHCLIENT_PIDFILE --exec /sbin/dhclient
380             echo "dhclient."
381         fi            
382
383         echo -n "Stopping $DESC: "
384         start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE \
385             --exec $DAEMON
386         echo "$NAME."
387
388         check_op "Deleting datapath" ovs-dpctl del-dp of0
389         check_op "Unloading kernel module" modprobe -r openvswitch_mod
390         ;;
391     force-stop)
392         echo -n "Forcefully stopping $DESC: "
393         force_stop
394         if ! running; then
395             echo "$NAME."
396         else
397             echo " ERROR."
398         fi
399         ;;
400     reload)
401         ;;
402     force-reload)
403         start-stop-daemon --stop --test --quiet --pidfile \
404             $PIDFILE --exec $DAEMON \
405             && $0 restart \
406             || exit 0
407         ;;
408     restart)
409         $0 stop || true
410         $0 start
411         ;;
412     status)
413         echo -n "$NAME is "
414         if running ;  then
415             echo "running"
416         else
417             echo " not running."
418             exit 1
419         fi
420         ;;
421     *)
422         N=/etc/init.d/$NAME
423         echo "Usage: $N {start|stop|restart|force-reload|status|force-stop}" >&2
424         exit 1
425         ;;
426 esac
427
428 exit 0