diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 5ee3bdfbc..fdb975957 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -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 "; } } diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index 7ee5d5c39..fca47f70c 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -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 # diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index 28feae1aa..dc1a36bad 100644 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -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 diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index 033bfe2b9..a03eba14b 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -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 ----------------------------------------------------------------------------