diff --git a/Shorewall/Perl/Shorewall/ARP.pm b/Shorewall/Perl/Shorewall/ARP.pm index 1fcad2c62..77f6457e3 100644 --- a/Shorewall/Perl/Shorewall/ARP.pm +++ b/Shorewall/Perl/Shorewall/ARP.pm @@ -278,7 +278,7 @@ sub create_arptables_load( $ ) { 'if [ $? != 0 ]; then', qq( fatal_error "arptables-restore Failed. Input is in \${VARDIR}/.arptables-input"), "fi\n", - "run_ip neigh flush nud noarp nud stale nud reachable\n", + "run_ip neigh flush nud stale nud reachable\n", ); pop_indent; diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 6ae34bcce..f16b53fca 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -407,7 +407,7 @@ use constant { use constant { OPTIMIZE_MASK => OPTIMIZE_POLICY_MASK | OPTIMIZE_RULESET_MASK }; -use constant { DONT_OPTIMIZE => 1 , DONT_DELETE => 2, DONT_MOVE => 4 }; +use constant { DONT_OPTIMIZE => 1 , DONT_DELETE => 2, DONT_MOVE => 4, RETURNS => 8, RETURNS_DONT_MOVE => 12 }; our %dscpmap = ( CS0 => 0x00, CS1 => 0x08, @@ -462,6 +462,9 @@ use constant { NULL_MODE => 0 , # Emitting neither shell commands nor iptables CMD_MODE => 2 }; # Emitting shell commands. 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 }; # @@ -664,9 +667,7 @@ sub initialize( $$$ ) { %isocodes = (); %nfobjects = (); %switches = (); - # - # Initialize this here so we can make it dynamic without moving the initialization - # + %terminating = ( ACCEPT => 1, DROP => 1, RETURN => 1, @@ -680,6 +681,7 @@ sub initialize( $$$ ) { NOTRACK => 1, REDIRECT => 1, RAWDNAT => 1, + RAWSNAT => 1, REJECT => 1, SAME => 1, SNAT => 1, @@ -1036,7 +1038,7 @@ sub push_rule( $$ ) { push @{$chainref->{rules}}, $ruleref; $chainref->{referenced} = 1; - $chainref->{optflags} |= DONT_MOVE if ( $ruleref->{target} || '' ) eq 'RETURN'; + $chainref->{optflags} |= RETURNS_DONT_MOVE if ( $ruleref->{target} || '' ) eq 'RETURN'; trace( $chainref, 'A', @{$chainref->{rules}}, "-A $chainref->{name} $_[1]" ) if $debug; $chainref->{complete} = 1 if $complete; @@ -1053,7 +1055,7 @@ sub add_trule( $$ ) { assert( reftype $ruleref , $ruleref ); push @{$chainref->{rules}}, $ruleref; $chainref->{referenced} = 1; - $chainref->{optflags} |= DONT_MOVE if ( $ruleref->{target} || '' ) eq 'RETURN'; + $chainref->{optflags} |= RETURNS_DONT_MOVE if ( $ruleref->{target} || '' ) eq 'RETURN'; trace( $chainref, 'A', @{$chainref->{rules}}, format_rule( $chainref, $ruleref ) ) if $debug; @@ -1233,7 +1235,7 @@ sub push_irule( $$$;@ ) { if ( $jump ) { $ruleref->{jump} = $jump; $ruleref->{target} = $target; - $chainref->{optflags} |= DONT_MOVE if $target eq 'RETURN'; + $chainref->{optflags} |= RETURNS_DONT_MOVE if $target eq 'RETURN'; $ruleref->{targetopts} = $targetopts if $targetopts; } else { $ruleref->{target} = ''; @@ -2850,6 +2852,7 @@ sub optimize_level4( $$ ) { # The search continues until no short chains remain # Chains with 'DONT_OPTIMIZE' are exempted from optimization # + while ( $progress ) { $progress = 0; $passes++; @@ -2888,100 +2891,112 @@ sub optimize_level4( $$ ) { delete_references $chainref; $progress = 1; } - } elsif ( $numrules == 1) { - my $firstrule = $chainref->{rules}[0]; - # - # Chain has a single rule - # - if ( $firstrule ->{simple} ) { - # - # Easy case -- the rule is a simple jump - # - if ( $chainref->{builtin} ) { - # - # A built-in chain. If the target is a user chain without 'dont_move', - # we can copy its rules to the built-in - # - if ( conditionally_copy_rules $chainref, $firstrule->{target} ) { - # - # Target was a user chain -- rules moved - # - $progress = 1; - } else { - # - # Target was a built-in. Ignore this chain in follow-on passes - # - $chainref->{optflags} |= DONT_OPTIMIZE; - } - } elsif ( ( $firstrule->{target} || '' ) eq 'RETURN' ) { - # - # A chain with a single 'RETURN' rule -- get rid of it - # - delete_chain_and_references( $chainref ); - } else { - # - # Replace all references to this chain with references to the target - # - replace_references $chainref, $firstrule->{target}, $firstrule->{targetopts}; - $progress = 1; - } - } elsif ( $firstrule->{target} ) { - # - # Not so easy -- the rule contains matches - # - if ( $chainref->{builtin} || ! $globals{KLUDGEFREE} || $firstrule->{policy} ) { - # - # This case requires a new rule merging algorithm. Ignore this chain for - # now on. - # - $chainref->{optflags} |= DONT_OPTIMIZE; - } else { - # - # Replace references to this chain with the target and add the matches - # - $progress = 1 if replace_references1 $chainref, $firstrule; - } - } } else { # - # Chain has more than one rule. If the last rule is a simple jump, then delete - # all immediately preceding rules that have the same target + # The chain has rules -- determine if it is terminating # - my $rulesref = $chainref->{rules}; - my $lastref = $rulesref->[-1]; + my $name = $chainref->{name}; + my $lastref = $chainref->{rules}[-1]; - if ( $lastref->{simple} && $lastref->{target} && ! $lastref->{targetopts} ) { - my $target = $lastref->{target}; - my $count = 0; - my $rule = @$rulesref - 1; + unless ( $chainref->{optflags} & RETURNS || $terminating{$name} ) { + $progress = 1 if $terminating{$name} = ( ( $terminating{$lastref->{target} || ''} ) || ( $lastref->{jump} || '' ) eq 'g' ); + } - pop @$rulesref; #Pop the last simple rule + if ( $numrules == 1) { + # + # Chain has a single rule + # + my $firstrule = $lastref; - while ( @$rulesref ) { - my $rule1ref = $rulesref->[-1]; - - last unless ( $rule1ref->{target} || '' ) eq $target && ! $rule1ref->{targetopts}; - - trace ( $chainref, 'D', $rule, $rule1ref ) if $debug; - - pop @$rulesref; - $progress = 1; - $count++; - $rule--; - } - - if ( @$rulesref || ! $chainref->{builtin} || $target !~ /^(?:ACCEPT|DROP|REJECT)$/ ) { - push @$rulesref, $lastref; # Restore the last simple rule - } else { + if ( $firstrule ->{simple} ) { # - #empty builtin chain -- change it's policy + # Easy case -- the rule is a simple jump # - $chainref->{policy} = $target; - trace( $chainref, 'P', undef, 'ACCEPT' ) if $debug; - $count++; + if ( $chainref->{builtin} ) { + # + # A built-in chain. If the target is a user chain without 'dont_move', + # we can copy its rules to the built-in + # + if ( conditionally_copy_rules $chainref, $firstrule->{target} ) { + # + # Target was a user chain -- rules moved + # + $progress = 1; + } else { + # + # Target was a built-in. Ignore this chain in follow-on passes + # + $chainref->{optflags} |= DONT_OPTIMIZE; + } + } elsif ( ( $firstrule->{target} || '' ) eq 'RETURN' ) { + # + # A chain with a single 'RETURN' rule -- get rid of it + # + delete_chain_and_references( $chainref ); + } else { + # + # Replace all references to this chain with references to the target + # + replace_references $chainref, $firstrule->{target}, $firstrule->{targetopts}; + $progress = 1; + } + } elsif ( $firstrule->{target} ) { + # + # Not so easy -- the rule contains matches + # + if ( $chainref->{builtin} || ! $globals{KLUDGEFREE} || $firstrule->{policy} ) { + # + # This case requires a new rule merging algorithm. Ignore this chain for + # now on. + # + $chainref->{optflags} |= DONT_OPTIMIZE; + } else { + # + # Replace references to this chain with the target and add the matches + # + $progress = 1 if replace_references1 $chainref, $firstrule; + } } + } else { + # + # Chain has more than one rule. If the last rule is a simple jump, then delete + # all immediately preceding rules that have the same target + # + my $rulesref = $chainref->{rules}; - progress_message " $count $target rules deleted from chain $chainref->{name}" if $count; + if ( $lastref->{simple} && $lastref->{target} && ! $lastref->{targetopts} ) { + my $target = $lastref->{target}; + my $count = 0; + my $rule = @$rulesref - 1; + + pop @$rulesref; #Pop the last simple rule + + while ( @$rulesref ) { + my $rule1ref = $rulesref->[-1]; + + last unless ( $rule1ref->{target} || '' ) eq $target && ! $rule1ref->{targetopts}; + + trace ( $chainref, 'D', $rule, $rule1ref ) if $debug; + + pop @$rulesref; + $progress = 1; + $count++; + $rule--; + } + + if ( @$rulesref || ! $chainref->{builtin} || $target !~ /^(?:ACCEPT|DROP|REJECT)$/ ) { + push @$rulesref, $lastref; # Restore the last simple rule + } else { + # + #empty builtin chain -- change it's policy + # + $chainref->{policy} = $target; + trace( $chainref, 'P', undef, 'ACCEPT' ) if $debug; + $count++; + } + + progress_message " $count $target rules deleted from chain $name" if $count; + } } } } diff --git a/Shorewall/Perl/Shorewall/Nat.pm b/Shorewall/Perl/Shorewall/Nat.pm index d9730e1d7..2c5a6b4c1 100644 --- a/Shorewall/Perl/Shorewall/Nat.pm +++ b/Shorewall/Perl/Shorewall/Nat.pm @@ -724,8 +724,6 @@ sub handle_nonat_rule( $$$$$$$$$$ ) { } } - set_optflags( $nonat_chain, DONT_MOVE | DONT_OPTIMIZE ) if $tgt eq 'RETURN'; - expand_rule( $nonat_chain , PREROUTE_RESTRICT , $rule , diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 122535d2a..95c0a1f47 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -2475,8 +2475,6 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) { if ( $actiontype & ACTION ) { $action = $usedactions{$normalized_target}{name}; $loglevel = ''; - } else { - set_optflags( $chainref , DONT_MOVE | DONT_OPTIMIZE ) if $action eq 'RETURN'; } if ( $origdest ) { diff --git a/Shorewall/Perl/lib.core b/Shorewall/Perl/lib.core index 9d48337a2..923806a87 100644 --- a/Shorewall/Perl/lib.core +++ b/Shorewall/Perl/lib.core @@ -216,8 +216,8 @@ get_routed_networks() # $1 = interface name, $2-n = Fatal error message delete_tc1() { clear_one_tc() { - $TC qdisc del dev $1 root 2> /dev/null - $TC qdisc del dev $1 ingress 2> /dev/null + $TC qdisc del dev ${1%@*} root 2> /dev/null + $TC qdisc del dev ${1%@*} ingress 2> /dev/null } diff --git a/Shorewall/manpages/shorewall-tcrules.xml b/Shorewall/manpages/shorewall-tcrules.xml index a6bc173fa..a2f8d4aa0 100644 --- a/Shorewall/manpages/shorewall-tcrules.xml +++ b/Shorewall/manpages/shorewall-tcrules.xml @@ -1051,10 +1051,10 @@ Normal-Service => 0x00 role="bold">:[max]] - Optional - packet Length. This field, if present allow you to - match the length of a packet against a specific value or range of - values. You must have iptables length support for this to work. A - range is specified in the form + Optional - packet payload length. This field, if present allow + you to match the length of a packet payload (Layer 4 data ) against + a specific value or range of values. You must have iptables length + support for this to work. A range is specified in the form min:max where either min or max (but not both) may be omitted. If min is omitted, then 0 is diff --git a/Shorewall6/manpages/shorewall6-tcrules.xml b/Shorewall6/manpages/shorewall6-tcrules.xml index c545b3695..6ac580ee4 100644 --- a/Shorewall6/manpages/shorewall6-tcrules.xml +++ b/Shorewall6/manpages/shorewall6-tcrules.xml @@ -913,10 +913,10 @@ Normal-Service => 0x00 role="bold">:[max]] - Optional packet Length. This field, if present allow you to - match the length of a packet against a specific value or range of - values. You must have ip6tables length support for this to work. A - range is specified in the form + Optional - packet payload length. This field, if present allow + you to match the length of a packet payload (Layer 4 data ) against + a specific value or range of values. You must have iptables length + support for this to work. A range is specified in the form min:max where either min or max (but not both) may be omitted. If min is omitted, then 0 is diff --git a/docs/configuration_file_basics.xml b/docs/configuration_file_basics.xml index dfef73b20..fc70b3f45 100644 --- a/docs/configuration_file_basics.xml +++ b/docs/configuration_file_basics.xml @@ -142,10 +142,16 @@ - /etc/shorewall/blacklist - lists + /etc/shorewall/blacklist - Deprecated in + favor of /etc/shorewall/blrules. Lists blacklisted IP/subnet/MAC addresses. + + /etc/shorewall/blrules — Added in + Shorewall 4.5.0. Define blacklisting and whitelisting. + + /etc/shorewall/init - commands that you wish to execute at the beginning of a shorewall start @@ -258,6 +264,11 @@ start/restart when LOAD_HELPERS_ONLY=Yes in shorewall.conf. + + + /usr/share/arprules — Added in Shorewall + 4.5.12. Allows specification of arptables rules. + If you need to change a file in @@ -297,6 +308,12 @@ # This is a comment ACCEPT net $FW tcp www #This is an end-of-line comment + + + If a comment ends with a backslash ("\"), the next line will also + be treated as a comment. See Line + Continuation below. +
@@ -516,6 +533,19 @@ ACCEPT net:\ continuation line does not end with a comma or colon, the leading white space in the last line is not ignored. + + + A trailing backslash is not ignored in a comment. So the continued + rule above can be commented out with a single '#' as follows: + + #ACTION SOURCE DEST PROTO DEST +# PORT(S) +#ACCEPT net:\ + 206.124.146.177,\ + 206.124.146.178,\ + 206.124.146.180\ + dmz tcp 873 +