ovs-ctl: Add option to delete transient ports.
[cascardo/ovs.git] / utilities / ovs-ctl.in
1 #! /bin/sh
2 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
3 #
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:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15
16 case $0 in
17     */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;;
18     *) dir0=./ ;;
19 esac
20 . "$dir0/ovs-lib" || exit 1
21
22 for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do
23     case :$PATH: in
24         *:$dir:*) ;;
25         *) PATH=$PATH:$dir ;;
26     esac
27 done
28
29 ## ----- ##
30 ## start ##
31 ## ----- ##
32
33 # Keep track of removed vports so we can reload them if needed
34 removed_vports=""
35
36 insert_mods () {
37     # Try loading openvswitch again.
38     action "Inserting openvswitch module" modprobe openvswitch
39
40     for vport in $removed_vports; do
41         # Don't treat failures to load vports as fatal error
42         action "Inserting $vport module" modprobe $vport || true
43     done
44 }
45
46 insert_mod_if_required () {
47     # If this kernel has no module support, expect we're done.
48     if test ! -e /proc/modules
49     then
50         log_success_msg "Kernel has no loadable module support. Skipping modprobe"
51         return 0
52     fi
53
54     # If openvswitch is already loaded then we're done.
55     test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod && \
56      return 0
57
58     # Load openvswitch.  If that's successful then we're done.
59     insert_mods && return 0
60
61     # If the bridge module is loaded, then that might be blocking
62     # openvswitch.  Try to unload it, if there are no bridges.
63     test -e /sys/module/bridge || return 1
64     bridges=`echo /sys/class/net/*/bridge | sed 's,/sys/class/net/,,g;s,/bridge,,g'`
65     if test "$bridges" != "*"; then
66         log_warning_msg "not removing bridge module because bridges exist ($bridges)"
67         return 1
68     fi
69     action "removing bridge module" rmmod bridge || return 1
70
71     # Try loading openvswitch again.
72     insert_mods
73 }
74
75 ovs_vsctl () {
76     ovs-vsctl --no-wait "$@"
77 }
78
79 ovsdb_tool () {
80     ovsdb-tool -vconsole:off "$@"
81 }
82
83 create_db () {
84     action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
85 }
86
87 upgrade_db () {
88     schemaver=`ovsdb_tool schema-version "$DB_SCHEMA"`
89     if test ! -e "$DB_FILE"; then
90         log_warning_msg "$DB_FILE does not exist"
91         install -d -m 755 -o root -g root `dirname $DB_FILE`
92         create_db
93     elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then
94         # Back up the old version.
95         version=`ovsdb_tool db-version "$DB_FILE"`
96         cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'`
97         backup=$DB_FILE.backup$version-$cksum
98         action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1
99
100         # Compact database.  This is important if the old schema did not enable
101         # garbage collection (i.e. if it did not have any tables with "isRoot":
102         # true) but the new schema does.  In that situation the old database
103         # may contain a transaction that creates a record followed by a
104         # transaction that creates the first use of the record.  Replaying that
105         # series of transactions against the new database schema (as "convert"
106         # does) would cause the record to be dropped by the first transaction,
107         # then the second transaction would cause a referential integrity
108         # failure (for a strong reference).
109         #
110         # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't
111         # understand some feature of the schema used in the OVSDB version that
112         # we're downgrading from, so we don't give up on error.
113         action "Compacting database" ovsdb_tool compact "$DB_FILE"
114
115         # Upgrade or downgrade schema.
116         if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
117             :
118         else
119             log_warning_msg "Schema conversion failed, using empty database instead"
120             rm -f "$DB_FILE"
121             create_db
122         fi
123     fi
124 }
125
126 set_system_ids () {
127     set ovs_vsctl set Open_vSwitch .
128
129     OVS_VERSION=`ovs-vswitchd --version | sed 's/.*) //;1q'`
130     set "$@" ovs-version="$OVS_VERSION"
131
132     case $SYSTEM_ID in
133         random)
134             id_file=$etcdir/system-id.conf
135             uuid_file=$etcdir/install_uuid.conf
136             if test -e "$id_file"; then
137                 SYSTEM_ID=`cat "$id_file"`
138             elif test -e "$uuid_file"; then
139                 # Migrate from old file name.
140                 . "$uuid_file"
141                 SYSTEM_ID=$INSTALLATION_UUID
142                 echo "$SYSTEM_ID" > "$id_file"
143             elif SYSTEM_ID=`uuidgen`; then
144                 echo "$SYSTEM_ID" > "$id_file"
145             else
146                 log_failure_msg "missing uuidgen, could not generate system ID"
147             fi
148             ;;
149
150         '')
151             log_failure_msg "system ID not configured, please use --system-id"
152             ;;
153
154         *)
155             ;;
156     esac
157     set "$@" external-ids:system-id="\"$SYSTEM_ID\""
158
159     if test X"$SYSTEM_TYPE" != X; then
160         set "$@" system-type="\"$SYSTEM_TYPE\""
161     else
162         log_failure_msg "no default system type, please use --system-type"
163     fi
164
165     if test X"$SYSTEM_VERSION" != X; then
166         set "$@" system-version="\"$SYSTEM_VERSION\""
167     else
168         log_failure_msg "no default system version, please use --system-version"
169     fi
170
171     action "Configuring Open vSwitch system IDs" "$@" $extra_ids
172 }
173
174 check_force_cores () {
175     if test X"$FORCE_COREFILES" = Xyes; then
176         ulimit -c 67108864
177     fi
178 }
179
180 del_transient_ports () {
181     for port in `ovs-vsctl --bare -- --columns=name find port other_config:transient=true`; do
182         ovs_vsctl -- del-port "$port"
183     done
184 }
185
186 start_ovsdb () {
187     check_force_cores
188
189     if daemon_is_running ovsdb-server; then
190         log_success_msg "ovsdb-server is already running"
191     else
192         # Create initial database or upgrade database schema.
193         upgrade_db || return 1
194
195         # Start ovsdb-server.
196         set ovsdb-server "$DB_FILE"
197         for db in $EXTRA_DBS; do
198             case $db in
199                 /*) ;;
200                 *) db=$dbdir/$db ;;
201             esac
202
203             if test ! -f "$db"; then
204                 log_warning_msg "$db (from \$EXTRA_DBS) does not exist."
205             elif ovsdb-tool db-version "$db" >/dev/null; then
206                 set "$@" "$db"
207             else
208                 log_warning_msg "$db (from \$EXTRA_DBS) cannot be read as a database (see error message above)"
209             fi
210         done
211         set "$@" -vconsole:emer -vsyslog:err -vfile:info
212         set "$@" --remote=punix:"$DB_SOCK"
213         set "$@" --private-key=db:Open_vSwitch,SSL,private_key
214         set "$@" --certificate=db:Open_vSwitch,SSL,certificate
215         set "$@" --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert
216         start_daemon "$OVSDB_SERVER_PRIORITY" "$OVSDB_SERVER_WRAPPER" "$@" \
217             || return 1
218
219         # Initialize database settings.
220         ovs_vsctl -- init -- set Open_vSwitch . db-version="$schemaver" \
221             || return 1
222         set_system_ids || return 1
223         if test X"$DELETE_BRIDGES" = Xyes; then
224             for bridge in `ovs_vsctl list-br`; do
225                 ovs_vsctl del-br $bridge
226             done
227         fi
228         if test X"$DELETE_TRANSIENT_PORTS" = Xyes; then
229             del_transient_ports
230         fi
231     fi
232 }
233
234 add_managers () {
235     # Now that ovs-vswitchd has started and completed its initial
236     # configuration, tell ovsdb-server to conenct to the remote managers.  We
237     # used to do this at ovsdb-server startup time, but waiting for
238     # ovs-vswitchd to finish configuring means that remote managers see less
239     # churn in the database at startup or restart.  (For example, managers
240     # won't briefly see empty datapath-id or ofport columns for records that
241     # exist at startup.)
242     action "Enabling remote OVSDB managers" \
243         ovs-appctl -t ovsdb-server ovsdb-server/add-remote \
244             db:Open_vSwitch,Open_vSwitch,manager_options
245 }
246
247 start_forwarding () {
248     check_force_cores
249
250     insert_mod_if_required || return 1
251
252     if daemon_is_running ovs-vswitchd; then
253         log_success_msg "ovs-vswitchd is already running"
254     else
255         # Increase the limit on the number of open file descriptors.
256         # On Linux, ovs-vswitchd needs about three file descriptors
257         # per bridge and "n-handler-threads" file descriptors per bridge
258         # port, so this allows a very large number of bridges and ports.
259         MAXFD=65535
260         if [ $(ulimit -n) -lt $MAXFD ]; then
261             ulimit -n $MAXFD
262         fi
263
264             # Start ovs-vswitchd.
265             set ovs-vswitchd unix:"$DB_SOCK"
266             set "$@" -vconsole:emer -vsyslog:err -vfile:info
267             if test X"$MLOCKALL" != Xno; then
268                 set "$@" --mlockall
269             fi
270             start_daemon "$OVS_VSWITCHD_PRIORITY" "$OVS_VSWITCHD_WRAPPER" "$@"
271     fi
272 }
273
274 ## ---- ##
275 ## stop ##
276 ## ---- ##
277
278 stop_ovsdb () {
279     stop_daemon ovsdb-server
280 }
281
282 stop_forwarding () {
283     stop_daemon ovs-vswitchd
284 }
285
286 ## ----------------- ##
287 ## force-reload-kmod ##
288 ## ----------------- ##
289
290 internal_interfaces () {
291     # Outputs a list of internal interfaces:
292     #
293     #   - There is an internal interface for every bridge, whether it
294     #     has an Interface record or not and whether the Interface
295     #     record's 'type' is properly set or not.
296     #
297     #   - There is an internal interface for each Interface record whose
298     #     'type' is 'internal'.
299     #
300     # But ignore interfaces that don't really exist.
301     for d in `(ovs_vsctl --bare \
302                 -- --columns=name find Interface type=internal \
303                     -- list-br) | sort -u`
304     do
305         if test -e "/sys/class/net/$d"; then
306                 printf "%s " "$d"
307             fi
308     done
309 }
310
311 ovs_save () {
312     bridges=`ovs_vsctl -- --real list-br`
313     if [ -n "${bridges}" ] && \
314         "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
315         chmod +x "$2"
316         return 0
317     fi
318     [ -z "${bridges}" ] && return 0
319 }
320
321 save_ofports_if_required () {
322     # Save OpenFlow port numbers if we are upgrading from a pre-1.10 branch.
323     #
324     # (Versions 1.10 and later save OpenFlow port numbers without assistance,
325     # so we don't have to do anything for them.
326     case `ovs-appctl version | sed 1q` in
327         "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
328             action "Saving ofport values" ovs_save save-ofports \
329                 "${script_ofports}"
330             ;;
331     esac
332 }
333
334 save_flows_if_required () {
335     if test X"$DELETE_BRIDGES" != Xyes; then
336         action "Saving flows" ovs_save save-flows "${script_flows}"
337     fi
338 }
339
340 save_interfaces () {
341     "$datadir/scripts/ovs-save" save-interfaces ${ifaces} \
342         > "${script_interfaces}"
343 }
344
345 restore_ofports () {
346     [ -x "${script_ofports}" ] && \
347         action "Restoring ofport values" "${script_ofports}"
348 }
349
350 flow_restore_wait () {
351     ovs_vsctl set open_vswitch . other_config:flow-restore-wait="true"
352 }
353
354 flow_restore_complete () {
355     ovs_vsctl --if-exists remove open_vswitch . other_config \
356         flow-restore-wait="true"
357 }
358
359 restore_flows () {
360     [ -x "${script_flows}" ] && \
361         action "Restoring saved flows" "${script_flows}"
362 }
363
364 restore_interfaces () {
365     [ ! -x "${script_interfaces}" ] && return 0
366     action "Restoring interface configuration" "${script_interfaces}"
367     rc=$?
368     if test $rc = 0; then
369         level=debug
370     else
371         level=err
372     fi
373     log="logger -p daemon.$level -t ovs-save"
374     $log "interface restore script exited with status $rc:"
375     $log -f "$script_interfaces"
376 }
377
378 init_restore_scripts () {
379     script_interfaces=`mktemp`
380     script_flows=`mktemp`
381     script_ofports=`mktemp`
382     trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0
383 }
384
385 force_reload_kmod () {
386     ifaces=`internal_interfaces`
387     action "Detected internal interfaces: $ifaces" true
388
389     init_restore_scripts
390     save_flows_if_required
391     save_ofports_if_required
392
393     # Restart the database first, since a large database may take a
394     # while to load, and we want to minimize forwarding disruption.
395     stop_ovsdb
396     start_ovsdb
397
398     # Restore of ofports should happen before vswitchd is restarted.
399     restore_ofports
400
401     stop_forwarding
402
403     if action "Saving interface configuration" save_interfaces; then
404         :
405     else
406         log_warning_msg "Failed to save configuration, not replacing kernel module"
407         start_forwarding
408         add_managers
409         exit 1
410     fi
411     chmod +x "$script_interfaces"
412
413     for dp in `ovs-dpctl dump-dps`; do
414         action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
415     done
416
417     for vport in `awk '/^vport_/ { print $1 }' /proc/modules`; do
418         action "Removing $vport module" rmmod $vport
419         if ! grep -q $vport /proc/modules; then
420             removed_vports="$removed_vports $vport"
421         fi
422     done
423
424     # try both old and new names in case this is post upgrade
425     if test -e /sys/module/openvswitch_mod; then
426         action "Removing openvswitch module" rmmod openvswitch_mod
427     elif test -e /sys/module/openvswitch; then
428         action "Removing openvswitch module" rmmod openvswitch
429     fi
430
431     # Start vswitchd by asking it to wait till flow restore is finished.
432     flow_restore_wait
433     start_forwarding
434
435     # Restore saved flows and inform vswitchd that we are done.
436     restore_flows
437     flow_restore_complete
438     add_managers
439
440     restore_interfaces
441
442     "$datadir/scripts/ovs-check-dead-ifs"
443 }
444
445 ## ------- ##
446 ## restart ##
447 ## ------- ##
448
449 save_interfaces_if_required () {
450     # Save interfaces if we are upgrading from a pre-1.10 branch.
451     case `ovs-appctl version | sed 1q` in
452         "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
453             ifaces=`internal_interfaces`
454             action "Detected internal interfaces: $ifaces" true
455             if action "Saving interface configuration" save_interfaces; then
456                 chmod +x "$script_interfaces"
457             fi
458             ;;
459     esac
460 }
461
462 restart () {
463     if daemon_is_running ovsdb-server && daemon_is_running ovs-vswitchd; then
464         init_restore_scripts
465         save_interfaces_if_required
466         save_flows_if_required
467         save_ofports_if_required
468     fi
469
470     # Restart the database first, since a large database may take a
471     # while to load, and we want to minimize forwarding disruption.
472     stop_ovsdb
473     start_ovsdb
474
475     # Restore of ofports, if required, should happen before vswitchd is
476     # restarted.
477     restore_ofports
478
479     stop_forwarding
480
481     # Start vswitchd by asking it to wait till flow restore is finished.
482     flow_restore_wait
483     start_forwarding
484
485     # Restore saved flows and inform vswitchd that we are done.
486     restore_flows
487     flow_restore_complete
488     add_managers
489
490     # Restore the interfaces if required. Return true even if restore fails.
491     restore_interfaces || true
492 }
493
494 ## --------------- ##
495 ## enable-protocol ##
496 ## --------------- ##
497
498 enable_protocol () {
499     # Translate the protocol name to a number, because "iptables -n -L" prints
500     # some protocols by name (despite the -n) and therefore we need to look for
501     # both forms.
502     #
503     # (iptables -S output is more uniform but old iptables doesn't have it.)
504     protonum=`grep "^$PROTOCOL[         ]" /etc/protocols | awk '{print $2}'`
505     if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
506         log_failure_msg "unknown protocol $PROTOCOL"
507         return 1
508     fi
509
510     name=$PROTOCOL
511     match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
512     insert="iptables -I INPUT -p $PROTOCOL"
513     if test X"$DPORT" != X; then
514         name="$name to port $DPORT"
515         match="$match && /dpt:$DPORT/"
516         insert="$insert --dport $DPORT"
517     fi
518     if test X"$SPORT" != X; then
519         name="$name from port $SPORT"
520         match="$match && /spt:$SPORT/"
521         insert="$insert --sport $SPORT"
522     fi
523     insert="$insert -j ACCEPT"
524
525     if (iptables -n -L INPUT) >/dev/null 2>&1; then
526         if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
527         then
528             # There's already a rule for this protocol.  Don't override it.
529             log_success_msg "iptables already has a rule for $name, not explicitly enabling"
530         else
531             action "Enabling $name with iptables" $insert
532         fi
533     elif (iptables --version) >/dev/null 2>&1; then
534         action "cannot list iptables rules, not adding a rule for $name"
535     else
536         action "iptables binary not installed, not adding a rule for $name"
537     fi
538 }
539
540 ## ---- ##
541 ## main ##
542 ## ---- ##
543
544 set_defaults () {
545     SYSTEM_ID=
546
547     DELETE_BRIDGES=no
548     DELETE_TRANSIENT_PORTS=no
549
550     DAEMON_CWD=/
551     FORCE_COREFILES=yes
552     MLOCKALL=yes
553     OVSDB_SERVER_PRIORITY=-10
554     OVS_VSWITCHD_PRIORITY=-10
555     OVSDB_SERVER_WRAPPER=
556     OVS_VSWITCHD_WRAPPER=
557
558     DB_FILE=$dbdir/conf.db
559     DB_SOCK=$rundir/db.sock
560     DB_SCHEMA=$datadir/vswitch.ovsschema
561     EXTRA_DBS=
562
563     PROTOCOL=gre
564     DPORT=
565     SPORT=
566
567     type_file=$etcdir/system-type.conf
568     version_file=$etcdir/system-version.conf
569
570     if test -e "$type_file" ; then
571         SYSTEM_TYPE=`cat $type_file`
572         SYSTEM_VERSION=`cat $version_file`
573     elif (lsb_release --id) >/dev/null 2>&1; then
574         SYSTEM_TYPE=`lsb_release --id -s`
575         system_release=`lsb_release --release -s`
576         system_codename=`lsb_release --codename -s`
577         SYSTEM_VERSION="${system_release}-${system_codename}"
578     else
579         SYSTEM_TYPE=unknown
580         SYSTEM_VERSION=unknown
581     fi
582 }
583
584 usage () {
585     set_defaults
586     cat <<EOF
587 $0: controls Open vSwitch daemons
588 usage: $0 [OPTIONS] COMMAND
589
590 This program is intended to be invoked internally by Open vSwitch startup
591 scripts.  System administrators should not normally invoke it directly.
592
593 Commands:
594   start              start Open vSwitch daemons
595   stop               stop Open vSwitch daemons
596   restart            stop and start Open vSwitch daemons
597   status             check whether Open vSwitch daemons are running
598   version            print versions of Open vSwitch daemons
599   load-kmod          insert modules if not already present
600   force-reload-kmod  save OVS network device state, stop OVS, unload kernel
601                      module, reload kernel module, start OVS, restore state
602   enable-protocol    enable protocol specified in options with iptables
603   help               display this help message
604
605 One of the following options is required for "start", "restart" and "force-reload-kmod":
606   --system-id=UUID   set specific ID to uniquely identify this system
607   --system-id=random  use a random but persistent UUID to identify this system
608
609 Other important options for "start", "restart" and "force-reload-kmod":
610   --system-type=TYPE  set system type (e.g. "XenServer")
611   --system-version=VERSION  set system version (e.g. "5.6.100-39265p")
612   --external-id="key=value"
613                      add given key-value pair to Open_vSwitch external-ids
614   --delete-bridges   delete all bridges just before starting ovs-vswitchd
615
616 Less important options for "start", "restart" and "force-reload-kmod":
617   --daemon-cwd=DIR               set working dir for OVS daemons (default: $DAEMON_CWD)
618   --no-force-corefiles           do not force on core dumps for OVS daemons
619   --no-mlockall                  do not lock all of ovs-vswitchd into memory
620   --ovsdb-server-priority=NICE   set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
621   --ovs-vswitchd-priority=NICE   set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
622
623 Debugging options for "start", "restart" and "force-reload-kmod":
624   --ovsdb-server-wrapper=WRAPPER
625   --ovs-vswitchd-wrapper=WRAPPER
626   --ovs-vswitchd-wrapper=WRAPPER
627      run specified daemon under WRAPPER (either 'valgrind' or 'strace')
628
629 File location options:
630   --db-file=FILE     database file name (default: $DB_FILE)
631   --db-sock=SOCKET   JSON-RPC socket name (default: $DB_SOCK)
632   --db-schema=FILE   database schema file name (default: $DB_SCHEMA)
633
634 Options for "enable-protocol":
635   --protocol=PROTOCOL  protocol to enable with iptables (default: gre)
636   --sport=PORT       source port to match (for tcp or udp protocol)
637   --dport=PORT       ddestination port to match (for tcp or udp protocol)
638
639 Other options:
640   -h, --help                  display this help message
641   -V, --version               display version information
642
643 Default directories with "configure" option and environment variable override:
644   logs: @LOGDIR@ (--with-logdir, OVS_LOGDIR)
645   pidfiles and sockets: @RUNDIR@ (--with-rundir, OVS_RUNDIR)
646   conf.db: @DBDIR@ (--with-dbdir, OVS_DBDIR)
647   system configuration: @sysconfdir@ (--sysconfdir, OVS_SYSCONFDIR)
648   data files: @pkgdatadir@ (--pkgdatadir, OVS_PKGDATADIR)
649   user binaries: @bindir@ (--bindir, OVS_BINDIR)
650   system binaries: @sbindir@ (--sbindir, OVS_SBINDIR)
651
652 Please report bugs to bugs@openvswitch.org (see REPORTING-BUGS for details).
653 EOF
654
655     exit 0
656 }
657
658 set_option () {
659     var=`echo "$option" | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`
660     eval set=\${$var+yes}
661     eval old_value=\$$var
662     if test X$set = X || \
663         (test $type = bool && \
664         test X"$old_value" != Xno && test X"$old_value" != Xyes); then
665         echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
666         return
667     fi
668     eval $var=\$value
669 }
670
671 daemons () {
672     echo ovsdb-server ovs-vswitchd
673 }
674
675 set_defaults
676 extra_ids=
677 command=
678 for arg
679 do
680     case $arg in
681         -h | --help)
682             usage
683             ;;
684         -V | --version)
685             echo "$0 (Open vSwitch) $VERSION"
686             exit 0
687             ;;
688         --external-id=*)
689             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
690             case $value in
691                 *=*)
692                     extra_ids="$extra_ids external-ids:$value"
693                     ;;
694                 *)
695                     echo >&2 "$0: --external-id argument not in the form \"key=value\""
696                     exit 1
697                     ;;
698             esac
699             ;;
700         --[a-z]*=*)
701             option=`expr X"$arg" : 'X--\([^=]*\)'`
702             value=`expr X"$arg" : 'X[^=]*=\(.*\)'`
703             type=string
704             set_option
705             ;;
706         --no-[a-z]*)
707             option=`expr X"$arg" : 'X--no-\(.*\)'`
708             value=no
709             type=bool
710             set_option
711             ;;
712         --[a-z]*)
713             option=`expr X"$arg" : 'X--\(.*\)'`
714             value=yes
715             type=bool
716             set_option
717             ;;
718         -*)
719             echo >&2 "$0: unknown option \"$arg\" (use --help for help)"
720             exit 1
721             ;;
722         *)
723             if test X"$command" = X; then
724                 command=$arg
725             else
726                 echo >&2 "$0: exactly one non-option argument required (use --help for help)"
727                 exit 1
728             fi
729             ;;
730     esac
731 done
732 case $command in
733     start)
734         start_ovsdb || exit 1
735         start_forwarding
736         add_managers
737         ;;
738     stop)
739         stop_forwarding
740         stop_ovsdb
741         ;;
742     restart)
743         restart
744         ;;
745     status)
746         rc=0
747         for daemon in `daemons`; do
748             daemon_status $daemon || rc=$?
749         done
750         exit $rc
751         ;;
752     version)
753         for daemon in `daemons`; do
754             $daemon --version
755         done
756         ;;
757     force-reload-kmod)
758             force_reload_kmod
759         ;;
760     load-kmod)
761         insert_mod_if_required
762         ;;
763     enable-protocol)
764         enable_protocol
765         ;;
766     help)
767         usage
768         ;;
769     '')
770         echo >&2 "$0: missing command name (use --help for help)"
771         exit 1
772         ;;
773     *)
774         echo >&2 "$0: unknown command \"$command\" (use --help for help)"
775         exit 1
776         ;;
777 esac