Add the 'loopback' interface option

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2015-01-03 09:22:40 -08:00
parent 33e2e19193
commit 7dd9ccd06b
5 changed files with 84 additions and 27 deletions

View File

@ -412,7 +412,7 @@ our %capdesc = ( NAT_ENABLED => 'NAT',
SIP0_HELPER => 'SIP-0 Helper', SIP0_HELPER => 'SIP-0 Helper',
SNMP_HELPER => 'SNMP Helper', SNMP_HELPER => 'SNMP Helper',
TFTP_HELPER => 'TFTP Helper', TFTP_HELPER => 'TFTP Helper',
TFTP0_HELPER => 'TFTP-0 Helper', TFTP0_HELPER => 'TFTP-0 Helper',
# #
# Constants # Constants
# #

View File

@ -854,7 +854,7 @@ sub add_common_rules ( $$ ) {
my $interfaceref = find_interface $interface; 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} ) { unless ( $interfaceref->{options}{ignore} & NO_SFILTER || $interfaceref->{options}{rpfilter} ) {
my @filters = @{$interfaceref->{filter}}; my @filters = @{$interfaceref->{filter}};
@ -1452,7 +1452,7 @@ sub handle_loopback_traffic() {
my $rawout = $raw_table->{OUTPUT}; my $rawout = $raw_table->{OUTPUT};
my $rulenum = 0; my $rulenum = 0;
my $loopback = loopback_zones; my $loopback = loopback_zones;
my $loref = known_interface('lo'); my $loref = known_interface(loopback_interface);
my $unmanaged; my $unmanaged;
my $outchainref; my $outchainref;
@ -1463,17 +1463,17 @@ sub handle_loopback_traffic() {
# We have a vserver zone -- route output through a separate chain # We have a vserver zone -- route output through a separate chain
# #
$outchainref = new_standard_chain 'loopback'; $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 { } else {
# #
# Only the firewall -- just use the OUTPUT chain # Only the firewall -- just use the OUTPUT chain
# #
if ( $unmanaged = $loref && $loref->{options}{unmanaged} ) { if ( $unmanaged = $loref && $loref->{options}{unmanaged} ) {
add_ijump( $filter_table->{INPUT}, j => 'ACCEPT', i => 'lo' ); add_ijump( $filter_table->{INPUT}, j => 'ACCEPT', i => loopback_interface );
add_ijump( $filter_table->{OUTPUT}, j => 'ACCEPT', o => 'lo' ); add_ijump( $filter_table->{OUTPUT}, j => 'ACCEPT', o => loopback_interface );
} else { } else {
$outchainref = $filter_table->{OUTPUT}; $outchainref = $filter_table->{OUTPUT};
@rule = ( o => 'lo'); @rule = ( o => loopback_interface);
} }
} }
@ -1552,7 +1552,7 @@ sub add_interface_jumps {
our %forward_jump_added; our %forward_jump_added;
my @interfaces = grep $_ ne '%vserver%', @_; my @interfaces = grep $_ ne '%vserver%', @_;
my $dummy; 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 # Add Nat jumps
# #
@ -1582,7 +1582,7 @@ sub add_interface_jumps {
my $outputref = $filter_table->{output_chain $interface}; my $outputref = $filter_table->{output_chain $interface};
my $interfaceref = find_interface($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} ) { if ( $interfaceref->{options}{port} ) {
my $bridge = $interfaceref->{bridge}; 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; handle_loopback_traffic;
} }
@ -2551,8 +2551,8 @@ EOF
process_routestopped unless process_stoppedrules; process_routestopped unless process_stoppedrules;
add_ijump $input, j => 'ACCEPT', i => 'lo'; add_ijump $input, j => 'ACCEPT', i => loopback_interface;
add_ijump $output, j => 'ACCEPT', o => 'lo' unless $config{ADMINISABSENTMINDED}; add_ijump $output, j => 'ACCEPT', o => loopback_interface unless $config{ADMINISABSENTMINDED};
my $interfaces = find_interfaces_by_option 'dhcp'; my $interfaces = find_interfaces_by_option 'dhcp';

View File

@ -55,6 +55,7 @@ our @EXPORT = ( qw( NOTHING
find_zone find_zone
firewall_zone firewall_zone
loopback_zones loopback_zones
loopback_interface
local_zones local_zones
defined_zone defined_zone
zone_type zone_type
@ -219,6 +220,7 @@ our $minroot;
our $zonemark; our $zonemark;
our $zonemarkincr; our $zonemarkincr;
our $zonemarklimit; our $zonemarklimit;
our $loopback_interface;
use constant { FIREWALL => 1, use constant { FIREWALL => 1,
IP => 2, IP => 2,
@ -329,6 +331,7 @@ sub initialize( $$ ) {
%mapbase1 = (); %mapbase1 = ();
$baseseq = 0; $baseseq = 0;
$minroot = 0; $minroot = 0;
$loopback_interface = '';
if ( $family == F_IPV4 ) { if ( $family == F_IPV4 ) {
%validinterfaceoptions = (arp_filter => BINARY_IF_OPTION, %validinterfaceoptions = (arp_filter => BINARY_IF_OPTION,
@ -341,6 +344,7 @@ sub initialize( $$ ) {
ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK, ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK,
maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST, maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
logmartians => BINARY_IF_OPTION, logmartians => BINARY_IF_OPTION,
loopback => BINARY_IF_OPTION,
nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER, nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER,
norfc1918 => OBSOLETE_IF_OPTION, norfc1918 => OBSOLETE_IF_OPTION,
nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST, nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST,
@ -386,6 +390,7 @@ sub initialize( $$ ) {
destonly => SIMPLE_IF_OPTION + IF_OPTION_HOST, destonly => SIMPLE_IF_OPTION + IF_OPTION_HOST,
dhcp => SIMPLE_IF_OPTION, dhcp => SIMPLE_IF_OPTION,
ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK, ignore => NUMERIC_IF_OPTION + IF_OPTION_WILDOK,
loopback => BINARY_IF_OPTION,
maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST, maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER, nets => IPLIST_IF_OPTION + IF_OPTION_ZONEONLY + IF_OPTION_VSERVER,
nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST, nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST,
@ -1353,8 +1358,15 @@ sub process_interface( $$ ) {
$options{ignore} ||= 0; $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} ) { 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 ) ) { while ( my ( $option, $value ) = each( %options ) ) {
fatal_error "The $option option may not be specified with 'unmanaged'" if $prohibitunmanaged{$option}; fatal_error "The $option option may not be specified with 'unmanaged'" if $prohibitunmanaged{$option};
@ -1382,9 +1394,9 @@ sub process_interface( $$ ) {
if ( $zone ) { if ( $zone ) {
fatal_error "Unmanaged interfaces may not be associated with a zone" if $options{unmanaged}; fatal_error "Unmanaged interfaces may not be associated with a zone" if $options{unmanaged};
if ( $physical eq 'lo' ) { if ( $options{loopback} ) {
fatal_error "Only a loopback zone may be assigned to 'lo'" unless $zoneref->{type} == LOOPBACK; fatal_error "Only a loopback zone may be assigned to '$physical'" unless $zoneref->{type} == LOOPBACK;
fatal_error "Invalid definition of 'lo'" if $bridge ne $interface; fatal_error "Invalid definition of '$physical'" if $bridge ne $interface;
for ( qw/arp_filter for ( qw/arp_filter
arp_ignore arp_ignore
@ -1406,10 +1418,10 @@ sub process_interface( $$ ) {
upnpclient upnpclient
mss 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 { } 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 ]; $netsref ||= [ allip ];
@ -1466,6 +1478,22 @@ sub validate_interfaces_file( $ ) {
# #
fatal_error "No network interfaces defined" unless @interfaces; 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 ) { if ( vserver_zones ) {
# #
# While the user thinks that vservers are associated with a particular interface, they really are not. # 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 , broadcasts => undef ,
options => {} , options => {} ,
zone => '', zone => '',
physical => 'lo', physical => $loopback_interface,
}; };
push @interfaces, $interface; push @interfaces, $interface;
@ -1543,6 +1571,13 @@ sub known_interface($)
$physical{$interface} || 0; $physical{$interface} || 0;
} }
#
# Return the loopback interface physical name
#
sub loopback_interface() {
$loopback_interface;
}
# #
# Return interface number # 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). # Return a list of unmanaged interfaces (skip 'lo' since it is implicitly unmanaged when there are no loopback zones).
# #
sub unmanaged_interfaces() { 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 "Unknown interface ($interface)" unless ($interfaceref = $interfaces{$interface}) && $interfaceref->{root};
fatal_error "Unmanaged interfaces may not be associated with a zone" if $interfaceref->{unmanaged}; fatal_error "Unmanaged interfaces may not be associated with a zone" if $interfaceref->{unmanaged};
if ( $interfaceref->{name} eq 'lo' ) { if ( $interfaceref->{physical} eq $loopback_interface ) {
fatal_error "Only a loopback zone may be associated with the loopback interface (lo)" if $type != LOOPBACK; fatal_error "Only a loopback zone may be associated with the loopback interface ($loopback_interface)" if $type != LOOPBACK;
} else { } 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 { } else {
fatal_error "Invalid HOST(S) column contents: $hosts" fatal_error "Invalid HOST(S) column contents: $hosts"

View File

@ -213,7 +213,7 @@ loc eth2 -</programlisting>
changed; the value assigned to the setting will be the value changed; the value assigned to the setting will be the value
specified (if any) or 1 if no value is given.</para> specified (if any) or 1 if no value is given.</para>
<para></para> <para/>
<note> <note>
<para>This option does not work with a wild-card <para>This option does not work with a wild-card
@ -247,7 +247,7 @@ loc eth2 -</programlisting>
<para>8 - do not reply for all local addresses</para> <para>8 - do not reply for all local addresses</para>
<para></para> <para/>
<note> <note>
<para>This option does not work with a wild-card <para>This option does not work with a wild-card
@ -255,7 +255,7 @@ loc eth2 -</programlisting>
the INTERFACE column.</para> the INTERFACE column.</para>
</note> </note>
<para></para> <para/>
<warning> <warning>
<para>Do not specify <emphasis <para>Do not specify <emphasis
@ -382,6 +382,17 @@ loc eth2 -</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>loopback</term>
<listitem>
<para>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>loopback</option> option specified.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><emphasis <term><emphasis
role="bold">logmartians[={0|1}]</emphasis></term> role="bold">logmartians[={0|1}]</emphasis></term>
@ -414,7 +425,7 @@ loc eth2 -</programlisting>
1 1
teastep@lists:~$ </programlisting> teastep@lists:~$ </programlisting>
<para></para> <para/>
<note> <note>
<para>This option does not work with a wild-card <para>This option does not work with a wild-card

View File

@ -323,6 +323,17 @@ loc eth2 -</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>loopback</term>
<listitem>
<para>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>loopback</option> option specified.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><emphasis <term><emphasis
role="bold">mss</emphasis>=<emphasis>number</emphasis></term> role="bold">mss</emphasis>=<emphasis>number</emphasis></term>