From b3a375f242c70ff85c30f84ce311628de4a6f022 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 21 Jun 2011 16:40:44 -0700 Subject: [PATCH] Avoid inserting duplicate iptables rules when restarting vswitch. 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 --- debian/openvswitch-switch.init | 6 ++-- utilities/ovs-ctl.8 | 57 ++++++++++++++++++++++++++++++-- utilities/ovs-ctl.in | 56 +++++++++++++++++++++++++++++++ xenserver/etc_init.d_openvswitch | 3 +- 4 files changed, 113 insertions(+), 9 deletions(-) diff --git a/debian/openvswitch-switch.init b/debian/openvswitch-switch.init index a65af0ce1..36bc20891 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 d649d5625..7aa8408d7 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,51 @@ 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 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 accepts traffic of the +specified protocol. +. +.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 44afbd272..4d1ce1881 100755 --- a/utilities/ovs-ctl.in +++ b/utilities/ovs-ctl.in @@ -265,6 +265,49 @@ 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 + 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 + 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 +327,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 +358,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 +387,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 +496,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 39d4d364e..810390040 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 } -- 2.45.2