[ovs-dev] [ovs-ctl 4/4] Avoid inserting duplicate iptables rules when restarting vswitch.

Ben Pfaff blp at nicira.com
Tue Jun 21 19:45:34 UTC 2011


On startup, some OVS initscripts insert an iptables rule to allow GRE
traffic (because GRE support is an important OVS feature).  I noticed that,
each time I restarted OVS, this added another GRE-related rule to the
iptables chain.  This is wasteful, because each additional rule increases
the time it takes to process a packet in the IP stack.

This commit avoids the problem by inserting an iptables rule when there
isn't already an appropriate rule.  It also avoids inserting an iptables
rule if the iptables policy is ACCEPT, meaning that packets are accepted
by default; in such a case, if the GRE packet would be dropped, it is
because the system administrator made that decision explicitly.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 debian/openvswitch-switch.init   |    6 +--
 utilities/ovs-ctl.8              |   63 ++++++++++++++++++++++++++++++++++++--
 utilities/ovs-ctl.in             |   60 ++++++++++++++++++++++++++++++++++++
 xenserver/etc_init.d_openvswitch |    3 +-
 4 files changed, 123 insertions(+), 9 deletions(-)

diff --git a/debian/openvswitch-switch.init b/debian/openvswitch-switch.init
index a65af0c..36bc208 100755
--- a/debian/openvswitch-switch.init
+++ b/debian/openvswitch-switch.init
@@ -34,11 +34,9 @@ start () {
     if test X"$FORCE_COREFILES" != X; then
 	set "$@" --force-corefiles="$FORCE_COREFILES"
     fi
+    "$@" || exit $?
 
-    # Allow GRE traffic.
-    test ! -x /sbin/iptables || /sbin/iptables -I INPUT -p gre -j ACCEPT
-
-    "$@"
+    $ovs_ctl --protocol=gre enable-protocol
 }
 
 stop () {
diff --git a/utilities/ovs-ctl.8 b/utilities/ovs-ctl.8
index d649d56..c57631b 100644
--- a/utilities/ovs-ctl.8
+++ b/utilities/ovs-ctl.8
@@ -17,7 +17,7 @@
 ovs\-ctl \- OVS startup helper script
 .
 .SH SYNOPSIS
-\fBovs\-ctl\fR [\fB\-\-system\-id=random\fR | \fIuuid\fR]
+\fBovs\-ctl\fR \fB\-\-system\-id=random\fR|\fIuuid\fR
 [\fIoptions\fR] \fBstart
 .br
 \fBovs\-ctl stop
@@ -26,7 +26,16 @@ ovs\-ctl \- OVS startup helper script
 .br
 \fBovs\-ctl version
 .br
-\fBovs\-ctl force-reload-kmod
+\fBovs\-ctl
+\fB\-\-system\-id=random\fR|\fIuuid\fR
+[\fIoptions\fR]
+\fBforce\-reload\-kmod\fR
+.br
+\fBovs\-ctl
+\fR[\fB\-\-protocol=\fIprotocol\fR]
+[\fB\-\-sport=\fIsport\fR]
+[\fB\-\-dport=\fIdport\fR]
+\fBenable\-protocol\fR
 .br
 \fBovs\-ctl help \fR| \fB\-h \fR| \fB\-\-help
 .br
@@ -231,9 +240,57 @@ ISC DHCP client is running on an OVS internal interface, then it will
 have to be restarted after completing the above procedure.
 .
 .PP
-Because \fBforce\-kmod\-reload\fR internally stops and starts OVS, it
+\fBforce\-kmod\-reload\fR internally stops and starts OVS, so it
 accepts all of the options accepted by the \fBstart\fR command.
 .
+.SS "The ``enable\-protocol'' command"
+.
+.PP
+The \fBenable\-protocol\fR command checks for rules related to a
+specified protocol in the system's \fBiptables\fR(8) configuration.  If there
+are no rules specifically related to that protocol, then it inserts a
+rule to accept the specified protocol.
+.
+.PP
+More specifically:
+.
+.IP \(bu
+If \fBiptables\fR is not installed or not enabled, this command does
+nothing, assuming that lack of filtering means that the protocol is
+enabled.
+.
+.IP \(bu
+If the \fBINPUT\fR chain has a default \fBACCEPT\fR policy, this
+command does nothing, assuming that if there are rules installed to
+drop the traffic then this is intentional policy on the system
+administrator's part.
+.
+.IP \(bu
+If the \fBINPUT\fR chain has a rule that matches the specified
+protocol, then this command does nothing, assuming that whatever rule
+is installed reflects the system administrator's decisions.
+.
+.IP \(bu
+Otherwise, this command installs a rule that caused traffic of the
+specified protocol to be accepted.
+.
+.PP
+This command normally completes successfully, even if it does
+nothing.  Only the failure of an attempt to insert a rule normally
+causes it to return an exit code other than 0.
+.
+The following options control the protocol to be enabled:
+.
+.IP "\fB\-\-protocol=\fIprotocol\fR"
+The name of the IP protocol to be enabled, such as \fBgre\fR or
+\fBtcp\fR.  The default is \fBgre\fR.
+.
+.IP "\fB\-\-sport=\fIsport\fR"
+.IQ "\fB\-\-dport=\fIdport\fR"
+TCP or UDP source or destination port to match.  These are optional
+and allowed only with \fB\-\-protocol=tcp\fR or
+\fB\-\-protocol=udp\fR.
+.
 .SS "The ``help'' command"
 .
 Prints a usage message and exits successfully.
diff --git a/utilities/ovs-ctl.in b/utilities/ovs-ctl.in
index 44afbd2..9a6d26e 100755
--- a/utilities/ovs-ctl.in
+++ b/utilities/ovs-ctl.in
@@ -265,6 +265,53 @@ force_reload_kmod () {
     $log -f "$script"
 }
 
+## --------------- ##
+## enable-protocol ##
+## --------------- ##
+
+enable_protocol () {
+    set X "-p $PROTOCOL"
+    name=$PROTOCOL
+    if test X"$DPORT" != X; then
+        set "$@" "--dport $DPORT"
+        name="$name to port $DPORT"
+    fi
+    if test X"$SPORT" != X; then
+        set "$@" "--sport $SPORT"
+        name="$name from port $SPORT"
+    fi
+    shift
+
+    search="/^-A INPUT/!d"
+    insert="iptables -I INPUT"
+    for arg; do
+        search="$search
+/ $arg /!d"
+        insert="$insert $arg"
+    done
+    insert="$insert -j ACCEPT"
+
+    if (iptables -S INPUT) >/dev/null 2>&1; then
+        if iptables -S INPUT | grep '^-P INPUT ACCEPT$' >/dev/null; then
+            log_success_msg "iptables INPUT policy is ACCEPT, not explicitly enabling $name"
+        else
+            case `iptables -S INPUT | sed "$search"` in
+                '')
+                    action "Enabling $name with iptables" $insert
+                    ;;
+                *)
+                    # 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"
+                    ;;
+            esac
+        fi
+    elif (iptables --version) >/dev/null 2>&1; then
+        action "iptables binary not installed, not adding a rule for $name"
+    else
+        action "cannot list iptables rules, not adding a rule for $name"
+    fi
+}
+
 ## ---- ##
 ## main ##
 ## ---- ##
@@ -284,6 +331,10 @@ set_defaults () {
     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`
@@ -311,6 +362,7 @@ Commands:
   version            print versions of Open vSwitch daemons
   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:
@@ -339,6 +391,11 @@ File location options:
   --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
@@ -443,6 +500,9 @@ case $command in
     force-reload-kmod)
 	force_reload_kmod
         ;;
+    enable-protocol)
+        enable_protocol
+        ;;
     help)
         usage
         ;;
diff --git a/xenserver/etc_init.d_openvswitch b/xenserver/etc_init.d_openvswitch
index 39d4d36..8103900 100755
--- a/xenserver/etc_init.d_openvswitch
+++ b/xenserver/etc_init.d_openvswitch
@@ -76,8 +76,7 @@ start () {
             --pidfile --detach --monitor unix:/var/run/openvswitch/db.sock
     fi
 
-    # Allow GRE traffic.
-    /sbin/iptables -I INPUT -p gre -j ACCEPT
+    $ovs_ctl --protocol=gre enable-protocol
 
     touch /var/lock/subsys/openvswitch
 }
-- 
1.7.4.4




More information about the dev mailing list