forked from extern/shorewall_code
Optimize nonat rules in certain cases
This commit is contained in:
parent
58f0110ad3
commit
55045ace4b
@ -114,6 +114,7 @@ our %EXPORT_TAGS = (
|
|||||||
finish_section
|
finish_section
|
||||||
setup_zone_mss
|
setup_zone_mss
|
||||||
newexclusionchain
|
newexclusionchain
|
||||||
|
newnonatchain
|
||||||
source_exclusion
|
source_exclusion
|
||||||
dest_exclusion
|
dest_exclusion
|
||||||
clearrule
|
clearrule
|
||||||
@ -242,7 +243,6 @@ use constant { NO_RESTRICT => 0, # FORWARD chain rule - Both -i and
|
|||||||
POSTROUTE_RESTRICT => 16, # POSTROUTING chain rule - -i converted to -s <address list> using main routing table
|
POSTROUTE_RESTRICT => 16, # POSTROUTING chain rule - -i converted to -s <address list> using main routing table
|
||||||
ALL_RESTRICT => 12 # fw->fw rule - neither -i nor -o allowed
|
ALL_RESTRICT => 12 # fw->fw rule - neither -i nor -o allowed
|
||||||
};
|
};
|
||||||
our $exclseq;
|
|
||||||
our $iprangematch;
|
our $iprangematch;
|
||||||
our $chainseq;
|
our $chainseq;
|
||||||
our $idiotcount;
|
our $idiotcount;
|
||||||
@ -335,11 +335,7 @@ sub initialize( $ ) {
|
|||||||
#
|
#
|
||||||
$comment = '';
|
$comment = '';
|
||||||
#
|
#
|
||||||
# Used to sequence 'exclusion' chains with names 'excl0', 'excl1', ...
|
# Used to sequence chains names.
|
||||||
#
|
|
||||||
$exclseq = 0;
|
|
||||||
#
|
|
||||||
# Used to sequence 'log' chains with names 'log0', 'log1', etc.
|
|
||||||
#
|
#
|
||||||
$chainseq = 0;
|
$chainseq = 0;
|
||||||
#
|
#
|
||||||
@ -1261,7 +1257,7 @@ sub setup_zone_mss() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub newexclusionchain() {
|
sub newexclusionchain() {
|
||||||
my $seq = $exclseq++;
|
my $seq = $chainseq++;
|
||||||
"excl${seq}";
|
"excl${seq}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1270,6 +1266,11 @@ sub newlogchain() {
|
|||||||
"log${seq}";
|
"log${seq}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub newnonatchain() {
|
||||||
|
my $seq = $chainseq++;
|
||||||
|
"nonat${seq}";
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# If the passed exclusion array is non-empty then:
|
# If the passed exclusion array is non-empty then:
|
||||||
#
|
#
|
||||||
@ -2358,7 +2359,7 @@ sub set_global_variables( $ ) {
|
|||||||
#
|
#
|
||||||
# Returns the destination interface specified in the rule, if any.
|
# Returns the destination interface specified in the rule, if any.
|
||||||
#
|
#
|
||||||
sub expand_rule( $$$$$$$$$$ )
|
sub expand_rule( $$$$$$$$$$;$ )
|
||||||
{
|
{
|
||||||
my ($chainref , # Chain
|
my ($chainref , # Chain
|
||||||
$restriction, # Determines what to do with interface names in the SOURCE or DEST
|
$restriction, # Determines what to do with interface names in the SOURCE or DEST
|
||||||
@ -2369,7 +2370,8 @@ sub expand_rule( $$$$$$$$$$ )
|
|||||||
$target, # Target ('-j' part of the rule)
|
$target, # Target ('-j' part of the rule)
|
||||||
$loglevel , # Log level (and tag)
|
$loglevel , # Log level (and tag)
|
||||||
$disposition, # Primative part of the target (RETURN, ACCEPT, ...)
|
$disposition, # Primative part of the target (RETURN, ACCEPT, ...)
|
||||||
$exceptionrule # Caller's matches used in exclusion case
|
$exceptionrule,# Caller's matches used in exclusion case
|
||||||
|
$logname, # Name of chain to name in log messages
|
||||||
) = @_;
|
) = @_;
|
||||||
|
|
||||||
my ($iiface, $diface, $inets, $dnets, $iexcl, $dexcl, $onets , $oexcl, $trivialiexcl, $trivialdexcl );
|
my ($iiface, $diface, $inets, $dnets, $iexcl, $dexcl, $onets , $oexcl, $trivialiexcl, $trivialdexcl );
|
||||||
@ -2756,28 +2758,42 @@ sub expand_rule( $$$$$$$$$$ )
|
|||||||
|
|
||||||
if ( $loglevel ne '' ) {
|
if ( $loglevel ne '' ) {
|
||||||
if ( $disposition ne 'LOG' ) {
|
if ( $disposition ne 'LOG' ) {
|
||||||
#
|
unless ( $logname ) {
|
||||||
# Create a chain that both logs and applies the target action
|
#
|
||||||
#
|
# Create a chain that both logs and applies the target action
|
||||||
my $logchainref = new_chain $chainref->{table}, newlogchain;
|
#
|
||||||
#
|
my $logchainref = new_chain $chainref->{table}, newlogchain;
|
||||||
# Jump to the log chain if all of the rule's conditions are met
|
#
|
||||||
#
|
# Jump to the log chain if all of the rule's conditions are met
|
||||||
add_jump( $chainref, $logchainref, $builtin_target{$disposition}, $predicates, 1 );
|
#
|
||||||
#
|
add_jump( $chainref, $logchainref, $builtin_target{$disposition}, $predicates, 1 );
|
||||||
# Now add the log rule and target rule without predicates to the log chain.
|
#
|
||||||
#
|
# Now add the log rule and target rule without predicates to the log chain.
|
||||||
log_rule_limit(
|
#
|
||||||
$loglevel ,
|
log_rule_limit(
|
||||||
$chainref = $logchainref ,
|
$loglevel ,
|
||||||
$chain ,
|
$chainref = $logchainref ,
|
||||||
$disposition ,
|
$chain ,
|
||||||
'',
|
$disposition ,
|
||||||
$logtag,
|
'',
|
||||||
'add',
|
$logtag,
|
||||||
'' );
|
'add',
|
||||||
|
'' );
|
||||||
|
|
||||||
add_rule( $chainref, $target );
|
add_rule( $chainref, $target );
|
||||||
|
} else {
|
||||||
|
log_rule_limit(
|
||||||
|
$loglevel ,
|
||||||
|
$chainref ,
|
||||||
|
$logname ,
|
||||||
|
$disposition ,
|
||||||
|
'',
|
||||||
|
$logtag,
|
||||||
|
'add',
|
||||||
|
$predicates );
|
||||||
|
|
||||||
|
add_rule( $chainref, $predicates . $target, 1 );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
#
|
#
|
||||||
# The log rule must be added with predicates to the rule chain
|
# The log rule must be added with predicates to the rule chain
|
||||||
|
@ -1296,43 +1296,76 @@ sub process_rule1 ( $$$$$$$$$$$$$ ) {
|
|||||||
|
|
||||||
my $nonat_chain;
|
my $nonat_chain;
|
||||||
|
|
||||||
|
my $chn;
|
||||||
|
|
||||||
if ( $sourceref->{type} == FIREWALL ) {
|
if ( $sourceref->{type} == FIREWALL ) {
|
||||||
$nonat_chain = $nat_table->{OUTPUT};
|
$nonat_chain = $nat_table->{OUTPUT};
|
||||||
} else {
|
} else {
|
||||||
$nonat_chain = ensure_chain 'nat', dnat_chain $sourcezone;
|
$nonat_chain = ensure_chain 'nat', dnat_chain $sourcezone;
|
||||||
|
|
||||||
my $chn;
|
my @interfaces = keys %{zone_interfaces $sourcezone};
|
||||||
|
|
||||||
for ( keys %{zone_interfaces $sourcezone} ) {
|
for ( @interfaces ) {
|
||||||
my $ichain = input_chain $_;
|
my $ichain = input_chain $_;
|
||||||
|
|
||||||
if ( $nat_table->{$ichain} ) {
|
if ( $nat_table->{$ichain} ) {
|
||||||
#
|
#
|
||||||
# Static NAT is defined on this interface
|
# Static NAT is defined on this interface
|
||||||
#
|
#
|
||||||
$chn = new_chain( 'nat', newexclusionchain ) unless $chn;
|
$chn = new_chain( 'nat', newnonatchain ) unless $chn;
|
||||||
add_jump $chn, $nat_table->{$ichain}, 0, "-i $_ ";
|
add_jump $chn, $nat_table->{$ichain}, 0, @interfaces > 1 ? "-i $_ " : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $chn ) {
|
if ( $chn ) {
|
||||||
add_rule $chn, '-j ACCEPT';
|
#
|
||||||
|
# Call expand_rule() to correctly handle logging. Because
|
||||||
|
# the 'logname' argument is passed, expand_rule() will
|
||||||
|
# not create a separate logging chain but will rather emit
|
||||||
|
# any logging rule in-line.
|
||||||
|
#
|
||||||
|
expand_rule( $chn,
|
||||||
|
PREROUTE_RESTRICT,
|
||||||
|
'', # Rule
|
||||||
|
'', # Source
|
||||||
|
'', # Dest
|
||||||
|
'', # Original dest
|
||||||
|
'-j ACCEPT',
|
||||||
|
$loglevel,
|
||||||
|
$log_action,
|
||||||
|
'',
|
||||||
|
dnat_chain( $sourcezone ) );
|
||||||
|
$loglevel = '';
|
||||||
$tgt = $chn->{name};
|
$tgt = $chn->{name};
|
||||||
} else {
|
} else {
|
||||||
$tgt = 'ACCEPT';
|
$tgt = 'ACCEPT';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expand_rule( $nonat_chain ,
|
expand_rule( $nonat_chain ,
|
||||||
PREROUTE_RESTRICT ,
|
PREROUTE_RESTRICT ,
|
||||||
$rule ,
|
$rule ,
|
||||||
$source ,
|
$source ,
|
||||||
$dest ,
|
$dest ,
|
||||||
$origdest ,
|
$origdest ,
|
||||||
" -j $tgt ",
|
"-j $tgt",
|
||||||
$loglevel ,
|
$loglevel ,
|
||||||
$log_action ,
|
$log_action ,
|
||||||
'' );
|
''
|
||||||
|
);
|
||||||
|
#
|
||||||
|
# Possible optimization if the rule just generated was a simple jump to the nonat chain
|
||||||
|
#
|
||||||
|
if ( $chn && ${$nonat_chain->{rules}}[-1] eq "-A -j $tgt" ) {
|
||||||
|
#
|
||||||
|
# It was -- delete that rule
|
||||||
|
#
|
||||||
|
pop @{$nonat_chain->{rules}};
|
||||||
|
#
|
||||||
|
# And move the rules from the nonat chain to the zone dnat chain
|
||||||
|
#
|
||||||
|
move_rules ( $chn, $nonat_chain );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user