summaryrefslogtreecommitdiff
path: root/debian/openvswitch-switch.init
blob: b238f72e1409e82b9670bd73c5422b6fb84f58cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
#! /bin/sh
#
# /etc/init.d/openvswitch-switch
#
# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
# Modified for Debian by Ian Murdock <imurdock@gnu.ai.mit.edu>.
# Further changes by Javier Fernandez-Sanguino <jfs@debian.org>
# 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/secchan
NAME=secchan
DESC=secchan

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 secchan 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 secchan 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