diff --git a/Shorewall/Perl/Shorewall/Actions.pm b/Shorewall/Perl/Shorewall/Actions.pm index e9b26c81c..32d2373c2 100644 --- a/Shorewall/Perl/Shorewall/Actions.pm +++ b/Shorewall/Perl/Shorewall/Actions.pm @@ -39,19 +39,16 @@ our @EXPORT = qw( get_target_param normalize_action normalize_action_name - createactionchain + use_action + process_actions2 + %actions - %usedactions %logactionchains %default_actions ); our @EXPORT_OK = qw( initialize ); our $VERSION = '4.4_16'; -# -# Used Actions. Each action that is actually used has an entry with value 1. -# -our %usedactions; # # Default actions for each policy. # @@ -86,7 +83,6 @@ our $family; sub initialize( $ ) { $family = shift; - %usedactions = (); %default_actions = ( DROP => 'none' , REJECT => 'none' , ACCEPT => 'none' , @@ -149,11 +145,15 @@ sub normalize_action( $$$ ) { $tag = '' unless defined $tag; $param = '' unless defined $param; - ( $action, $level, $tag, $param ); + join( ':', $action, $level, $tag, $param ); } -sub normalize_action_name( $$$ ) { - join (':', &normalize_action( @_ ) ); +sub normalize_action_name( $ ) { + my $target = shift; + my ( $action, $loglevel) = split_action $target; + + normalize_action( $action, $loglevel, '' ); + } # @@ -261,4 +261,62 @@ sub createactionchain( $ ) { } } +# +# Mark an action as used and create its chain. Returns one if the chain was +# created on this call or 0 otherwise. +# +sub use_action( $ ) { + my $normalized = shift; + + if ( $logactionchains{$normalized} ) { + 0; + } else { + createactionchain $normalized; + } +} + +sub merge_action_levels( $$ ) { + my $superior = shift; + my $subordinate = shift; + + my ( $unused, $suplevel, $suptag, $supparam ) = split /:/, $superior; + my ( $action, $sublevel, $subtag, $subparam ) = split /:/, $subordinate; + + assert defined $supparam; + + if ( $suplevel =~ /!$/ ) { + ( $sublevel, $subtag ) = ( $suplevel, $subtag ); + } else { + $sublevel = 'none' unless defined $sublevel && $sublevel ne ''; + if ( $sublevel =~ /^none~/ ) { + $subtag = ''; + } else { + $subtag = '' unless defined $subtag; + } + } + + $subparam = $supparam unless defined $subparam && $subparam ne ''; + + join ':', $action, $sublevel, $subtag, $subparam; +} + +sub process_actions2 () { + progress_message2 'Generating Transitive Closure of Used-action List...'; + + my $changed = 1; + + while ( $changed ) { + $changed = 0; + for my $target (keys %logactionchains) { + my ( $action, $level, $tag, $param ) = split ':', $target; + my $actionref = $actions{$action}; + assert( $actionref ); + for my $action1 ( keys %{$actionref->{requires}} ) { + my $action2 = merge_action_levels( $target, $action1 ); + $changed = 1 if use_action( $action2 ); + } + } + } +} + 1; diff --git a/Shorewall/Perl/Shorewall/Policy.pm b/Shorewall/Perl/Shorewall/Policy.pm index 9008547ba..3273eb4f5 100644 --- a/Shorewall/Perl/Shorewall/Policy.pm +++ b/Shorewall/Perl/Shorewall/Policy.pm @@ -177,11 +177,7 @@ sub process_a_policy() { my $defaulttype = $targets{$default} || 0; if ( $defaulttype & ACTION ) { - my $normalized = "$default:none::"; - unless ( $usedactions{$normalized} ) { - $usedactions{$normalized} = 1; - createactionchain $normalized; - } + use_action( normalize_action_name $default ); } else { fatal_error "Unknown Default Action ($default)"; } @@ -322,12 +318,7 @@ sub validate_policy() fatal_error "Default Action $option=$action not found"; } - my $normalized = "$action:none::"; - - unless ( $usedactions{$normalized} ) { - $usedactions{$normalized} = 1; - createactionchain $normalized; - } + use_action( normalize_action_name $action ); $default_actions{$map{$option}} = $action; } diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index ce116540f..d13706466 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -38,7 +38,6 @@ use strict; our @ISA = qw(Exporter); our @EXPORT = qw( process_actions1 - process_actions2 process_actions3 process_rules @@ -267,8 +266,9 @@ sub find_logactionchain( $ ) { # %n is used where the name is truncated on the right where necessary to ensure that the total # length of the chain name does not exceed 30 characters. # -# The second phase (process_actions2) occurs after the rules file is scanned. The transitive closure of -# %usedactions is generated; again, as new actions are merged into the hash, their action chains are created. +# The second phase (process_actions2 -- see Actions.pm) occurs after the rules file is scanned. The transitive +# closure of %usedactions is generated; again, as new actions are merged into the hash, their action chains +# are created. # # The final phase (process_actions3) traverses the keys of %usedactions populating each chain appropriately # by reading the related action definition file and creating rules. Note that a given action definition file is @@ -349,54 +349,6 @@ sub process_actions1() { } } -sub merge_action_levels( $$ ) { - my $superior = shift; - my $subordinate = shift; - - my ( $unused, $suplevel, $suptag, $supparam ) = split /:/, $superior; - my ( $action, $sublevel, $subtag, $subparam ) = split /:/, $subordinate; - - assert defined $supparam; - - if ( $suplevel =~ /!$/ ) { - ( $sublevel, $subtag ) = ( $suplevel, $subtag ); - } else { - $sublevel = 'none' unless defined $sublevel && $sublevel ne ''; - if ( $sublevel =~ /^none~/ ) { - $subtag = ''; - } else { - $subtag = '' unless defined $subtag; - } - } - - $subparam = $supparam unless defined $subparam && $subparam ne ''; - - join ':', $action, $sublevel, $subtag, $subparam; -} - -sub process_actions2 () { - progress_message2 'Generating Transitive Closure of Used-action List...'; - - my $changed = 1; - - while ( $changed ) { - $changed = 0; - for my $target (keys %usedactions) { - my ( $action, $level, $tag, $param ) = split ':', $target; - my $actionref = $actions{$action}; - assert( $actionref ); - for my $action1 ( keys %{$actionref->{requires}} ) { - my $action2 = merge_action_levels $target, $action1; - unless ( $usedactions{ $action2 } ) { - $usedactions{ $action2 } = 1; - createactionchain $action2; - $changed = 1; - } - } - } - } -} - # # Generate chain for non-builtin action invocation # @@ -601,8 +553,7 @@ sub process_actions3 () { 'forwardUPnP' => \&forwardUPnP, 'Limit' => \&Limit, ); - for my $wholeaction ( keys %usedactions ) { - my $chainref = find_logactionchain $wholeaction; + while ( my ( $wholeaction, $chainref ) = each %logactionchains ) { my ( $action, $level, $tag, $param ) = split /:/, $wholeaction; if ( $targets{$action} & BUILTIN ) { @@ -834,14 +785,12 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) { # Handle actions # if ( $actiontype & ACTION ) { - $normalized_target = normalize_action_name( $basictarget, $loglevel, $param ); + $normalized_target = normalize_action( $basictarget, $loglevel, $param ); if ( $inaction1 ) { add_requiredby( $target , $inaction1 ); } else { - unless ( $usedactions{$normalized_target} ) { - $usedactions{$normalized_target} = 1; - my $ref = createactionchain $normalized_target; + if ( my $ref = use_action( $normalized_target ) ) { new_nat_chain $ref->{name} if $actiontype & ( NATRULE | NONAT ); } }