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
|
||||
setup_zone_mss
|
||||
newexclusionchain
|
||||
newnonatchain
|
||||
source_exclusion
|
||||
dest_exclusion
|
||||
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
|
||||
ALL_RESTRICT => 12 # fw->fw rule - neither -i nor -o allowed
|
||||
};
|
||||
our $exclseq;
|
||||
our $iprangematch;
|
||||
our $chainseq;
|
||||
our $idiotcount;
|
||||
@ -335,11 +335,7 @@ sub initialize( $ ) {
|
||||
#
|
||||
$comment = '';
|
||||
#
|
||||
# Used to sequence 'exclusion' chains with names 'excl0', 'excl1', ...
|
||||
#
|
||||
$exclseq = 0;
|
||||
#
|
||||
# Used to sequence 'log' chains with names 'log0', 'log1', etc.
|
||||
# Used to sequence chains names.
|
||||
#
|
||||
$chainseq = 0;
|
||||
#
|
||||
@ -1261,7 +1257,7 @@ sub setup_zone_mss() {
|
||||
}
|
||||
|
||||
sub newexclusionchain() {
|
||||
my $seq = $exclseq++;
|
||||
my $seq = $chainseq++;
|
||||
"excl${seq}";
|
||||
}
|
||||
|
||||
@ -1270,6 +1266,11 @@ sub newlogchain() {
|
||||
"log${seq}";
|
||||
}
|
||||
|
||||
sub newnonatchain() {
|
||||
my $seq = $chainseq++;
|
||||
"nonat${seq}";
|
||||
}
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
sub expand_rule( $$$$$$$$$$ )
|
||||
sub expand_rule( $$$$$$$$$$;$ )
|
||||
{
|
||||
my ($chainref , # Chain
|
||||
$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)
|
||||
$loglevel , # Log level (and tag)
|
||||
$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 );
|
||||
@ -2756,28 +2758,42 @@ sub expand_rule( $$$$$$$$$$ )
|
||||
|
||||
if ( $loglevel ne '' ) {
|
||||
if ( $disposition ne 'LOG' ) {
|
||||
#
|
||||
# Create a chain that both logs and applies the target action
|
||||
#
|
||||
my $logchainref = new_chain $chainref->{table}, newlogchain;
|
||||
#
|
||||
# Jump to the log chain if all of the rule's conditions are met
|
||||
#
|
||||
add_jump( $chainref, $logchainref, $builtin_target{$disposition}, $predicates, 1 );
|
||||
#
|
||||
# Now add the log rule and target rule without predicates to the log chain.
|
||||
#
|
||||
log_rule_limit(
|
||||
$loglevel ,
|
||||
$chainref = $logchainref ,
|
||||
$chain ,
|
||||
$disposition ,
|
||||
'',
|
||||
$logtag,
|
||||
'add',
|
||||
'' );
|
||||
unless ( $logname ) {
|
||||
#
|
||||
# Create a chain that both logs and applies the target action
|
||||
#
|
||||
my $logchainref = new_chain $chainref->{table}, newlogchain;
|
||||
#
|
||||
# Jump to the log chain if all of the rule's conditions are met
|
||||
#
|
||||
add_jump( $chainref, $logchainref, $builtin_target{$disposition}, $predicates, 1 );
|
||||
#
|
||||
# Now add the log rule and target rule without predicates to the log chain.
|
||||
#
|
||||
log_rule_limit(
|
||||
$loglevel ,
|
||||
$chainref = $logchainref ,
|
||||
$chain ,
|
||||
$disposition ,
|
||||
'',
|
||||
$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 {
|
||||
#
|
||||
# The log rule must be added with predicates to the rule chain
|
||||
|
@ -1296,43 +1296,76 @@ sub process_rule1 ( $$$$$$$$$$$$$ ) {
|
||||
|
||||
my $nonat_chain;
|
||||
|
||||
my $chn;
|
||||
|
||||
if ( $sourceref->{type} == FIREWALL ) {
|
||||
$nonat_chain = $nat_table->{OUTPUT};
|
||||
} else {
|
||||
$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 $_;
|
||||
|
||||
if ( $nat_table->{$ichain} ) {
|
||||
#
|
||||
# Static NAT is defined on this interface
|
||||
#
|
||||
$chn = new_chain( 'nat', newexclusionchain ) unless $chn;
|
||||
add_jump $chn, $nat_table->{$ichain}, 0, "-i $_ ";
|
||||
$chn = new_chain( 'nat', newnonatchain ) unless $chn;
|
||||
add_jump $chn, $nat_table->{$ichain}, 0, @interfaces > 1 ? "-i $_ " : '';
|
||||
}
|
||||
}
|
||||
|
||||
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};
|
||||
} else {
|
||||
$tgt = 'ACCEPT';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
expand_rule( $nonat_chain ,
|
||||
PREROUTE_RESTRICT ,
|
||||
$rule ,
|
||||
$source ,
|
||||
$dest ,
|
||||
$origdest ,
|
||||
" -j $tgt ",
|
||||
"-j $tgt",
|
||||
$loglevel ,
|
||||
$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