2 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;;
20 . "$dir0/ovs-lib" || exit 1
22 for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do
33 insert_mod_if_required () {
34 # If this kernel has no module support, expect we're done.
35 if test ! -e /proc/modules
37 log_success_msg "Kernel has no loadable module support. Skipping modprobe"
41 # If openvswitch is already loaded then we're done.
42 test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
45 # Load openvswitch. If that's successful then we're done.
46 action "Inserting openvswitch module" modprobe openvswitch && return 0
48 # If the bridge module is loaded, then that might be blocking
49 # openvswitch. Try to unload it, if there are no bridges.
50 test -e /sys/module/bridge || return 1
51 bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
52 if test "$bridges" != "*"; then
53 log_warning_msg "not removing bridge module because bridges exist ($bridges)"
56 action "removing bridge module" rmmod bridge || return 1
58 # Try loading openvswitch again.
59 action "Inserting openvswitch module" modprobe openvswitch
63 ovs-vsctl --no-wait "$@"
67 ovsdb-tool -vconsole:off "$@"
71 action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
75 schemaver=`ovsdb_tool schema-version "$DB_SCHEMA"`
76 if test ! -e "$DB_FILE"; then
77 log_warning_msg "$DB_FILE does not exist"
78 install -d -m 755 -o root -g root `dirname $DB_FILE`
80 elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then
81 # Back up the old version.
82 version=`ovsdb_tool db-version "$DB_FILE"`
83 cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'`
84 backup=$DB_FILE.backup$version-$cksum
85 action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1
87 # Compact database. This is important if the old schema did not enable
88 # garbage collection (i.e. if it did not have any tables with "isRoot":
89 # true) but the new schema does. In that situation the old database
90 # may contain a transaction that creates a record followed by a
91 # transaction that creates the first use of the record. Replaying that
92 # series of transactions against the new database schema (as "convert"
93 # does) would cause the record to be dropped by the first transaction,
94 # then the second transaction would cause a referential integrity
95 # failure (for a strong reference).
97 # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't
98 # understand some feature of the schema used in the OVSDB version that
99 # we're downgrading from, so we don't give up on error.
100 action "Compacting database" ovsdb_tool compact "$DB_FILE"
102 # Upgrade or downgrade schema.
103 if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
106 log_warning_msg "Schema conversion failed, using empty database instead"
114 set ovs_vsctl set Open_vSwitch .
116 OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'`
117 set "$@" ovs-version="$OVS_VERSION"
121 id_file=$etcdir/system-id.conf
122 uuid_file=$etcdir/install_uuid.conf
123 if test -e "$id_file"; then
124 SYSTEM_ID=`cat "$id_file"`
125 elif test -e "$uuid_file"; then
126 # Migrate from old file name.
128 SYSTEM_ID=$INSTALLATION_UUID
129 echo "$SYSTEM_ID" > "$id_file"
130 elif SYSTEM_ID=`uuidgen`; then
131 echo "$SYSTEM_ID" > "$id_file"
133 log_failure_msg "missing uuidgen, could not generate system ID"
138 log_failure_msg "system ID not configured, please use --system-id"
144 set "$@" external-ids:system-id="\"$SYSTEM_ID\""
146 if test X"$SYSTEM_TYPE" != X; then
147 set "$@" system-type="\"$SYSTEM_TYPE\""
149 log_failure_msg "no default system type, please use --system-type"
152 if test X"$SYSTEM_VERSION" != X; then
153 set "$@" system-version="\"$SYSTEM_VERSION\""
155 log_failure_msg "no default system version, please use --system-version"
158 action "Configuring Open vSwitch system IDs" "$@" $extra_ids
161 check_force_cores () {
162 if test X"$FORCE_COREFILES" = Xyes; then
170 if daemon_is_running ovsdb-server; then
171 log_success_msg "ovsdb-server is already running"
173 # Create initial database or upgrade database schema.
174 upgrade_db || return 1
176 # Start ovsdb-server.
177 set ovsdb-server "$DB_FILE"
178 for db in $EXTRA_DBS; do
184 if test ! -f "$db"; then
185 log_warning_msg "$db (from \$EXTRA_DBS) does not exist."
186 elif ovsdb-tool db-version "$db" >/dev/null; then
189 log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
192 set "$@" -vconsole:emer -vsyslog:err -vfile:info
193 set "$@" --remote=punix:"$DB_SOCK"
194 set "$@" --private-key=db:Open_vSwitch,SSL,private_key
195 set "$@" --certificate=db:Open_vSwitch,SSL,certificate
196 set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert
197 start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
200 # Initialize database settings.
201 ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
203 set_system_ids || return 1
204 if test X"$DELETE_BRIDGES" = Xyes; then
205 for bridge in `ovs_vsctl list-br`; do
206 ovs_vsctl del-br $bridge
213 # Now that ovs-vswitchd has started and completed its initial
214 # configuration, tell ovsdb-server to conenct to the remote managers. We
215 # used to do this at ovsdb-server startup time, but waiting for
216 # ovs-vswitchd to finish configuring means that remote managers see less
217 # churn in the database at startup or restart. (For example, managers
218 # won't briefly see empty datapath-id or ofport columns for records that
220 action "Enabling remote OVSDB managers" \
221 ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
222 db:Open_vSwitch,Open_vSwitch,manager_options
225 start_forwarding () {
228 insert_mod_if_required || return 1
230 if daemon_is_running ovs-vswitchd; then
231 log_success_msg "ovs-vswitchd is already running"
233 # Increase the limit on the number of open file descriptors.
234 # On Linux, ovs-vswitchd needs about three file descriptors
235 # per bridge and "n-handler-threads" file descriptors per bridge
236 # port, so this allows a very large number of bridges and ports.
238 if [ $(ulimit -n) -lt $MAXFD ]; then
242 # Start ovs-vswitchd.
243 set ovs-vswitchd unix:"$DB_SOCK"
244 set "$@" -vconsole:emer -vsyslog:err -vfile:info
245 if test X"$MLOCKALL" != Xno; then
248 start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
257 stop_daemon ovsdb-server
261 stop_daemon ovs-vswitchd
264 ## ----------------- ##
265 ## force-reload-kmod ##
266 ## ----------------- ##
268 internal_interfaces () {
269 # Outputs a list of internal interfaces:
271 # - There is an internal interface for every bridge, whether it
272 # has an Interface record or not and whether the Interface
273 # record's 'type' is properly set or not.
275 # - There is an internal interface for each Interface record whose
276 # 'type' is 'internal'.
278 # But ignore interfaces that don't really exist.
279 for d in `(ovs_vsctl --bare \
280 -- --columns=name find Interface type=internal \
281 -- list-br) | sort -u`
283 if test -e "/sys/class/net/$d"; then
290 bridges=`ovs_vsctl -- --real list-br`
291 if [ -n "${bridges}" ] && \
292 "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
296 [ -z "${bridges}" ] && return 0
299 save_ofports_if_required () {
300 # Save OpenFlow port numbers if we are upgrading from a pre-1.10 branch.
302 # (Versions 1.10 and later save OpenFlow port numbers without assistance,
303 # so we don't have to do anything for them.
304 case `ovs-appctl version | sed 1q` in
305 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
306 action "Saving ofport values" ovs_save save-ofports \
313 "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
314 > "${script_interfaces}"
318 [ -x "${script_ofports}" ] && \
319 action "Restoring ofport values" "${script_ofports}"
322 flow_restore_wait () {
323 ovs_vsctl set open_vswitch . other_config:flow-restore-wait="true"
326 flow_restore_complete () {
327 ovs_vsctl --if-exists remove open_vswitch . other_config \
328 flow-restore-wait="true"
332 [ -x "${script_flows}" ] && \
333 action "Restoring saved flows" "${script_flows}"
336 restore_interfaces () {
337 [ ! -x "${script_interfaces}" ] && return 0
338 action "Restoring interface configuration" "${script_interfaces}"
340 if test $rc = 0; then
345 log="logger -p daemon.$level -t ovs-save"
346 $log "interface restore script exited with status $rc:"
347 $log -f "$script_interfaces"
350 init_restore_scripts () {
351 script_interfaces=`mktemp`
352 script_flows=`mktemp`
353 script_ofports=`mktemp`
354 trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0
357 force_reload_kmod () {
358 ifaces=`internal_interfaces`
359 action "Detected internal interfaces: $ifaces" true
363 action "Saving flows" ovs_save save-flows "${script_flows}"
365 save_ofports_if_required
367 # Restart the database first, since a large database may take a
368 # while to load, and we want to minimize forwarding disruption.
372 # Restore of ofports should happen before vswitchd is restarted.
377 if action "Saving interface configuration" save_interfaces; then
380 log_warning_msg "Failed to save configuration, not replacing kernel module"
385 chmod +x "$script_interfaces"
387 for dp in `ovs-dpctl dump-dps`; do
388 action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
391 # try both old and new names in case this is post upgrade
392 if test -e /sys/module/openvswitch_mod; then
393 action "Removing openvswitch module" rmmod openvswitch_mod
394 elif test -e /sys/module/openvswitch; then
395 action "Removing openvswitch module" rmmod openvswitch
398 # Start vswitchd by asking it to wait till flow restore is finished.
402 # Restore saved flows and inform vswitchd that we are done.
404 flow_restore_complete
409 "$datadir/scripts/ovs-check-dead-ifs"
416 save_interfaces_if_required () {
417 # Save interfaces if we are upgrading from a pre-1.10 branch.
418 case `ovs-appctl version | sed 1q` in
419 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
420 ifaces=`internal_interfaces`
421 action "Detected internal interfaces: $ifaces" true
422 if action "Saving interface configuration" save_interfaces; then
423 chmod +x "$script_interfaces"
430 if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
432 save_interfaces_if_required
433 action "Saving flows" ovs_save save-flows "${script_flows}"
434 save_ofports_if_required
437 # Restart the database first, since a large database may take a
438 # while to load, and we want to minimize forwarding disruption.
442 # Restore of ofports, if required, should happen before vswitchd is
448 # Start vswitchd by asking it to wait till flow restore is finished.
452 # Restore saved flows and inform vswitchd that we are done.
454 flow_restore_complete
457 # Restore the interfaces if required. Return true even if restore fails.
458 restore_interfaces || true
461 ## --------------- ##
462 ## enable-protocol ##
463 ## --------------- ##
466 # Translate the protocol name to a number, because "iptables -n -L" prints
467 # some protocols by name (despite the -n) and therefore we need to look for
470 # (iptables -S output is more uniform but old iptables doesn't have it.)
471 protonum=`grep "^$PROTOCOL[ ]" /etc/protocols | awk '{print $2}'`
472 if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
473 log_failure_msg "unknown protocol $PROTOCOL"
478 match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
479 insert="iptables -I INPUT -p $PROTOCOL"
480 if test X"$DPORT" != X; then
481 name="$name to port $DPORT"
482 match="$match && /dpt:$DPORT/"
483 insert="$insert --dport $DPORT"
485 if test X"$SPORT" != X; then
486 name="$name from port $SPORT"
487 match="$match && /spt:$SPORT/"
488 insert="$insert --sport $SPORT"
490 insert="$insert -j ACCEPT"
492 if (iptables -n -L INPUT) >/dev/null 2>&1; then
493 if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
495 # There's already a rule for this protocol. Don't override it.
496 log_success_msg "iptables already has a rule for $name, not explicitly enabling"
498 action "Enabling $name with iptables" $insert
500 elif (iptables --version) >/dev/null 2>&1; then
501 action "cannot list iptables rules, not adding a rule for $name"
503 action "iptables binary not installed, not adding a rule for $name"
519 OVSDB_SERVER_PRIORITY=-10
520 OVS_VSWITCHD_PRIORITY=-10
521 OVSDB_SERVER_WRAPPER=
522 OVS_VSWITCHD_WRAPPER=
524 DB_FILE=$dbdir/conf.db
525 DB_SOCK=$rundir/db.sock
526 DB_SCHEMA=$datadir/vswitch.ovsschema
533 type_file=$etcdir/system-type.conf
534 version_file=$etcdir/system-version.conf
536 if test -e "$type_file" ; then
537 SYSTEM_TYPE=`cat $type_file`
538 SYSTEM_VERSION=`cat $version_file`
539 elif (lsb_release --id) >/dev/null 2>&1; then
540 SYSTEM_TYPE=`lsb_release --id -s`
541 system_release=`lsb_release --release -s`
542 system_codename=`lsb_release --codename -s`
543 SYSTEM_VERSION="${system_release}-${system_codename}"
546 SYSTEM_VERSION=unknown
553 $0: controls Open vSwitch daemons
554 usage: $0 [OPTIONS] COMMAND
556 This program is intended to be invoked internally by Open vSwitch startup
557 scripts. System administrators should not normally invoke it directly.
560 start start Open vSwitch daemons
561 stop stop Open vSwitch daemons
562 restart stop and start Open vSwitch daemons
563 status check whether Open vSwitch daemons are running
564 version print versions of Open vSwitch daemons
565 load-kmod insert modules if not already present
566 force-reload-kmod save OVS network device state, stop OVS, unload kernel
567 module, reload kernel module, start OVS, restore state
568 enable-protocol enable protocol specified in options with iptables
569 help display this help message
571 One of the following options is required for "start", "restart" and "force-reload-kmod":
572 --system-id=UUID set specific ID to uniquely identify this system
573 --system-id=random use a random but persistent UUID to identify this system
575 Other important options for "start", "restart" and "force-reload-kmod":
576 --system-type=TYPE set system type (e.g. "XenServer")
577 --system-version=VERSION set system version (e.g. "5.6.100-39265p")
578 --external-id="key=value"
579 add given key-value pair to Open_vSwitch external-ids
580 --delete-bridges delete all bridges just before starting ovs-vswitchd
582 Less important options for "start", "restart" and "force-reload-kmod":
583 --daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD)
584 --no-force-corefiles do not force on core dumps for OVS daemons
585 --no-mlockall do not lock all of ovs-vswitchd into memory
586 --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
587 --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
589 Debugging options for "start", "restart" and "force-reload-kmod":
590 --ovsdb-server-wrapper=WRAPPER
591 --ovs-vswitchd-wrapper=WRAPPER
592 --ovs-vswitchd-wrapper=WRAPPER
593 run specified daemon under WRAPPER (either 'valgrind' or 'strace')
595 File location options:
596 --db-file=FILE database file name (default: $DB_FILE)
597 --db-sock=SOCKET JSON-RPC socket name (default: $DB_SOCK)
598 --db-schema=FILE database schema file name (default: $DB_SCHEMA)
600 Options for "enable-protocol":
601 --protocol=PROTOCOL protocol to enable with iptables (default: gre)
602 --sport=PORT source port to match (for tcp or udp protocol)
603 --dport=PORT ddestination port to match (for tcp or udp protocol)
606 -h, --help display this help message
607 -V, --version display version information
609 Default directories with "configure" option and environment variable override:
610 logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
611 pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
612 conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
613 system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
614 data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
615 user binaries: @bindir@ (--bindir, OVS_BINDIR)
616 system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
618 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
625 var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
626 eval set=\${$var+yes}
627 eval old_value=\$$var
628 if test X$set = X || \
629 (test $type = bool && \
630 test X"$old_value" != Xno && test X"$old_value" != Xyes); then
631 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
638 echo ovsdb-server ovs-vswitchd
651 echo "$0 (Open vSwitch) $VERSION"
655 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
658 extra_ids="$extra_ids external-ids:$value"
661 echo >&2 "$0: --external-id argument not in the form \"key=value\""
667 option=`expr X"$arg" : 'X--\([^=]*\)'`
668 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
673 option=`expr X"$arg" : 'X--no-\(.*\)'`
679 option=`expr X"$arg" : 'X--\(.*\)'`
685 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
689 if test X"$command" = X; then
692 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
713 for daemon in `daemons`; do
714 daemon_status $daemon || rc=$?
719 for daemon in `daemons`; do
727 insert_mod_if_required
736 echo >&2 "$0: missing command name (use --help for help)"
740 echo >&2 "$0: unknown command \"$command\" (use --help for help)"