Tom Eastep wrote:
Regrettably, Shorewall 4.5.16 has a serious problem when used on systems
running a 3.x kernel that include CT Target support and that do not use
a capabilities file.
I am attaching 4 patches, implementing 3 new features and fixing one minor inconsistency in this version. These are:

1. Introduce DEST interface capabilities to "rtrules". I did report this as a "bug" previously, but, as it turned out, "source" and "destination" interfaces are not treated the same as source and destination ip addresses (I've had a long-drawn arguments about this in the netfilter mailing list, so I won't go into anything like this on here). So, what this new feature does is to allow output interface to be specified, along with destination ip address, in the DEST column in "rtrules" and generate the necessary "ip rule" rules to make it happen.

This patch comes with one caveat though - the "oif" ip rule capability in the iproute package was introduced fairly "recently", so if this feature is going to be made available "mainstream", I suspect a new capability needs to be added to shorewall (my perl skills aren't quite there yet, so I'll leave this up to you Tom, if you decide to incorporate this new feature into shorewall - "It works for me (tm)").

2. Allow "blackhole", "unreachable" and "prohibit" COPY options to be specified in "providers" (this is in addition to interfaces) so that these type of routes can also be transferred over to the new provider tables, as desired, and not, as it was the case up until now - at the behest of shorewall.

This also addresses a bug I reported recently where there was a possible clash during adding/creating/transferring blackhole-type routes in between 'main' and the provider's tables. Example of use:

dmz7 2 - main eth0 10.1.7.1 - blackhole,eth0,prohibit

The above statement copies all "blackhole" and "prohibit" routes from 'main' to the 'dmz7' provider table, in addition to all 'eth0' routes (it does *not* touch the "unreachable" routes in main, if they exist).

3. Introduce a new pair of OPTIONs in "providers" called "autosrc" and "noautosrc". Up until now, shorewall used to create iproute rule in "firewall" for each provider, adding the provider's interface source IP address and placing that rule with priority 20000 automatically. The above pair of options allows for fine-tuning of this.

Specifically, if "noautosrc" is specified, no such rule is created by default (useful, if either no such rule is needed or that rule needs to be created with a different priority, other than the one "assumed" by shorewall). By default (and to keep backwards compatibility with previous releases), if nothing is specified, then "autosrc" is assumed (in other words, the "old" behaviour is in effect - the rule is created). Example of use:

dmz7 2 - main eth0 10.1.7.1 noautosrc blackhole,eth0,prohibit

With the above statement, the "ip rule del from <eth0_src>" and "ip rule add from <eth0_src> pref 20000" rules are *not* created, but can be added by the user, if needed (and with a different priority!), by adding the following statement in "rtrules":

- eth0 dmz7 26001

4. A minor bugfix, which ensures consistency in creating ip rules, always using "pref" instead of "priority".
--- a/Shorewall/Perl/Shorewall/Providers.pm
+++ b/Shorewall/Perl/Shorewall/Providers.pm
@@ -1051,9 +1051,29 @@
 
     if ( $dest eq '-' ) {
        $dest = 'to ' . ALLIP;
+    } elsif ( $family == F_IPV4 ) {
+       if ( $dest =~ /:/ ) {
+           ( my $interface, $dest , my $remainder ) = split( /:/, $dest, 3 );
+           fatal_error "Invalid DEST" if defined $remainder;
+           $dest = validate_net ( $dest, 0 );
+           $interface = physical_name $interface;
+           $dest = "oif $interface to $dest";
+       } elsif ( $dest =~ /\..*\..*/ ) {
+           $dest = validate_net ( $dest, 0 );
+           $dest = "to $dest";
     } else {
-       $dest = validate_net( $dest, 0 );
+           $dest = 'oif ' . physical_name $dest;
+       }
+    } elsif ( $dest =~  /^(.+?):<(.+)>\s*$/ ||  $dest =~  
/^(.+?):\[(.+)\]\s*$/ || $dest =~ /^(.+?):(\[.+?\](?:\/\d+))$/ ) {
+       my ($interface, $dest ) = ($1, $2);
+       $dest = validate_net ($dest, 0);
+       $interface = physical_name $interface;
+       $dest = "oif $interface to $dest";
+    } elsif (  $dest =~ /:.*:/ || $dest =~ /\..*\..*/ ) {
+       $dest = validate_net ( $dest, 0 );
        $dest = "to $dest";
+    } else {
+       $dest = 'oif ' . physical_name $dest;
     }
 
     if ( $source eq '-' ) {

--- a/Shorewall/Perl/Shorewall/Providers.pm
+++ b/Shorewall/Perl/Shorewall/Providers.pm
@@ -226,16 +225,23 @@
     my $filter = $family == F_IPV6 ? q(fgrep -v ' cache ' | sed 's/ via :: / 
/' | ) : '';
     my %copied;
     my @copy;
+    my @bup_copy;
+    my $bup_copy;
     #
     # Remove duplicates
     #
     for ( split ',', $copy ) {
        unless ( $copied{$_} ) {
-           fatal_error "Unknown interface ($_)" unless known_interface($_);
-           push @copy, $_;
+           fatal_error "Unknown interface ($_)" unless ( known_interface($_) 
|| $_ =~ /^(?:blackhole|unreachable|prohibit)$/ );
+           if ( $_ =~ /^(?:blackhole|unreachable|prohibit)$/ ) {
+               push @bup_copy, $_ ;
+            } else {
+               push @copy, $_
+            }
            $copied{$_} = 1;
        }
     }
+    $bup_copy = join( '|' , @bup_copy );
     #
     # Map physical names in $copy to logical names
     #
@@ -255,11 +261,13 @@
 
     emit (  '    case $net in',
            '        default)',
-           '            ;;',
-           '        blackhole|prohibit|unreachable)',
+           '            ;;' );
+    if ( $bup_copy ) {
+      emit ("        $bup_copy)",
            "            run_ip route add table $id \$net \$route $realm",
-           '            ;;',
-           '        *)',
+           '            ;;' );
+    }
+    emit (  '        *)',
            '            case $(find_device $route) in',
            "                $copy)" );
     if ( $family == F_IPV4 ) {

--- a/Shorewall/Perl/Shorewall/Providers.pm
+++ b/Shorewall/Perl/Shorewall/Providers.pm
@@ -432,6 +440,7 @@
     ( $interface, my $address ) = split /:/, $interface;
 
     my $shared = 0;
+    my $noautosrc = 0;
 
     if ( defined $address ) {
        validate_address $address, 0;
@@ -520,6 +529,10 @@
            } elsif ( $option =~ /^load=(0?\.\d{1,8})/ ) {
                $load = $1;
                require_capability 'STATISTIC_MATCH', "load=$load", 's';
+           } elsif ( $option eq 'autosrc' ) {
+               $noautosrc = 0;
+           } elsif ( $option eq 'noautosrc' ) {
+               $noautosrc = 1;
            } else {
                fatal_error "Invalid option ($option)";
            }
@@ -617,6 +630,7 @@
                           balance     => $balance ,
                           pref        => $pref ,
                           mtu         => $mtu ,
+                          noautosrc   => $noautosrc ,
                           track       => $track ,
                           loose       => $loose ,
                           duplicate   => $duplicate ,
@@ -691,6 +705,7 @@
     my $balance     = $providerref->{balance};
     my $pref        = $providerref->{pref};
     my $mtu         = $providerref->{mtu};
+    my $noautosrc   = $providerref->{noautosrc};
     my $track       = $providerref->{track};
     my $loose       = $providerref->{loose};
     my $duplicate   = $providerref->{duplicate};
@@ -833,7 +848,8 @@
                       'done'
                     );
            }
-       } elsif ( $shared ) {
+       } elsif ( ! $noautosrc ) {
+           if ( $shared ) {
            emit  "qt \$IP -$family rule del from $address" if 
$config{DELETE_THEN_ADD};
            emit( "run_ip rule add from $address pref 20000 table $id" ,
                  "echo \"\$IP -$family rule del from $address > /dev/null 
2>&1\" >> \${VARDIR}/undo_${table}_routing" );
@@ -847,6 +863,7 @@
                  );
        }
     }
+    }
 
     if ( @{$providerref->{rules}} ) {
        emit '';

--- a/Shorewall/Perl/Shorewall/Providers.pm
+++ b/Shorewall/Perl/Shorewall/Providers.pm
@@ -1099,7 +1136,7 @@
 
     fatal_error "Invalid priority ($priority)" unless $priority && $priority 
=~ /^\d{1,5}$/;
 
-    $priority = "priority $priority";
+    $priority = "pref $priority";
 
     push @{$providerref->{rules}}, "qt \$IP -$family rule del $source 
${dest}${mark} $priority" if $config{DELETE_THEN_ADD};
     push @{$providerref->{rules}}, "run_ip rule add $source ${dest}${mark} 
$priority table $id";

------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1
_______________________________________________
Shorewall-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/shorewall-devel

Reply via email to