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