forked from extern/shorewall_code
Add optimizations in basic chain handling
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@8122 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
e75be13ff4
commit
2a2a7530c2
@ -76,10 +76,16 @@ our %EXPORT_TAGS = (
|
|||||||
chain_base
|
chain_base
|
||||||
forward_chain
|
forward_chain
|
||||||
zone_forward_chain
|
zone_forward_chain
|
||||||
|
use_interface_forward_chain
|
||||||
|
interface_forward_chain
|
||||||
input_chain
|
input_chain
|
||||||
zone_input_chain
|
zone_input_chain
|
||||||
|
use_interface_input_chain
|
||||||
|
interface_input_chain
|
||||||
output_chain
|
output_chain
|
||||||
zone_output_chain
|
zone_output_chain
|
||||||
|
use_output_chain
|
||||||
|
interface_output_chain
|
||||||
masq_chain
|
masq_chain
|
||||||
syn_flood_chain
|
syn_flood_chain
|
||||||
mac_chain
|
mac_chain
|
||||||
@ -520,6 +526,32 @@ sub zone_forward_chain($) {
|
|||||||
chain_base($_[0]) . '_frwd';
|
chain_base($_[0]) . '_frwd';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns true if we're to use the interface's forward chain
|
||||||
|
#
|
||||||
|
sub use_interface_forward_chain($) {
|
||||||
|
my $interface = $_[0];
|
||||||
|
my $chainref = $filter_table->{forward_chain($interface)};
|
||||||
|
my $interfaceref = find_interface($interface);
|
||||||
|
#
|
||||||
|
# We must use the interfaces's chain if it is referenced (has rules in it) or if the interface is associated with multiple zone nets
|
||||||
|
#
|
||||||
|
$interfaceref->{nets} != 1 || $chainref->{referenced};
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns a reference to the forward chain for an interface
|
||||||
|
#
|
||||||
|
sub interface_forward_chain($) {
|
||||||
|
my $interface = $_[0];
|
||||||
|
my $chainref = $filter_table->{forward_chain($interface)};
|
||||||
|
my $interfaceref = find_interface($interface);
|
||||||
|
#
|
||||||
|
# We must use the interfaces's chain if it is referenced (has rules in it) or if the interface is associated with multiple zone nets
|
||||||
|
#
|
||||||
|
$interfaceref->{nets} != 1 || $chainref->{referenced} ? $chainref : $filter_table->{zone_forward_chain $interfaceref->{zone}};
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Input Chain for an interface
|
# Input Chain for an interface
|
||||||
#
|
#
|
||||||
@ -535,6 +567,48 @@ sub zone_input_chain($) {
|
|||||||
chain_base($_[0]) . '_input';
|
chain_base($_[0]) . '_input';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns true if we're to use the interface's input chain
|
||||||
|
#
|
||||||
|
sub use_interface_input_chain($) {
|
||||||
|
my $interface = $_[0];
|
||||||
|
my $chainref = $filter_table->{input_chain($interface)};
|
||||||
|
my $interfaceref = find_interface($interface);
|
||||||
|
#
|
||||||
|
# We must use the interfaces's chain if it is referenced (has rules in it) or if the interface is associated with multiple zone nets
|
||||||
|
#
|
||||||
|
return 1 if $interfaceref->{nets} != 1 || $chainref->{referenced};
|
||||||
|
|
||||||
|
my $chainref1 = $filter_table->{zone_input_chain $interfaceref->{zone}};
|
||||||
|
|
||||||
|
return 1 if $chainref1;
|
||||||
|
|
||||||
|
$chainref1 = $filter_table->{join( '' , $interfaceref->{zone} , '2' , firewall_zone )};
|
||||||
|
|
||||||
|
! $chainref1->{referenced};
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns a reference to the input chain for the passed interface
|
||||||
|
#
|
||||||
|
sub interface_input_chain($) {
|
||||||
|
my $interface = $_[0];
|
||||||
|
my $chainref = $filter_table->{input_chain($interface)};
|
||||||
|
my $interfaceref = find_interface($interface);
|
||||||
|
#
|
||||||
|
# We must use the interfaces's chain if it is referenced (has rules in it) or if the interface is associated with multiple zone nets
|
||||||
|
#
|
||||||
|
return $chainref if $interfaceref->{nets} != 1 || $chainref->{referenced};
|
||||||
|
|
||||||
|
my $chainref1 = $filter_table->{zone_input_chain $interfaceref->{zone}};
|
||||||
|
|
||||||
|
return $chainref1 if $chainref1;
|
||||||
|
|
||||||
|
$chainref1 = $filter_table->{join( '', $interfaceref->{zone} , '2', firewall_zone )};
|
||||||
|
|
||||||
|
$chainref1->{referenced} ? $chainref1 : $chainref;
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Output Chain for an interface
|
# Output Chain for an interface
|
||||||
#
|
#
|
||||||
@ -551,6 +625,48 @@ sub zone_output_chain($) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
|
# Returns true if we're to use the interface's output chain
|
||||||
|
#
|
||||||
|
sub use_output_chain($) {
|
||||||
|
my $interface = $_[0];
|
||||||
|
my $chainref = $filter_table->{output_chain($interface)};
|
||||||
|
my $interfaceref = find_interface($interface);
|
||||||
|
#
|
||||||
|
# We must use the interfaces's chain if it is referenced (has rules in it) or if the interface is associated with multiple zone nets
|
||||||
|
#
|
||||||
|
return 1 if $interfaceref->{nets} != 1 || $chainref->{referenced};
|
||||||
|
|
||||||
|
my $chainref1 = $filter_table->{zone_output_chain $interfaceref->{zone}};
|
||||||
|
|
||||||
|
return 1 if $chainref1;
|
||||||
|
|
||||||
|
$chainref1 = $filter_table->{join( '', firewall_zone , '2', $interfaceref->{zone} )};
|
||||||
|
|
||||||
|
! $chainref1->{referenced};
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Returns a reference to the output chain for a zone
|
||||||
|
#
|
||||||
|
sub interface_output_chain($) {
|
||||||
|
my $interface = $_[0];
|
||||||
|
my $chainref = $filter_table->{output_chain($interface)};
|
||||||
|
my $interfaceref = find_interface($interface);
|
||||||
|
#
|
||||||
|
# We must use the interfaces's chain if it is referenced (has rules in it) or if the interface is associated with multiple zone nets
|
||||||
|
#
|
||||||
|
return $chainref if $interfaceref->{nets} != 1 || $chainref->{referenced};
|
||||||
|
|
||||||
|
my $chainref1 = $filter_table->{zone_output_chain $interfaceref->{zone}};
|
||||||
|
|
||||||
|
return $chainref1 if $chainref1;
|
||||||
|
|
||||||
|
$chainref1 = $filter_table->{join( '', firewall_zone , '2', $interfaceref->{zone} )};
|
||||||
|
|
||||||
|
$chainref1->{referenced} ? $chainref1 : $chainref;
|
||||||
|
}
|
||||||
|
|
||||||
|
##
|
||||||
# Masquerade Chain for an interface
|
# Masquerade Chain for an interface
|
||||||
#
|
#
|
||||||
sub masq_chain($)
|
sub masq_chain($)
|
||||||
|
@ -503,8 +503,8 @@ sub add_common_rules() {
|
|||||||
add_rule_pair new_standard_chain( 'logreject' ), ' ' , 'reject' , $level ;
|
add_rule_pair new_standard_chain( 'logreject' ), ' ' , 'reject' , $level ;
|
||||||
|
|
||||||
for $interface ( all_interfaces ) {
|
for $interface ( all_interfaces ) {
|
||||||
new_standard_chain( $_ ) for first_chains( $interface );
|
ensure_chain( 'filter', $_ ) for first_chains( $interface );
|
||||||
new_standard_chain output_chain( $interface );
|
ensure_chain( 'filter', output_chain( $interface ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
run_user_exit1 'initdone';
|
run_user_exit1 'initdone';
|
||||||
@ -1534,14 +1534,16 @@ sub generate_matrix() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for my $interface ( keys %$source_ref ) {
|
for my $interface ( keys %$source_ref ) {
|
||||||
my $arrayref = $source_ref->{$interface};
|
if ( use_interface_forward_chain( $interface ) ) {
|
||||||
for my $hostref ( @{$arrayref} ) {
|
my $arrayref = $source_ref->{$interface};
|
||||||
my $ipsec_match = match_ipsec_in $zone , $hostref;
|
for my $hostref ( @{$arrayref} ) {
|
||||||
for my $net ( @{$hostref->{hosts}} ) {
|
my $ipsec_match = match_ipsec_in $zone , $hostref;
|
||||||
add_rule(
|
for my $net ( @{$hostref->{hosts}} ) {
|
||||||
$filter_table->{forward_chain $interface} ,
|
add_rule(
|
||||||
join( '', match_source_net( $net ), $ipsec_match, "-j $frwd_ref->{name}" )
|
$filter_table->{forward_chain $interface} ,
|
||||||
);
|
join( '', match_source_net( $net ), $ipsec_match, "-j $frwd_ref->{name}" )
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1621,20 +1623,22 @@ sub generate_matrix() {
|
|||||||
|
|
||||||
if ( $chain1 ) {
|
if ( $chain1 ) {
|
||||||
my $nextchain;
|
my $nextchain;
|
||||||
my $outputref = $filter_table->{output_chain $interface};
|
my $outputref = interface_output_chain $interface;
|
||||||
|
|
||||||
if ( @$exclusions ) {
|
if ( use_output_chain $interface ) {
|
||||||
my $output = zone_output_chain $zone;
|
if ( @$exclusions ) {
|
||||||
add_rule $outputref , join( '', $dest, $ipsec_out_match, "-j $output" );
|
my $output = zone_output_chain $zone;
|
||||||
add_rule $filter_table->{$output} , "-j $chain1";
|
add_rule $outputref , join( '', $dest, $ipsec_out_match, "-j $output" );
|
||||||
$nextchain = $output;
|
add_rule $filter_table->{$output} , "-j $chain1";
|
||||||
} else {
|
$nextchain = $output;
|
||||||
add_rule $outputref , join( '', $dest, $ipsec_out_match, "-j $chain1" );
|
} else {
|
||||||
$nextchain = $chain1;
|
add_rule $outputref , join( '', $dest, $ipsec_out_match, "-j $chain1" );
|
||||||
|
$nextchain = $chain1;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_rule( $outputref , join('', '-d 255.255.255.255 ' , $ipsec_out_match, "-j $nextchain" ) )
|
||||||
|
if $hostref->{options}{broadcast};
|
||||||
}
|
}
|
||||||
|
|
||||||
add_rule( $outputref , join('', match_source_net $net, '-d 255.255.255.255 ' . $ipsec_out_match, "-j $nextchain" ) )
|
|
||||||
if $hostref->{options}{broadcast};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next if $hostref->{options}{destonly};
|
next if $hostref->{options}{destonly};
|
||||||
@ -1654,18 +1658,22 @@ sub generate_matrix() {
|
|||||||
#
|
#
|
||||||
add_rule $preroutingref, join( '', match_source_dev( $interface), $source, $ipsec_in_match, '-j RETURN' ) if $nested;
|
add_rule $preroutingref, join( '', match_source_dev( $interface), $source, $ipsec_in_match, '-j RETURN' ) if $nested;
|
||||||
|
|
||||||
if ( $chain2 ) {
|
if ( use_interface_input_chain $interface ) {
|
||||||
if ( @$exclusions ) {
|
if ( $chain2 ) {
|
||||||
my $input = zone_input_chain $zone;
|
if ( @$exclusions ) {
|
||||||
add_rule $filter_table->{input_chain $interface}, join( '', $source, $ipsec_in_match, "-j $input" );
|
my $input = zone_input_chain $zone;
|
||||||
add_rule $filter_table->{ $input } , "-j $chain2";
|
add_rule $filter_table->{input_chain $interface}, join( '', $source, $ipsec_in_match, "-j $input" );
|
||||||
} else {
|
add_rule $filter_table->{ $input } , "-j $chain2";
|
||||||
add_rule $filter_table->{input_chain $interface}, join( '', $source, $ipsec_in_match, "-j $chain2" );
|
} else {
|
||||||
|
add_rule $filter_table->{input_chain $interface}, join( '', $source, $ipsec_in_match, "-j $chain2" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add_rule $filter_table->{forward_chain $interface} , join( '', $source, $ipsec_in_match. "-j $frwd_ref->{name}" )
|
if ( use_interface_forward_chain $interface ) {
|
||||||
if $hostref->{ipsec} ne 'ipsec';
|
add_rule $filter_table->{forward_chain $interface} , join( '', $source, $ipsec_in_match. "-j $frwd_ref->{name}" )
|
||||||
|
if $hostref->{ipsec} ne 'ipsec';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1831,9 +1839,9 @@ sub generate_matrix() {
|
|||||||
# Now add the jumps to the interface chains from FORWARD, INPUT, OUTPUT and POSTROUTING
|
# Now add the jumps to the interface chains from FORWARD, INPUT, OUTPUT and POSTROUTING
|
||||||
#
|
#
|
||||||
for my $interface ( @interfaces ) {
|
for my $interface ( @interfaces ) {
|
||||||
add_rule $filter_table->{FORWARD} , match_source_dev( $interface ) . "-j " . forward_chain $interface;
|
add_rule $filter_table->{FORWARD} , match_source_dev( $interface ) . "-j " . interface_forward_chain($interface)->{name};
|
||||||
add_rule $filter_table->{INPUT} , match_source_dev( $interface ) . "-j " . input_chain $interface;
|
add_rule $filter_table->{INPUT} , match_source_dev( $interface ) . "-j " . interface_input_chain($interface)->{name};
|
||||||
add_rule $filter_table->{OUTPUT} , "-o $interface -j " . output_chain $interface unless get_interface_option( $interface, 'port' );
|
add_rule $filter_table->{OUTPUT} , "-o $interface -j " . interface_output_chain($interface)->{name} unless get_interface_option( $interface, 'port' );
|
||||||
addnatjump 'POSTROUTING' , masq_chain( $interface ) , match_dest_dev( $interface );
|
addnatjump 'POSTROUTING' , masq_chain( $interface ) , match_dest_dev( $interface );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +125,7 @@ our %reservedName = ( all => 1,
|
|||||||
# ...
|
# ...
|
||||||
# }
|
# }
|
||||||
# zone => <zone name>
|
# zone => <zone name>
|
||||||
|
# nets => <number of nets in interface/hosts records referring to this interface>
|
||||||
# bridge => <bridge>
|
# bridge => <bridge>
|
||||||
# broadcasts => 'none', 'detect' or [ <addr1>, <addr2>, ... ]
|
# broadcasts => 'none', 'detect' or [ <addr1>, <addr2>, ... ]
|
||||||
# }
|
# }
|
||||||
@ -461,6 +462,8 @@ sub add_group_to_zone($$$$$)
|
|||||||
$ifacezone = '' unless defined $ifacezone;
|
$ifacezone = '' unless defined $ifacezone;
|
||||||
|
|
||||||
for my $host ( @$networks ) {
|
for my $host ( @$networks ) {
|
||||||
|
$interfaces{$interface}{nets}++;
|
||||||
|
|
||||||
fatal_error "Invalid Host List" unless defined $host and $host ne '';
|
fatal_error "Invalid Host List" unless defined $host and $host ne '';
|
||||||
|
|
||||||
if ( substr( $host, 0, 1 ) eq '!' ) {
|
if ( substr( $host, 0, 1 ) eq '!' ) {
|
||||||
@ -636,6 +639,7 @@ sub validate_interfaces_file( $ )
|
|||||||
}
|
}
|
||||||
|
|
||||||
$interfaces{$interface}{name} = $interface;
|
$interfaces{$interface}{name} = $interface;
|
||||||
|
$interfaces{$interface}{nets} = 0;
|
||||||
|
|
||||||
my $wildcard = 0;
|
my $wildcard = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user