From 7dd9ccd06bf81f0aff44c304d0f5cc3f7f4d5c87 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sat, 3 Jan 2015 09:22:40 -0800 Subject: [PATCH] Add the 'loopback' interface option Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Config.pm | 2 +- Shorewall/Perl/Shorewall/Misc.pm | 22 +++---- Shorewall/Perl/Shorewall/Zones.pm | 57 +++++++++++++++---- Shorewall/manpages/shorewall-interfaces.xml | 19 +++++-- Shorewall6/manpages/shorewall6-interfaces.xml | 11 ++++ 5 files changed, 84 insertions(+), 27 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index e9c375c49..203c261ac 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -412,7 +412,7 @@ our %capdesc = ( NAT_ENABLED => 'NAT', SIP0_HELPER => 'SIP-0 Helper', SNMP_HELPER => 'SNMP Helper', TFTP_HELPER => 'TFTP Helper', - TFTP0_HELPER => 'TFTP-0 Helper', + TFTP0_HELPER => 'TFTP-0 Helper', # # Constants # diff --git a/Shorewall/Perl/Shorewall/Misc.pm b/Shorewall/Perl/Shorewall/Misc.pm index d35c46db0..81f464c9d 100644 --- a/Shorewall/Perl/Shorewall/Misc.pm +++ b/Shorewall/Perl/Shorewall/Misc.pm @@ -854,7 +854,7 @@ sub add_common_rules ( $$ ) { my $interfaceref = find_interface $interface; - unless ( $interfaceref->{physical} eq 'lo' ) { + unless ( $interfaceref->{physical} eq loopback_interface ) { unless ( $interfaceref->{options}{ignore} & NO_SFILTER || $interfaceref->{options}{rpfilter} ) { my @filters = @{$interfaceref->{filter}}; @@ -1452,7 +1452,7 @@ sub handle_loopback_traffic() { my $rawout = $raw_table->{OUTPUT}; my $rulenum = 0; my $loopback = loopback_zones; - my $loref = known_interface('lo'); + my $loref = known_interface(loopback_interface); my $unmanaged; my $outchainref; @@ -1463,17 +1463,17 @@ sub handle_loopback_traffic() { # We have a vserver zone -- route output through a separate chain # $outchainref = new_standard_chain 'loopback'; - add_ijump $filter_table->{OUTPUT}, j => $outchainref, o => 'lo'; + add_ijump $filter_table->{OUTPUT}, j => $outchainref, o => loopback_interface; } else { # # Only the firewall -- just use the OUTPUT chain # if ( $unmanaged = $loref && $loref->{options}{unmanaged} ) { - add_ijump( $filter_table->{INPUT}, j => 'ACCEPT', i => 'lo' ); - add_ijump( $filter_table->{OUTPUT}, j => 'ACCEPT', o => 'lo' ); + add_ijump( $filter_table->{INPUT}, j => 'ACCEPT', i => loopback_interface ); + add_ijump( $filter_table->{OUTPUT}, j => 'ACCEPT', o => loopback_interface ); } else { $outchainref = $filter_table->{OUTPUT}; - @rule = ( o => 'lo'); + @rule = ( o => loopback_interface); } } @@ -1552,7 +1552,7 @@ sub add_interface_jumps { our %forward_jump_added; my @interfaces = grep $_ ne '%vserver%', @_; my $dummy; - my $lo_jump_added = interface_zone( 'lo' ) && ! get_interface_option( 'lo', 'destonly' ); + my $lo_jump_added = interface_zone( loopback_interface ) && ! get_interface_option( loopback_interface, 'destonly' ); # # Add Nat jumps # @@ -1582,7 +1582,7 @@ sub add_interface_jumps { my $outputref = $filter_table->{output_chain $interface}; my $interfaceref = find_interface($interface); - add_ijump $filter_table->{INPUT} , j => 'ACCEPT', i => 'lo' if $interfaceref->{physical} eq '+' && ! $lo_jump_added++; + add_ijump $filter_table->{INPUT} , j => 'ACCEPT', i => loopback_interface if $interfaceref->{physical} eq '+' && ! $lo_jump_added++; if ( $interfaceref->{options}{port} ) { my $bridge = $interfaceref->{bridge}; @@ -1621,7 +1621,7 @@ sub add_interface_jumps { } } - add_ijump $filter_table->{INPUT} , j => 'ACCEPT', i => 'lo' unless $lo_jump_added++; + add_ijump $filter_table->{INPUT} , j => 'ACCEPT', i => loopback_interface unless $lo_jump_added++; handle_loopback_traffic; } @@ -2551,8 +2551,8 @@ EOF process_routestopped unless process_stoppedrules; - add_ijump $input, j => 'ACCEPT', i => 'lo'; - add_ijump $output, j => 'ACCEPT', o => 'lo' unless $config{ADMINISABSENTMINDED}; + add_ijump $input, j => 'ACCEPT', i => loopback_interface; + add_ijump $output, j => 'ACCEPT', o => loopback_interface unless $config{ADMINISABSENTMINDED}; my $interfaces = find_interfaces_by_option 'dhcp'; diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index 98b323c67..85d7235f6 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -55,6 +55,7 @@ our @EXPORT = ( qw( NOTHING find_zone firewall_zone loopback_zones + loopback_interface local_zones defined_zone zone_type @@ -219,6 +220,7 @@ our $minroot; our $zonemark; our $zonemarkincr; our $zonemarklimit; +our $loopback_interface; use constant { FIREWALL => 1, IP => 2, @@ -329,6 +331,7 @@ sub initialize( $$ ) { %mapbase1 = (); $baseseq = 0; $minroot = 0; + $loopback_interface = ''; if ( $family == F_IPV4 ) { %validinterfaceoptions = (arp_filter => BINARY_IF_OPTION, @@ -341,6 +344,7 @@ sub initialize( $$ ) { ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK, maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST, logmartians => BINARY_IF_OPTION, + loopback => BINARY_IF_OPTION, nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER, norfc1918 => OBSOLETE_IF_OPTION, nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST, @@ -386,6 +390,7 @@ sub initialize( $$ ) { destonly => SIMPLE_IF_OPTION + IF_OPTION_HOST, dhcp => SIMPLE_IF_OPTION, ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK, + loopback => BINARY_IF_OPTION, maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST, nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER, nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST, @@ -1353,8 +1358,15 @@ sub process_interface( $$ ) { $options{ignore} ||= 0; } + $options{loopback} ||= ( $physical eq 'lo' ); + + if ( $options{loopback} ) { + fatal_error "Only one 'loopback' interface is allowed" if $loopback_interface; + $loopback_interface = $physical; + } + if ( $options{unmanaged} ) { - fatal_error "The 'lo' interface may not be unmanaged when there are vserver zones" if $physical eq 'lo' && vserver_zones; + fatal_error "The loopback interface ($loopback_interface) may not be unmanaged when there are vserver zones" if $options{loopback} && vserver_zones; while ( my ( $option, $value ) = each( %options ) ) { fatal_error "The $option option may not be specified with 'unmanaged'" if $prohibitunmanaged{$option}; @@ -1382,9 +1394,9 @@ sub process_interface( $$ ) { if ( $zone ) { fatal_error "Unmanaged interfaces may not be associated with a zone" if $options{unmanaged}; - if ( $physical eq 'lo' ) { - fatal_error "Only a loopback zone may be assigned to 'lo'" unless $zoneref->{type} == LOOPBACK; - fatal_error "Invalid definition of 'lo'" if $bridge ne $interface; + if ( $options{loopback} ) { + fatal_error "Only a loopback zone may be assigned to '$physical'" unless $zoneref->{type} == LOOPBACK; + fatal_error "Invalid definition of '$physical'" if $bridge ne $interface; for ( qw/arp_filter arp_ignore @@ -1406,10 +1418,10 @@ sub process_interface( $$ ) { upnpclient mss / ) { - fatal_error "The 'lo' interface may not specify the '$_' option" if supplied $options{$_}; + fatal_error "The '$config{LOOPBACK}' interface may not specify the '$_' option" if supplied $options{$_}; } } else { - fatal_error "A loopback zone may only be assigned to 'lo'" if $zoneref->{type} == LOOPBACK; + fatal_error "A loopback zone may only be assigned to the loopback interface" if $zoneref->{type} == LOOPBACK; } $netsref ||= [ allip ]; @@ -1466,6 +1478,22 @@ sub validate_interfaces_file( $ ) { # fatal_error "No network interfaces defined" unless @interfaces; + # + # Define the loopback interface if it hasn't been already + # + unless ( $loopback_interface ) { + $interfaces{lo} = { name => 'lo', + bridge => 'lo', + nets => 0, + number => $nextinum++, + root => 'lo', + broadcasts => undef, + options => { unmanaged => 1, loopback => 1 , ignore => 1 }, + zone => '', + physical => 'lo' }; + push @interfaces, $loopback_interface = 'lo'; + } + if ( vserver_zones ) { # # While the user thinks that vservers are associated with a particular interface, they really are not. @@ -1481,7 +1509,7 @@ sub validate_interfaces_file( $ ) { broadcasts => undef , options => {} , zone => '', - physical => 'lo', + physical => $loopback_interface, }; push @interfaces, $interface; @@ -1543,6 +1571,13 @@ sub known_interface($) $physical{$interface} || 0; } +# +# Return the loopback interface physical name +# +sub loopback_interface() { + $loopback_interface; +} + # # Return interface number # @@ -1589,7 +1624,7 @@ sub managed_interfaces() { # Return a list of unmanaged interfaces (skip 'lo' since it is implicitly unmanaged when there are no loopback zones). # sub unmanaged_interfaces() { - grep ( $interfaces{$_}{options}{unmanaged} && $_ ne 'lo', @interfaces ); + grep ( $interfaces{$_}{options}{unmanaged} && ! $interfaces{$_}{options}{loopback}, @interfaces ); } # @@ -1989,10 +2024,10 @@ sub process_host( ) { fatal_error "Unknown interface ($interface)" unless ($interfaceref = $interfaces{$interface}) && $interfaceref->{root}; fatal_error "Unmanaged interfaces may not be associated with a zone" if $interfaceref->{unmanaged}; - if ( $interfaceref->{name} eq 'lo' ) { - fatal_error "Only a loopback zone may be associated with the loopback interface (lo)" if $type != LOOPBACK; + if ( $interfaceref->{physical} eq $loopback_interface ) { + fatal_error "Only a loopback zone may be associated with the loopback interface ($loopback_interface)" if $type != LOOPBACK; } else { - fatal_error "Loopback zones may only be associated with the loopback interface (lo)" if $type == LOOPBACK; + fatal_error "Loopback zones may only be associated with the loopback interface ($loopback_interface)" if $type == LOOPBACK; } } else { fatal_error "Invalid HOST(S) column contents: $hosts" diff --git a/Shorewall/manpages/shorewall-interfaces.xml b/Shorewall/manpages/shorewall-interfaces.xml index 5b3072d6f..197b090d4 100644 --- a/Shorewall/manpages/shorewall-interfaces.xml +++ b/Shorewall/manpages/shorewall-interfaces.xml @@ -213,7 +213,7 @@ loc eth2 - changed; the value assigned to the setting will be the value specified (if any) or 1 if no value is given. - + This option does not work with a wild-card @@ -247,7 +247,7 @@ loc eth2 - 8 - do not reply for all local addresses - + This option does not work with a wild-card @@ -255,7 +255,7 @@ loc eth2 - the INTERFACE column. - + Do not specify + + loopback + + + Added in Shorewall 4.6.6. Designates the interface as + the loopback interface. This option is assumed if the + interface's physical name is 'lo'. Only one interface man have + the option specified. + + + logmartians[={0|1}] @@ -414,7 +425,7 @@ loc eth2 - 1 teastep@lists:~$ - + This option does not work with a wild-card diff --git a/Shorewall6/manpages/shorewall6-interfaces.xml b/Shorewall6/manpages/shorewall6-interfaces.xml index bba8f1a76..57bca16a5 100644 --- a/Shorewall6/manpages/shorewall6-interfaces.xml +++ b/Shorewall6/manpages/shorewall6-interfaces.xml @@ -323,6 +323,17 @@ loc eth2 - + + loopback + + + Added in Shorewall 4.6.6. Designates the interface as + the loopback interface. This option is assumed if the + interface's physical name is 'lo'. Only one interface man have + the option specified. + + + mss=number