gre: Add kernel GRE support.
[openvswitch] / 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         echo -n "Loading ip_gre_mod: "
265         if grep -q '^ip_gre$' /proc/modules; then
266             modprobe -r ip_gre
267         fi
268         if grep -q '^ip_gre_mod$' /proc/modules; then
269             echo "already loaded, nothing to do."
270         elif modprobe ip_gre_mod; then
271             echo "success."
272         else
273             echo "could not find module."
274         fi
275
276         for netdev in $NETDEVS; do
277             check_op "Removing IP address from $netdev" ifconfig $netdev 0.0.0.0
278         done
279
280         must_succeed "Creating datapath" ovs-dpctl add-dp of0 $NETDEVS
281
282         xx='[0-9abcdefABCDEF][0-9abcdefABCDEF]'
283         case $DATAPATH_ID in
284             '')
285                 # Check if the DMI System UUID contains a Nicira mac address
286                 # that should be used for this datapath.  The UUID is assumed 
287                 # to be RFC 4122 compliant.
288                 DMIDECODE=`which dmidecode`
289                 if [ -n $DMIDECODE ]; then
290                     UUID_MAC=`$DMIDECODE -s system-uuid | cut -d'-' -f 5`
291                     case $UUID_MAC in
292                         $NICIRA_OUI*)
293                             ifconfig of0 down
294                             must_succeed "Setting of0 MAC address to $UUID_MAC" ifconfig of0 hw ether $UUID_MAC
295                             ifconfig of0 up
296                             ;;
297                     esac
298                 fi  
299                 ;;
300             $xx:$xx:$xx:$xx:$xx:$xx)
301                 ifconfig of0 down
302                 must_succeed "Setting of0 MAC address to $DATAPATH_ID" ifconfig of0 hw ether $DATAPATH_ID
303                 ifconfig of0 up
304                 ;;
305             *)
306                 echo "DATAPATH_ID is not a valid MAC address in the form XX:XX:XX:XX:XX:XX, ignoring" >&2
307                 ;;
308         esac
309
310         if test "$MODE" = in-band; then
311             if test "$SWITCH_IP" = dhcp; then
312                 must_succeed "Temporarily disabling of0" ifconfig of0 down
313             else
314                 COMMAND="ifconfig of0 $SWITCH_IP"
315                 if test -n "$SWITCH_NETMASK"; then
316                     COMMAND="$COMMAND netmask $SWITCH_NETMASK"
317                 fi
318                 must_succeed "Configuring of0: $COMMAND" $COMMAND
319                 if test -n "$SWITCH_GATEWAY"; then
320                     # This can fail because the route already exists,
321                     # so we don't insist that it succeed.
322                     COMMAND="route add default gw $SWITCH_GATEWAY"
323                     check_op "Adding default route: $COMMAND" $COMMAND
324                 fi
325             fi
326         else
327             must_succeed "Disabling of0" ifconfig of0 down
328         fi
329
330         if test -n "$CORE_LIMIT"; then
331             check_op "Setting core limit to $CORE_LIMIT" ulimit -c "$CORE_LIMIT"
332         fi
333
334         # Compose ovs-openflowd options.
335         set --
336         set -- "$@" --verbose=ANY:console:emer --verbose=ANY:syslog:err
337         set -- "$@" --log-file
338         set -- "$@" --detach --pidfile=$PIDFILE
339         for vconn in $MGMT_VCONNS; do
340             set -- "$@" --listen="$vconn"
341         done
342         if test -n "$COMMANDS"; then
343             set -- "$@" --command-acl="$COMMANDS"
344         fi
345         case $STP in
346             yes) set -- "$@" --stp ;;
347             no) set -- "$@" --no-stp ;;
348         esac
349         case $DISCONNECTED_MODE in
350             switch) set -- "$@" --fail=open ;;
351             drop) set -- "$@" --fail=closed ;;
352         esac
353         if test -n "$RATE_LIMIT"; then
354             set -- "$@" --rate-limit=$RATE_LIMIT
355         fi
356         if test -n "$INACTIVITY_PROBE"; then
357             set -- "$@" --inactivity-probe=$INACTIVITY_PROBE
358         fi
359         if test -n "$MAX_BACKOFF"; then
360             set -- "$@" --max-backoff=$MAX_BACKOFF
361         fi
362         set -- "$@" $SSL_OPTS $DAEMON_OPTS
363         if test "$MODE" = out-of-band; then
364             set -- "$@" --out-of-band
365         fi
366         set -- "$@" of0 "$CONTROLLER"
367         echo -n "Starting $DESC: "
368         start-stop-daemon --start --quiet --pidfile $PIDFILE \
369             --exec $DAEMON -- "$@"
370         if running; then
371             echo "$NAME."
372         else
373             echo " ERROR."
374         fi
375
376         if test "$MODE" = in-band && test "$SWITCH_IP" = dhcp; then
377             echo -n "Starting dhclient on of0: "
378             start-stop-daemon --start --quiet --pidfile $DHCLIENT_PIDFILE \
379                 --exec /sbin/dhclient -- -q -pf $DHCLIENT_PIDFILE of0
380             if running; then
381                 echo "dhclient."
382             else
383                 echo " ERROR."
384             fi
385         fi
386         ;;
387     stop)
388         if test -e /var/run/dhclient.of0.pid; then
389             echo -n "Stopping dhclient on of0: "
390             start-stop-daemon --stop --quiet --oknodo \
391                 --pidfile $DHCLIENT_PIDFILE --exec /sbin/dhclient
392             echo "dhclient."
393         fi            
394
395         echo -n "Stopping $DESC: "
396         start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE \
397             --exec $DAEMON
398         echo "$NAME."
399
400         check_op "Deleting datapath" ovs-dpctl del-dp of0
401         echo -n "Unloading ip_gre module: "
402         if modprobe -r ip_gre_mod; then
403             echo "success."
404         fi
405         check_op "Unloading kernel module" modprobe -r openvswitch_mod
406         ;;
407     force-stop)
408         echo -n "Forcefully stopping $DESC: "
409         force_stop
410         if ! running; then
411             echo "$NAME."
412         else
413             echo " ERROR."
414         fi
415         ;;
416     reload)
417         ;;
418     force-reload)
419         start-stop-daemon --stop --test --quiet --pidfile \
420             $PIDFILE --exec $DAEMON \
421             && $0 restart \
422             || exit 0
423         ;;
424     restart)
425         $0 stop || true
426         $0 start
427         ;;
428     status)
429         echo -n "$NAME is "
430         if running ;  then
431             echo "running"
432         else
433             echo " not running."
434             exit 1
435         fi
436         ;;
437     *)
438         N=/etc/init.d/$NAME
439         echo "Usage: $N {start|stop|restart|force-reload|status|force-stop}" >&2
440         exit 1
441         ;;
442 esac
443
444 exit 0