forked from extern/shorewall_code
First working version of new Bridge code
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@6470 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
40f3593f69
commit
a3961093be
@ -98,6 +98,8 @@ our @EXPORT = qw( STANDARD
|
||||
do_ratelimit
|
||||
do_user
|
||||
do_tos
|
||||
match_source_dev
|
||||
match_dest_dev
|
||||
iprange_match
|
||||
match_source_net
|
||||
match_dest_net
|
||||
@ -1029,6 +1031,32 @@ sub do_tos( $ ) {
|
||||
$tos ne '-' ? "-m tos --tos $tos " : '';
|
||||
}
|
||||
|
||||
#
|
||||
# Match Source Interface
|
||||
#
|
||||
sub match_source_dev( $ ) {
|
||||
my $interface = shift;
|
||||
my $interfaceref = $interfaces{$interface};
|
||||
if ( $interfaceref->{options}{port} ) {
|
||||
"-i $interfaceref->{bridge} -m physdev --physdev-in $interface ";
|
||||
} else {
|
||||
"-i $interface ";
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Match Dest device
|
||||
#
|
||||
sub match_dest_dev( $ ) {
|
||||
my $interface = shift;
|
||||
my $interfaceref = $interfaces{$interface};
|
||||
if ( $interfaceref->{options}{port} ) {
|
||||
"-o $interfaceref->{bridge} -m physdev --physdev-out $interface ";
|
||||
} else {
|
||||
"-o $interface ";
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Avoid generating a second '-m iprange' in a single rule.
|
||||
#
|
||||
@ -1414,6 +1442,8 @@ sub expand_rule( $$$$$$$$$$ )
|
||||
#
|
||||
# An interface in the SOURCE column of a masq file
|
||||
#
|
||||
fatal_error "Bridge ports may not appear in the SOURCE column of this file" if port_to_bridge( $iiface );
|
||||
|
||||
my $networks = get_interface_nets ( $iiface );
|
||||
|
||||
add_command( $chainref , join( '', 'for source in ', $networks, '; do' ) );
|
||||
@ -1424,9 +1454,8 @@ sub expand_rule( $$$$$$$$$$ )
|
||||
#
|
||||
$chainref->{loopcount}++;
|
||||
} else {
|
||||
fatal_error "Source Interface ($iiface) not allowed when the source zone is $firewall_zone"
|
||||
if $restriction & OUTPUT_RESTRICT;
|
||||
$rule .= "-i $iiface ";
|
||||
fatal_error "Source Interface ($iiface) not allowed when the source zone is $firewall_zone" if $restriction & OUTPUT_RESTRICT;
|
||||
$rule .= match_source_dev( $iiface );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1480,13 +1509,19 @@ sub expand_rule( $$$$$$$$$$ )
|
||||
#
|
||||
# ADDRESS 'detect' in the masq file.
|
||||
#
|
||||
fatal_error "Bridge port ( $diface) not allowed" if port_to_bridge( $diface );
|
||||
add_command( $chainref , 'for dest in ' . get_interface_addresses( $diface) . '; do' );
|
||||
$rule .= '-d $dest';
|
||||
$chainref->{loopcount}++;
|
||||
} else {
|
||||
fatal_error "Destination Interface ($diface) not allowed when the destination zone is $firewall_zone"
|
||||
if $restriction & INPUT_RESTRICT;
|
||||
$rule .= "-o $diface ";
|
||||
fatal_error "Destination Interface ($diface) not allowed when the destination zone is $firewall_zone" if $restriction & INPUT_RESTRICT;
|
||||
|
||||
if ( $iiface ) {
|
||||
my $bridge = port_to_bridge( $diface );
|
||||
fatal_error "Source interface ( $iiface) is not a port on the same bridge as the destination interface ( $diface )" if $bridge && $bridge ne source_port_to_bridge( $iiface );
|
||||
}
|
||||
|
||||
$rule .= match_dest_dev( $diface );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw( add_group_to_zone
|
||||
validate_interfaces_file
|
||||
known_interface
|
||||
port_to_bridge
|
||||
interface_is_optional
|
||||
find_interfaces_by_option
|
||||
get_interface_option
|
||||
@ -182,13 +183,15 @@ sub validate_interfaces_file()
|
||||
|
||||
my $first_entry = 1;
|
||||
|
||||
my @ifaces;
|
||||
|
||||
while ( read_a_line ) {
|
||||
|
||||
if ( $first_entry ) {
|
||||
progress_message2 "$doing $fn...";
|
||||
$first_entry = 0;
|
||||
}
|
||||
|
||||
|
||||
my ($zone, $interface, $networks, $options ) = split_line 2, 4, 'interfaces file';
|
||||
my $zoneref;
|
||||
my $bridge = '';
|
||||
@ -209,23 +212,32 @@ sub validate_interfaces_file()
|
||||
|
||||
fatal_error "Invalid INTERFACE" if defined $extra || ! $interface;
|
||||
|
||||
fatal_error "Duplicate Interface ($interface)" if $interfaces{$interface};
|
||||
|
||||
fatal_error "Invalid Interface Name: $interface" if $interface eq '+';
|
||||
fatal_error "Invalid Interface Name ( $interface )" if $interface eq '+';
|
||||
|
||||
if ( defined $port ) {
|
||||
require_capability( 'PHYSDEV_MATCH', 'Bridge Ports', '');
|
||||
require_capability( 'KLUDGEFREE', 'Bridge Ports', '');
|
||||
fatal_error "Duplicate Interface ( $port )" if $interfaces{$port};
|
||||
fatal_error "$interface is not a defined bridge" unless $interfaces{$interface} && $interfaces{$interface}{options}{bridge};
|
||||
fatal_error "Invalid Bridge Port Name ($port)" unless $port =~ /^([\w.@%-]+\+?)$/;
|
||||
fatal_error "Invalid Interface Name ( $interface:$port )" unless $port =~ /^[\w.@%-]+\+?$/;
|
||||
fatal_error "Bridge Ports may only be associated with 'bport' zones" if $zone && $zoneref->{type} ne 'bport4';
|
||||
|
||||
if ( $zone ) {
|
||||
if ( $zoneref->{bridge} ) {
|
||||
fatal_error "Bridge Port zones may only be associated with a single bridge" if $zoneref->{bridge} ne $interface;
|
||||
} else {
|
||||
$zoneref->{bridge} = $interface;
|
||||
}
|
||||
}
|
||||
|
||||
$interfaces{$port}{bridge} = $bridge = $interface;
|
||||
$interface = $port;
|
||||
} else {
|
||||
fatal_error "Duplicate Interface ( $interface )" if $interfaces{$interface};
|
||||
fatal_error "Zones of type 'bport' may only be associated with bridge ports" if $zone && $zoneref->{type} eq 'bport4';
|
||||
$interfaces{$interface}{bridge} = $interface;
|
||||
}
|
||||
|
||||
|
||||
my $wildcard = 0;
|
||||
|
||||
if ( $interface =~ /\+$/ ) {
|
||||
@ -234,7 +246,7 @@ sub validate_interfaces_file()
|
||||
} else {
|
||||
$interfaces{$interface}{root} = $interface;
|
||||
}
|
||||
|
||||
|
||||
unless ( $networks eq '' || $networks eq 'detect' ) {
|
||||
|
||||
for my $address ( split /,/, $networks ) {
|
||||
@ -300,7 +312,7 @@ sub validate_interfaces_file()
|
||||
|
||||
$interfaces{$interface}{options} = $optionsref = \%options;
|
||||
|
||||
push @interfaces, $interface;
|
||||
push @ifaces, $interface;
|
||||
|
||||
my @networks;
|
||||
|
||||
@ -316,10 +328,27 @@ sub validate_interfaces_file()
|
||||
add_group_to_zone( $zone, $zoneref->{type}, $interface, \@networks, $optionsref ) if $zone && @networks;
|
||||
|
||||
$interfaces{$interface}{zone} = $zone; #Must follow the call to add_group_to_zone()
|
||||
|
||||
|
||||
progress_message " Interface \"$line\" Validated";
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# We now assemble the @interfaces array such that bridge ports immediately precede their associated bridge
|
||||
#
|
||||
for my $interface ( @ifaces ) {
|
||||
my $interfaceref = $interfaces{$interface};
|
||||
|
||||
next if $interfaceref->{options}{port};
|
||||
|
||||
if ( $interfaceref->{options}{bridge} ) {
|
||||
for my $port ( grep $interfaces{$_}{options}{port} && $interfaces{$_}{bridge} eq $interface, @ifaces ) {
|
||||
push @interfaces, $port;
|
||||
}
|
||||
}
|
||||
|
||||
push @interfaces, $interface;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
@ -349,6 +378,24 @@ sub known_interface($)
|
||||
0;
|
||||
}
|
||||
|
||||
#
|
||||
# Return the bridge associated with the passed interface. If the interface is not a bridge port,
|
||||
# return ''
|
||||
#
|
||||
sub port_to_bridge( $ ) {
|
||||
my $portref = $interfaces{$_[0]};
|
||||
return $portref && $portref->{options}{port} ? $portref->{bridge} : '';
|
||||
}
|
||||
|
||||
#
|
||||
# Return the bridge associated with the passed interface. If the interface is not a bridge port, return
|
||||
# the name of the interface itself.
|
||||
#
|
||||
sub source_port_to_bridge( $ ) {
|
||||
my $portref = $interfaces{$_[0]};
|
||||
return $portref ? $portref->{bridge} : '';
|
||||
}
|
||||
|
||||
#
|
||||
# Return the 'optional' setting of the passed interface
|
||||
#
|
||||
|
@ -1374,32 +1374,6 @@ sub generate_matrix() {
|
||||
add_rule $chainref, "-j $name";
|
||||
}
|
||||
|
||||
#
|
||||
# Match Source Interface
|
||||
#
|
||||
sub match_source_dev( $ ) {
|
||||
my $interface = shift;
|
||||
my $interfaceref = $interfaces{$interface};
|
||||
if ( $interfaceref->{options}{port} ) {
|
||||
"-i $interfaceref->{bridge} -m physdev --physdev-in $interface ";
|
||||
} else {
|
||||
"-i $interface ";
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Match Dest device
|
||||
#
|
||||
sub match_dest_dev( $ ) {
|
||||
my $interface = shift;
|
||||
my $interfaceref = $interfaces{$interface};
|
||||
if ( $interfaceref->{options}{port} ) {
|
||||
"-o $interfaceref->{bridge} -m physdev --physdev-out $interface ";
|
||||
} else {
|
||||
"-o $interface ";
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Insert the passed exclusions at the front of the passed chain.
|
||||
#
|
||||
@ -1611,6 +1585,10 @@ sub generate_matrix() {
|
||||
next if ( %{ $zoneref->{interfaces} } < 2 ) && ! ( $zoneref->{options}{in_out}{routeback} || @$exclusions );
|
||||
}
|
||||
|
||||
if ( $zone1ref->{type} eq 'bport4' ) {
|
||||
next unless $zoneref->{bridge} eq $zone1ref->{bridge};
|
||||
}
|
||||
|
||||
if ( $chain =~ /2all$/ ) {
|
||||
if ( $chain ne $last_chain ) {
|
||||
$last_chain = $chain;
|
||||
@ -1665,6 +1643,10 @@ sub generate_matrix() {
|
||||
next ZONE1 if ( $num_ifaces = %{$zoneref->{interfaces}} ) < 2 && ! ( $zoneref->{options}{in_out}{routeback} || @$exclusions );
|
||||
}
|
||||
|
||||
if ( $zone1ref->{type} eq 'bport4' ) {
|
||||
next ZONE1 unless $zoneref->{bridge} eq $zone1ref->{bridge};
|
||||
}
|
||||
|
||||
my $chainref = $filter_table->{$chain};
|
||||
my $exclusions1 = $zone1ref->{exclusions};
|
||||
|
||||
|
@ -234,12 +234,6 @@ sub determine_zones()
|
||||
$zoneref->{type} = 'ipsec4';
|
||||
} elsif ( $type =~ /^bport4?$/i ) {
|
||||
fatal_error "Bridge Port zones must have a single parent zone" unless @parents == 1;
|
||||
|
||||
for my $p ( @parents ) {
|
||||
my $interfaceref = $interfaces{$1};
|
||||
fatal_error "Parent Zone $p is not associated with device $1" unless $interfaceref && $interfaceref->{zone} eq $zone;
|
||||
}
|
||||
|
||||
$zoneref->{type} = 'bport4';
|
||||
|
||||
} elsif ( $type eq 'firewall' ) {
|
||||
|
Loading…
Reference in New Issue
Block a user