diff --git a/Shorewall-perl/Shorewall/Interfaces.pm b/Shorewall-perl/Shorewall/Interfaces.pm index 67de7536d..0384e4372 100644 --- a/Shorewall-perl/Shorewall/Interfaces.pm +++ b/Shorewall-perl/Shorewall/Interfaces.pm @@ -115,6 +115,36 @@ sub add_group_to_zone($$$$$) push @{$arrayref}, \%h; } +sub get_routed_networks ( $$ ) { + my ( $interface , $error_message ) = @_; + my @networks; + + if ( open IP , '-|' , "ip route show dev $interface 2> /dev/null" ) { + while ( my $route = ) { + $route =~ s/^\s+//; + my $network = ( split /\s+/, $route )[0]; + if ( $network eq 'default' ) { + if ( $error_message ) { + fatal_error $error_message; + } else { + warning_message "default route ignored on interface $interface"; + } + } else { + my ( $address, $vlsm ) = split '/', $network; + $vlsm = 32 unless defined $vlsm; + push @networks, "$address/$vlsm"; + } + } + close IP + } else { + fatal_error "Cannot get routes through interface $interface"; + } + + fatal_error "detectnets: There are no routes through interface $interface" unless @networks; + + @networks; +} + # # Parse the interfaces file. # @@ -186,12 +216,10 @@ sub validate_interfaces_file() my $optionsref = {}; - if ( $options ) - { - my %options; - - for my $option (split ',', $options ) - { + my %options; + + if ( $options ) { + for my $option (split ',', $options ) { next if $option eq '-'; ( $option, my $value ) = split /=/, $option; @@ -219,19 +247,22 @@ sub validate_interfaces_file() $options{arp_ignore} = 1; } } else { - fatal_error "Internal Error in validate_interfaces_file" + fatal_error "Internal Error in validate_interfaces_file"; } } } $zoneref->{options}{in_out}{routeback} = 1 if $options{routeback}; - - $interfaces{$interface}{options} = $optionsref = \%options; + } + + $interfaces{$interface}{options} = $optionsref = \%options; push @interfaces, $interface; - add_group_to_zone( $zone, $zoneref->{type}, $interface, \@allipv4, $optionsref ) if $zone; + my @networks = $options{detectnets} ? get_routed_networks( $interface , "detectnets not allowed on interface with default route - $interface" ) : @allipv4; + + add_group_to_zone( $zone, $zoneref->{type}, $interface, \@networks, $optionsref ) if $zone; $interfaces{$interface}{zone} = $zone; #Must follow the call to add_group_to_zone()