Implement 'physical' option

This commit is contained in:
Tom Eastep 2009-11-06 07:27:44 -08:00
parent a98195e156
commit 89bdcf9a3d
4 changed files with 90 additions and 29 deletions

View File

@ -165,7 +165,7 @@ our %EXPORT_TAGS = (
Exporter::export_ok_tags('internal');
our $VERSION = '4.4_2';
our $VERSION = '4.4_4';
#
# Chain Table
@ -1725,11 +1725,12 @@ sub match_source_dev( $ ) {
my $interface = shift;
return '' if $interface eq '+';
my $interfaceref = known_interface( $interface );
my $physical = $interfaceref->{physical};
if ( $interfaceref && $interfaceref->{options}{port} ) {
$interface =~ s/\++/+/;
"-i $interfaceref->{bridge} -m physdev --physdev-in $interface ";
"-i $interfaceref->{bridge} -m physdev --physdev-in $physical ";
} else {
"-i $interface ";
"-i $physical ";
}
}
@ -1740,15 +1741,16 @@ sub match_dest_dev( $ ) {
my $interface = shift;
return '' if $interface eq '+';
my $interfaceref = known_interface( $interface );
my $physical = $interfaceref->{physical};
if ( $interfaceref && $interfaceref->{options}{port} ) {
if ( $capabilities{PHYSDEV_BRIDGE} ) {
$interface =~ s/\++/+/;
"-o $interfaceref->{bridge} -m physdev --physdev-is-bridged --physdev-out $interface ";
"-o $interfaceref->{bridge} -m physdev --physdev-is-bridged --physdev-out $physical ";
} else {
"-o $interfaceref->{bridge} -m physdev --physdev-out $interface ";
"-o $interfaceref->{bridge} -m physdev --physdev-out $physical ";
}
} else {
"-o $interface ";
"-o $physical ";
}
}

View File

@ -60,6 +60,7 @@ our @EXPORT = qw( NOTHING
interface_number
find_interface
known_interface
get_physical
have_bridges
port_to_bridge
source_port_to_bridge
@ -73,7 +74,7 @@ our @EXPORT = qw( NOTHING
);
our @EXPORT_OK = qw( initialize );
our $VERSION = '4.4_1';
our $VERSION = '4.4_4';
#
# IPSEC Option types
@ -163,6 +164,8 @@ use constant { SIMPLE_IF_OPTION => 1,
NUMERIC_IF_OPTION => 4,
OBSOLETE_IF_OPTION => 5,
IPLIST_IF_OPTION => 6,
STRING_IF_OPTION => 7,
MASK_IF_OPTION => 7,
IF_OPTION_ZONEONLY => 8,
@ -215,6 +218,7 @@ sub initialize( $ ) {
upnp => SIMPLE_IF_OPTION,
upnpclient => SIMPLE_IF_OPTION,
mss => NUMERIC_IF_OPTION,
physical => STRING_IF_OPTION + IF_OPTION_HOST,
);
%validhostoptions = (
blacklist => 1,
@ -240,6 +244,7 @@ sub initialize( $ ) {
tcpflags => SIMPLE_IF_OPTION + IF_OPTION_HOST,
mss => NUMERIC_IF_OPTION,
forward => NUMERIC_IF_OPTION,
physical => STRING_IF_OPTION + IF_OPTION_HOST,
);
%validhostoptions = (
blacklist => 1,
@ -769,6 +774,7 @@ sub process_interface( $ ) {
$root = $interface;
}
my $physical = $interface;
my $broadcasts;
unless ( $networks eq '' || $networks eq 'detect' ) {
@ -870,6 +876,11 @@ sub process_interface( $ ) {
# Assume 'broadcast'
#
$hostoptions{broadcast} = 1;
} elsif ( $type == STRING_IF_OPTION ) {
fatal_error "The $option option requires a value" unless defined $value;
fatal_error "Invalid Physical interface name ($value)" unless $value =~ /^[\w.@%-]+\+?$/;
fatal_error "The $option option is only allowed on bridge ports" unless $port;
$physical = $value;
} else {
warning_message "Support for the $option interface option has been removed from Shorewall";
}
@ -893,7 +904,8 @@ sub process_interface( $ ) {
root => $root ,
broadcasts => $broadcasts ,
options => \%options ,
zone => ''
zone => '',
physical => $physical
};
if ( $zone ) {
@ -951,6 +963,20 @@ sub validate_interfaces_file( $ ) {
fatal_error "No network interfaces defined" unless @interfaces;
}
#
# Map the passed name to the corresponding physical name in the passed interface
#
sub map_physical( $$ ) {
my ( $name, $interfaceref ) = @_;
my $physical = $interfaceref->{physical};
return $physical if $name eq $interfaceref->{name};
$physical =~ s/\+$//;
$physical . substr( $name, length $interfaceref->{root} );
}
#
# Returns true if passed interface matches an entry in /etc/shorewall/interfaces
#
@ -971,7 +997,12 @@ sub known_interface($)
#
# Cache this result for future reference. We set the 'name' to the name of the entry that appears in /etc/shorewall/interfaces.
#
return $interfaces{$interface} = { options => $interfaceref->{options}, bridge => $interfaceref->{bridge} , name => $i , number => $interfaceref->{number} };
return $interfaces{$interface} = { options => $interfaceref->{options},
bridge => $interfaceref->{bridge} ,
name => $i ,
number => $interfaceref->{number} ,
physical => map_physical( $interface, $interfaceref )
};
}
}
@ -1011,6 +1042,13 @@ sub find_interface( $ ) {
$interfaceref;
}
#
# Returns the physical interface associated with the passed logical name
#
sub get_physical( $ ) {
known_interface( $_[0] )->{physical};
}
#
# Returns true if there are bridge port zones defined in the config
#

View File

@ -8,7 +8,7 @@ Changes in Shorewall 4.4.4
4) Allow long port lists in /etc/shorewall/routestopped.
5) Handle duplicate wildcard ports on different bridges.
5) Implement 'physical' interface option.
Changes in Shorewall 4.4.3

View File

@ -190,25 +190,6 @@ Shorewall 4.4.4
2) The Shorewall operations log (specified by STARTUP_LOG) is now
secured 0600.
3) Previously, the following valid configuration would produce a fatal
error reporting "Duplicate interface name (p+)"
/etc/shorewall/zones:
#ZONE TYPE
fw firewall
world ipv4
z1:world bport4
z2:world bport4
/etc/shorewall/interfaces:
#ZONE INTERFACE BROADCAST OPTIONS
world br0 - bridge
world br1 - bridge
z1 br0:p+
z2 br1:p+
----------------------------------------------------------------------------
K N O W N P R O B L E M S R E M A I N I N G
----------------------------------------------------------------------------
@ -226,6 +207,46 @@ None.
2) The limit of 15 entries in a port list has been relaxed in
/etc/shorewall/routestopped.
3) The following seemingly valid configuration produces a fatal
error reporting "Duplicate interface name (p+)"
/etc/shorewall/zones:
#ZONE TYPE
fw firewall
world ipv4
z1:world bport4
z2:world bport4
/etc/shorewall/interfaces:
#ZONE INTERFACE BROADCAST OPTIONS
world br0 - bridge
world br1 - bridge
z1 br0:p+
z2 br1:p+
That is because the Shorewall implementation requires each bridge
port to have a unique name.
To work around this problem, a new 'physical' interface option has
been created. The above configuration may be defined using the
following in /etc/shorewall/interfaces:
#ZONE INTERFACE BROADCAST OPTIONS
world br0 - bridge
world br1 - bridge
z1 br0:x+ - physical=p+
z2 br1:y+ - physical=p+
In this configuration, 'x+' is the logical name for ports p+ on
bridge br0 while 'y+' is the logical name for ports p+ on bridge
br1.
If you need to refer to a particular port on br1 (for example
p1023), you write it as y1023; Shorewall will translate that name
to p1023 when needed.
----------------------------------------------------------------------------
N E W F E A T U R E S I N 4 . 4 . 0
----------------------------------------------------------------------------