Carefully suppress duplicate rules in all tables

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2012-12-02 12:20:24 -08:00
parent c05c928c6c
commit cd5e9be467
3 changed files with 79 additions and 110 deletions

View File

@ -3370,6 +3370,13 @@ sub combine_dports {
\@rules; \@rules;
} }
my %bad_match = ( conntrack => 1,
dscp => 1,
ecn => 1,
mark => 1,
set => 1,
tos => 1,
u32 => 1 );
# #
# Delete duplicate rules from the passed chain. # Delete duplicate rules from the passed chain.
# #
@ -3382,105 +3389,61 @@ sub delete_duplicates {
my $lastrule = @_; my $lastrule = @_;
my $baseref = pop; my $baseref = pop;
my $ruleref; my $ruleref;
my $duplicate = 0;
while ( @_ && ! $duplicate ) { while ( @_ ) {
{ my $docheck;
my $duplicate = 0;
if ( $baseref->{mode} == CAT_MODE ) {
my $ports1; my $ports1;
my @keys1 = sort( keys( %$baseref ) ); my @keys1 = sort( keys( %$baseref ) );
my $rulenum = @_; my $rulenum = @_;
my $duplicate = 0; my $adjacent = 1;
{
RULE:
if ( $baseref->{mode} == CAT_MODE ) { while ( --$rulenum >= 0 ) {
{ $ruleref = $_[$rulenum];
RULE:
while ( --$rulenum >= 0 ) { last unless $ruleref->{mode} == CAT_MODE;
$ruleref = $_[$rulenum];
last unless $ruleref->{mode} == CAT_MODE; my @keys2 = sort(keys( %$ruleref ) );
my @keys2 = sort(keys( %$ruleref ) ); next unless @keys1 == @keys2 ;
next unless @keys1 == @keys2 ; my $keynum = 0;
my $keynum = 0;
if ( $adjacent > 0 ) {
for my $key ( @keys1 ) { for my $key ( @keys1 ) {
next RULE unless $key eq $keys2[$keynum++]; next RULE unless $key eq $keys2[$keynum++];
next RULE unless compare_values( $baseref->{$key}, $ruleref->{$key} ); next RULE unless compare_values( $baseref->{$key}, $ruleref->{$key} );
} }
} else {
$duplicate = 1;
}
}
}
if ( $duplicate ) {
trace( $chainref, 'D', $lastrule, $baseref ) if $debug;
} else {
unshift @rules, $baseref;
}
$baseref = pop @_;
$lastrule--;
}
}
unshift @rules, $baseref if $baseref;
\@rules;
}
sub delete_adjacent_duplicates {
my @rules;
my $chainref = shift;
my $lastrule = @_;
my $baseref = pop;
my $ruleref;
my $duplicate = 0;
while ( @_ && ! $duplicate ) {
{
my $ports1;
my @keys1 = sort( keys( %$baseref ) );
my $rulenum = @_;
my $duplicate = 0;
if ( $baseref->{mode} == CAT_MODE ) {
{
RULE:
while ( --$rulenum >= 0 ) {
$ruleref = $_[$rulenum];
last unless $ruleref->{mode} == CAT_MODE;
my @keys2 = sort(keys( %$ruleref ) );
last RULE unless @keys1 == @keys2 ;
my $keynum = 0;
for my $key ( @keys1 ) { for my $key ( @keys1 ) {
last RULE unless $key eq $keys2[$keynum++]; last RULE if $bad_match{$key};
last RULE unless compare_values( $baseref->{$key}, $ruleref->{$key} ); next RULE unless $key eq $keys2[$keynum++];
next RULE unless compare_values( $baseref->{$key}, $ruleref->{$key} );
} }
$duplicate = 1;
} }
$duplicate = 1;
$adjacent++;
} continue {
$adjacent--;
} }
} }
if ( $duplicate ) {
trace( $chainref, 'D', $lastrule, $baseref ) if $debug;
} else {
unshift @rules, $baseref;
}
$baseref = pop @_;
$lastrule--;
} }
if ( $duplicate ) {
trace( $chainref, 'D', $lastrule, $baseref ) if $debug;
} else {
unshift @rules, $baseref;
}
$baseref = pop @_;
$lastrule--;
} }
unshift @rules, $baseref if $baseref; unshift @rules, $baseref if $baseref;
@ -3497,19 +3460,7 @@ sub optimize_level16( $$$ ) {
progress_message "\n Table $table pass $passes, $chains referenced user chains, level 16..."; progress_message "\n Table $table pass $passes, $chains referenced user chains, level 16...";
for my $chainref ( @chains ) { for my $chainref ( @chains ) {
if ( $table eq 'raw' ) { $chainref->{rules} = delete_duplicates( $chainref, @{$chainref->{rules}} );
#
# Helpers in rules have the potential for generating lots of duplicate iptables rules
# in the raw table. This step eliminates those duplicates
#
$chainref->{rules} = delete_duplicates( $chainref, @{$chainref->{rules}} );
} else {
#
# Conservative version that only deletes adjacent duplicates
#
$chainref->{rules} = delete_adjacent_duplicates( $chainref, @{$chainref->{rules}} );
}
} }
$passes++; $passes++;

View File

@ -96,7 +96,7 @@
role="bold">none</emphasis>}</term> role="bold">none</emphasis>}</term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -106,7 +106,7 @@
role="bold">none</emphasis>}</term> role="bold">none</emphasis>}</term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -116,7 +116,7 @@
role="bold">none</emphasis>}</term> role="bold">none</emphasis>}</term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -126,7 +126,7 @@
role="bold">none</emphasis>}</term> role="bold">none</emphasis>}</term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -523,7 +523,7 @@
</itemizedlist> </itemizedlist>
<blockquote> <blockquote>
<para></para> <para/>
<para>If CONFIG_PATH is not given or if it is set to the empty <para>If CONFIG_PATH is not given or if it is set to the empty
value then the contents of /usr/share/shorewall/configpath are value then the contents of /usr/share/shorewall/configpath are
@ -930,7 +930,7 @@ net all DROP info</programlisting>then the chain name is 'net2all'
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<para></para> <para/>
<blockquote> <blockquote>
<para>If this variable is not set or is given an empty value <para>If this variable is not set or is given an empty value
@ -1140,7 +1140,7 @@ net all DROP info</programlisting>then the chain name is 'net2all'
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para></para> <para/>
<blockquote> <blockquote>
<para>For example, using the default LOGFORMAT, the log prefix for <para>For example, using the default LOGFORMAT, the log prefix for
@ -1157,7 +1157,7 @@ net all DROP info</programlisting>then the chain name is 'net2all'
control your firewall after you enable this option.</para> control your firewall after you enable this option.</para>
</important> </important>
<para></para> <para/>
<caution> <caution>
<para>Do not use this option if the resulting log messages will <para>Do not use this option if the resulting log messages will
@ -1724,6 +1724,15 @@ net all DROP info</programlisting>then the chain name is 'net2all'
'Others and'. Empty comments at the end of a group of combined 'Others and'. Empty comments at the end of a group of combined
comments are replaced by 'and others'.</para> comments are replaced by 'and others'.</para>
<para>Beginning in Shorewall 4.5.10, this option also suppresses
duplicate adjacent rules and duplicate non-adjacent rules that
don't include <emphasis role="bold">mark</emphasis>, <emphasis
role="bold">connmark</emphasis>, <emphasis
role="bold">dscp</emphasis>, <emphasis
role="bold">ecn</emphasis>, <emphasis
role="bold">set</emphasis>, <emphasis role="bold">tos</emphasis>
or <emphasis role="bold">u32</emphasis> matches.</para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term>Example 1:</term> <term>Example 1:</term>
@ -1821,7 +1830,7 @@ net all DROP info</programlisting>then the chain name is 'net2all'
role="bold">"</emphasis></term> role="bold">"</emphasis></term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -82,7 +82,7 @@
role="bold">none</emphasis>}</term> role="bold">none</emphasis>}</term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -92,7 +92,7 @@
role="bold">none</emphasis>}</term> role="bold">none</emphasis>}</term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -102,7 +102,7 @@
role="bold">none</emphasis>}</term> role="bold">none</emphasis>}</term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -112,7 +112,7 @@
role="bold">none</emphasis>}</term> role="bold">none</emphasis>}</term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1006,7 +1006,7 @@ net all DROP info</programlisting>then the chain name is 'net2all'
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para></para> <para/>
<blockquote> <blockquote>
<para>For example, using the default LOGFORMAT, the log prefix for <para>For example, using the default LOGFORMAT, the log prefix for
@ -1023,7 +1023,7 @@ net all DROP info</programlisting>then the chain name is 'net2all'
control your firewall after you enable this option.</para> control your firewall after you enable this option.</para>
</important> </important>
<para></para> <para/>
<caution> <caution>
<para>Do not use this option if the resulting log messages will <para>Do not use this option if the resulting log messages will
@ -1525,6 +1525,15 @@ net all DROP info</programlisting>then the chain name is 'net2all'
'Others and'. Empty comments at the end of a group of combined 'Others and'. Empty comments at the end of a group of combined
comments are replaced by 'and others'.</para> comments are replaced by 'and others'.</para>
<para>Beginning in Shorewall 4.5.10, this option also suppresses
duplicate adjacent rules and duplicate non-adjacent rules that
don't include <emphasis role="bold">mark</emphasis>, <emphasis
role="bold">connmark</emphasis>, <emphasis
role="bold">dscp</emphasis>, <emphasis
role="bold">ecn</emphasis>, <emphasis
role="bold">set</emphasis>, <emphasis role="bold">tos</emphasis>
or <emphasis role="bold">u32</emphasis> matches.</para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term>Example 1:</term> <term>Example 1:</term>
@ -1622,7 +1631,7 @@ net all DROP info</programlisting>then the chain name is 'net2all'
role="bold">"</emphasis></term> role="bold">"</emphasis></term>
<listitem> <listitem>
<para></para> <para/>
</listitem> </listitem>
</varlistentry> </varlistentry>