utilites: rename ovs-lib.sh to ovs-lib
[sliver-openvswitch.git] / utilities / ovs-ctl.in
index a127149..ee6035c 100755 (executable)
@@ -17,7 +17,7 @@ case $0 in
     */*) dir0=`echo "$0" | sed 's,/[^/]*$,,'` ;;
     *) dir0=./ ;;
 esac
-. "$dir0/ovs-lib.sh" || exit 1
+. "$dir0/ovs-lib" || exit 1
 
 for dir in "$sbindir" "$bindir" /sbin /bin /usr/sbin /usr/bin; do
     case :$PATH: in
@@ -30,7 +30,7 @@ done
 ## start ##
 ## ----- ##
 
-insert_modules_if_required () {
+insert_openvswitch_mod_if_required () {
     # If openvswitch_mod is already loaded then we're done.
     test -e /sys/module/openvswitch_mod && return 0
 
@@ -51,12 +51,28 @@ insert_modules_if_required () {
     action "Inserting openvswitch module" modprobe openvswitch_mod
 }
 
+insert_brcompat_mod_if_required () {
+    test -e /sys/module/brcompat_mod && return 0
+    action "Inserting brcompat module" modprobe brcompat_mod
+}
+
+insert_mod_if_required () {
+    insert_openvswitch_mod_if_required || return 1
+    if test X"$BRCOMPAT" = Xyes; then
+        insert_brcompat_mod_if_required || return 1
+    fi
+}
+
 ovs_vsctl () {
     ovs-vsctl --no-wait --timeout=5 "$@"
 }
 
 ovsdb_tool () {
-    ovsdb-tool -vANY:console:emer "$@"
+    ovsdb-tool -vANY:console:off "$@"
+}
+
+create_db () {
+    action "Creating empty database $DB_FILE" ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
 }
 
 upgrade_db () {
@@ -64,14 +80,13 @@ upgrade_db () {
     if test ! -e "$DB_FILE"; then
         log_warning_msg "$DB_FILE does not exist"
         install -d -m 755 -o root -g root `dirname $DB_FILE`
-
-        action "Creating empty database $DB_FILE" true
-        ovsdb_tool create "$DB_FILE" "$DB_SCHEMA"
+        create_db
     elif test X"`ovsdb_tool needs-conversion "$DB_FILE" "$DB_SCHEMA"`" != Xno; then
         # Back up the old version.
         version=`ovsdb_tool db-version "$DB_FILE"`
         cksum=`ovsdb_tool db-cksum "$DB_FILE" | awk '{print $1}'`
-        cp "$DB_FILE" "$DB_FILE.backup$version-$cksum"
+        backup=$DB_FILE.backup$version-$cksum
+        action "Backing up database to $backup" cp "$DB_FILE" "$backup" || return 1
 
         # Compact database.  This is important if the old schema did not enable
         # garbage collection (i.e. if it did not have any tables with "isRoot":
@@ -82,10 +97,20 @@ upgrade_db () {
         # does) would cause the record to be dropped by the first transaction,
         # then the second transaction would cause a referential integrity
         # failure (for a strong reference).
-        ovsdb_tool compact "$DB_FILE"
+        #
+        # Errors might occur on an Open vSwitch downgrade if ovsdb-tool doesn't
+        # understand some feature of the schema used in the OVSDB version that
+        # we're downgrading from, so we don't give up on error.
+        action "Compacting database" ovsdb_tool compact "$DB_FILE"
 
         # Upgrade or downgrade schema.
-        ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"
+        if action "Converting database schema" ovsdb_tool convert "$DB_FILE" "$DB_SCHEMA"; then
+            :
+        else
+            log_warning_msg "Schema conversion failed, using empty database instead"
+            rm -f "$DB_FILE"
+            create_db
+        fi
     fi
 }
 
@@ -142,7 +167,7 @@ start () {
         ulimit -Sc 67108864
     fi
 
-    insert_modules_if_required || return 1
+    insert_mod_if_required || return 1
 
     if daemon_is_running ovsdb-server; then
        log_success_msg "ovsdb-server is already running"
@@ -184,7 +209,15 @@ start () {
        if test X"$MLOCKALL" != Xno; then
            set "$@" --mlockall
        fi
-       start_daemon "$VSWITCHD_PRIORITY" "$@"
+       start_daemon "$OVS_VSWITCHD_PRIORITY" "$@"
+    fi
+
+    if daemon_is_running ovs-brcompatd; then
+       log_success_msg "ovs-brcompatd is already running"
+    elif test X"$BRCOMPAT" = Xyes; then
+        set ovs-brcompatd
+       set "$@" -vANY:CONSOLE:EMER -vANY:SYSLOG:ERR -vANY:FILE:INFO
+       start_daemon "$OVS_BRCOMPATD_PRIORITY" "$@"
     fi
 }
 
@@ -193,6 +226,7 @@ start () {
 ## ---- ##
 
 stop () {
+    stop_daemon ovs-brcompatd
     stop_daemon ovs-vswitchd
     stop_daemon ovsdb-server
 }
@@ -233,7 +267,8 @@ force_reload_kmod () {
     stop
 
     script=`mktemp`
-    if action "Save interface configuration to $script" save_interfaces; then
+    trap 'rm -f "$script"' 0 1 2 13 15
+    if action "Saving interface configuration" save_interfaces; then
         :
     else
         log_warning_msg "Failed to save configuration, not replacing kernel module"
@@ -243,16 +278,74 @@ force_reload_kmod () {
     chmod +x "$script"
 
     for dp in `ovs-dpctl dump-dps`; do
-        action "Removing datapath: $dp" "$dpctl" del-dp "$dp"
+        action "Removing datapath: $dp" ovs-dpctl del-dp "$dp"
     done
 
+    if test -e /sys/module/brcompat_mod; then
+        action "Removing brcompat module" rmmod brcompat_mod
+    fi
     if test -e /sys/module/openvswitch_mod; then
         action "Removing openvswitch module" rmmod openvswitch_mod
     fi
 
     start
 
-    action "Restore interface configuration from $script" "$script"
+    action "Restoring interface configuration" "$script"
+    rc=$?
+    if test $rc = 0; then
+        level=debug
+    else
+        level=err
+    fi
+    log="logger -p daemon.$level -t ovs-save"
+    $log "force-reload-kmod interface restore script exited with status $rc:"
+    $log -f "$script"
+}
+
+## --------------- ##
+## enable-protocol ##
+## --------------- ##
+
+enable_protocol () {
+    # Translate the protocol name to a number, because "iptables -n -L" prints
+    # some protocols by name (despite the -n) and therefore we need to look for
+    # both forms.
+    #
+    # (iptables -S output is more uniform but old iptables doesn't have it.)
+    protonum=`grep "^$PROTOCOL[        ]" /etc/protocols | awk '{print $2}'`
+    if expr X"$protonum" : X'[0-9]\{1,\}$' > /dev/null; then :; else
+        log_failure_msg "unknown protocol $PROTOCOL"
+        return 1
+    fi
+
+    name=$PROTOCOL
+    match="(\$2 == \"$PROTOCOL\" || \$2 == $protonum)"
+    insert="iptables -I INPUT -p $PROTOCOL"
+    if test X"$DPORT" != X; then
+        name="$name to port $DPORT"
+        match="$match && /dpt:$DPORT/"
+        insert="$insert --dport $DPORT"
+    fi
+    if test X"$SPORT" != X; then
+        name="$name from port $SPORT"
+        match="$match && /spt:$SPORT/"
+        insert="$insert --sport $SPORT"
+    fi
+    insert="$insert -j ACCEPT"
+
+    if (iptables -n -L INPUT) >/dev/null 2>&1; then
+        if iptables -n -L INPUT | awk "$match { n++ } END { exit n == 0 }"
+        then
+            # There's already a rule for this protocol.  Don't override it.
+            log_success_msg "iptables already has a rule for $name, not explicitly enabling"
+        else
+            action "Enabling $name with iptables" $insert
+        fi
+    elif (iptables --version) >/dev/null 2>&1; then
+        action "cannot list iptables rules, not adding a rule for $name"
+    else
+        action "iptables binary not installed, not adding a rule for $name"
+    fi
 }
 
 ## ---- ##
@@ -263,17 +356,23 @@ set_defaults () {
     SYSTEM_ID=
 
     DELETE_BRIDGES=no
+    BRCOMPAT=no
 
     DAEMON_CWD=/
     FORCE_COREFILES=yes
     MLOCKALL=yes
     OVSDB_SERVER_PRIORITY=-10
     OVS_VSWITCHD_PRIORITY=-10
+    OVS_BRCOMPATD_PRIORITY=-10
 
     DB_FILE=$etcdir/conf.db
     DB_SOCK=$rundir/db.sock
     DB_SCHEMA=$datadir/vswitch.ovsschema
 
+    PROTOCOL=gre
+    DPORT=
+    SPORT=
+
     if (lsb_release --id) >/dev/null 2>&1; then
         SYSTEM_TYPE=`lsb_release --id -s`
         system_release=`lsb_release --release -s`
@@ -299,36 +398,44 @@ Commands:
   stop               stop Open vSwitch daemons
   status             check whether Open vSwitch daemons are running
   version            print versions of Open vSwitch daemons
+  load-kmod          insert modules if not already present
   force-reload-kmod  save OVS network device state, stop OVS, unload kernel
                      module, reload kernel module, start OVS, restore state
+  enable-protocol    enable protocol specified in options with iptables
   help               display this help message
 
-One of the following options should be specified when starting Open vSwitch:
+One of the following options is required for "start" and "force-reload-kmod":
   --system-id=UUID   set specific ID to uniquely identify this system
   --system-id=random  use a random but persistent UUID to identify this system
 
-Other important options for starting Open vSwitch:
+Other important options for "start" and "force-reload-kmod":
   --system-type=TYPE  set system type (e.g. "XenServer")
   --system-version=VERSION  set system version (e.g. "5.6.100-39265p")
   --external-id="key=value"
                      add given key-value pair to Open_vSwitch external-ids
   --delete-bridges   delete all bridges just before starting ovs-vswitchd
 
-Less important options for starting Open vSwitch:
-  --daemon-cwd=DIR   current working directory for OVS daemons (default: $DAEMON_CWD)
-  --no-force-corefiles
-                     do not forcibly enable core dumps for OVS daemons
-  --no-mlockall      do not lock all of ovs-vswitchd into memory
-  --ovsdb-server-priority=NICE
-                     set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
-  --ovs-vswitchd-priority=NICE
-                     set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
+Less important options for "start" and "force-reload-kmod":
+  --daemon-cwd=DIR               set working dir for OVS daemons (default: $DAEMON_CWD)
+  --no-force-corefiles           do not force on core dumps for OVS daemons
+  --no-mlockall                  do not lock all of ovs-vswitchd into memory
+  --ovsdb-server-priority=NICE   set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
+  --ovs-vswitchd-priority=NICE   set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
+  --ovs-brcompatd-priority=NICE  set ovs-brcompatd's niceness (default: $OVS_BRCOMPATD_PRIORITY)
+
+Options for "start", "force-reload-kmod", "load-kmod", "status", and "version":
+  --brcompat         enable Linux bridge compatibility module and daemon
 
 File location options:
   --db-file=FILE     database file name (default: $DB_FILE)
   --db-sock=SOCKET   JSON-RPC socket name (default: $DB_SOCK)
   --db-schema=FILE   database schema file name (default: $DB_SCHEMA)
 
+Options for "enable-protocol":
+  --protocol=PROTOCOL  protocol to enable with iptables (default: gre)
+  --sport=PORT       source port to match (for tcp or udp protocol)
+  --dport=PORT       ddestination port to match (for tcp or udp protocol)
+
 Other options:
   -h, --help                  display this help message
   -V, --version               display version information
@@ -360,6 +467,13 @@ set_option () {
     eval $var=\$value
 }
 
+daemons () {
+    echo ovsdb-server ovs-vswitchd
+    if test X"$BRCOMPAT" = Xyes; then
+        echo ovs-brcompatd
+    fi
+}
+
 set_defaults
 extra_ids=
 command=
@@ -425,14 +539,26 @@ case $command in
         stop
         ;;
     status)
-        daemon_status ovsdb-server && daemon_status ovs-vswitchd
+        rc=0
+        for daemon in `daemons`; do
+            daemon_status $daemon || rc=$?
+        done
+        exit $rc
         ;;
     version)
-        ovsdb-server --version && ovs-vswitchd --version
+        for daemon in `daemons`; do
+            $daemon --version
+        done
         ;;
     force-reload-kmod)
        force_reload_kmod
         ;;
+    load-kmod)
+        insert_mod_if_required
+        ;;
+    enable-protocol)
+        enable_protocol
+        ;;
     help)
         usage
         ;;