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_ratelimit
|
||||||
do_user
|
do_user
|
||||||
do_tos
|
do_tos
|
||||||
|
match_source_dev
|
||||||
|
match_dest_dev
|
||||||
iprange_match
|
iprange_match
|
||||||
match_source_net
|
match_source_net
|
||||||
match_dest_net
|
match_dest_net
|
||||||
@ -1029,6 +1031,32 @@ sub do_tos( $ ) {
|
|||||||
$tos ne '-' ? "-m tos --tos $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.
|
# 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
|
# 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 );
|
my $networks = get_interface_nets ( $iiface );
|
||||||
|
|
||||||
add_command( $chainref , join( '', 'for source in ', $networks, '; do' ) );
|
add_command( $chainref , join( '', 'for source in ', $networks, '; do' ) );
|
||||||
@ -1424,9 +1454,8 @@ sub expand_rule( $$$$$$$$$$ )
|
|||||||
#
|
#
|
||||||
$chainref->{loopcount}++;
|
$chainref->{loopcount}++;
|
||||||
} else {
|
} else {
|
||||||
fatal_error "Source Interface ($iiface) not allowed when the source zone is $firewall_zone"
|
fatal_error "Source Interface ($iiface) not allowed when the source zone is $firewall_zone" if $restriction & OUTPUT_RESTRICT;
|
||||||
if $restriction & OUTPUT_RESTRICT;
|
$rule .= match_source_dev( $iiface );
|
||||||
$rule .= "-i $iiface ";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1480,13 +1509,19 @@ sub expand_rule( $$$$$$$$$$ )
|
|||||||
#
|
#
|
||||||
# ADDRESS 'detect' in the masq file.
|
# 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' );
|
add_command( $chainref , 'for dest in ' . get_interface_addresses( $diface) . '; do' );
|
||||||
$rule .= '-d $dest';
|
$rule .= '-d $dest';
|
||||||
$chainref->{loopcount}++;
|
$chainref->{loopcount}++;
|
||||||
} else {
|
} else {
|
||||||
fatal_error "Destination Interface ($diface) not allowed when the destination zone is $firewall_zone"
|
fatal_error "Destination Interface ($diface) not allowed when the destination zone is $firewall_zone" if $restriction & INPUT_RESTRICT;
|
||||||
if $restriction & INPUT_RESTRICT;
|
|
||||||
$rule .= "-o $diface ";
|
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
|
our @EXPORT = qw( add_group_to_zone
|
||||||
validate_interfaces_file
|
validate_interfaces_file
|
||||||
known_interface
|
known_interface
|
||||||
|
port_to_bridge
|
||||||
interface_is_optional
|
interface_is_optional
|
||||||
find_interfaces_by_option
|
find_interfaces_by_option
|
||||||
get_interface_option
|
get_interface_option
|
||||||
@ -182,13 +183,15 @@ sub validate_interfaces_file()
|
|||||||
|
|
||||||
my $first_entry = 1;
|
my $first_entry = 1;
|
||||||
|
|
||||||
|
my @ifaces;
|
||||||
|
|
||||||
while ( read_a_line ) {
|
while ( read_a_line ) {
|
||||||
|
|
||||||
if ( $first_entry ) {
|
if ( $first_entry ) {
|
||||||
progress_message2 "$doing $fn...";
|
progress_message2 "$doing $fn...";
|
||||||
$first_entry = 0;
|
$first_entry = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ($zone, $interface, $networks, $options ) = split_line 2, 4, 'interfaces file';
|
my ($zone, $interface, $networks, $options ) = split_line 2, 4, 'interfaces file';
|
||||||
my $zoneref;
|
my $zoneref;
|
||||||
my $bridge = '';
|
my $bridge = '';
|
||||||
@ -209,23 +212,32 @@ sub validate_interfaces_file()
|
|||||||
|
|
||||||
fatal_error "Invalid INTERFACE" if defined $extra || ! $interface;
|
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 ) {
|
if ( defined $port ) {
|
||||||
require_capability( 'PHYSDEV_MATCH', 'Bridge Ports', '');
|
require_capability( 'PHYSDEV_MATCH', 'Bridge Ports', '');
|
||||||
require_capability( 'KLUDGEFREE', '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 "$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';
|
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;
|
$interfaces{$port}{bridge} = $bridge = $interface;
|
||||||
$interface = $port;
|
$interface = $port;
|
||||||
} else {
|
} 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';
|
fatal_error "Zones of type 'bport' may only be associated with bridge ports" if $zone && $zoneref->{type} eq 'bport4';
|
||||||
$interfaces{$interface}{bridge} = $interface;
|
$interfaces{$interface}{bridge} = $interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $wildcard = 0;
|
my $wildcard = 0;
|
||||||
|
|
||||||
if ( $interface =~ /\+$/ ) {
|
if ( $interface =~ /\+$/ ) {
|
||||||
@ -234,7 +246,7 @@ sub validate_interfaces_file()
|
|||||||
} else {
|
} else {
|
||||||
$interfaces{$interface}{root} = $interface;
|
$interfaces{$interface}{root} = $interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
unless ( $networks eq '' || $networks eq 'detect' ) {
|
unless ( $networks eq '' || $networks eq 'detect' ) {
|
||||||
|
|
||||||
for my $address ( split /,/, $networks ) {
|
for my $address ( split /,/, $networks ) {
|
||||||
@ -300,7 +312,7 @@ sub validate_interfaces_file()
|
|||||||
|
|
||||||
$interfaces{$interface}{options} = $optionsref = \%options;
|
$interfaces{$interface}{options} = $optionsref = \%options;
|
||||||
|
|
||||||
push @interfaces, $interface;
|
push @ifaces, $interface;
|
||||||
|
|
||||||
my @networks;
|
my @networks;
|
||||||
|
|
||||||
@ -316,10 +328,27 @@ sub validate_interfaces_file()
|
|||||||
add_group_to_zone( $zone, $zoneref->{type}, $interface, \@networks, $optionsref ) if $zone && @networks;
|
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()
|
$interfaces{$interface}{zone} = $zone; #Must follow the call to add_group_to_zone()
|
||||||
|
|
||||||
progress_message " Interface \"$line\" Validated";
|
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;
|
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
|
# Return the 'optional' setting of the passed interface
|
||||||
#
|
#
|
||||||
|
@ -1374,32 +1374,6 @@ sub generate_matrix() {
|
|||||||
add_rule $chainref, "-j $name";
|
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.
|
# 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 );
|
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 =~ /2all$/ ) {
|
||||||
if ( $chain ne $last_chain ) {
|
if ( $chain ne $last_chain ) {
|
||||||
$last_chain = $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 );
|
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 $chainref = $filter_table->{$chain};
|
||||||
my $exclusions1 = $zone1ref->{exclusions};
|
my $exclusions1 = $zone1ref->{exclusions};
|
||||||
|
|
||||||
|
@ -234,12 +234,6 @@ sub determine_zones()
|
|||||||
$zoneref->{type} = 'ipsec4';
|
$zoneref->{type} = 'ipsec4';
|
||||||
} elsif ( $type =~ /^bport4?$/i ) {
|
} elsif ( $type =~ /^bport4?$/i ) {
|
||||||
fatal_error "Bridge Port zones must have a single parent zone" unless @parents == 1;
|
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';
|
$zoneref->{type} = 'bport4';
|
||||||
|
|
||||||
} elsif ( $type eq 'firewall' ) {
|
} elsif ( $type eq 'firewall' ) {
|
||||||
|
Loading…
Reference in New Issue
Block a user