From 3e87efc82b611d8b4a73570729b20e1b27754880 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Mon, 17 Feb 2014 12:50:59 -0800 Subject: [PATCH] Document -t option - Also copy compiler directives to the mangle file. --- Shorewall/Perl/Shorewall/Config.pm | 238 +++++++++++++++-------------- Shorewall/Perl/Shorewall/Tc.pm | 4 +- Shorewall/manpages/shorewall.xml | 34 ++++- Shorewall6/manpages/shorewall6.xml | 32 ++++ 4 files changed, 195 insertions(+), 113 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index c3ccbfe88..cd0849b73 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -158,6 +158,7 @@ our %EXPORT_TAGS = ( internal => [ qw( create_temp_script set_section_function section_warning clear_section_function + directive_callback $product $Product @@ -562,6 +563,7 @@ our $warningcount1; # Used to suppress duplicate warnings about COMMENT our $warningcount2; # Used to suppress duplicate warnings about FORMAT being deprecated our $warningcount3; # Used to suppress duplicate warnings about SECTION being deprecated our $checkinline; # The -i option to check/compile/etc. +our $directive_callback; # Function to call in compiler_directive our $shorewall_dir; # Shorewall Directory; if non-empty, search here first for files. @@ -687,6 +689,8 @@ sub initialize( $;$$) { $ifstack = 0; @ifstack = (); $embedded = 0; + $directive_callback + = 0; # # Contents of last COMMENT line. # @@ -2490,6 +2494,13 @@ sub evaluate_expression( $$$ ) { $val; } +# +# Set callback +# +sub directive_callback( $ ) { + $directive_callback = shift; +} + # # Each entry in @ifstack consists of a 4-tupple # @@ -2518,127 +2529,128 @@ sub process_compiler_directive( $$$$ ) { my ( $lastkeyword, $prioromit, $included, $lastlinenumber ) = @ifstack ? @{$ifstack[-1]} : ('', 0, 0, 0 ); - my %directives = ( IF => sub() { - directive_error( "Missing IF expression" , $filename, $linenumber ) unless supplied $expression; - my $nextomitting = $omitting || ! evaluate_expression( $expression , $filename, $linenumber ); - push @ifstack, [ 'IF', $omitting, ! $nextomitting, $linenumber ]; - $omitting = $nextomitting; - } , + my %directives = + ( IF => sub() { + directive_error( "Missing IF expression" , $filename, $linenumber ) unless supplied $expression; + my $nextomitting = $omitting || ! evaluate_expression( $expression , $filename, $linenumber ); + push @ifstack, [ 'IF', $omitting, ! $nextomitting, $linenumber ]; + $omitting = $nextomitting; + } , - ELSIF => sub() { - directive_error( "?ELSIF has no matching ?IF" , $filename, $linenumber ) unless @ifstack > $ifstack && $lastkeyword =~ /IF/; - directive_error( "Missing IF expression" , $filename, $linenumber ) unless $expression; - if ( $omitting && ! $included ) { - # - # We can only change to including if we were previously omitting - # - $omitting = $prioromit || ! evaluate_expression( $expression , $filename, $linenumber ); - $included = ! $omitting; - } else { - # - # We have already included -- so we don't want to include this part - # - $omitting = 1; - } - $ifstack[-1] = [ 'ELSIF', $prioromit, $included, $lastlinenumber ]; - } , + ELSIF => sub() { + directive_error( "?ELSIF has no matching ?IF" , $filename, $linenumber ) unless @ifstack > $ifstack && $lastkeyword =~ /IF/; + directive_error( "Missing IF expression" , $filename, $linenumber ) unless $expression; + if ( $omitting && ! $included ) { + # + # We can only change to including if we were previously omitting + # + $omitting = $prioromit || ! evaluate_expression( $expression , $filename, $linenumber ); + $included = ! $omitting; + } else { + # + # We have already included -- so we don't want to include this part + # + $omitting = 1; + } + $ifstack[-1] = [ 'ELSIF', $prioromit, $included, $lastlinenumber ]; + } , - ELSE => sub() { - directive_error( "Invalid ?ELSE" , $filename, $linenumber ) unless $expression eq ''; - directive_error( "?ELSE has no matching ?IF" , $filename, $linenumber ) unless @ifstack > $ifstack && $lastkeyword =~ /IF/; - $omitting = $included || ! $omitting unless $prioromit; - $ifstack[-1] = [ 'ELSE', $prioromit, 1, $lastlinenumber ]; - } , + ELSE => sub() { + directive_error( "Invalid ?ELSE" , $filename, $linenumber ) unless $expression eq ''; + directive_error( "?ELSE has no matching ?IF" , $filename, $linenumber ) unless @ifstack > $ifstack && $lastkeyword =~ /IF/; + $omitting = $included || ! $omitting unless $prioromit; + $ifstack[-1] = [ 'ELSE', $prioromit, 1, $lastlinenumber ]; + } , - ENDIF => sub() { - directive_error( "Invalid ?ENDIF" , $filename, $linenumber ) unless $expression eq ''; - directive_error( q(Unexpected "?ENDIF" without matching ?IF or ?ELSE) , $filename, $linenumber ) if @ifstack <= $ifstack; - $omitting = $prioromit; - pop @ifstack; - } , + ENDIF => sub() { + directive_error( "Invalid ?ENDIF" , $filename, $linenumber ) unless $expression eq ''; + directive_error( q(Unexpected "?ENDIF" without matching ?IF or ?ELSE) , $filename, $linenumber ) if @ifstack <= $ifstack; + $omitting = $prioromit; + pop @ifstack; + } , - SET => sub() { - unless ( $omitting ) { - directive_error( "Missing SET variable", $filename, $linenumber ) unless supplied $expression; - ( my $var , $expression ) = split ' ', $expression, 2; - directive_error( "Invalid SET variable ($var)", $filename, $linenumber) unless $var =~ /^(\$)?([a-zA-Z]\w*)$/ || $var =~ /^(@)(\d+|[a-zA-Z]\w*)/; - directive_error( "Missing SET expression" , $filename, $linenumber) unless supplied $expression; + SET => sub() { + unless ( $omitting ) { + directive_error( "Missing SET variable", $filename, $linenumber ) unless supplied $expression; + ( my $var , $expression ) = split ' ', $expression, 2; + directive_error( "Invalid SET variable ($var)", $filename, $linenumber) unless $var =~ /^(\$)?([a-zA-Z]\w*)$/ || $var =~ /^(@)(\d+|[a-zA-Z]\w*)/; + directive_error( "Missing SET expression" , $filename, $linenumber) unless supplied $expression; - if ( ( $1 || '' ) eq '@' ) { - $var = $2; - $var = numeric_value( $var ) if $var =~ /^\d/; - $var = $2 || 'chain'; - directive_error( "Shorewall variables may only be SET in the body of an action", $filename, $linenumber ) unless $actparms{0}; - my $val = $actparms{$var} = evaluate_expression ( $expression, - $filename, - $linenumber ); - $parmsmodified = 1; - } else { - $variables{$2} = evaluate_expression( $expression, - $filename, - $linenumber ); - } - } - } , + if ( ( $1 || '' ) eq '@' ) { + $var = $2; + $var = numeric_value( $var ) if $var =~ /^\d/; + $var = $2 || 'chain'; + directive_error( "Shorewall variables may only be SET in the body of an action", $filename, $linenumber ) unless $actparms{0}; + my $val = $actparms{$var} = evaluate_expression ( $expression, + $filename, + $linenumber ); + $parmsmodified = 1; + } else { + $variables{$2} = evaluate_expression( $expression, + $filename, + $linenumber ); + } + } + } , - FORMAT => sub() { - unless ( $omitting ) { - directive_error( "?FORMAT is not allowed in this file", $filename, $linenumber ) unless $max_format > 1; - directive_error( "Missing format", $filename, $linenumber ) unless supplied $expression; - directive_error( "Invalid format ($expression)", $filename, $linenumber ) unless $expression =~ /^\d+$/; - directive_error( "Format must be between 1 and $max_format", $filename, $linenumber ) unless $expression && $expression <= $max_format; - $file_format = $expression; - } - } , + 'FORMAT' => sub() { + unless ( $omitting ) { + directive_error( "?FORMAT is not allowed in this file", $filename, $linenumber ) unless $max_format > 1; + directive_error( "Missing format", $filename, $linenumber ) unless supplied $expression; + directive_error( "Invalid format ($expression)", $filename, $linenumber ) unless $expression =~ /^\d+$/; + directive_error( "Format must be between 1 and $max_format", $filename, $linenumber ) unless $expression && $expression <= $max_format; + $file_format = $expression; + } + } , - RESET => sub() { - unless ( $omitting ) { - my $var = $expression; - directive_error( "Missing RESET variable", $filename, $linenumber) unless supplied $var; - directive_error( "Invalid RESET variable ($var)", $filename, $linenumber) unless $var =~ /^(\$)?([a-zA-Z]\w*)$/ || $var =~ /^(@)(\d+|[a-zA-Z]\w*)/; + RESET => sub() { + unless ( $omitting ) { + my $var = $expression; + directive_error( "Missing RESET variable", $filename, $linenumber) unless supplied $var; + directive_error( "Invalid RESET variable ($var)", $filename, $linenumber) unless $var =~ /^(\$)?([a-zA-Z]\w*)$/ || $var =~ /^(@)(\d+|[a-zA-Z]\w*)/; - if ( ( $1 || '' ) eq '@' ) { - $var = numeric_value( $var ) if $var =~ /^\d/; - $var = $2 || 'chain'; - directive_error( "Shorewall variables may only be RESET in the body of an action", $filename, $linenumber ) unless $actparms{0}; - if ( exists $actparms{$var} ) { - if ( $var =~ /^loglevel|logtag|chain|disposition|caller$/ ) { - $actparms{$var} = ''; - } else { - delete $actparms{$var} - } - } else { - directive_warning( "Shorewall variable $2 does not exist", $filename, $linenumber ); - } + if ( ( $1 || '' ) eq '@' ) { + $var = numeric_value( $var ) if $var =~ /^\d/; + $var = $2 || 'chain'; + directive_error( "Shorewall variables may only be RESET in the body of an action", $filename, $linenumber ) unless $actparms{0}; + if ( exists $actparms{$var} ) { + if ( $var =~ /^loglevel|logtag|chain|disposition|caller$/ ) { + $actparms{$var} = ''; + } else { + delete $actparms{$var} + } + } else { + directive_warning( "Shorewall variable $2 does not exist", $filename, $linenumber ); + } - } else { - if ( exists $variables{$2} ) { - delete $variables{$2}; - } else { - directive_warning( "Shell variable $2 does not exist", $filename, $linenumber ); - } - } - } - } , + } else { + if ( exists $variables{$2} ) { + delete $variables{$2}; + } else { + directive_warning( "Shell variable $2 does not exist", $filename, $linenumber ); + } + } + } + } , - COMMENT => sub() { - unless ( $omitting ) { - if ( $comments_allowed ) { - unless ( $nocomment ) { - if ( have_capability( 'COMMENTS' ) ) { - ( $comment = $line ) =~ s/^\s*\?COMMENT\s*//; - $comment =~ s/\s*$//; - } else { - directive_warning( "COMMENTs ignored -- require comment support in iptables/Netfilter" , $filename, $linenumber ) unless $warningcount++; - } - } - } else { - directive_error ( "?COMMENT is not allowed in this file", $filename, $linenumber ); - } - } - } + COMMENT => sub() { + unless ( $omitting ) { + if ( $comments_allowed ) { + unless ( $nocomment ) { + if ( have_capability( 'COMMENTS' ) ) { + ( $comment = $line ) =~ s/^\s*\?COMMENT\s*//; + $comment =~ s/\s*$//; + } else { + directive_warning( "COMMENTs ignored -- require comment support in iptables/Netfilter" , $filename, $linenumber ) unless $warningcount++; + } + } + } else { + directive_error ( "?COMMENT is not allowed in this file", $filename, $linenumber ); + } + } + } - ); + ); if ( my $function = $directives{$keyword} ) { $function->(); @@ -2646,7 +2658,11 @@ sub process_compiler_directive( $$$$ ) { assert( 0, $keyword ); } - $omitting; + if ( $directive_callback ) { + $directive_callback->( $keyword, $line ) + } else { + $omitting; + } } # diff --git a/Shorewall/Perl/Shorewall/Tc.pm b/Shorewall/Perl/Shorewall/Tc.pm index d96ca836e..7e5635878 100644 --- a/Shorewall/Perl/Shorewall/Tc.pm +++ b/Shorewall/Perl/Shorewall/Tc.pm @@ -3154,6 +3154,8 @@ sub setup_tc( $ ) { # We are going to convert this tcrules file to the equivalent mangle file # open( $mangle , '>>', $fn1 = find_file('mangle') ) || fatal_error "Unable to open $fn1:$!"; + + directive_callback( sub () { print $mangle "$_[1]\n" unless $_[0] eq 'FORMAT'; 0; } ); } first_entry "$doing $fn..."; @@ -3173,7 +3175,7 @@ sub setup_tc( $ ) { } } - close $mangle if $tcrules; + close $mangle, directive_callback( 0 ) if $tcrules; } if ( my $fn = open_file( 'mangle', 1, 1 ) ) { diff --git a/Shorewall/manpages/shorewall.xml b/Shorewall/manpages/shorewall.xml index 379c67a99..a7b298f67 100644 --- a/Shorewall/manpages/shorewall.xml +++ b/Shorewall/manpages/shorewall.xml @@ -1864,9 +1864,41 @@ url="shorewall-mangle.html">shorewall-mangle(5). The old file is renamed with a .bak suffix. + + There are some notable restrictions with the + option: + + + + Converted rules will be appended to the existing + mangle file; if there is no + mangle file in the CONFIG_PATH, one will + be created in /etc/shorewall. + + + + Existing comments in the tcrules + file will not be transferred to the + mangle file. + + + + INCLUDEd files will be expanded inline in the + mangle file. + + + + Columns in the mangle file will be + separated by a single tab character; there is no attempt made + to otherwise align the columns. + + + + The option was added in Shorewall 4.6.0 and is equivalent to specifying the , - and the options. + and the options. For a description of the other options, see the check command above. diff --git a/Shorewall6/manpages/shorewall6.xml b/Shorewall6/manpages/shorewall6.xml index f5580568b..db0174b0f 100644 --- a/Shorewall6/manpages/shorewall6.xml +++ b/Shorewall6/manpages/shorewall6.xml @@ -1700,6 +1700,38 @@ url="shorewall6-mangle.html">shorewall6-mangle(5). The old file is renamed with a .bak suffix. + + There are some notable restrictions with the + option: + + + + Converted rules will be appended to the existing + mangle file; if there is no + mangle file in the CONFIG_PATH, one will + be created in /etc/shorewall6. + + + + Existing comments in the tcrules + file will not be transferred to the + mangle file. + + + + INCLUDEd files will be expanded inline in the + mangle file. + + + + Columns in the mangle file will be + separated by a single tab character; there is no attempt made + to otherwise align the columns. + + + + The option was added in Shorewall 4.6.0 and is equivalent to specifying the , and the options.