2 # Copyright (C) 2009, 2010, 2011, 2012, 2013 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_openvswitch_mod_if_required () {
34 # If openvswitch is already loaded then we're done.
35 test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
38 # Load openvswitch. If that's successful then we're done.
39 action "Inserting openvswitch module" modprobe openvswitch && return 0
41 # If the bridge module is loaded, then that might be blocking
42 # openvswitch. Try to unload it, if there are no bridges.
43 test -e /sys/module/bridge || return 1
44 bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
45 if test "$bridges" != "*"; then
46 log_warning_msg "not removing bridge module because bridges exist ($bridges)"
49 action "removing bridge module" rmmod bridge || return 1
51 # Try loading openvswitch again.
52 action "Inserting openvswitch module" modprobe openvswitch
55 insert_mod_if_required () {
56 insert_openvswitch_mod_if_required || return 1
60 ovs-vsctl --no-wait "$@"
64 ovsdb-tool -vconsole:off "$@"
68 action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
72 schemaver=`ovsdb_tool schema-version "$DB_SCHEMA"`
73 if test ! -e "$DB_FILE"; then
74 log_warning_msg "$DB_FILE does not exist"
75 install -d -m 755 -o root -g root `dirname $DB_FILE`
77 elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then
78 # Back up the old version.
79 version=`ovsdb_tool db-version "$DB_FILE"`
80 cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'`
81 backup=$DB_FILE.backup$version-$cksum
82 action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1
84 # Compact database. This is important if the old schema did not enable
85 # garbage collection (i.e. if it did not have any tables with "isRoot":
86 # true) but the new schema does. In that situation the old database
87 # may contain a transaction that creates a record followed by a
88 # transaction that creates the first use of the record. Replaying that
89 # series of transactions against the new database schema (as "convert"
90 # does) would cause the record to be dropped by the first transaction,
91 # then the second transaction would cause a referential integrity
92 # failure (for a strong reference).
94 # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't
95 # understand some feature of the schema used in the OVSDB version that
96 # we're downgrading from, so we don't give up on error.
97 action "Compacting database" ovsdb_tool compact "$DB_FILE"
99 # Upgrade or downgrade schema.
100 if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
103 log_warning_msg "Schema conversion failed, using empty database instead"
111 set ovs_vsctl set Open_vSwitch .
113 OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'`
114 set "$@" ovs-version="$OVS_VERSION"
118 id_file=$etcdir/system-id.conf
119 uuid_file=$etcdir/install_uuid.conf
120 if test -e "$id_file"; then
121 SYSTEM_ID=`cat "$id_file"`
122 elif test -e "$uuid_file"; then
123 # Migrate from old file name.
125 SYSTEM_ID=$INSTALLATION_UUID
126 echo "$SYSTEM_ID" > "$id_file"
127 elif SYSTEM_ID=`uuidgen`; then
128 echo "$SYSTEM_ID" > "$id_file"
130 log_failure_msg "missing uuidgen, could not generate system ID"
135 log_failure_msg "system ID not configured, please use --system-id"
141 set "$@" external-ids:system-id="\"$SYSTEM_ID\""
143 if test X"$SYSTEM_TYPE" != X; then
144 set "$@" system-type="\"$SYSTEM_TYPE\""
146 log_failure_msg "no default system type, please use --system-type"
149 if test X"$SYSTEM_VERSION" != X; then
150 set "$@" system-version="\"$SYSTEM_VERSION\""
152 log_failure_msg "no default system version, please use --system-version"
155 action "Configuring Open vSwitch system IDs" "$@" $extra_ids
158 check_force_cores () {
159 if test X"$FORCE_COREFILES" = Xyes; then
167 if daemon_is_running ovsdb-server; then
168 log_success_msg "ovsdb-server is already running"
170 # Create initial database or upgrade database schema.
171 upgrade_db || return 1
173 # Start ovsdb-server.
174 set ovsdb-server "$DB_FILE"
175 for db in $EXTRA_DBS; do
181 if test ! -f "$db"; then
182 log_warning_msg "$db (from \$EXTRA_DBS) does not exist."
183 elif ovsdb-tool db-version "$db" >/dev/null; then
186 log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
189 set "$@" -vconsole:emer -vsyslog:err -vfile:info
190 set "$@" --remote=punix:"$DB_SOCK"
191 set "$@" --private-key=db:Open_vSwitch,SSL,private_key
192 set "$@" --certificate=db:Open_vSwitch,SSL,certificate
193 set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert
194 start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
197 # Initialize database settings.
198 ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
200 set_system_ids || return 1
201 if test X"$DELETE_BRIDGES" = Xyes; then
202 for bridge in `ovs_vsctl list-br`; do
203 ovs_vsctl del-br $bridge
209 start_forwarding () {
212 insert_mod_if_required || return 1
214 if daemon_is_running ovs-vswitchd; then
215 log_success_msg "ovs-vswitchd is already running"
217 # Increase the limit on the number of open file descriptors.
218 # On Linux, ovs-vswitchd needs about one file descriptor per
219 # switch port, so this allows a very large number of switch
223 # Start ovs-vswitchd.
224 set ovs-vswitchd unix:"$DB_SOCK"
225 set "$@" -vconsole:emer -vsyslog:err -vfile:info
226 if test X"$MLOCKALL" != Xno; then
229 start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
232 # Now that ovs-vswitchd has started and completed its initial
233 # configuration, tell ovsdb-server to conenct to the remote managers. We
234 # used to do this at ovsdb-server startup time, but waiting for
235 # ovs-vswitchd to finish configuring means that remote managers see less
236 # churn in the database at startup or restart. (For example, managers
237 # won't briefly see empty datapath-id or ofport columns for records that
239 action "Enabling remote OVSDB managers" \
240 ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
241 db:Open_vSwitch,Open_vSwitch,manager_options
249 stop_daemon ovsdb-server
253 stop_daemon ovs-vswitchd
256 ## ----------------- ##
257 ## force-reload-kmod ##
258 ## ----------------- ##
260 internal_interfaces () {
261 # Outputs a list of internal interfaces:
263 # - There is an internal interface for every bridge, whether it
264 # has an Interface record or not and whether the Interface
265 # record's 'type' is properly set or not.
267 # - There is an internal interface for each Interface record whose
268 # 'type' is 'internal'.
270 # But ignore interfaces that don't really exist.
271 for d in `(ovs_vsctl --bare \
272 -- --columns=name find Interface type=internal \
273 -- list-br) | sort -u`
275 if test -e "/sys/class/net/$d"; then
282 bridges=`ovs_vsctl -- --real list-br`
283 if [ -n "${bridges}" ] && \
284 "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
288 [ -z "${bridges}" ] && return 0
291 save_ofports_if_required () {
292 # Save ofports if we are upgrading from a pre-1.10 branch.
293 case `ovs-appctl version | sed 1q` in
294 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
295 action "Saving ofport values" ovs_save save-ofports \
302 "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
303 > "${script_interfaces}"
307 [ -x "${script_ofports}" ] && \
308 action "Restoring ofport values" "${script_ofports}"
312 [ -x "${script_flows}" ] && \
313 action "Restoring saved flows" "${script_flows}"
316 restore_interfaces () {
317 [ ! -x "${script_interfaces}" ] && return 0
318 action "Restoring interface configuration" "${script_interfaces}"
320 if test $rc = 0; then
325 log="logger -p daemon.$level -t ovs-save"
326 $log "interface restore script exited with status $rc:"
327 $log -f "$script_interfaces"
330 init_restore_scripts () {
331 script_interfaces=`mktemp`
332 script_flows=`mktemp`
333 script_ofports=`mktemp`
334 trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0
337 force_reload_kmod () {
338 ifaces=`internal_interfaces`
339 action "Detected internal interfaces: $ifaces" true
343 action "Saving flows" ovs_save save-flows "${script_flows}"
345 save_ofports_if_required
347 # Restart the database first, since a large database may take a
348 # while to load, and we want to minimize forwarding disruption.
352 # Restore of ofports should happen before vswitchd is restarted.
357 if action "Saving interface configuration" save_interfaces; then
360 log_warning_msg "Failed to save configuration, not replacing kernel module"
364 chmod +x "$script_interfaces"
366 for dp in `ovs-dpctl dump-dps`; do
367 action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
370 # try both old and new names in case this is post upgrade
371 if test -e /sys/module/openvswitch_mod; then
372 action "Removing openvswitch module" rmmod openvswitch_mod
373 elif test -e /sys/module/openvswitch; then
374 action "Removing openvswitch module" rmmod openvswitch
383 "$datadir/scripts/ovs-check-dead-ifs"
390 save_interfaces_if_required () {
391 # Save interfaces if we are upgrading from a pre-1.10 branch.
392 case `ovs-appctl version | sed 1q` in
393 "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
394 ifaces=`internal_interfaces`
395 action "Detected internal interfaces: $ifaces" true
396 if action "Saving interface configuration" save_interfaces; then
397 chmod +x "$script_interfaces"
404 if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
406 save_interfaces_if_required
407 action "Saving flows" ovs_save save-flows "${script_flows}"
408 save_ofports_if_required
411 # Restart the database first, since a large database may take a
412 # while to load, and we want to minimize forwarding disruption.
416 # Restore of ofports, if required, should happen before vswitchd is
423 # Restore the saved flows.
426 # Restore the interfaces if required. Return true even if restore fails.
427 restore_interfaces || true
430 ## --------------- ##
431 ## enable-protocol ##
432 ## --------------- ##
435 # Translate the protocol name to a number, because "iptables -n -L" prints
436 # some protocols by name (despite the -n) and therefore we need to look for
439 # (iptables -S output is more uniform but old iptables doesn't have it.)
440 protonum=`grep "^$PROTOCOL[ ]" /etc/protocols | awk '{print $2}'`
441 if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
442 log_failure_msg "unknown protocol $PROTOCOL"
447 match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
448 insert="iptables -I INPUT -p $PROTOCOL"
449 if test X"$DPORT" != X; then
450 name="$name to port $DPORT"
451 match="$match && /dpt:$DPORT/"
452 insert="$insert --dport $DPORT"
454 if test X"$SPORT" != X; then
455 name="$name from port $SPORT"
456 match="$match && /spt:$SPORT/"
457 insert="$insert --sport $SPORT"
459 insert="$insert -j ACCEPT"
461 if (iptables -n -L INPUT) >/dev/null 2>&1; then
462 if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
464 # There's already a rule for this protocol. Don't override it.
465 log_success_msg "iptables already has a rule for $name, not explicitly enabling"
467 action "Enabling $name with iptables" $insert
469 elif (iptables --version) >/dev/null 2>&1; then
470 action "cannot list iptables rules, not adding a rule for $name"
472 action "iptables binary not installed, not adding a rule for $name"
488 OVSDB_SERVER_PRIORITY=-10
489 OVS_VSWITCHD_PRIORITY=-10
490 OVSDB_SERVER_WRAPPER=
491 OVS_VSWITCHD_WRAPPER=
493 DB_FILE=$dbdir/conf.db
494 DB_SOCK=$rundir/db.sock
495 DB_SCHEMA=$datadir/vswitch.ovsschema
502 type_file=$etcdir/system-type.conf
503 version_file=$etcdir/system-version.conf
505 if test -e "$type_file" ; then
506 SYSTEM_TYPE=`cat $type_file`
507 SYSTEM_VERSION=`cat $version_file`
508 elif (lsb_release --id) >/dev/null 2>&1; then
509 SYSTEM_TYPE=`lsb_release --id -s`
510 system_release=`lsb_release --release -s`
511 system_codename=`lsb_release --codename -s`
512 SYSTEM_VERSION="${system_release}-${system_codename}"
515 SYSTEM_VERSION=unknown
522 $0: controls Open vSwitch daemons
523 usage: $0 [OPTIONS] COMMAND
525 This program is intended to be invoked internally by Open vSwitch startup
526 scripts. System administrators should not normally invoke it directly.
529 start start Open vSwitch daemons
530 stop stop Open vSwitch daemons
531 restart stop and start Open vSwitch daemons
532 status check whether Open vSwitch daemons are running
533 version print versions of Open vSwitch daemons
534 load-kmod insert modules if not already present
535 force-reload-kmod save OVS network device state, stop OVS, unload kernel
536 module, reload kernel module, start OVS, restore state
537 enable-protocol enable protocol specified in options with iptables
538 help display this help message
540 One of the following options is required for "start", "restart" and "force-reload-kmod":
541 --system-id=UUID set specific ID to uniquely identify this system
542 --system-id=random use a random but persistent UUID to identify this system
544 Other important options for "start", "restart" and "force-reload-kmod":
545 --system-type=TYPE set system type (e.g. "XenServer")
546 --system-version=VERSION set system version (e.g. "5.6.100-39265p")
547 --external-id="key=value"
548 add given key-value pair to Open_vSwitch external-ids
549 --delete-bridges delete all bridges just before starting ovs-vswitchd
551 Less important options for "start", "restart" and "force-reload-kmod":
552 --daemon-cwd=DIR set working dir for OVS daemons (default: $DAEMON_CWD)
553 --no-force-corefiles do not force on core dumps for OVS daemons
554 --no-mlockall do not lock all of ovs-vswitchd into memory
555 --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
556 --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
558 Debugging options for "start", "restart" and "force-reload-kmod":
559 --ovsdb-server-wrapper=WRAPPER
560 --ovs-vswitchd-wrapper=WRAPPER
561 --ovs-vswitchd-wrapper=WRAPPER
562 run specified daemon under WRAPPER (either 'valgrind' or 'strace')
564 File location options:
565 --db-file=FILE database file name (default: $DB_FILE)
566 --db-sock=SOCKET JSON-RPC socket name (default: $DB_SOCK)
567 --db-schema=FILE database schema file name (default: $DB_SCHEMA)
569 Options for "enable-protocol":
570 --protocol=PROTOCOL protocol to enable with iptables (default: gre)
571 --sport=PORT source port to match (for tcp or udp protocol)
572 --dport=PORT ddestination port to match (for tcp or udp protocol)
575 -h, --help display this help message
576 -V, --version display version information
578 Default directories with "configure" option and environment variable override:
579 logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
580 pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
581 conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
582 system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
583 data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
584 user binaries: @bindir@ (--bindir, OVS_BINDIR)
585 system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
587 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
594 var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
595 eval set=\${$var+yes}
596 eval old_value=\$$var
597 if test X$set = X || \
598 (test $type = bool && \
599 test X"$old_value" != Xno && test X"$old_value" != Xyes); then
600 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
607 echo ovsdb-server ovs-vswitchd
620 echo "$0 (Open vSwitch) $VERSION"
624 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
627 extra_ids="$extra_ids external-ids:$value"
630 echo >&2 "$0: --external-id argument not in the form \"key=value\""
636 option=`expr X"$arg" : 'X--\([^=]*\)'`
637 value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
642 option=`expr X"$arg" : 'X--no-\(.*\)'`
648 option=`expr X"$arg" : 'X--\(.*\)'`
654 echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
658 if test X"$command" = X; then
661 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
681 for daemon in `daemons`; do
682 daemon_status $daemon || rc=$?
687 for daemon in `daemons`; do
695 insert_mod_if_required
704 echo >&2 "$0: missing command name (use --help for help)"
708 echo >&2 "$0: unknown command \"$command\" (use --help for help)"