From 0791ea6698a6755f9a8d6a359b2d55eb5ac66e96 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Thu, 21 Jul 2011 12:57:20 -0700 Subject: [PATCH] Make 'KLUDGEFREE' a global to make it faster to test. Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 50 ++++++++++++++++-------------- Shorewall/Perl/Shorewall/Config.pm | 20 ++++++------ Shorewall/Perl/Shorewall/Zones.pm | 2 +- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 5f19fbf8f..747c25d2f 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -619,15 +619,17 @@ sub set_rule_option( $$$ ) { if ( exists $ruleref->{$option} ) { assert( defined $ruleref->{$option} ); - if ( $special != EXCLUSIVE ) { - if ( $special == UNIQUE ) { - assert(0); - } elsif ( $special == MATCH ) { - $ruleref->{$option} = [ $ruleref->{$option} ] unless reftype $ruleref->{$option}; - push @{$ruleref->{$option}}, ( reftype $value ? @$value : $value ); - } else { - assert(0); - } + + if ( $special == MATCH ) { + assert( $globals{KLUDGEFREE} ); + $ruleref->{$option} = [ $ruleref->{$option} ] unless reftype $ruleref->{$option}; + push @{$ruleref->{$option}}, ( reftype $value ? @$value : $value ); + } elsif ( $special == EXCLUSIVE ) { + $ruleref->{$option} .= ",$value"; + } elsif ( $special == UNIQUE ) { + fatal_error "Multiple $option settings in one rule is prohibited"; + } else { + assert(0); } } else { $ruleref->{$option} = $value; @@ -654,9 +656,9 @@ sub transform_rule( $ ) { $invert = '!' if $1; my $opt = $option = $2; - fatal_error "Unrecognized iptables command ($opt}" unless $option = $aliases{$option}; + fatal_error "Unrecognized iptables option ($opt}" unless $option = $aliases{$option}; } else { - fatal_error "Unrecognized iptables command string ($input)"; + fatal_error "Unrecognized iptables option string ($input)"; } if ( $option eq 'j' or $option eq 'g' ) { @@ -2519,7 +2521,7 @@ sub optimize_level4( $$ ) { # # Not so easy -- the rule contains matches # - if ( $chainref->{builtin} || ! have_capability 'KLUDGEFREE' ) { + if ( $chainref->{builtin} || ! $globals{KLUDGEFREE} ) { # # This case requires a new rule merging algorithm. Ignore this chain for # now. @@ -3452,7 +3454,7 @@ sub iprange_match() { require_capability( 'IPRANGE_MATCH' , 'Address Ranges' , '' ); unless ( $iprangematch ) { $match = '-m iprange '; - $iprangematch = 1 unless have_capability( 'KLUDGEFREE' ); + $iprangematch = 1 unless $globals{KLUDGEFREE}; } $match; @@ -3576,7 +3578,7 @@ sub match_source_net( $;$\$ ) { my $result = ''; my @sets = mysplit $1, 1; - require_capability 'KLUDGEFREE', 'Multiple ipset matches', '' if @sets > 1; + fatal_error "Multiple ipset matches requires the Repeat Match capability in your kernel and iptables" unless $globals{KLUDGEFREE}; for $net ( @sets ) { fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; @@ -3612,7 +3614,7 @@ sub imatch_source_net( $;$\$ ) { ( $family == F_IPV6 && $net =~ /^(!?)(.*:.*)-(.*:.*)$/ ) ) { my ($addr1, $addr2) = ( $2, $3 ); $net =~ s/!// if my $invert = $1 ? '! ' : ''; - require_capability( 'IPRANGE_MATCH' , 'Address Ranges' , '' ); + fatal_error "Address Ranges require the Multiple Match capability in your kernel and iptables" unless $globals{KLUDGEFREE}; return ( iprange => "${invert}--src-range $net" ); } @@ -3630,7 +3632,7 @@ sub imatch_source_net( $;$\$ ) { my @result = (); my @sets = mysplit $1, 1; - require_capability 'KLUDGEFREE', 'Multiple ipset matches', '' if @sets > 1; + fatal_error "Multiple ipset matches requires the Repeat Match capability in your kernel and iptables" unless $globals{KLUDGEFREE}; for $net ( @sets ) { fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; @@ -3679,7 +3681,7 @@ sub match_dest_net( $ ) { my $result = ''; my @sets = mysplit $1, 1; - require_capability 'KLUDGEFREE', 'Multiple ipset matches', '' if @sets > 1; + fatal_error "Multiple ipset matches requires the Repeat Match capability in your kernel and iptables" unless $globals{KLUDGEFREE}; for $net ( @sets ) { fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; @@ -3726,7 +3728,7 @@ sub imatch_dest_net( $ ) { my @result; my @sets = mysplit $1, 1; - require_capability 'KLUDGEFREE', 'Multiple ipset matches', '' if @sets > 1; + fatal_error "Multiple ipset matches requires the Repeat Match capability in your kernel and iptables" unless $globals{KLUDGEFREE}; for $net ( @sets ) { fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; @@ -4793,7 +4795,9 @@ sub expand_rule( $$$$$$$$$$;$ ) # We can't use an exclusion chain -- we mark those packets to be excluded and then condition the rules generated in the block below on the mark value # require_capability 'MARK_ANYWHERE' , 'Exclusion in ACCEPT+/CONTINUE/NONAT rules', 's' unless $table eq 'mangle'; - require_capability 'KLUDGEFREE' , 'Exclusion in ACCEPT+/CONTINUE/NONAT rules', 's' if $rule =~ / -m mark /; + + fatal_error "Exclusion in ACCEPT+/CONTINUE/NONAT rules requires the Multiple Match capability in your kernel and iptables" + if $rule =~ / -m mark / && ! $globals{KLUDGEFREE}; # # Clear the exclusion bit # @@ -4844,10 +4848,10 @@ sub expand_rule( $$$$$$$$$$;$ ) my $cond = conditional_rule( $chainref, $inet ); - my $source_match = match_source_net( $inet, $restriction, $mac ) if have_capability( 'KLUDGEFREE' ); + my $source_match = match_source_net( $inet, $restriction, $mac ) if $globals{KLUDGEFREE}; for my $dnet ( mysplit $dnets ) { - $source_match = match_source_net( $inet, $restriction, $mac ) unless have_capability( 'KLUDGEFREE' ); + $source_match = match_source_net( $inet, $restriction, $mac ) unless $globals{KLUDGEFREE}; add_jump( $chainref, $echainref, 0, join( '', $rule, $source_match, match_dest_net( $dnet ), $onet ), 1 ); } @@ -4911,10 +4915,10 @@ sub expand_rule( $$$$$$$$$$;$ ) my $cond = conditional_rule( $chainref, $inet ); - $source_match = match_source_net( $inet, $restriction, $mac ) if have_capability( 'KLUDGEFREE' ); + $source_match = match_source_net( $inet, $restriction, $mac ) if $globals{KLUDGEFREE}; for my $dnet ( mysplit $dnets ) { - $source_match = match_source_net( $inet, $restriction, $mac ) unless have_capability( 'KLUDGEFREE' ); + $source_match = match_source_net( $inet, $restriction, $mac ) unless $globals{KLUDGEFREE}; my $dest_match = match_dest_net( $dnet ); my $matches = join( '', $rule, $source_match, $dest_match, $onet ); diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index cb10f37d6..701e5c933 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -432,6 +432,7 @@ sub initialize( $ ) { LOGPARMS => '', TC_SCRIPT => '', EXPORT => 0, + KLUDGEFREE => '', STATEMATCH => '-m state --state', UNTRACKED => 0, VERSION => "4.4.22-Beta1", @@ -2731,9 +2732,11 @@ sub have_capability( $ ) { my $capability = shift; our %detect_capability; - $capabilities{ $capability } = detect_capability( $capability ) unless defined $capabilities{ $capability }; + my $setting = $capabilities{ $capability }; - $capabilities{ $capability }; + $setting = $capabilities{ $capability } = detect_capability( $capability ) unless defined $setting; + + $setting; } # @@ -2758,6 +2761,7 @@ sub determine_capabilities() { qt1( "$iptables -A $sillyname -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") || qt1( "$iptables -A $sillyname -m state --state ESTABLISHED,RELATED -j ACCEPT");; + $globals{KLUDGEFREE} = $capabilities{KLUDGEFREE} = detect_capability 'KLUDGEFREE'; unless ( $config{ LOAD_HELPERS_ONLY } ) { # @@ -2776,24 +2780,17 @@ sub determine_capabilities() { $capabilities{OLD_CONNTRACK_MATCH} = ''; } - if ( $capabilities{ MULTIPORT } = detect_capability( 'MULTIPORT' ) ) { - $capabilities{KLUDGEFREE} = Kludgefree1; - } - + $capabilities{ MULTIPORT } = detect_capability( 'MULTIPORT' ); $capabilities{XMULTIPORT} = detect_capability( 'XMULTIPORT' ); $capabilities{POLICY_MATCH} = detect_capability( 'POLICY_MATCH' ); if ( $capabilities{PHYSDEV_MATCH} = detect_capability( 'PHYSDEV_MATCH' ) ) { $capabilities{PHYSDEV_BRIDGE} = detect_capability( 'PHYSDEV_BRIDGE' ); - $capabilities{KLUDGEFREE} ||= Kludgefree2; } else { $capabilities{PHYSDEV_BRIDGE} = ''; } - if ( $capabilities{IPRANGE_MATCH} = detect_capability( 'IPRANGE_MATCH' ) ) { - $capabilities{KLUDGEFREE} ||= Kludgefree3; - } - + $capabilities{IPRANGE_MATCH} = detect_capability( 'IPRANGE_MATCH' ); $capabilities{RECENT_MATCH} = detect_capability( 'RECENT_MATCH' ); $capabilities{OWNER_MATCH} = detect_capability( 'OWNER_MATCH' ); $capabilities{CONNMARK_MATCH} = detect_capability( 'CONNMARK_MATCH' ); @@ -3148,6 +3145,7 @@ sub read_capabilities() { $capabilities{$_} = '' unless defined $capabilities{$_}; } + $globals{KLUDGEFREE} = $capabilities{KLUDGEFREE}; } # diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index a90b2538a..2660e2a6a 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -890,7 +890,7 @@ sub process_interface( $$ ) { if ( supplied $port ) { fatal_error qq("Virtual" interfaces are not supported -- see http://www.shorewall.net/Shorewall_and_Aliased_Interfaces.html) if $port =~ /^\d+$/; require_capability( 'PHYSDEV_MATCH', 'Bridge Ports', ''); - fatal_error "Your iptables is not recent enough to support bridge ports" unless have_capability( 'KLUDGEFREE' ); + fatal_error "Your iptables is not recent enough to support bridge ports" unless $globals{KLUDGEFREE}; fatal_error "Invalid Interface Name ($interface:$port)" unless $port =~ /^[\w.@%-]+\+?$/; fatal_error "Duplicate Interface ($port)" if $interfaces{$port};