Make 'KLUDGEFREE' a global to make it faster to test.

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2011-07-21 12:57:20 -07:00
parent 4eeb233d95
commit 0791ea6698
3 changed files with 37 additions and 35 deletions

View File

@ -619,15 +619,17 @@ sub set_rule_option( $$$ ) {
if ( exists $ruleref->{$option} ) { if ( exists $ruleref->{$option} ) {
assert( defined $ruleref->{$option} ); assert( defined $ruleref->{$option} );
if ( $special != EXCLUSIVE ) {
if ( $special == UNIQUE ) { if ( $special == MATCH ) {
assert(0); assert( $globals{KLUDGEFREE} );
} elsif ( $special == MATCH ) { $ruleref->{$option} = [ $ruleref->{$option} ] unless reftype $ruleref->{$option};
$ruleref->{$option} = [ $ruleref->{$option} ] unless reftype $ruleref->{$option}; push @{$ruleref->{$option}}, ( reftype $value ? @$value : $value );
push @{$ruleref->{$option}}, ( reftype $value ? @$value : $value ); } elsif ( $special == EXCLUSIVE ) {
} else { $ruleref->{$option} .= ",$value";
assert(0); } elsif ( $special == UNIQUE ) {
} fatal_error "Multiple $option settings in one rule is prohibited";
} else {
assert(0);
} }
} else { } else {
$ruleref->{$option} = $value; $ruleref->{$option} = $value;
@ -654,9 +656,9 @@ sub transform_rule( $ ) {
$invert = '!' if $1; $invert = '!' if $1;
my $opt = $option = $2; 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 { } else {
fatal_error "Unrecognized iptables command string ($input)"; fatal_error "Unrecognized iptables option string ($input)";
} }
if ( $option eq 'j' or $option eq 'g' ) { if ( $option eq 'j' or $option eq 'g' ) {
@ -2519,7 +2521,7 @@ sub optimize_level4( $$ ) {
# #
# Not so easy -- the rule contains matches # 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 # This case requires a new rule merging algorithm. Ignore this chain for
# now. # now.
@ -3452,7 +3454,7 @@ sub iprange_match() {
require_capability( 'IPRANGE_MATCH' , 'Address Ranges' , '' ); require_capability( 'IPRANGE_MATCH' , 'Address Ranges' , '' );
unless ( $iprangematch ) { unless ( $iprangematch ) {
$match = '-m iprange '; $match = '-m iprange ';
$iprangematch = 1 unless have_capability( 'KLUDGEFREE' ); $iprangematch = 1 unless $globals{KLUDGEFREE};
} }
$match; $match;
@ -3576,7 +3578,7 @@ sub match_source_net( $;$\$ ) {
my $result = ''; my $result = '';
my @sets = mysplit $1, 1; 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 ) { for $net ( @sets ) {
fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/;
@ -3612,7 +3614,7 @@ sub imatch_source_net( $;$\$ ) {
( $family == F_IPV6 && $net =~ /^(!?)(.*:.*)-(.*:.*)$/ ) ) { ( $family == F_IPV6 && $net =~ /^(!?)(.*:.*)-(.*:.*)$/ ) ) {
my ($addr1, $addr2) = ( $2, $3 ); my ($addr1, $addr2) = ( $2, $3 );
$net =~ s/!// if my $invert = $1 ? '! ' : ''; $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" ); return ( iprange => "${invert}--src-range $net" );
} }
@ -3630,7 +3632,7 @@ sub imatch_source_net( $;$\$ ) {
my @result = (); my @result = ();
my @sets = mysplit $1, 1; 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 ) { for $net ( @sets ) {
fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/;
@ -3679,7 +3681,7 @@ sub match_dest_net( $ ) {
my $result = ''; my $result = '';
my @sets = mysplit $1, 1; 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 ) { for $net ( @sets ) {
fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/;
@ -3726,7 +3728,7 @@ sub imatch_dest_net( $ ) {
my @result; my @result;
my @sets = mysplit $1, 1; 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 ) { for $net ( @sets ) {
fatal_error "Expected ipset name ($net)" unless $net =~ /^(!?)(\+?)[a-zA-Z][-\w]*(\[.*\])?/; 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 # 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 '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 # Clear the exclusion bit
# #
@ -4844,10 +4848,10 @@ sub expand_rule( $$$$$$$$$$;$ )
my $cond = conditional_rule( $chainref, $inet ); 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 ) { 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 ); 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 ); 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 ) { 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 $dest_match = match_dest_net( $dnet );
my $matches = join( '', $rule, $source_match, $dest_match, $onet ); my $matches = join( '', $rule, $source_match, $dest_match, $onet );

View File

@ -432,6 +432,7 @@ sub initialize( $ ) {
LOGPARMS => '', LOGPARMS => '',
TC_SCRIPT => '', TC_SCRIPT => '',
EXPORT => 0, EXPORT => 0,
KLUDGEFREE => '',
STATEMATCH => '-m state --state', STATEMATCH => '-m state --state',
UNTRACKED => 0, UNTRACKED => 0,
VERSION => "4.4.22-Beta1", VERSION => "4.4.22-Beta1",
@ -2731,9 +2732,11 @@ sub have_capability( $ ) {
my $capability = shift; my $capability = shift;
our %detect_capability; 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 conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT") ||
qt1( "$iptables -A $sillyname -m state --state 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 } ) { unless ( $config{ LOAD_HELPERS_ONLY } ) {
# #
@ -2776,24 +2780,17 @@ sub determine_capabilities() {
$capabilities{OLD_CONNTRACK_MATCH} = ''; $capabilities{OLD_CONNTRACK_MATCH} = '';
} }
if ( $capabilities{ MULTIPORT } = detect_capability( 'MULTIPORT' ) ) { $capabilities{ MULTIPORT } = detect_capability( 'MULTIPORT' );
$capabilities{KLUDGEFREE} = Kludgefree1;
}
$capabilities{XMULTIPORT} = detect_capability( 'XMULTIPORT' ); $capabilities{XMULTIPORT} = detect_capability( 'XMULTIPORT' );
$capabilities{POLICY_MATCH} = detect_capability( 'POLICY_MATCH' ); $capabilities{POLICY_MATCH} = detect_capability( 'POLICY_MATCH' );
if ( $capabilities{PHYSDEV_MATCH} = detect_capability( 'PHYSDEV_MATCH' ) ) { if ( $capabilities{PHYSDEV_MATCH} = detect_capability( 'PHYSDEV_MATCH' ) ) {
$capabilities{PHYSDEV_BRIDGE} = detect_capability( 'PHYSDEV_BRIDGE' ); $capabilities{PHYSDEV_BRIDGE} = detect_capability( 'PHYSDEV_BRIDGE' );
$capabilities{KLUDGEFREE} ||= Kludgefree2;
} else { } else {
$capabilities{PHYSDEV_BRIDGE} = ''; $capabilities{PHYSDEV_BRIDGE} = '';
} }
if ( $capabilities{IPRANGE_MATCH} = detect_capability( 'IPRANGE_MATCH' ) ) { $capabilities{IPRANGE_MATCH} = detect_capability( 'IPRANGE_MATCH' );
$capabilities{KLUDGEFREE} ||= Kludgefree3;
}
$capabilities{RECENT_MATCH} = detect_capability( 'RECENT_MATCH' ); $capabilities{RECENT_MATCH} = detect_capability( 'RECENT_MATCH' );
$capabilities{OWNER_MATCH} = detect_capability( 'OWNER_MATCH' ); $capabilities{OWNER_MATCH} = detect_capability( 'OWNER_MATCH' );
$capabilities{CONNMARK_MATCH} = detect_capability( 'CONNMARK_MATCH' ); $capabilities{CONNMARK_MATCH} = detect_capability( 'CONNMARK_MATCH' );
@ -3148,6 +3145,7 @@ sub read_capabilities() {
$capabilities{$_} = '' unless defined $capabilities{$_}; $capabilities{$_} = '' unless defined $capabilities{$_};
} }
$globals{KLUDGEFREE} = $capabilities{KLUDGEFREE};
} }
# #

View File

@ -890,7 +890,7 @@ sub process_interface( $$ ) {
if ( supplied $port ) { if ( supplied $port ) {
fatal_error qq("Virtual" interfaces are not supported -- see http://www.shorewall.net/Shorewall_and_Aliased_Interfaces.html) if $port =~ /^\d+$/; 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', ''); 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 "Invalid Interface Name ($interface:$port)" unless $port =~ /^[\w.@%-]+\+?$/;
fatal_error "Duplicate Interface ($port)" if $interfaces{$port}; fatal_error "Duplicate Interface ($port)" if $interfaces{$port};