Introduce x2nrealloc() helper function.
[sliver-openvswitch.git] / debian / openflow-switch.init
1 #! /bin/sh
2 #
3 # /etc/init.d/openflow-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 openflow-switch.
9 #
10 # Version:      @(#)skeleton  1.9  26-Feb-2001  miquels@cistron.nl
11 #
12 ### BEGIN INIT INFO
13 # Provides:          openflow-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: OpenFlow switch
19 ### END INIT INFO
20
21 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
22 DAEMON=/usr/sbin/secchan
23 NAME=secchan
24 DESC=secchan
25
26 test -x $DAEMON || exit 0
27
28 LOGDIR=/var/log/openflow
29 PIDFILE=/var/run/$NAME.pid
30 DHCLIENT_PIDFILE=/var/run/dhclient.of0.pid
31 DODTIME=1                   # Time to wait for the server to die, in seconds
32                             # If this value is set too low you might not
33                             # let some servers to die gracefully and
34                             # 'restart' will not work
35
36 # Include secchan defaults if available
37 unset NETDEVS
38 unset MODE
39 unset SWITCH_IP
40 unset CONTROLLER
41 unset PRIVKEY
42 unset CERT
43 unset CACERT
44 unset CACERT_MODE
45 unset MGMT_VCONNS
46 unset COMMANDS
47 unset DAEMON_OPTS
48 unset CORE_LIMIT
49 unset DATAPATH_ID
50 default=/etc/default/openflow-switch
51 if [ -f $default ] ; then
52         . $default
53 fi
54
55 set -e
56
57 running_pid()
58 {
59     # Check if a given process pid's cmdline matches a given name
60     pid=$1
61     name=$2
62     [ -z "$pid" ] && return 1 
63     [ ! -d /proc/$pid ] &&  return 1
64     cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1`
65     # Is this the expected child?
66     case $cmd in
67         $name|*/$name)
68             return 0
69             ;;
70         *)
71             return 1
72             ;;
73     esac
74 }
75
76 running()
77 {
78 # Check if the process is running looking at /proc
79 # (works for all users)
80
81     # No pidfile, probably no daemon present
82     [ ! -f "$PIDFILE" ] && return 1
83     # Obtain the pid and check it against the binary name
84     pid=`cat $PIDFILE`
85     running_pid $pid $NAME || return 1
86     return 0
87 }
88
89 force_stop() {
90 # Forcefully kill the process
91     [ ! -f "$PIDFILE" ] && return
92     if running ; then
93         kill -15 $pid
94         # Is it really dead?
95         [ -n "$DODTIME" ] && sleep "$DODTIME"s
96         if running ; then
97             kill -9 $pid
98             [ -n "$DODTIME" ] && sleep "$DODTIME"s
99             if running ; then
100                 echo "Cannot kill $NAME (pid=$pid)!"
101                 exit 1
102             fi
103         fi
104     fi
105     rm -f $PIDFILE
106     return 0
107 }
108
109 must_succeed() {
110     echo -n "$1: "
111     shift
112     if "$@"; then
113         echo "success."
114     else
115         echo " ERROR."
116         exit 1
117     fi
118 }
119
120 check_op() {
121     echo -n "$1: "
122     shift
123     if "$@"; then
124         echo "success."
125     else
126         echo " ERROR."
127     fi
128 }
129
130 configure_ssl() {
131     if (test "$CACERT_MODE" != secure && test "$CACERT_MODE" != bootstrap) \
132        || test ! -e "$PRIVKEY" || test ! -e "$CERT" \
133        || (test ! -e "$CACERT" && test "$CACERT_MODE" != bootstrap); then
134         if test "$CACERT_MODE" != secure && test "$CACERT_MODE" != bootstrap
135         then
136             echo "CACERT_MODE is not set to 'secure' or 'bootstrap'"
137         fi
138         if test ! -e "$PRIVKEY"; then
139             echo "$PRIVKEY: private key missing" >&2
140         fi
141         if test ! -e "$CERT"; then
142             echo "$CERT: certificate for private key missing" >&2
143         fi
144         if test ! -e "$CACERT" && test "$CACERT_MODE" != bootstrap; then
145             echo "$CACERT: CA certificate missing (and CA certificate bootstrapping not enabled)" >&2
146         fi
147         echo "Run ofp-switch-setup (in the openflow-switch-config package) or edit /etc/default/openflow-switch to configure" >&2
148         if test "$MODE" = discovery; then
149             echo "You may also delete or rename $PRIVKEY to disable SSL requirement" >&2
150         fi
151         exit 1
152     fi
153
154     SSL_OPTS="--private-key=$PRIVKEY --certificate=$CERT"
155     if test ! -e "$CACERT" && test "$CACERT_MODE" = bootstrap; then
156         SSL_OPTS="$SSL_OPTS --bootstrap-ca-cert=$CACERT"
157     else
158         SSL_OPTS="$SSL_OPTS --ca-cert=$CACERT"
159     fi
160 }
161
162 case "$1" in
163     start)
164         if test -z "$NETDEVS"; then
165             echo "$default: No network devices configured, switch disabled" >&2
166             echo "Run ofp-switch-setup (in the openflow-switch-config package) or edit /etc/default/openflow-switch to configure" >&2
167             exit 0
168         fi
169         if test "$MODE" = discovery; then
170             unset CONTROLLER
171         elif test "$MODE" = in-band || test "$MODE" = out-of-band; then
172             if test -z "$CONTROLLER"; then
173                 echo "$default: No controller configured and not configured for discovery, switch disabled" >&2
174                 echo "Run ofp-switch-setup (in the openflow-switch-config package) or edit /etc/default/openflow-switch to configure" >&2
175                 exit 0
176             fi
177         else
178             echo "$default: MODE must set to 'discovery', 'in-band', or 'out-of-band'" >&2
179             echo "Run ofp-switch-setup (in the openflow-switch-config package) or edit /etc/default/openflow-switch to configure" >&2
180             exit 1
181         fi
182         : ${PRIVKEY:=/etc/openflow-switch/of0-privkey.pem}
183         : ${CERT:=/etc/openflow-switch/of0-cert.pem}
184         : ${CACERT:=/etc/openflow-switch/cacert.pem}
185         case $CONTROLLER in
186             '')
187                 # Discovery mode.
188                 if test -e "$PRIVKEY"; then
189                     configure_ssl
190                 fi
191                 ;;
192             tcp:*)
193                 ;;
194             ssl:*)
195                 configure_ssl
196                 ;;
197             *)
198                 echo "$default: CONTROLLER must be in the form 'ssl:HOST[:PORT]' or 'tcp:HOST[:PORT]' when not in discovery mode" >&2
199                 echo "Run ofp-switch-setup (in the openflow-switch-config package) or edit /etc/default/openflow-switch to configure" >&2
200                 exit 1
201         esac
202
203         echo -n "Loading openflow_mod: "
204         if grep -q '^openflow_mod$' /proc/modules; then
205             echo "already loaded, nothing to do."
206         elif modprobe openflow_mod; then
207             echo "success."
208         else
209             echo "ERROR."
210             echo "openflow_mod has probably not been built for this kernel."
211             if ! test -d /usr/share/doc/openflow-datapath-source; then
212                 echo "Install the openflow-datapath-source package, then read"
213                 echo "/usr/share/doc/openflow-datapath-source/README.Debian"
214             else
215                 echo "For instructions, read"
216                 echo "/usr/share/doc/openflow-datapath-source/README.Debian"
217             fi
218             exit 1
219         fi
220
221         must_succeed "Adding datapath" dpctl adddp nl:0
222         for netdev in $NETDEVS; do
223             must_succeed "Adding $netdev to datapath" dpctl addif nl:0 $netdev
224         done
225
226         xx='[0-9abcdefABCDEF][0-9abcdefABCDEF]'
227         case $DATAPATH_ID in
228             '')
229                 ;;
230             $xx:$xx:$xx:$xx:$xx:$xx)
231                 ifconfig of0 down
232                 must_succeed "Setting of0 MAC address to $DATAPATH_ID" ifconfig of0 hw ether $DATAPATH_ID
233                 ifconfig of0 up
234                 ;;
235             *)
236                 echo "DATAPATH_ID is not a valid MAC address in the form XX:XX:XX:XX:XX:XX, ignoring" >&2
237                 ;;
238         esac
239
240         if test "$MODE" = in-band; then
241             if test "$SWITCH_IP" = dhcp; then
242                 must_succeed "Temporarily disabling of0" ifconfig of0 down
243             else
244                 COMMAND="ifconfig of0 $SWITCH_IP"
245                 if test -n "$SWITCH_NETMASK"; then
246                     COMMAND="$COMMAND netmask $SWITCH_NETMASK"
247                 fi
248                 must_succeed "Configuring of0: $COMMAND" $COMMAND
249                 if test -n "$SWITCH_GATEWAY"; then
250                     # This can fail because the route already exists,
251                     # so we don't insist that it succeed.
252                     COMMAND="route add default gw $SWITCH_GATEWAY"
253                     check_op "Adding default route: $COMMAND" $COMMAND
254                 fi
255             fi
256         else
257             must_succeed "Disabling of0" ifconfig of0 down
258         fi
259
260         MGMT_OPTS=
261         for vconn in $MGMT_VCONNS; do
262             MGMT_OPTS="$MGMT_OPTS --listen=$vconn"
263         done
264
265         MONITOR_OPT=
266         if test -n "$MONITOR_VCONN"; then
267             MONITOR_OPT="--monitor=$MONITOR_VCONN"
268         fi
269
270         COMMAND_OPT=
271         if test -n "$COMMANDS"; then
272             COMMAND_OPT="--command-acl=$COMMANDS"
273         fi
274
275         if test "$MODE" = out-of-band; then
276             DAEMON_OPTS="$DAEMON_OPTS --out-of-band"
277         fi
278
279         if test -n "$CORE_LIMIT"; then
280             check_op "Setting core limit to $CORE_LIMIT" ulimit -c "$CORE_LIMIT"
281         fi
282
283         echo -n "Starting $DESC: "
284         start-stop-daemon --start --quiet --pidfile $PIDFILE \
285             --exec $DAEMON -- nl:0 $CONTROLLER --detach --pidfile=$PIDFILE \
286             --verbose=ANY:console:emer --verbose=ANY:syslog:err --log-file \
287             $DAEMON_OPTS $MGMT_OPTS $MONITOR_OPT $SSL_OPTS "$COMMAND_OPT"
288         if running; then
289             echo "$NAME."
290         else
291             echo " ERROR."
292         fi
293
294         if test "$MODE" = in-band && test "$SWITCH_IP" = dhcp; then
295             echo -n "Starting dhclient on of0: "
296             start-stop-daemon --start --quiet --pidfile $DHCLIENT_PIDFILE \
297                 --exec /sbin/dhclient -- -q -pf $DHCLIENT_PIDFILE of0
298             if running; then
299                 echo "dhclient."
300             else
301                 echo " ERROR."
302             fi
303         fi
304         ;;
305     stop)
306         if test -e /var/run/dhclient.of0.pid; then
307             echo -n "Stopping dhclient on of0: "
308             start-stop-daemon --stop --quiet --oknodo \
309                 --pidfile $DHCLIENT_PIDFILE --exec /sbin/dhclient
310             echo "dhclient."
311         fi            
312
313         echo -n "Stopping $DESC: "
314         start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE \
315             --exec $DAEMON
316         echo "$NAME."
317
318         for netdev in $NETDEVS; do
319             check_op "Removing $netdev from datapath" dpctl delif nl:0 $netdev
320         done
321         check_op "Deleting datapath" dpctl deldp nl:0
322         check_op "Unloading kernel module" modprobe -r openflow_mod
323         ;;
324     force-stop)
325         echo -n "Forcefully stopping $DESC: "
326         force_stop
327         if ! running; then
328             echo "$NAME."
329         else
330             echo " ERROR."
331         fi
332         ;;
333     reload)
334         ;;
335     force-reload)
336         start-stop-daemon --stop --test --quiet --pidfile \
337             $PIDFILE --exec $DAEMON \
338             && $0 restart \
339             || exit 0
340         ;;
341     restart)
342         $0 stop || true
343         $0 start
344         ;;
345     status)
346         echo -n "$NAME is "
347         if running ;  then
348             echo "running"
349         else
350             echo " not running."
351             exit 1
352         fi
353         ;;
354     *)
355         N=/etc/init.d/$NAME
356         echo "Usage: $N {start|stop|restart|force-reload|status|force-stop}" >&2
357         exit 1
358         ;;
359 esac
360
361 exit 0