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