Add 'noanycast' interface option

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2020-09-06 13:19:50 -07:00
parent 1e90a52b31
commit 4253f23d6b
No known key found for this signature in database
GPG Key ID: 96E6B3F2423A4D10
3 changed files with 114 additions and 3 deletions

View File

@ -7522,7 +7522,7 @@ sub set_global_variables( $$ ) {
emit 'ALL_BCASTS="$(get_all_bcasts) 255.255.255.255"'; emit 'ALL_BCASTS="$(get_all_bcasts) 255.255.255.255"';
emit $interfacebcasts{$_} for sortkeysiftest %interfacebcasts; emit $interfacebcasts{$_} for sortkeysiftest %interfacebcasts;
} else { } else {
emit 'ALL_ACASTS="$(get_all_acasts)"'; generate_all_acasts;
emit $interfaceacasts{$_} for sortkeysiftest %interfaceacasts; emit $interfaceacasts{$_} for sortkeysiftest %interfaceacasts;
} }
} }

View File

@ -75,6 +75,7 @@ our @EXPORT = ( qw( NOTHING
all_interfaces all_interfaces
all_real_interfaces all_real_interfaces
all_plain_interfaces all_plain_interfaces
interface_is_plain
all_bridges all_bridges
managed_interfaces managed_interfaces
unmanaged_interfaces unmanaged_interfaces
@ -103,6 +104,7 @@ our @EXPORT = ( qw( NOTHING
find_zone_hosts_by_option find_zone_hosts_by_option
find_zones_by_option find_zones_by_option
have_ipsec have_ipsec
generate_all_acasts
), ),
); );
@ -418,7 +420,8 @@ sub initialize( $$ ) {
32 => 'loopback', 32 => 'loopback',
64 => 'local' ); 64 => 'local' );
} else { } else {
%validinterfaceoptions = ( accept_ra => NUMERIC_IF_OPTION, %validinterfaceoptions = (
accept_ra => NUMERIC_IF_OPTION,
blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST, blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST,
bridge => SIMPLE_IF_OPTION, bridge => SIMPLE_IF_OPTION,
dbl => ENUM_IF_OPTION + IF_OPTION_WILDOK, dbl => ENUM_IF_OPTION + IF_OPTION_WILDOK,
@ -428,6 +431,7 @@ sub initialize( $$ ) {
loopback => BINARY_IF_OPTION, 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,
noanycast => SIMPLE_IF_OPTION + IF_OPTION_WILDOK,
nodbl => SIMPLE_IF_OPTION, nodbl => SIMPLE_IF_OPTION,
nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST, nosmurfs => SIMPLE_IF_OPTION + IF_OPTION_HOST,
optional => SIMPLE_IF_OPTION, optional => SIMPLE_IF_OPTION,
@ -1536,7 +1540,7 @@ sub process_interface( $$ ) {
zones => {}, zones => {},
origin => shortlineinfo( '' ), origin => shortlineinfo( '' ),
wildcard => $wildcard, wildcard => $wildcard,
physwild => $physwild, # Currently unused physwild => $physwild,
}; };
$interfaces{$physical} = $interfaceref if $physical ne $interface; $interfaces{$physical} = $interfaceref if $physical ne $interface;
@ -2385,4 +2389,99 @@ sub find_zones_by_option( $$ ) {
\@zns; \@zns;
} }
#
# Generate the shell code to populate the ALL_ACASTS run-time variable
#
sub generate_all_acasts() {
my ( @acasts, @noacasts, @wildacasts, @wildnoacasts );
for my $interface ( @interfaces ) {
my $interfaceref = $interfaces{$interface};
my $physical = $interfaceref->{physical};
if ( $interfaceref->{physwild} ) {
$physical =~ s/\+/*/;
if ( $interfaceref->{options}{noanycast} ) {
if ( $physical eq '*' ) {
@wildnoacasts = ( '*' );
} else {
push @wildnoacasts, $physical;
}
} else {
if ( $physical eq '*' ) {
@wildacasts = ( '*' );
} else {
push @wildacasts, $physical;
}
}
} else {
if ( $interfaceref->{options}{noanycast} ) {
push @noacasts, $physical;
} else {
push @acasts, $physical;
}
}
}
unless( @noacasts || @wildnoacasts ) {
emit( 'ALL_ACASTS="$(get_all_acasts)"' );
return;
}
@wildacasts = '*' unless @wildacasts;
emit( 'local iface',
'',
'ALL_ACASTS=',
'',
'for iface in $(find_all_interfaces1); do' );
push_indent;
emit( 'case $iface in' );
push_indent;
if ( @noacasts ) {
unless ( @wildacasts ) {
push @noacasts, @wildnoacasts;
@wildnoacasts = ();
}
emit( join( '|', @noacasts) . ')',
' ;;' );
}
if ( @wildnoacasts ) {
if ( @acasts ) {
emit( join( '|', @acasts) . ')',
' if [ -n "$ALL_ACASTS" ]; then',
' ALL_ACASTS="$ALL_ACASTS $(get_interface_acasts $iface)"',
' else',
' ALL_ACASTS="$(get_interface_acasts $iface)"',
' ;;' );
}
emit( join( '|', @wildnoacasts) . ')',
' ;;' );
} else {
@wildacasts = ( '*' );
}
emit( join( '|', @wildacasts ) . ')',
' if [ -n "$ALL_ACASTS" ]; then',
' ALL_ACASTS="$ALL_ACASTS $(get_interface_acasts $iface)"',
' else',
' ALL_ACASTS="$(get_interface_acasts $iface)"',
' ;;' );
pop_indent;
pop_indent;
emit( 'esac',
'' );
}
1; 1;

View File

@ -627,6 +627,18 @@ loc eth2 -</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>noanycast</term>
<listitem>
<para>IPv6 only. Added in Shorewall 5.2.8. Shorewall6 normally
generates rules to silently drop anycast packets for subnets
on all available interfaces. This can be inhibited for
individual interfaces by specifying <emphasis
role="bold">noanycast</emphasis> for those interfaces.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><emphasis role="bold">nodbl</emphasis></term> <term><emphasis role="bold">nodbl</emphasis></term>