mirror of
https://gitlab.com/shorewall/code.git
synced 2024-12-23 22:58:52 +01:00
Order matches in rules.
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
6950cd2576
commit
0da38cc38e
@ -513,7 +513,7 @@ our $mode;
|
||||
#
|
||||
# A reference to this rule is returned when we try to push a rule onto a 'complete' chain
|
||||
#
|
||||
our $dummyrule = { simple => 1, mode => CAT_MODE };
|
||||
our $dummyrule = { simple => 1, matches => [], mode => CAT_MODE };
|
||||
|
||||
#
|
||||
# Address Family
|
||||
@ -619,6 +619,7 @@ our %opttype = ( rule => CONTROL,
|
||||
mode => CONTROL,
|
||||
cmdlevel => CONTROL,
|
||||
simple => CONTROL,
|
||||
matches => CONTROL,
|
||||
|
||||
i => UNIQUE,
|
||||
s => UNIQUE,
|
||||
@ -634,6 +635,8 @@ our %opttype = ( rule => CONTROL,
|
||||
|
||||
policy => MATCH,
|
||||
state => EXCLUSIVE,
|
||||
'conntrack --ctstate' =>
|
||||
EXCLUSIVE,
|
||||
|
||||
conntrack => COMPLEX,
|
||||
|
||||
@ -831,12 +834,13 @@ sub set_rule_option( $$$ ) {
|
||||
}
|
||||
} else {
|
||||
$ruleref->{$option} = $value;
|
||||
push @{$ruleref->{matches}}, $option;
|
||||
}
|
||||
}
|
||||
|
||||
sub transform_rule( $;\$ ) {
|
||||
my ( $input, $completeref ) = @_;
|
||||
my $ruleref = { mode => CAT_MODE, target => '' };
|
||||
my $ruleref = { mode => CAT_MODE, matches => [], target => '' };
|
||||
my $simple = 1;
|
||||
my $target = '';
|
||||
my $jump = '';
|
||||
@ -950,11 +954,17 @@ sub format_option( $$ ) {
|
||||
$rule;
|
||||
}
|
||||
|
||||
sub debug() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub format_rule( $$;$ ) {
|
||||
my ( $chainref, $ruleref, $suppresshdr ) = @_;
|
||||
|
||||
return $ruleref->{cmd} if exists $ruleref->{cmd};
|
||||
|
||||
debug if $chainref->{name} eq 'drct-net';
|
||||
|
||||
my $rule = $suppresshdr ? '' : "-A $chainref->{name}";
|
||||
|
||||
for ( @unique_options ) {
|
||||
@ -971,10 +981,19 @@ sub format_rule( $$;$ ) {
|
||||
}
|
||||
}
|
||||
|
||||
$rule .= format_option( 'state', $ruleref->{state} ) if defined $ruleref->{state};
|
||||
$rule .= format_option( 'policy', $ruleref->{policy} ) if defined $ruleref->{policy};
|
||||
|
||||
$rule .= format_option( $_, $ruleref->{$_} ) for sort ( grep ! $opttype{$_}, keys %{$ruleref} );
|
||||
if ( defined ( my $state = $ruleref->{'conntrack --ctstate'} ) ) {
|
||||
$rule .= format_option( 'conntrack --ctstate' , $state );
|
||||
} elsif ( defined $ruleref->{state} ) {
|
||||
$rule .= format_option( 'state', $ruleref->{state} );
|
||||
}
|
||||
|
||||
my %done;
|
||||
|
||||
for ( grep ! $opttype{$_}, @{$ruleref->{matches}} ) {
|
||||
$rule .= format_option( $_, $ruleref->{$_} ) unless $done{$_}++;
|
||||
}
|
||||
|
||||
if ( $ruleref->{target} ) {
|
||||
$rule .= join( ' ', " -$ruleref->{jump}", $ruleref->{target} );
|
||||
@ -1041,6 +1060,12 @@ sub merge_rules( $$$ ) {
|
||||
set_rule_option ( $toref, 'state', $fromref->{state} ) if $fromref->{state};
|
||||
}
|
||||
|
||||
unless ( $toref->{'conntrack --ctstate'} ) {
|
||||
set_rule_option( $toref,
|
||||
'conntrack --ctstate',
|
||||
$fromref->{'conntrack --ctstate'} ) if $fromref->{'conntrack --ctstate'};
|
||||
}
|
||||
|
||||
set_rule_option( $toref, 'policy', $fromref->{policy} ) if exists $fromref->{policy};
|
||||
|
||||
unless ( $toref->{comment} ) {
|
||||
@ -1302,6 +1327,7 @@ sub push_matches {
|
||||
} else {
|
||||
$ruleref->{$option} = $value;
|
||||
$dont_optimize ||= $option =~ /^[piosd]$/ && $value =~ /^!/;
|
||||
push @{$ruleref->{matches}}, $option;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1313,7 +1339,7 @@ sub push_irule( $$$;@ ) {
|
||||
|
||||
( $target, my $targetopts ) = split ' ', $target, 2;
|
||||
|
||||
my $ruleref = {};
|
||||
my $ruleref = { matches => [] };
|
||||
|
||||
$ruleref->{mode} = ( $ruleref->{cmdlevel} = $chainref->{cmdlevel} ) ? CMD_MODE : CAT_MODE;
|
||||
|
||||
@ -1476,8 +1502,13 @@ sub clone_rule( $ ) {
|
||||
my $newruleref = {};
|
||||
|
||||
while ( my ( $key, $value ) = each %$oldruleref ) {
|
||||
if ( reftype $value ) {
|
||||
my @array = @$value;
|
||||
$newruleref->{$key} = \@array;
|
||||
} else {
|
||||
$newruleref->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$newruleref;
|
||||
}
|
||||
@ -3548,6 +3579,20 @@ sub combine_dports {
|
||||
$baseref->{'multiport'} = '--dports ' . join( ',' , @ports );
|
||||
}
|
||||
|
||||
my @matches = @{$baseref->{matches}};
|
||||
|
||||
$baseref->{matches} = [];
|
||||
|
||||
my $switched = 0;
|
||||
|
||||
for ( @matches ) {
|
||||
if ( $_ eq 'dport' || $_ eq 'sport' ) {
|
||||
push @{$baseref->{matches}}, 'multiport' unless $switched++;
|
||||
} else {
|
||||
push @{$baseref->{matches}}, $_;
|
||||
}
|
||||
}
|
||||
|
||||
$baseref->{comment} = $comment if $comment;
|
||||
|
||||
trace ( $chainref, 'R', $basenum, $baseref ) if $debug;
|
||||
|
@ -1965,12 +1965,14 @@ sub handle_stickiness( $ ) {
|
||||
$rule2 = clone_rule( $_ );
|
||||
|
||||
clear_rule_target( $rule2 );
|
||||
set_rule_option( $rule2, 'mark', "--mark 0/$mask -m recent --name $list --remove" );
|
||||
set_rule_option( $rule2, 'mark', "--mark 0\/$mask" );
|
||||
set_rule_option( $rule2, 'recent', "--name $list --remove" );
|
||||
} else {
|
||||
$rule1 = clone_rule( $_ );
|
||||
|
||||
clear_rule_target( $rule1 );
|
||||
set_rule_option( $rule1, 'mark', "--mark $mark\/$mask -m recent --name $list --set" );
|
||||
set_rule_option( $rule1, 'mark', "--mark $mark\/$mask" );
|
||||
set_rule_option( $rule1, 'recent', "--name $list --set" );
|
||||
|
||||
$rule2 = '';
|
||||
}
|
||||
@ -1990,32 +1992,22 @@ sub handle_stickiness( $ ) {
|
||||
|
||||
for my $chainref ( $stickoref, $setstickoref ) {
|
||||
if ( $chainref->{name} eq 'sticko' ) {
|
||||
$rule1 = {};
|
||||
|
||||
while ( my ( $key, $value ) = each %$_ ) {
|
||||
$rule1->{$key} = $value;
|
||||
}
|
||||
$rule1 = clone_rule $_;
|
||||
|
||||
set_rule_target( $rule1, 'MARK', "--set-mark $mark" );
|
||||
set_rule_option( $rule1, 'recent', " --name $list --rdest --update --seconds 300" );
|
||||
|
||||
$rule2 = {};
|
||||
|
||||
while ( my ( $key, $value ) = each %$_ ) {
|
||||
$rule2->{$key} = $value;
|
||||
}
|
||||
$rule2 = clone_rule $_;
|
||||
|
||||
clear_rule_target( $rule2 );
|
||||
set_rule_option ( $rule2, 'mark', "--mark 0\/$mask -m recent --name $list --rdest --remove" );
|
||||
set_rule_option ( $rule2, 'mark', "--mark 0\/$mask" );
|
||||
set_rule_option ( $rule2, 'recent', "--name $list --rdest --remove" );
|
||||
} else {
|
||||
$rule1 = {};
|
||||
|
||||
while ( my ( $key, $value ) = each %$_ ) {
|
||||
$rule1->{$key} = $value;
|
||||
}
|
||||
$rule1 = clone_rule $_;
|
||||
|
||||
clear_rule_target( $rule1 );
|
||||
set_rule_option ( $rule1, 'mark', "--mark $mark -m recent --name $list --rdest --set" );
|
||||
set_rule_option ( $rule1, 'mark', "--mark $mark" );
|
||||
set_rule_option ( $rule1, 'recent', "--name $list --rdest --set" );
|
||||
|
||||
$rule2 = '';
|
||||
}
|
||||
|
@ -2082,6 +2082,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
||||
my $normalized_action;
|
||||
my $blacklist = ( $section == BLACKLIST_SECTION );
|
||||
my $matches = $rule;
|
||||
my $raw_matches = '';
|
||||
|
||||
if ( $inchain = defined $chainref ) {
|
||||
( $inaction, undef, undef, undef ) = split /:/, $normalized_action = $chainref->{action}, 4 if $chainref->{action};
|
||||
@ -2093,13 +2094,13 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
||||
my $inline_matches = get_inline_matches;
|
||||
|
||||
if ( $inline_matches =~ /^(.*\s+)-j\s+(.+)$/ ) {
|
||||
$matches .= $1;
|
||||
$raw_matches .= $1;
|
||||
$action = $2;
|
||||
my ( $target ) = split ' ', $action;
|
||||
fatal_error "Unknown jump target ($action)" unless $targets{$target};
|
||||
fatal_error "INLINE may not have a parameter when '-j' is specified in the free-form area" if $param ne '';
|
||||
} else {
|
||||
$matches .= "$inline_matches ";
|
||||
$raw_matches .= "$inline_matches ";
|
||||
|
||||
if ( $param eq '' ) {
|
||||
$action = $loglevel ? 'LOG' : '';
|
||||
@ -2109,8 +2110,6 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
||||
$param = '' unless defined $param;
|
||||
}
|
||||
}
|
||||
|
||||
$rule = $matches;
|
||||
}
|
||||
#
|
||||
# Determine the validity of the action
|
||||
@ -2133,7 +2132,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
||||
|
||||
my $generated = process_macro( $basictarget,
|
||||
$chainref,
|
||||
$rule,
|
||||
$rule . $raw_matches,
|
||||
$target,
|
||||
$current_param,
|
||||
$source,
|
||||
@ -2477,7 +2476,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
||||
|
||||
my $generated = process_inline( $basictarget,
|
||||
$chainref,
|
||||
$rule,
|
||||
$rule . $raw_matches,
|
||||
$loglevel,
|
||||
$target,
|
||||
$current_param,
|
||||
@ -2519,6 +2518,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
||||
do_time( $time ) ,
|
||||
do_headers( $headers ) ,
|
||||
do_condition( $condition , $chain ) ,
|
||||
$raw_matches ,
|
||||
);
|
||||
} elsif ( $section & ( ESTABLISHED_SECTION | INVALID_SECTION | RELATED_SECTION | UNTRACKED_SECTION ) ) {
|
||||
$rule .= join( '',
|
||||
@ -2531,6 +2531,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
||||
do_headers( $headers ) ,
|
||||
do_condition( $condition , $chain ) ,
|
||||
do_helper( $helper ) ,
|
||||
$raw_matches ,
|
||||
);
|
||||
} else {
|
||||
$rule .= join( '',
|
||||
@ -2542,6 +2543,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
||||
do_time( $time ) ,
|
||||
do_headers( $headers ) ,
|
||||
do_condition( $condition , $chain ) ,
|
||||
$raw_matches ,
|
||||
);
|
||||
}
|
||||
|
||||
@ -2615,7 +2617,8 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
||||
do_ratelimit( $ratelimit, 'ACCEPT' ),
|
||||
do_user $user,
|
||||
do_test( $mark , $globals{TC_MASK} ),
|
||||
do_condition( $condition , $chain )
|
||||
do_condition( $condition , $chain ),
|
||||
$raw_matches,
|
||||
);
|
||||
$loglevel = '';
|
||||
$action = 'ACCEPT';
|
||||
|
Loading…
Reference in New Issue
Block a user