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