Erradicate IPv6 experimentation

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@7329 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2007-09-12 15:03:47 +00:00
parent 9b079d57e9
commit bbcf8fdcf8
10 changed files with 279 additions and 336 deletions

View File

@ -75,7 +75,7 @@ sub process_accounting_rule( $$$$$$$$$ ) {
sub jump_to_chain( $ ) { sub jump_to_chain( $ ) {
my $jumpchain = $_[0]; my $jumpchain = $_[0];
$jumpchainref = ensure_chain( 'filter', IPv4, $jumpchain ); $jumpchainref = ensure_chain( 'filter', $jumpchain );
check_for_builtin( $jumpchainref ); check_for_builtin( $jumpchainref );
mark_referenced $jumpchainref; mark_referenced $jumpchainref;
"-j $jumpchain"; "-j $jumpchain";
@ -124,7 +124,7 @@ sub process_accounting_rule( $$$$$$$$$ ) {
$chain = 'accounting' unless $chain and $chain ne '-'; $chain = 'accounting' unless $chain and $chain ne '-';
if ( $dest eq 'any' || $dest eq 'all' || $dest eq ALLIPv4 ) { if ( $dest eq 'any' || $dest eq 'all' || $dest eq ALLIPv4 ) {
expand_rule( expand_rule(
ensure_filter_chain( IPv4, 'accountout' , 0 ) , ensure_filter_chain( 'accountout' , 0 ) ,
OUTPUT_RESTRICT , OUTPUT_RESTRICT ,
$rule , $rule ,
$source , $source ,
@ -141,7 +141,7 @@ sub process_accounting_rule( $$$$$$$$$ ) {
$dest = ALLIPv4 if $dest eq 'any' || $dest eq 'all'; $dest = ALLIPv4 if $dest eq 'any' || $dest eq 'all';
} }
my $chainref = ensure_filter_chain IPv4, $chain , 0; my $chainref = ensure_filter_chain $chain , 0;
check_for_builtin( $chainref ); check_for_builtin( $chainref );
@ -197,19 +197,19 @@ sub setup_accounting() {
clear_comment; clear_comment;
if ( have_bridges ) { if ( have_bridges ) {
if ( $filter_table->{1}->{accounting} ) { if ( $filter_table->{accounting} ) {
for my $chain ( qw/INPUT FORWARD/ ) { for my $chain ( qw/INPUT FORWARD/ ) {
insert_rule $filter_table->{1}{$chain}, 1, '-j accounting'; insert_rule $filter_table->{$chain}, 1, '-j accounting';
} }
} }
if ( $filter_table->{1}->{accountout} ) { if ( $filter_table->{accountout} ) {
insert_rule $filter_table->{1}{OUTPUT}, 1, '-j accountout'; insert_rule $filter_table->{OUTPUT}, 1, '-j accountout';
} }
} else { } else {
if ( $filter_table->{1}->{accounting} ) { if ( $filter_table->{accounting} ) {
for my $chain ( qw/INPUT FORWARD OUTPUT/ ) { for my $chain ( qw/INPUT FORWARD OUTPUT/ ) {
insert_rule $filter_table->{1}{$chain}, 1, '-j accounting'; insert_rule $filter_table->{$chain}, 1, '-j accounting';
} }
} }
} }

View File

@ -264,16 +264,20 @@ sub createlogactionchain( $$ ) {
validate_level $lev; validate_level $lev;
$chain = substr $chain, 0, 28 if ( length $chain ) > 28;
while ( $chain_table{filter}{1}{'%' . $chain . $actionref->{actchain}} ) {
$chain = substr $chain, 0, 27 if $actionref->{actchain} == 10 and length $chain == 28;
}
$actionref = new_action $action unless $actionref; $actionref = new_action $action unless $actionref;
$logactionchains{"$action:$level"} = $chainref = new_chain 'filter', IPv4, '%' . $chain . $actionref->{actchain}++; $chain = substr $chain, 0, 28 if ( length $chain ) > 28;
CHECKDUP:
{
$actionref->{actchain}++ while $chain_table{filter}{'%' . $chain . $actionref->{actchain}};
$chain = substr( $chain, 0, 27 ), redo CHECKDUP if ( $actionref->{actchain} || 0 ) >= 10 and length $chain == 28;
}
$logactionchains{"$action:$level"} = $chainref = new_chain 'filter', '%' . $chain . $actionref->{actchain}++;
fatal_error "Too many invocations of Action $action" if $actionref->{actchain} > 99;
mark_referenced $chainref; # Just in case the action body is empty. mark_referenced $chainref; # Just in case the action body is empty.
unless ( $targets{$action} & STANDARD ) { unless ( $targets{$action} & STANDARD ) {
@ -298,7 +302,7 @@ sub createlogactionchain( $$ ) {
sub createsimpleactionchain( $ ) { sub createsimpleactionchain( $ ) {
my $action = shift; my $action = shift;
my $chainref = new_chain 'filter', IPv4, $action; my $chainref = new_chain 'filter', $action;
$logactionchains{"$action:none"} = $chainref; $logactionchains{"$action:none"} = $chainref;
@ -768,7 +772,7 @@ sub process_actions3 () {
add_rule $chainref, "-m recent --name $set --set"; add_rule $chainref, "-m recent --name $set --set";
if ( $level ne '' ) { if ( $level ne '' ) {
my $xchainref = new_chain 'filter' , IPv4, "$chainref->{name}%"; my $xchainref = new_chain 'filter' , "$chainref->{name}%";
log_rule_limit $level, $xchainref, $tag[0], 'DROP', '', '', 'add', ''; log_rule_limit $level, $xchainref, $tag[0], 'DROP', '', '', 'add', '';
add_rule $xchainref, '-j DROP'; add_rule $xchainref, '-j DROP';
add_rule $chainref, "-m recent --name $set --update --seconds $tag[2] --hitcount $count -j $xchainref->{name}"; add_rule $chainref, "-m recent --name $set --update --seconds $tag[2] --hitcount $count -j $xchainref->{name}";

View File

@ -51,8 +51,6 @@ our @EXPORT = qw( STANDARD
OUTPUT_RESTRICT OUTPUT_RESTRICT
POSTROUTE_RESTRICT POSTROUTE_RESTRICT
ALL_RESTRICT ALL_RESTRICT
IPv4
IPv6
process_comment process_comment
clear_comment clear_comment
@ -131,35 +129,29 @@ our @EXPORT = qw( STANDARD
our @EXPORT_OK = qw( initialize ); our @EXPORT_OK = qw( initialize );
our $VERSION = '4.04'; our $VERSION = '4.04';
#
# IP Versions. Rather than using 4 and 6, we use 1 and 2 to match the zone IPVs.
#
use constant { IPv4 => ZT_IPV4, IPv6 => ZT_IPV6 };
# #
# Chain Table # Chain Table
# #
# %chain_table { <table> => { <ipv> => { <chain1> => { name => <chain name> # %chain_table { <table> => { <chain1> => { name => <chain name>
# table => <table name> # table => <table name>
# is_policy => 0|1 # is_policy => 0|1
# is_optional => 0|1 # is_optional => 0|1
# referenced => 0|1 # referenced => 0|1
# log => <logging rule number for use when LOGRULENUMBERS> # log => <logging rule number for use when LOGRULENUMBERS>
# policy => <policy> # policy => <policy>
# policychain => <name of policy chain> -- self-reference if this is a policy chain # policychain => <name of policy chain> -- self-reference if this is a policy chain
# policypair => [ <policy source>, <policy dest> ] -- Used for reporting duplicated policies # policypair => [ <policy source>, <policy dest> ] -- Used for reporting duplicated policies
# loglevel => <level> # loglevel => <level>
# synparams => <burst/limit> # synparams => <burst/limit>
# synchain => <name of synparam chain> # synchain => <name of synparam chain>
# default => <default action> # default => <default action>
# cmdlevel => <number of open loops or blocks in runtime commands> # cmdlevel => <number of open loops or blocks in runtime commands>
# rules => [ <rule1> # rules => [ <rule1>
# <rule2> # <rule2>
# ... # ...
# ] # ]
# } , # } ,
# <chain2> => ... # <chain2> => ...
# }
# } # }
# } # }
# #
@ -237,10 +229,10 @@ our $mode;
# #
sub initialize() { sub initialize() {
%chain_table = ( raw => { 1 => {} , 2=> {} }, %chain_table = ( raw => {} ,
mangle => { 1 => {} , 2=> {} }, mangle => {},
nat => { 1 => {} }, nat => {},
filter => { 1 => {} , 2=> {} } ); filter => {} );
$nat_table = $chain_table{nat}; $nat_table = $chain_table{nat};
$mangle_table = $chain_table{mangle}; $mangle_table = $chain_table{mangle};
@ -578,33 +570,42 @@ sub first_chains( $ ) #$1 = interface
# #
# Create a new chain and return a reference to it. # Create a new chain and return a reference to it.
# #
sub new_chain($$$) sub new_chain($$)
{ {
my ($table, $ipv, $chain) = @_; my ($table, $chain) = @_;
warning_message "Internal error in new_chain()" if $chain_table{$table}{1}{$chain}; warning_message "Internal error in new_chain()" if $chain_table{$table}{$chain};
$chain_table{$table}{1}{$chain} = { name => $chain, $chain_table{$table}{$chain} = { name => $chain,
rules => [], rules => [],
table => $table, table => $table,
ipv => $ipv, loglevel => '',
loglevel => '', log => 1,
log => 1, cmdlevel => 0 };
cmdlevel => 0 };
} }
#
# Create an anonymous chain
#
sub new_anon_chain( $ ) {
my $chainref = $_[0];
my $seq = $chainseq++;
new_chain( $chainref->{table}, 'chain' . "$seq" );
}
#
# #
# Create a chain if it doesn't exist already # Create a chain if it doesn't exist already
# #
sub ensure_chain($$$) sub ensure_chain($$)
{ {
my ($table, $ipv, $chain) = @_; my ($table, $chain) = @_;
my $ref = $chain_table{$table}{$ipv}{$chain}; my $ref = $chain_table{$table}{$chain};
return $ref if $ref; return $ref if $ref;
new_chain $table, $ipv, $chain; new_chain $table, $chain;
} }
sub finish_chain_section( $$ ); sub finish_chain_section( $$ );
@ -612,13 +613,13 @@ sub finish_chain_section( $$ );
# #
# Create a filter chain if necessary. Optionally populate it with the appropriate ESTABLISHED,RELATED rule(s) and perform SYN rate limiting. # Create a filter chain if necessary. Optionally populate it with the appropriate ESTABLISHED,RELATED rule(s) and perform SYN rate limiting.
# #
sub ensure_filter_chain( $$$ ) sub ensure_filter_chain( $$ )
{ {
my ($ipv, $chain, $populate) = @_; my ($chain, $populate) = @_;
my $chainref = $filter_table->{$ipv}{$chain}; my $chainref = $filter_table->{$chain};
$chainref = new_chain 'filter', $ipv, $chain unless $chainref; $chainref = new_chain 'filter' , $chain unless $chainref;
if ( $populate and ! $chainref->{referenced} ) { if ( $populate and ! $chainref->{referenced} ) {
if ( $section eq 'NEW' or $section eq 'DONE' ) { if ( $section eq 'NEW' or $section eq 'DONE' ) {
@ -633,10 +634,10 @@ sub ensure_filter_chain( $$$ )
$chainref; $chainref;
} }
sub ensure_mangle_chain($$) { sub ensure_mangle_chain($) {
my ($ipv, $chain ) = @_; my $chain = $_[0];
my $chainref = ensure_chain 'mangle', $ipv, $chain; my $chainref = ensure_chain 'mangle', $chain;
$chainref->{referenced} = 1; $chainref->{referenced} = 1;
@ -646,18 +647,18 @@ sub ensure_mangle_chain($$) {
# #
# Add a builtin chain # Add a builtin chain
# #
sub new_builtin_chain($$$$) sub new_builtin_chain($$$)
{ {
my ( $table, $ipv, $chain, $policy ) = @_; my ( $table, $chain, $policy ) = @_;
my $chainref = new_chain $table, $ipv, $chain; my $chainref = new_chain $table, $chain;
$chainref->{referenced} = 1; $chainref->{referenced} = 1;
$chainref->{policy} = $policy; $chainref->{policy} = $policy;
$chainref->{builtin} = 1; $chainref->{builtin} = 1;
} }
sub new_standard_chain($$) { sub new_standard_chain($) {
my $chainref = new_chain 'filter', $_[0] ,$_[1]; my $chainref = new_chain 'filter' ,$_[0];
$chainref->{referenced} = 1; $chainref->{referenced} = 1;
$chainref; $chainref;
} }
@ -669,24 +670,24 @@ sub new_standard_chain($$) {
sub initialize_chain_table() sub initialize_chain_table()
{ {
for my $chain qw(OUTPUT PREROUTING) { for my $chain qw(OUTPUT PREROUTING) {
new_builtin_chain 'raw', IPv4, $chain, 'ACCEPT'; new_builtin_chain 'raw', $chain, 'ACCEPT';
} }
for my $chain qw(INPUT OUTPUT FORWARD) { for my $chain qw(INPUT OUTPUT FORWARD) {
new_builtin_chain 'filter', IPv4, $chain, 'DROP'; new_builtin_chain 'filter', $chain, 'DROP';
} }
for my $chain qw(PREROUTING POSTROUTING OUTPUT) { for my $chain qw(PREROUTING POSTROUTING OUTPUT) {
new_builtin_chain 'nat', IPv4, $chain, 'ACCEPT'; new_builtin_chain 'nat', $chain, 'ACCEPT';
} }
for my $chain qw(PREROUTING INPUT OUTPUT ) { for my $chain qw(PREROUTING INPUT OUTPUT ) {
new_builtin_chain 'mangle', IPv4, $chain, 'ACCEPT'; new_builtin_chain 'mangle', $chain, 'ACCEPT';
} }
if ( $capabilities{MANGLE_FORWARD} ) { if ( $capabilities{MANGLE_FORWARD} ) {
for my $chain qw( FORWARD POSTROUTING ) { for my $chain qw( FORWARD POSTROUTING ) {
new_builtin_chain 'mangle', IPv4, $chain, 'ACCEPT'; new_builtin_chain 'mangle', $chain, 'ACCEPT';
} }
} }
} }
@ -697,14 +698,13 @@ sub initialize_chain_table()
sub finish_chain_section ($$) { sub finish_chain_section ($$) {
my ($chainref, $state ) = @_; my ($chainref, $state ) = @_;
my $chain = $chainref->{name}; my $chain = $chainref->{name};
my $ipv = $chainref->{ipv};
add_rule $chainref, "-m state --state $state -j ACCEPT" unless $config{FASTACCEPT}; add_rule $chainref, "-m state --state $state -j ACCEPT" unless $config{FASTACCEPT};
if ($sections{RELATED} ) { if ($sections{RELATED} ) {
if ( $chainref->{is_policy} ) { if ( $chainref->{is_policy} ) {
if ( $chainref->{synparams} ) { if ( $chainref->{synparams} ) {
my $synchainref = ensure_chain 'filter', $ipv, syn_flood_chain $chainref; my $synchainref = ensure_chain 'filter', syn_flood_chain $chainref;
if ( $section eq 'DONE' ) { if ( $section eq 'DONE' ) {
if ( $chainref->{policy} =~ /^(ACCEPT|CONTINUE|QUEUE|NFQUEUE)/ ) { if ( $chainref->{policy} =~ /^(ACCEPT|CONTINUE|QUEUE|NFQUEUE)/ ) {
add_rule $chainref, "-p tcp --syn -j $synchainref->{name}"; add_rule $chainref, "-p tcp --syn -j $synchainref->{name}";
@ -714,9 +714,9 @@ sub finish_chain_section ($$) {
} }
} }
} else { } else {
my $policychainref = $filter_table->{$ipv}{$chainref->{policychain}}; my $policychainref = $filter_table->{$chainref->{policychain}};
if ( $policychainref->{synparams} ) { if ( $policychainref->{synparams} ) {
my $synchainref = ensure_chain 'filter', $ipv, syn_flood_chain $policychainref; my $synchainref = ensure_chain 'filter', syn_flood_chain $policychainref;
add_rule $chainref, "-p tcp --syn -j $synchainref->{name}"; add_rule $chainref, "-p tcp --syn -j $synchainref->{name}";
} }
} }
@ -735,11 +735,9 @@ sub finish_section ( $ ) {
for my $zone ( all_zones ) { for my $zone ( all_zones ) {
for my $zone1 ( all_zones ) { for my $zone1 ( all_zones ) {
for my $ipv ( IPv4, IPv6 ) { my $chainref = $chain_table{'filter'}{"${zone}2${zone1}"};
my $chainref = $chain_table{'filter'}{$ipv}{"${zone}2${zone1}"}; if ( $chainref->{referenced} ) {
if ( $chainref->{referenced} ) { finish_chain_section $chainref, $sections;
finish_chain_section $chainref, $sections;
}
} }
} }
} }
@ -748,9 +746,9 @@ sub finish_section ( $ ) {
# #
# Helper for set_mss # Helper for set_mss
# #
sub set_mss1( $$$ ) { sub set_mss1( $$ ) {
my ( $ipv, $chain, $mss ) = @_; my ( $chain, $mss ) = @_;
my $chainref = ensure_chain 'filter', $ipv, $chain; my $chainref = ensure_chain 'filter', $chain;
if ( $chainref->{policy} ne 'NONE' ) { if ( $chainref->{policy} ne 'NONE' ) {
my $match = $capabilities{TCPMSS_MATCH} ? "-m tcpmss --mss $mss: " : ''; my $match = $capabilities{TCPMSS_MATCH} ? "-m tcpmss --mss $mss: " : '';
@ -764,14 +762,14 @@ sub set_mss1( $$$ ) {
sub set_mss( $$$ ) { sub set_mss( $$$ ) {
my ( $zone, $mss, $direction) = @_; my ( $zone, $mss, $direction) = @_;
for my $z ( all_ipv4_zones ) { for my $z ( all_zones ) {
if ( $direction eq '_in' ) { if ( $direction eq '_in' ) {
set_mss1 IPv4, "${zone}2${z}" , $mss; set_mss1 "${zone}2${z}" , $mss;
} elsif ( $direction eq '_out' ) { } elsif ( $direction eq '_out' ) {
set_mss1 IPv4, "${z}2${zone}", $mss; set_mss1 "${z}2${zone}", $mss;
} else { } else {
set_mss1 IPv4, "${z}2${zone}", $mss; set_mss1 "${z}2${zone}", $mss;
set_mss1 IPv4, "${zone}2${z}", $mss; set_mss1 "${zone}2${z}", $mss;
} }
} }
} }
@ -780,7 +778,7 @@ sub set_mss( $$$ ) {
# Interate over non-firewall zones and interfaces with 'mss=' setting adding TCPMSS rules as appropriate. # Interate over non-firewall zones and interfaces with 'mss=' setting adding TCPMSS rules as appropriate.
# #
sub setup_zone_mss() { sub setup_zone_mss() {
for my $zone ( all_ipv4_zones ) { for my $zone ( all_zones ) {
my $zoneref = find_zone( $zone ); my $zoneref = find_zone( $zone );
set_mss( $zone, $zoneref->{options}{in_out}{mss}, '' ) if $zoneref->{options}{in_out}{mss}; set_mss( $zone, $zoneref->{options}{in_out}{mss}, '' ) if $zoneref->{options}{in_out}{mss};
@ -1247,7 +1245,7 @@ sub match_ipsec_in( $$ ) {
my $zoneref = find_zone( $zone ); my $zoneref = find_zone( $zone );
my $optionsref = $zoneref->{options}; my $optionsref = $zoneref->{options};
if ( $zoneref->{type} & ZT_IPSEC ) { if ( $zoneref->{type} eq 'ipsec4' ) {
$match .= "ipsec $optionsref->{in_out}{ipsec}$optionsref->{in}{ipsec}"; $match .= "ipsec $optionsref->{in_out}{ipsec}$optionsref->{in}{ipsec}";
} elsif ( $capabilities{POLICY_MATCH} ) { } elsif ( $capabilities{POLICY_MATCH} ) {
$match .= "$hostref->{ipsec} $optionsref->{in_out}{ipsec}$optionsref->{in}{ipsec}"; $match .= "$hostref->{ipsec} $optionsref->{in_out}{ipsec}$optionsref->{in}{ipsec}";
@ -1265,7 +1263,7 @@ sub match_ipsec_out( $$ ) {
my $zoneref = find_zone( $zone ); my $zoneref = find_zone( $zone );
my $optionsref = $zoneref->{options}; my $optionsref = $zoneref->{options};
if ( $zoneref->{type} & ZT_IPSEC ) { if ( $zoneref->{type} eq 'ipsec4' ) {
$match .= "ipsec $optionsref->{in_out}{ipsec}$optionsref->{out}{ipsec}"; $match .= "ipsec $optionsref->{in_out}{ipsec}$optionsref->{out}{ipsec}";
} elsif ( $capabilities{POLICY_MATCH} ) { } elsif ( $capabilities{POLICY_MATCH} ) {
$match .= "$hostref->{ipsec} $optionsref->{in_out}{ipsec}$optionsref->{out}{ipsec}" $match .= "$hostref->{ipsec} $optionsref->{in_out}{ipsec}$optionsref->{out}{ipsec}"
@ -1745,7 +1743,7 @@ sub expand_rule( $$$$$$$$$$ )
# #
# Create the Exclusion Chain # Create the Exclusion Chain
# #
my $echainref = new_chain $chainref->{table}, IPv4, $echain; my $echainref = new_chain $chainref->{table}, $echain;
# #
# Generate RETURNs for each exclusion # Generate RETURNs for each exclusion
@ -1808,10 +1806,10 @@ sub expand_rule( $$$$$$$$$$ )
sub addnatjump( $$$ ) { sub addnatjump( $$$ ) {
my ( $source , $dest, $predicates ) = @_; my ( $source , $dest, $predicates ) = @_;
my $destref = $nat_table->{1}{$dest} || {}; my $destref = $nat_table->{$dest} || {};
if ( $destref->{referenced} ) { if ( $destref->{referenced} ) {
add_rule $nat_table->{1}{$source} , $predicates . "-j $dest"; add_rule $nat_table->{$source} , $predicates . "-j $dest";
} else { } else {
clearrule; clearrule;
} }
@ -1823,10 +1821,10 @@ sub addnatjump( $$$ ) {
sub insertnatjump( $$$$ ) { sub insertnatjump( $$$$ ) {
my ( $source, $dest, $countref, $predicates ) = @_; my ( $source, $dest, $countref, $predicates ) = @_;
my $destref = $nat_table->{1}{$dest} || {}; my $destref = $nat_table->{$dest} || {};
if ( $destref->{referenced} ) { if ( $destref->{referenced} ) {
insert_rule $nat_table->{1}{$source} , ($$countref)++, $predicates . "-j $dest"; insert_rule $nat_table->{$source} , ($$countref)++, $predicates . "-j $dest";
} else { } else {
clearrule; clearrule;
} }
@ -1966,7 +1964,7 @@ sub create_netfilter_load() {
# iptables-restore seems to be quite picky about the order of the builtin chains # iptables-restore seems to be quite picky about the order of the builtin chains
# #
for my $chain ( @builtins ) { for my $chain ( @builtins ) {
my $chainref = $chain_table{$table}{1}{$chain}; my $chainref = $chain_table{$table}{$chain};
if ( $chainref ) { if ( $chainref ) {
fatal_error "Internal error in create_netfilter_load()" if $chainref->{cmdlevel}; fatal_error "Internal error in create_netfilter_load()" if $chainref->{cmdlevel};
emit_unindented ":$chain $chainref->{policy} [0:0]"; emit_unindented ":$chain $chainref->{policy} [0:0]";
@ -1976,8 +1974,8 @@ sub create_netfilter_load() {
# #
# First create the chains in the current table # First create the chains in the current table
# #
for my $chain ( grep $chain_table{$table}{1}{$_}->{referenced} , ( sort keys %{$chain_table{$table}{1}} ) ) { for my $chain ( grep $chain_table{$table}{$_}->{referenced} , ( sort keys %{$chain_table{$table}} ) ) {
my $chainref = $chain_table{$table}{1}{$chain}; my $chainref = $chain_table{$table}{$chain};
unless ( $chainref->{builtin} ) { unless ( $chainref->{builtin} ) {
fatal_error "Internal error in create_netfilter_load()" if $chainref->{cmdlevel}; fatal_error "Internal error in create_netfilter_load()" if $chainref->{cmdlevel};
emit_unindented ":$chainref->{name} - [0:0]"; emit_unindented ":$chainref->{name} - [0:0]";
@ -2026,7 +2024,7 @@ sub create_chainlist_reload($) {
my @chains = split ',', $chains; my @chains = split ',', $chains;
unless ( @chains ) { unless ( @chains ) {
@chains = qw( blacklst ) if $filter_table->{1}{blacklst}; @chains = qw( blacklst ) if $filter_table->{blacklst};
} }
$mode = NULL_MODE; $mode = NULL_MODE;
@ -2060,7 +2058,7 @@ sub create_chainlist_reload($) {
( $table , $chain ) = split ':', $chain if $chain =~ /:/; ( $table , $chain ) = split ':', $chain if $chain =~ /:/;
fatal_error "Invalid table ( $table )" unless $table =~ /^(nat|mangle|filter)$/; fatal_error "Invalid table ( $table )" unless $table =~ /^(nat|mangle|filter)$/;
fatal_error "No $table chain found with name $chain" unless $chain_table{$table}{1}{$chain}; fatal_error "No $table chain found with name $chain" unless $chain_table{$table}{$chain};
$chains{$table} = [] unless $chains{$table}; $chains{$table} = [] unless $chains{$table};
@ -2072,7 +2070,7 @@ sub create_chainlist_reload($) {
emit_unindented "*$table"; emit_unindented "*$table";
my $tableref=$chain_table{$table}{1}; my $tableref=$chain_table{$table};
@chains = sort @{$chains{$table}}; @chains = sort @{$chains{$table}};

View File

@ -171,7 +171,7 @@ sub setup_one_masq($$$$$$$)
fatal_error "Unknown interface ($interface)" unless find_interface( $interface )->{root}; fatal_error "Unknown interface ($interface)" unless find_interface( $interface )->{root};
my $chainref = ensure_chain('nat', IPv4, $pre_nat ? snat_chain $interface : masq_chain $interface); my $chainref = ensure_chain('nat', $pre_nat ? snat_chain $interface : masq_chain $interface);
# #
# If there is no source or destination then allow all addresses # If there is no source or destination then allow all addresses
# #
@ -341,7 +341,7 @@ sub do_one_nat( $$$$$ )
fatal_error "Invalid alias ($alias:$remainder)" if defined $remainder; fatal_error "Invalid alias ($alias:$remainder)" if defined $remainder;
sub add_nat_rule( $$ ) { sub add_nat_rule( $$ ) {
add_rule ensure_chain( 'nat', IPv4, $_[0] ) , $_[1]; add_rule ensure_chain( 'nat', $_[0] ) , $_[1];
} }
my $add_ip_aliases = $config{ADD_IP_ALIASES}; my $add_ip_aliases = $config{ADD_IP_ALIASES};
@ -442,9 +442,9 @@ sub setup_netmap() {
fatal_error "Unknown Interface ($interface)" unless known_interface $interface; fatal_error "Unknown Interface ($interface)" unless known_interface $interface;
if ( $type eq 'DNAT' ) { if ( $type eq 'DNAT' ) {
add_rule ensure_chain( 'nat' , IPv4, input_chain $interface ) , "-d $net1 -j NETMAP --to $net2"; add_rule ensure_chain( 'nat' , input_chain $interface ) , "-d $net1 -j NETMAP --to $net2";
} elsif ( $type eq 'SNAT' ) { } elsif ( $type eq 'SNAT' ) {
add_rule ensure_chain( 'nat' , IPv4, output_chain $interface ) , "-s $net1 -j NETMAP --to $net2"; add_rule ensure_chain( 'nat' , output_chain $interface ) , "-s $net1 -j NETMAP --to $net2";
} else { } else {
fatal_error "Invalid type ($type)"; fatal_error "Invalid type ($type)";
} }

View File

@ -78,7 +78,7 @@ sub new_policy_chain($$$$)
{ {
my ($source, $dest, $policy, $optional) = @_; my ($source, $dest, $policy, $optional) = @_;
my $chainref = new_chain( 'filter', IPv4, "${source}2${dest}" ); my $chainref = new_chain( 'filter', "${source}2${dest}" );
convert_to_policy_chain( $chainref, $source, $dest, $policy, $optional ); convert_to_policy_chain( $chainref, $source, $dest, $policy, $optional );
@ -92,9 +92,9 @@ sub set_policy_chain($$$$$)
{ {
my ($source, $dest, $chain1, $chainref, $policy ) = @_; my ($source, $dest, $chain1, $chainref, $policy ) = @_;
my $chainref1 = $filter_table->{1}{$chain1}; my $chainref1 = $filter_table->{$chain1};
$chainref1 = new_chain 'filter', IPv4, $chain1 unless $chainref1; $chainref1 = new_chain 'filter', $chain1 unless $chainref1;
unless ( $chainref1->{policychain} ) { unless ( $chainref1->{policychain} ) {
if ( $config{EXPAND_POLICIES} ) { if ( $config{EXPAND_POLICIES} ) {
@ -130,7 +130,7 @@ use constant { OPTIONAL => 1 };
sub add_or_modify_policy_chain( $$ ) { sub add_or_modify_policy_chain( $$ ) {
my ( $zone, $zone1 ) = @_; my ( $zone, $zone1 ) = @_;
my $chain = "${zone}2${zone1}"; my $chain = "${zone}2${zone1}";
my $chainref = $filter_table->{1}{$chain}; my $chainref = $filter_table->{$chain};
if ( $chainref ) { if ( $chainref ) {
unless( $chainref->{is_policy} ) { unless( $chainref->{is_policy} ) {
@ -266,11 +266,11 @@ sub validate_policy()
fatal_error "NONE policy not allowed with \"all\"" fatal_error "NONE policy not allowed with \"all\""
if $clientwild || $serverwild; if $clientwild || $serverwild;
fatal_error "NONE policy not allowed to/from firewall zone" fatal_error "NONE policy not allowed to/from firewall zone"
if ( zone_type( $client ) == ZT_FIREWALL ) || ( zone_type( $server ) == ZT_FIREWALL ); if ( zone_type( $client ) eq 'firewall' ) || ( zone_type( $server ) eq 'firewall' );
} }
unless ( $clientwild || $serverwild ) { unless ( $clientwild || $serverwild ) {
if ( zone_type( $server ) & ZT_BPORT ) { if ( zone_type( $server ) eq 'bport4' ) {
fatal_error "Invalid policy - DEST zone is a Bridge Port zone but the SOURCE zone is not associated with the same bridge" fatal_error "Invalid policy - DEST zone is a Bridge Port zone but the SOURCE zone is not associated with the same bridge"
unless find_zone( $client )->{bridge} eq find_zone( $server)->{bridge} || single_interface( $client ) eq find_zone( $server )->{bridge}; unless find_zone( $client )->{bridge} eq find_zone( $server)->{bridge} || single_interface( $client ) eq find_zone( $server )->{bridge};
} }
@ -279,8 +279,8 @@ sub validate_policy()
my $chain = "${client}2${server}"; my $chain = "${client}2${server}";
my $chainref; my $chainref;
if ( defined $filter_table->{1}{$chain} ) { if ( defined $filter_table->{$chain} ) {
$chainref = $filter_table->{1}{$chain}; $chainref = $filter_table->{$chain};
if ( $chainref->{is_policy} ) { if ( $chainref->{is_policy} ) {
if ( $chainref->{is_optional} ) { if ( $chainref->{is_optional} ) {
@ -362,7 +362,7 @@ sub report_syn_flood_protection() {
sub default_policy( $$$ ) { sub default_policy( $$$ ) {
my $chainref = $_[0]; my $chainref = $_[0];
my $policyref = $filter_table->{1}{$chainref->{policychain}}; my $policyref = $filter_table->{$chainref->{policychain}};
my $synparams = $policyref->{synparams}; my $synparams = $policyref->{synparams};
my $default = $policyref->{default}; my $default = $policyref->{default};
my $policy = $policyref->{policy}; my $policy = $policyref->{policy};
@ -407,7 +407,7 @@ sub apply_policy_rules() {
if ( $policy ne 'NONE' ) { if ( $policy ne 'NONE' ) {
if ( ! $chainref->{referenced} && ( ! $optional && $policy ne 'CONTINUE' ) ) { if ( ! $chainref->{referenced} && ( ! $optional && $policy ne 'CONTINUE' ) ) {
ensure_filter_chain IPv4, $name, 1; ensure_filter_chain $name, 1;
} }
if ( $name =~ /^all2|2all$/ ) { if ( $name =~ /^all2|2all$/ ) {
@ -420,7 +420,7 @@ sub apply_policy_rules() {
for my $zone ( all_zones ) { for my $zone ( all_zones ) {
for my $zone1 ( all_zones ) { for my $zone1 ( all_zones ) {
my $chainref = $filter_table->{1}{"${zone}2${zone1}"}; my $chainref = $filter_table->{"${zone}2${zone1}"};
if ( $chainref->{referenced} ) { if ( $chainref->{referenced} ) {
run_user_exit $chainref; run_user_exit $chainref;
@ -446,11 +446,11 @@ sub complete_standard_chain ( $$$ ) {
run_user_exit $stdchainref; run_user_exit $stdchainref;
my $ruleschainref = $filter_table->{1}{"${zone}2${zone2}"}; my $ruleschainref = $filter_table->{"${zone}2${zone2}"};
my ( $policy, $loglevel, $default ) = ( 'DROP', 6, $config{DROP_DEFAULT} ); my ( $policy, $loglevel, $default ) = ( 'DROP', 6, $config{DROP_DEFAULT} );
my $policychainref; my $policychainref;
$policychainref = $filter_table->{1}{$ruleschainref->{policychain}} if $ruleschainref; $policychainref = $filter_table->{$ruleschainref->{policychain}} if $ruleschainref;
( $policy, $loglevel, $default ) = @{$policychainref}{'policy', 'loglevel', 'default' } if $policychainref; ( $policy, $loglevel, $default ) = @{$policychainref}{'policy', 'loglevel', 'default' } if $policychainref;
@ -463,9 +463,9 @@ sub complete_standard_chain ( $$$ ) {
sub setup_syn_flood_chains() { sub setup_syn_flood_chains() {
for my $chainref ( @policy_chains ) { for my $chainref ( @policy_chains ) {
my $limit = $chainref->{synparams}; my $limit = $chainref->{synparams};
if ( $limit && ! $filter_table->{1}{syn_flood_chain $chainref} ) { if ( $limit && ! $filter_table->{syn_flood_chain $chainref} ) {
my $level = $chainref->{loglevel}; my $level = $chainref->{loglevel};
my $synchainref = new_chain 'filter' , IPv4, syn_flood_chain $chainref; my $synchainref = new_chain 'filter' , syn_flood_chain $chainref;
add_rule $synchainref , "${limit}-j RETURN"; add_rule $synchainref , "${limit}-j RETURN";
log_rule_limit $level , $synchainref , $chainref->{name} , 'DROP', '-m limit --limit 5/min --limit-burst 5 ' , '' , 'add' , '' log_rule_limit $level , $synchainref , $chainref->{name} , 'DROP', '-m limit --limit 5/min --limit-burst 5 ' , '' , 'add' , ''
if $level ne ''; if $level ne '';

View File

@ -89,13 +89,13 @@ sub setup_route_marking() {
require_capability( 'CONNMARK_MATCH' , 'the provider \'track\' option' , 's' ); require_capability( 'CONNMARK_MATCH' , 'the provider \'track\' option' , 's' );
require_capability( 'CONNMARK' , 'the provider \'track\' option' , 's' ); require_capability( 'CONNMARK' , 'the provider \'track\' option' , 's' );
add_rule $mangle_table->{1}{PREROUTING} , "-m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask"; add_rule $mangle_table->{PREROUTING} , "-m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask";
add_rule $mangle_table->{1}{OUTPUT} , "-m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask"; add_rule $mangle_table->{OUTPUT} , "-m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask";
my $chainref = new_chain 'mangle', IPv4, 'routemark'; my $chainref = new_chain 'mangle', 'routemark';
while ( my ( $interface, $mark ) = ( each %routemarked_interfaces ) ) { while ( my ( $interface, $mark ) = ( each %routemarked_interfaces ) ) {
add_rule $mangle_table->{1}{PREROUTING} , "-i $interface -m mark --mark 0/$mask -j routemark"; add_rule $mangle_table->{PREROUTING} , "-i $interface -m mark --mark 0/$mask -j routemark";
add_rule $chainref, " -i $interface -j MARK $mark_op $mark"; add_rule $chainref, " -i $interface -j MARK $mark_op $mark";
} }

View File

@ -102,8 +102,8 @@ sub process_tos() {
if ( $first_entry ) { if ( $first_entry ) {
progress_message2 "$doing $fn..."; progress_message2 "$doing $fn...";
$pretosref = ensure_chain 'mangle' , IPv4, $chain; $pretosref = ensure_chain 'mangle' , $chain;
$outtosref = ensure_chain 'mangle' , IPv4, 'outtos'; $outtosref = ensure_chain 'mangle' , 'outtos';
$first_entry = 0; $first_entry = 0;
} }
@ -150,8 +150,8 @@ sub process_tos() {
} }
unless ( $first_entry ) { unless ( $first_entry ) {
add_rule $mangle_table->{1}{$stdchain}, "-j $chain" if $pretosref->{referenced}; add_rule $mangle_table->{$stdchain}, "-j $chain" if $pretosref->{referenced};
add_rule $mangle_table->{1}{OUTPUT}, "-j outtos" if $outtosref->{referenced}; add_rule $mangle_table->{OUTPUT}, "-j outtos" if $outtosref->{referenced};
} }
} }
} }
@ -194,14 +194,14 @@ sub setup_ecn()
progress_message "$doing ECN control on @interfaces..."; progress_message "$doing ECN control on @interfaces...";
for my $interface ( @interfaces ) { for my $interface ( @interfaces ) {
my $chainref = ensure_chain 'mangle', IPv4, ecn_chain( $interface ); my $chainref = ensure_chain 'mangle', ecn_chain( $interface );
add_rule $mangle_table->{1}{POSTROUTING}, "-p tcp -o $interface -j $chainref->{name}"; add_rule $mangle_table->{POSTROUTING}, "-p tcp -o $interface -j $chainref->{name}";
add_rule $mangle_table->{1}{OUTPUT}, "-p tcp -o $interface -j $chainref->{name}"; add_rule $mangle_table->{OUTPUT}, "-p tcp -o $interface -j $chainref->{name}";
} }
for my $host ( @hosts ) { for my $host ( @hosts ) {
add_rule $mangle_table->{1}{ecn_chain $host->[0]}, join ('', '-p tcp ', match_dest_net( $host->[1] ) , ' -j ECN --ecn-tcp-remove' ); add_rule $mangle_table->{ecn_chain $host->[0]}, join ('', '-p tcp ', match_dest_net( $host->[1] ) , ' -j ECN --ecn-tcp-remove' );
} }
} }
} }
@ -217,15 +217,15 @@ sub add_rule_pair( $$$$ ) {
sub setup_rfc1918_filteration( $ ) { sub setup_rfc1918_filteration( $ ) {
my $listref = $_[0]; my $listref = $_[0];
my $norfc1918ref = new_standard_chain IPv4, 'norfc1918'; my $norfc1918ref = new_standard_chain 'norfc1918';
my $rfc1918ref = new_standard_chain IPv4, 'rfc1918'; my $rfc1918ref = new_standard_chain 'rfc1918';
my $chainref = $norfc1918ref; my $chainref = $norfc1918ref;
log_rule $config{RFC1918_LOG_LEVEL} , $rfc1918ref , 'DROP' , ''; log_rule $config{RFC1918_LOG_LEVEL} , $rfc1918ref , 'DROP' , '';
add_rule $rfc1918ref , '-j DROP'; add_rule $rfc1918ref , '-j DROP';
$chainref = new_standard_chain IPv4, 'rfc1918d' if $config{RFC1918_STRICT}; $chainref = new_standard_chain 'rfc1918d' if $config{RFC1918_STRICT};
my $fn = open_file 'rfc1918'; my $fn = open_file 'rfc1918';
@ -266,7 +266,7 @@ sub setup_rfc1918_filteration( $ ) {
my $ipsec = $hostref->[1]; my $ipsec = $hostref->[1];
my $policy = $capabilities{POLICY_MATCH} ? "-m policy --pol $ipsec --dir in " : ''; my $policy = $capabilities{POLICY_MATCH} ? "-m policy --pol $ipsec --dir in " : '';
for my $chain ( @{first_chains $interface}) { for my $chain ( @{first_chains $interface}) {
add_rule $filter_table->{1}{$chain} , join( '', '-m state --state NEW ', match_source_net( $hostref->[2]) , "${policy}-j norfc1918" ); add_rule $filter_table->{$chain} , join( '', '-m state --state NEW ', match_source_net( $hostref->[2]) , "${policy}-j norfc1918" );
} }
} }
} }
@ -279,10 +279,10 @@ sub setup_blacklist() {
my $target = $disposition eq 'REJECT' ? 'reject' : $disposition; my $target = $disposition eq 'REJECT' ? 'reject' : $disposition;
if ( @$hosts ) { if ( @$hosts ) {
$chainref = new_standard_chain IPv4, 'blacklst'; $chainref = new_standard_chain 'blacklst';
if ( defined $level && $level ne '' ) { if ( defined $level && $level ne '' ) {
my $logchainref = new_standard_chain IPv4, 'blacklog'; my $logchainref = new_standard_chain 'blacklog';
log_rule_limit( $level , $logchainref , 'blacklst' , $disposition , "$globals{LOGLIMIT}" , '', 'add', '' ); log_rule_limit( $level , $logchainref , 'blacklst' , $disposition , "$globals{LOGLIMIT}" , '', 'add', '' );
@ -339,7 +339,7 @@ sub setup_blacklist() {
my $source = match_source_net $network; my $source = match_source_net $network;
for my $chain ( @{first_chains $interface}) { for my $chain ( @{first_chains $interface}) {
add_rule $filter_table->{1}{$chain} , "${source}${state}${policy}-j blacklst"; add_rule $filter_table->{$chain} , "${source}${state}${policy}-j blacklst";
} }
progress_message " Blacklisting enabled on ${interface}:${network}"; progress_message " Blacklisting enabled on ${interface}:${network}";
@ -503,28 +503,28 @@ sub add_common_rules() {
if ( $config{FASTACCEPT} ) { if ( $config{FASTACCEPT} ) {
for $chain qw( INPUT FORWARD OUTPUT ) { for $chain qw( INPUT FORWARD OUTPUT ) {
$chainref = $filter_table->{1}{$chain}; $chainref = $filter_table->{$chain};
add_rule( $chainref , "-m state --state ESTABLISHED,RELATED -j ACCEPT" ); add_rule( $chainref , "-m state --state ESTABLISHED,RELATED -j ACCEPT" );
} }
} }
my $rejectref = new_standard_chain IPv4, 'reject'; my $rejectref = new_standard_chain 'reject';
$level = $config{BLACKLIST_LOGLEVEL}; $level = $config{BLACKLIST_LOGLEVEL};
add_rule_pair new_standard_chain( IPv4, 'logdrop' ), ' ' , 'DROP' , $level ; add_rule_pair new_standard_chain( 'logdrop' ), ' ' , 'DROP' , $level ;
add_rule_pair new_standard_chain( IPv4, 'logreject' ), ' ' , 'reject' , $level ; add_rule_pair new_standard_chain( 'logreject' ), ' ' , 'reject' , $level ;
new_standard_chain IPv4, 'dynamic'; new_standard_chain 'dynamic';
my $state = $config{BLACKLISTNEWONLY} ? '-m state --state NEW,INVALID ' : ''; my $state = $config{BLACKLISTNEWONLY} ? '-m state --state NEW,INVALID ' : '';
for $interface ( all_interfaces ) { for $interface ( all_interfaces ) {
for $chain ( @{first_chains $interface} ) { for $chain ( @{first_chains $interface} ) {
add_rule new_standard_chain( IPv4, $chain ) , "$state -j dynamic"; add_rule new_standard_chain( $chain ) , "$state -j dynamic";
} }
new_standard_chain IPv4, output_chain( $interface ); new_standard_chain output_chain( $interface );
} }
run_user_exit1 'initdone'; run_user_exit1 'initdone';
@ -533,7 +533,7 @@ sub add_common_rules() {
$list = find_hosts_by_option 'nosmurfs'; $list = find_hosts_by_option 'nosmurfs';
$chainref = new_standard_chain IPv4, 'smurfs'; $chainref = new_standard_chain 'smurfs';
if ( $capabilities{ADDRTYPE} ) { if ( $capabilities{ADDRTYPE} ) {
add_rule $chainref , '-s 0.0.0.0 -j RETURN'; add_rule $chainref , '-s 0.0.0.0 -j RETURN';
@ -568,7 +568,7 @@ sub add_common_rules() {
my $ipsec = $hostref->[1]; my $ipsec = $hostref->[1];
my $policy = $capabilities{POLICY_MATCH} ? "-m policy --pol $ipsec --dir in " : ''; my $policy = $capabilities{POLICY_MATCH} ? "-m policy --pol $ipsec --dir in " : '';
for $chain ( @{first_chains $interface}) { for $chain ( @{first_chains $interface}) {
add_rule $filter_table->{1}{$chain} , join( '', '-m state --state NEW,INVALID ', match_source_net( $hostref->[2] ), "${policy}-j smurfs" ); add_rule $filter_table->{$chain} , join( '', '-m state --state NEW,INVALID ', match_source_net( $hostref->[2] ), "${policy}-j smurfs" );
} }
} }
} }
@ -590,10 +590,10 @@ sub add_common_rules() {
for $interface ( @$list ) { for $interface ( @$list ) {
for $chain ( input_chain $interface, output_chain $interface ) { for $chain ( input_chain $interface, output_chain $interface ) {
add_rule $filter_table->{1}{$chain} , '-p udp --dport 67:68 -j ACCEPT'; add_rule $filter_table->{$chain} , '-p udp --dport 67:68 -j ACCEPT';
} }
add_rule $filter_table->{1}{forward_chain $interface} , "-p udp -o $interface --dport 67:68 -j ACCEPT" if get_interface_option( $interface, 'bridge' ); add_rule $filter_table->{forward_chain $interface} , "-p udp -o $interface --dport 67:68 -j ACCEPT" if get_interface_option( $interface, 'bridge' );
} }
} }
@ -608,10 +608,10 @@ sub add_common_rules() {
progress_message2 "$doing TCP Flags filtering..."; progress_message2 "$doing TCP Flags filtering...";
$chainref = new_standard_chain IPv4, 'tcpflags'; $chainref = new_standard_chain 'tcpflags';
if ( $config{TCP_FLAGS_LOG_LEVEL} ne '' ) { if ( $config{TCP_FLAGS_LOG_LEVEL} ne '' ) {
my $logflagsref = new_standard_chain IPv4, 'logflags'; my $logflagsref = new_standard_chain 'logflags';
my $savelogparms = $globals{LOGPARMS}; my $savelogparms = $globals{LOGPARMS};
@ -643,7 +643,7 @@ sub add_common_rules() {
my $ipsec = $hostref->[1]; my $ipsec = $hostref->[1];
my $policy = $capabilities{POLICY_MATCH} ? "-m policy --pol $ipsec --dir in " : ''; my $policy = $capabilities{POLICY_MATCH} ? "-m policy --pol $ipsec --dir in " : '';
for $chain ( @{first_chains $interface}) { for $chain ( @{first_chains $interface}) {
add_rule $filter_table->{1}{$chain} , join( '', '-p tcp ', match_source_net( $hostref->[2]), "${policy}-j tcpflags" ); add_rule $filter_table->{$chain} , join( '', '-p tcp ', match_source_net( $hostref->[2]), "${policy}-j tcpflags" );
} }
} }
} }
@ -651,14 +651,14 @@ sub add_common_rules() {
if ( $config{DYNAMIC_ZONES} ) { if ( $config{DYNAMIC_ZONES} ) {
for $interface ( all_interfaces ) { for $interface ( all_interfaces ) {
for $chain ( @{dynamic_chains $interface} ) { for $chain ( @{dynamic_chains $interface} ) {
new_standard_chain IPv4, $chain; new_standard_chain $chain;
} }
mark_referenced( new_chain 'nat' , IPv4, $chain = dynamic_in($interface) ); mark_referenced( new_chain 'nat' , $chain = dynamic_in($interface) );
add_rule $filter_table->{1}{input_chain $interface}, "-j $chain"; add_rule $filter_table->{input_chain $interface}, "-j $chain";
add_rule $filter_table->{1}{forward_chain $interface}, '-j ' . dynamic_fwd $interface; add_rule $filter_table->{forward_chain $interface}, '-j ' . dynamic_fwd $interface;
add_rule $filter_table->{1}{output_chain $interface}, '-j ' . dynamic_out $interface; add_rule $filter_table->{output_chain $interface}, '-j ' . dynamic_out $interface;
} }
} }
@ -667,10 +667,10 @@ sub add_common_rules() {
if ( @$list ) { if ( @$list ) {
progress_message2 '$doing UPnP'; progress_message2 '$doing UPnP';
mark_referenced( new_chain( 'nat', IPv4, 'UPnP' ) ); mark_referenced( new_chain( 'nat', 'UPnP' ) );
for $interface ( @$list ) { for $interface ( @$list ) {
add_rule $nat_table->{1}{PREROUTING} , match_source_dev ( $interface ) . '-j UPnP'; add_rule $nat_table->{PREROUTING} , match_source_dev ( $interface ) . '-j UPnP';
} }
} }
@ -710,13 +710,13 @@ sub setup_mac_lists( $ ) {
if ( $phase == 1 ) { if ( $phase == 1 ) {
for my $interface ( @maclist_interfaces ) { for my $interface ( @maclist_interfaces ) {
my $chainref = new_chain $table , IPv4, mac_chain $interface; my $chainref = new_chain $table , mac_chain $interface;
add_rule $chainref , '-s 0.0.0.0 -d 255.255.255.255 -p udp --dport 67:68 -j RETURN' add_rule $chainref , '-s 0.0.0.0 -d 255.255.255.255 -p udp --dport 67:68 -j RETURN'
if ( $table eq 'mangle' ) && get_interface_option( $interface, 'dhcp' ); if ( $table eq 'mangle' ) && get_interface_option( $interface, 'dhcp' );
if ( $ttl ) { if ( $ttl ) {
my $chain1ref = new_chain $table, IPv4, macrecent_target $interface; my $chain1ref = new_chain $table, macrecent_target $interface;
my $chain = $chainref->{name}; my $chain = $chainref->{name};
@ -756,7 +756,7 @@ sub setup_mac_lists( $ ) {
fatal_error "No hosts on $interface have the maclist option specified"; fatal_error "No hosts on $interface have the maclist option specified";
} }
my $chainref = $chain_table{$table}{1}{( $ttl ? macrecent_target $interface : mac_chain $interface )}; my $chainref = $chain_table{$table}{( $ttl ? macrecent_target $interface : mac_chain $interface )};
$mac = '' unless $mac && ( $mac ne '-' ); $mac = '' unless $mac && ( $mac ne '-' );
$addresses = '' unless $addresses && ( $addresses ne '-' ); $addresses = '' unless $addresses && ( $addresses ne '-' );
@ -794,15 +794,15 @@ sub setup_mac_lists( $ ) {
my $target = mac_chain $interface; my $target = mac_chain $interface;
if ( $table eq 'filter' ) { if ( $table eq 'filter' ) {
for my $chain ( @{first_chains $interface}) { for my $chain ( @{first_chains $interface}) {
add_rule $filter_table->{1}{$chain} , "${source}-m state --state NEW ${policy}-j $target"; add_rule $filter_table->{$chain} , "${source}-m state --state NEW ${policy}-j $target";
} }
} else { } else {
add_rule $mangle_table->{1}{PREROUTING}, match_source_dev( $interface ) . "${source}-m state --state NEW ${policy}-j $target"; add_rule $mangle_table->{PREROUTING}, match_source_dev( $interface ) . "${source}-m state --state NEW ${policy}-j $target";
} }
} }
} else { } else {
for my $interface ( @maclist_interfaces ) { for my $interface ( @maclist_interfaces ) {
my $chainref = $chain_table{$table}{1}{( $ttl ? macrecent_target $interface : mac_chain $interface )}; my $chainref = $chain_table{$table}{( $ttl ? macrecent_target $interface : mac_chain $interface )};
my $chain = $chainref->{name}; my $chain = $chainref->{name};
if ( $level ne '' || $disposition ne 'ACCEPT' ) { if ( $level ne '' || $disposition ne 'ACCEPT' ) {
@ -1051,7 +1051,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
# #
# Check for illegal bridge port rule # Check for illegal bridge port rule
# #
if ( $destref->{type} & ZT_BPORT ) { if ( $destref->{type} eq 'bport4' ) {
unless ( $sourceref->{bridge} eq $destref->{bridge} || single_interface( $sourcezone ) eq $destref->{bridge} ) { unless ( $sourceref->{bridge} eq $destref->{bridge} || single_interface( $sourcezone ) eq $destref->{bridge} ) {
return 1 if $wildcard; return 1 if $wildcard;
fatal_error "Rules with a DESTINATION Bridge Port zone must have a SOURCE zone on the same bridge"; fatal_error "Rules with a DESTINATION Bridge Port zone must have a SOURCE zone on the same bridge";
@ -1061,7 +1061,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
# Take care of chain # Take care of chain
# #
my $chain = "${sourcezone}2${destzone}"; my $chain = "${sourcezone}2${destzone}";
my $chainref = ensure_chain 'filter', IPv4, $chain; my $chainref = ensure_chain 'filter', $chain;
# #
# Validate Policy # Validate Policy
# #
@ -1077,7 +1077,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
# Handle Optimization # Handle Optimization
# #
if ( $optimize > 0 ) { if ( $optimize > 0 ) {
my $loglevel = $filter_table->{1}{$chainref->{policychain}}{loglevel}; my $loglevel = $filter_table->{$chainref->{policychain}}{loglevel};
if ( $loglevel ne '' ) { if ( $loglevel ne '' ) {
return 1 if $target eq "${policy}:$loglevel}"; return 1 if $target eq "${policy}:$loglevel}";
} else { } else {
@ -1087,7 +1087,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
# #
# Mark the chain as referenced and add appropriate rules from earlier sections. # Mark the chain as referenced and add appropriate rules from earlier sections.
# #
$chainref = ensure_filter_chain IPv4, $chain, 1; $chainref = ensure_filter_chain $chain, 1;
# #
# For compatibility with older Shorewall versions # For compatibility with older Shorewall versions
# #
@ -1175,7 +1175,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
# #
# And generate the nat table rule(s) # And generate the nat table rule(s)
# #
expand_rule ( ensure_chain ('nat' , IPv4, $sourceref->{type} == ZT_FIREWALL ? 'OUTPUT' : dnat_chain $sourcezone ), expand_rule ( ensure_chain ('nat' , $sourceref->{type} eq 'firewall' ? 'OUTPUT' : dnat_chain $sourcezone ),
PREROUTE_RESTRICT , PREROUTE_RESTRICT ,
$rule , $rule ,
$source , $source ,
@ -1212,7 +1212,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
$origdest = $interfaces ? "detect:$interfaces" : ALLIPv4; $origdest = $interfaces ? "detect:$interfaces" : ALLIPv4;
} }
expand_rule( ensure_chain ('nat' , IPv4, $sourceref->{type} == ZT_FIREWALL ? 'OUTPUT' : dnat_chain $sourcezone) , expand_rule( ensure_chain ('nat' , $sourceref->{type} eq 'firewall' ? 'OUTPUT' : dnat_chain $sourcezone) ,
PREROUTE_RESTRICT , PREROUTE_RESTRICT ,
$rule , $rule ,
$source , $source ,
@ -1239,7 +1239,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
$origdest = ''; $origdest = '';
} }
expand_rule( ensure_chain ('filter', IPv4, $chain ) , expand_rule( ensure_chain ('filter', $chain ) ,
$restriction , $restriction ,
$rule , $rule ,
$source , $source ,
@ -1315,10 +1315,10 @@ sub process_rule ( $$$$$$$$$$ ) {
if ( $source eq 'all' ) { if ( $source eq 'all' ) {
for my $zone ( all_zones ) { for my $zone ( all_zones ) {
if ( $includesrcfw || ( zone_type( $zone ) != ZT_FIREWALL ) ) { if ( $includesrcfw || ( zone_type( $zone ) ne 'firewall' ) ) {
if ( $dest eq 'all' ) { if ( $dest eq 'all' ) {
for my $zone1 ( all_zones ) { for my $zone1 ( all_zones ) {
if ( $includedstfw || ( zone_type( $zone1 ) != ZT_FIREWALL ) ) { if ( $includedstfw || ( zone_type( $zone1 ) ne 'firewall' ) ) {
if ( $intrazone || ( $zone ne $zone1 ) ) { if ( $intrazone || ( $zone ne $zone1 ) ) {
process_rule1 $target, $zone, $zone1 , $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark, 1; process_rule1 $target, $zone, $zone1 , $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark, 1;
} }
@ -1336,7 +1336,7 @@ sub process_rule ( $$$$$$$$$$ ) {
} elsif ( $dest eq 'all' ) { } elsif ( $dest eq 'all' ) {
for my $zone ( all_zones ) { for my $zone ( all_zones ) {
my $sourcezone = ( split( /:/, $source, 2 ) )[0]; my $sourcezone = ( split( /:/, $source, 2 ) )[0];
if ( ( $includedstfw || ( zone_type( $zone ) != ZT_FIREWALL ) ) && ( ( $sourcezone ne $zone ) || $intrazone) ) { if ( ( $includedstfw || ( zone_type( $zone ) ne 'firewall') ) && ( ( $sourcezone ne $zone ) || $intrazone) ) {
process_rule1 $target, $source, $zone , $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark, 1; process_rule1 $target, $source, $zone , $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark, 1;
} }
} }
@ -1416,13 +1416,13 @@ sub generate_matrix() {
sub rules_target( $$ ) { sub rules_target( $$ ) {
my ( $zone, $zone1 ) = @_; my ( $zone, $zone1 ) = @_;
my $chain = "${zone}2${zone1}"; my $chain = "${zone}2${zone1}";
my $chainref = $filter_table->{1}{$chain}; my $chainref = $filter_table->{$chain};
return $chain if $chainref && $chainref->{referenced}; return $chain if $chainref && $chainref->{referenced};
return 'ACCEPT' if $zone eq $zone1; return 'ACCEPT' if $zone eq $zone1;
if ( $chainref->{policy} ne 'CONTINUE' ) { if ( $chainref->{policy} ne 'CONTINUE' ) {
my $policyref = $filter_table->{1}{$chainref->{policychain}}; my $policyref = $filter_table->{$chainref->{policychain}};
return $policyref->{name} if $policyref; return $policyref->{name} if $policyref;
fatal_error "No policy defined for zone $zone to zone $zone1"; fatal_error "No policy defined for zone $zone to zone $zone1";
} }
@ -1436,7 +1436,7 @@ sub generate_matrix() {
sub create_zone_dyn_chain( $$ ) { sub create_zone_dyn_chain( $$ ) {
my ( $zone , $chainref ) = @_; my ( $zone , $chainref ) = @_;
my $name = "${zone}_dyn"; my $name = "${zone}_dyn";
new_standard_chain IPv4, $name; new_standard_chain $name;
add_rule $chainref, "-j $name"; add_rule $chainref, "-j $name";
} }
@ -1507,15 +1507,15 @@ sub generate_matrix() {
# Special processing for complex zones # Special processing for complex zones
# #
for my $zone ( complex_zones ) { for my $zone ( complex_zones ) {
my $frwd_ref = new_standard_chain IPv4, "${zone}_frwd"; my $frwd_ref = new_standard_chain "${zone}_frwd";
my $zoneref = find_zone( $zone ); my $zoneref = find_zone( $zone );
my $exclusions = $zoneref->{exclusions}; my $exclusions = $zoneref->{exclusions};
if ( @$exclusions ) { if ( @$exclusions ) {
my $in_ref = new_standard_chain IPv4, "${zone}_input"; my $in_ref = new_standard_chain "${zone}_input";
my $out_ref = new_standard_chain IPv4, "${zone}_output"; my $out_ref = new_standard_chain "${zone}_output";
add_rule ensure_filter_chain( IPv4, "${zone}2${zone}", 1 ) , '-j ACCEPT' if rules_target( $zone, $zone ) eq 'ACCEPT'; add_rule ensure_filter_chain( "${zone}2${zone}", 1 ) , '-j ACCEPT' if rules_target( $zone, $zone ) eq 'ACCEPT';
for my $host ( @$exclusions ) { for my $host ( @$exclusions ) {
my ( $interface, $net ) = split /:/, $host; my ( $interface, $net ) = split /:/, $host;
@ -1528,11 +1528,11 @@ sub generate_matrix() {
if ( $capabilities{POLICY_MATCH} ) { if ( $capabilities{POLICY_MATCH} ) {
my $type = $zoneref->{type}; my $type = $zoneref->{type};
my $source_ref = ( $zoneref->{hosts}{+ZT_IPSEC4} ) || {}; my $source_ref = ( $zoneref->{hosts}{ipsec4} ) || {};
if ( $config{DYNAMIC_ZONES} ) { if ( $config{DYNAMIC_ZONES} ) {
no warnings; no warnings;
create_zone_dyn_chain $zone, $frwd_ref if (%$source_ref || $type & ZT_IPSEC ); create_zone_dyn_chain $zone, $frwd_ref if (%$source_ref || $type eq 'ipsec4' );
} }
for my $interface ( keys %$source_ref ) { for my $interface ( keys %$source_ref ) {
@ -1541,7 +1541,7 @@ sub generate_matrix() {
my $ipsec_match = match_ipsec_in $zone , $hostref; my $ipsec_match = match_ipsec_in $zone , $hostref;
for my $net ( @{$hostref->{hosts}} ) { for my $net ( @{$hostref->{hosts}} ) {
add_rule( add_rule(
$filter_table->{1}{forward_chain $interface} , $filter_table->{forward_chain $interface} ,
join( '', match_source_net( $net ), $ipsec_match, "-j $frwd_ref->{name}" ) join( '', match_source_net( $net ), $ipsec_match, "-j $frwd_ref->{name}" )
); );
} }
@ -1566,8 +1566,8 @@ sub generate_matrix() {
my %needbroadcast; my %needbroadcast;
if ( $complex ) { if ( $complex ) {
$frwd_ref = $filter_table->{1}{"${zone}_frwd"}; $frwd_ref = $filter_table->{"${zone}_frwd"};
my $dnat_ref = ensure_chain 'nat' , IPv4, dnat_chain( $zone ); my $dnat_ref = ensure_chain 'nat' , dnat_chain( $zone );
if ( @$exclusions ) { if ( @$exclusions ) {
insert_exclusions $dnat_ref, $exclusions if $dnat_ref->{referenced}; insert_exclusions $dnat_ref, $exclusions if $dnat_ref->{referenced};
} }
@ -1592,10 +1592,10 @@ sub generate_matrix() {
if ( $chain1 ) { if ( $chain1 ) {
if ( @$exclusions ) { if ( @$exclusions ) {
add_rule $filter_table->{1}{output_chain $interface} , join( '', $dest, $ipsec_out_match, "-j ${zone}_output" ); add_rule $filter_table->{output_chain $interface} , join( '', $dest, $ipsec_out_match, "-j ${zone}_output" );
add_rule $filter_table->{1}{"${zone}_output"} , "-j $chain1"; add_rule $filter_table->{"${zone}_output"} , "-j $chain1";
} else { } else {
add_rule $filter_table->{1}{output_chain $interface} , join( '', $dest, $ipsec_out_match, "-j $chain1" ); add_rule $filter_table->{output_chain $interface} , join( '', $dest, $ipsec_out_match, "-j $chain1" );
} }
} }
@ -1605,14 +1605,14 @@ sub generate_matrix() {
if ( $chain2 ) { if ( $chain2 ) {
if ( @$exclusions ) { if ( @$exclusions ) {
add_rule $filter_table->{1}{input_chain $interface}, join( '', $source, $ipsec_in_match, "-j ${zone}_input" ); add_rule $filter_table->{input_chain $interface}, join( '', $source, $ipsec_in_match, "-j ${zone}_input" );
add_rule $filter_table->{1}{"${zone}_input"} , "-j $chain2"; add_rule $filter_table->{"${zone}_input"} , "-j $chain2";
} else { } else {
add_rule $filter_table->{1}{input_chain $interface}, join( '', $source, $ipsec_in_match, "-j $chain2" ); add_rule $filter_table->{input_chain $interface}, join( '', $source, $ipsec_in_match, "-j $chain2" );
} }
} }
add_rule $filter_table->{1}{forward_chain $interface} , join( '', $source, $ipsec_in_match. "-j $frwd_ref->{name}" ) add_rule $filter_table->{forward_chain $interface} , join( '', $source, $ipsec_in_match. "-j $frwd_ref->{name}" )
if $complex && $hostref->{ipsec} ne 'ipsec'; if $complex && $hostref->{ipsec} ne 'ipsec';
$needbroadcast{$interface}{$source} = 1 if get_interface_option $interface, 'detectnets'; $needbroadcast{$interface}{$source} = 1 if get_interface_option $interface, 'detectnets';
@ -1624,11 +1624,11 @@ sub generate_matrix() {
if ( $chain1 ) { if ( $chain1 ) {
for my $interface ( keys %needbroadcast ) { for my $interface ( keys %needbroadcast ) {
if ( $capabilities{ADDRTYPE} ) { if ( $capabilities{ADDRTYPE} ) {
add_rule $filter_table->{1}{output_chain $interface} , "-m addrtype --dst-type BROADCAST -j $chain1"; add_rule $filter_table->{output_chain $interface} , "-m addrtype --dst-type BROADCAST -j $chain1";
} else { } else {
my $interfaceref = find_interface( $interface ); my $interfaceref = find_interface( $interface );
my $chain = output_chain $interface; my $chain = output_chain $interface;
my $chainref = $filter_table->{1}{$chain}; my $chainref = $filter_table->{$chain};
if ( $interfaceref->{broadcasts} ) { if ( $interfaceref->{broadcasts} ) {
for my $address ( @{$interfaceref->{broadcasts}} , '255.255.255.255' ) { for my $address ( @{$interfaceref->{broadcasts}} , '255.255.255.255' ) {
@ -1644,7 +1644,7 @@ sub generate_matrix() {
} }
} }
add_rule $filter_table->{1}{output_chain $interface} , "-d 224.0.0.0/4 -j $chain1"; add_rule $filter_table->{output_chain $interface} , "-d 224.0.0.0/4 -j $chain1";
} }
} }
# #
@ -1659,7 +1659,7 @@ sub generate_matrix() {
ZONE1: ZONE1:
for my $zone1 ( non_firewall_zones ) { for my $zone1 ( non_firewall_zones ) {
my $zone1ref = find_zone( $zone1 ); my $zone1ref = find_zone( $zone1 );
my $policy = $filter_table->{1}{"${zone}2${zone1}"}->{policy}; my $policy = $filter_table->{"${zone}2${zone1}"}->{policy};
next if $policy eq 'NONE'; next if $policy eq 'NONE';
@ -1671,7 +1671,7 @@ sub generate_matrix() {
next if ( scalar ( keys( %{ $zoneref->{interfaces}} ) ) < 2 ) && ! ( $zoneref->{options}{in_out}{routeback} || @$exclusions ); next if ( scalar ( keys( %{ $zoneref->{interfaces}} ) ) < 2 ) && ! ( $zoneref->{options}{in_out}{routeback} || @$exclusions );
} }
if ( $zone1ref->{type} & ZT_BPORT ) { if ( $zone1ref->{type} eq 'bport4' ) {
next unless $zoneref->{bridge} eq $zone1ref->{bridge}; next unless $zoneref->{bridge} eq $zone1ref->{bridge};
} }
@ -1709,7 +1709,7 @@ sub generate_matrix() {
ZONE1: ZONE1:
for my $zone1 ( @dest_zones ) { for my $zone1 ( @dest_zones ) {
my $zone1ref = find_zone( $zone1 ); my $zone1ref = find_zone( $zone1 );
my $policy = $filter_table->{1}{"${zone}2${zone1}"}->{policy}; my $policy = $filter_table->{"${zone}2${zone1}"}->{policy};
next if $policy eq 'NONE'; next if $policy eq 'NONE';
@ -1728,19 +1728,19 @@ sub generate_matrix() {
while ( my ($interface, $sourceref) = ( each %needbroadcast ) ) { while ( my ($interface, $sourceref) = ( each %needbroadcast ) ) {
if ( get_interface_option( $interface, 'bridge' ) ) { if ( get_interface_option( $interface, 'bridge' ) ) {
for my $source ( keys %$sourceref ) { for my $source ( keys %$sourceref ) {
add_rule $filter_table->{1}{forward_chain $interface} , "-o $interface ${source}-d 255.255.255.255 -j $chain3"; add_rule $filter_table->{forward_chain $interface} , "-o $interface ${source}-d 255.255.255.255 -j $chain3";
add_rule $filter_table->{1}{forward_chain $interface} , "-o $interface ${source}-d 224.0.0.0/4 -j $chain3"; add_rule $filter_table->{forward_chain $interface} , "-o $interface ${source}-d 224.0.0.0/4 -j $chain3";
} }
} }
} }
} }
} }
if ( $zone1ref->{type} & ZT_BPORT ) { if ( $zone1ref->{type} eq 'bport4' ) {
next ZONE1 unless $zoneref->{bridge} eq $zone1ref->{bridge}; next ZONE1 unless $zoneref->{bridge} eq $zone1ref->{bridge};
} }
my $chainref = $filter_table->{1}{$chain}; my $chainref = $filter_table->{$chain};
my $exclusions1 = $zone1ref->{exclusions}; my $exclusions1 = $zone1ref->{exclusions};
my $dest_hosts_ref = $zone1ref->{hosts}; my $dest_hosts_ref = $zone1ref->{hosts};
@ -1757,7 +1757,7 @@ sub generate_matrix() {
unless ( $chain1 ) { unless ( $chain1 ) {
$chain1 = newexclusionchain; $chain1 = newexclusionchain;
$policy_exclusions{"${chain}_${zone1}"} = $chain1; $policy_exclusions{"${chain}_${zone1}"} = $chain1;
my $chain1ref = ensure_filter_chain IPv4, $chain1, 0; my $chain1ref = ensure_filter_chain $chain1, 0;
add_exclusions $chain1ref, $exclusions1; add_exclusions $chain1ref, $exclusions1;
add_rule $chain1ref, "-j $chain"; add_rule $chain1ref, "-j $chain";
} }
@ -1787,7 +1787,7 @@ sub generate_matrix() {
for my $typeref ( values %$source_hosts_ref ) { for my $typeref ( values %$source_hosts_ref ) {
for my $interface ( keys %$typeref ) { for my $interface ( keys %$typeref ) {
my $arrayref = $typeref->{$interface}; my $arrayref = $typeref->{$interface};
my $chain3ref = $filter_table->{1}{forward_chain $interface}; my $chain3ref = $filter_table->{forward_chain $interface};
for my $hostref ( @$arrayref ) { for my $hostref ( @$arrayref ) {
for my $net ( @{$hostref->{hosts}} ) { for my $net ( @{$hostref->{hosts}} ) {
for my $type1ref ( values %$dest_hosts_ref ) { for my $type1ref ( values %$dest_hosts_ref ) {
@ -1826,7 +1826,7 @@ sub generate_matrix() {
for my $typeref ( values %$source_hosts_ref ) { for my $typeref ( values %$source_hosts_ref ) {
for my $interface ( keys %$typeref ) { for my $interface ( keys %$typeref ) {
my $arrayref = $typeref->{$interface}; my $arrayref = $typeref->{$interface};
my $chain2ref = $filter_table->{1}{forward_chain $interface}; my $chain2ref = $filter_table->{forward_chain $interface};
for my $hostref ( @$arrayref ) { for my $hostref ( @$arrayref ) {
for my $net ( @{$hostref->{hosts}} ) { for my $net ( @{$hostref->{hosts}} ) {
add_rule $chain2ref, match_source_net($net) . "-j $last_chain"; add_rule $chain2ref, match_source_net($net) . "-j $last_chain";
@ -1842,32 +1842,32 @@ sub generate_matrix() {
# Now add the jumps to the interface chains from FORWARD, INPUT, OUTPUT and POSTROUTING # Now add the jumps to the interface chains from FORWARD, INPUT, OUTPUT and POSTROUTING
# #
for my $interface ( @interfaces ) { for my $interface ( @interfaces ) {
add_rule $filter_table->{1}{FORWARD} , match_source_dev( $interface ) . "-j " . forward_chain $interface; add_rule $filter_table->{FORWARD} , match_source_dev( $interface ) . "-j " . forward_chain $interface;
add_rule $filter_table->{1}{INPUT} , match_source_dev( $interface ) . "-j " . input_chain $interface; add_rule $filter_table->{INPUT} , match_source_dev( $interface ) . "-j " . input_chain $interface;
add_rule $filter_table->{1}{OUTPUT} , "-o $interface -j " . output_chain $interface unless get_interface_option( $interface, 'port' ); add_rule $filter_table->{OUTPUT} , "-o $interface -j " . output_chain $interface unless get_interface_option( $interface, 'port' );
addnatjump 'POSTROUTING' , masq_chain( $interface ) , match_dest_dev( $interface ); addnatjump 'POSTROUTING' , masq_chain( $interface ) , match_dest_dev( $interface );
} }
my $fw = firewall_zone; my $fw = firewall_zone;
my $chainref = $filter_table->{1}{"${fw}2${fw}"}; my $chainref = $filter_table->{"${fw}2${fw}"};
add_rule $filter_table->{1}{OUTPUT} , "-o lo -j " . ($chainref->{referenced} ? "$chainref->{name}" : 'ACCEPT' ); add_rule $filter_table->{OUTPUT} , "-o lo -j " . ($chainref->{referenced} ? "$chainref->{name}" : 'ACCEPT' );
add_rule $filter_table->{1}{INPUT} , '-i lo -j ACCEPT'; add_rule $filter_table->{INPUT} , '-i lo -j ACCEPT';
my %builtins = ( mangle => [ qw/PREROUTING INPUT FORWARD POSTROUTING/ ] , my %builtins = ( mangle => [ qw/PREROUTING INPUT FORWARD POSTROUTING/ ] ,
nat=> [ qw/PREROUTING OUTPUT POSTROUTING/ ] , nat=> [ qw/PREROUTING OUTPUT POSTROUTING/ ] ,
filter=> [ qw/INPUT FORWARD OUTPUT/ ] ); filter=> [ qw/INPUT FORWARD OUTPUT/ ] );
complete_standard_chain $filter_table->{1}{INPUT} , 'all' , firewall_zone; complete_standard_chain $filter_table->{INPUT} , 'all' , firewall_zone;
complete_standard_chain $filter_table->{1}{OUTPUT} , firewall_zone , 'all'; complete_standard_chain $filter_table->{OUTPUT} , firewall_zone , 'all';
complete_standard_chain $filter_table->{1}{FORWARD} , 'all' , 'all'; complete_standard_chain $filter_table->{FORWARD} , 'all' , 'all';
if ( $config{LOGALLNEW} ) { if ( $config{LOGALLNEW} ) {
for my $table qw/mangle nat filter/ { for my $table qw/mangle nat filter/ {
for my $chain ( @{$builtins{$table}} ) { for my $chain ( @{$builtins{$table}} ) {
log_rule_limit log_rule_limit
$config{LOGALLNEW} , $config{LOGALLNEW} ,
$chain_table{$table}{1}{$chain} , $chain_table{$table}{$chain} ,
$table , $table ,
$chain , $chain ,
'' , '' ,
@ -1883,7 +1883,7 @@ sub setup_mss( ) {
my $clampmss = $config{CLAMPMSS}; my $clampmss = $config{CLAMPMSS};
my $option; my $option;
my $match = ''; my $match = '';
my $chainref = $filter_table->{1}{FORWARD}; my $chainref = $filter_table->{FORWARD};
if ( $clampmss ) { if ( $clampmss ) {
if ( "\L$clampmss" eq 'yes' ) { if ( "\L$clampmss" eq 'yes' ) {
@ -1902,11 +1902,11 @@ sub setup_mss( ) {
# #
# Since we will need multiple rules, we create a separate chain # Since we will need multiple rules, we create a separate chain
# #
$chainref = new_chain 'filter', IPv4, 'settcpmss'; $chainref = new_chain 'filter', 'settcpmss';
# #
# Send all forwarded SYN packets to the 'settcpmss' chain # Send all forwarded SYN packets to the 'settcpmss' chain
# #
add_rule $filter_table->{1}{FORWARD} , "-p tcp --tcp-flags SYN,RST SYN -j settcpmss"; add_rule $filter_table->{FORWARD} , "-p tcp --tcp-flags SYN,RST SYN -j settcpmss";
my $in_match = ''; my $in_match = '';
my $out_match = ''; my $out_match = '';

View File

@ -275,7 +275,7 @@ sub process_tc_rule( $$$$$$$$$$ ) {
} }
if ( ( my $result = expand_rule( if ( ( my $result = expand_rule(
ensure_chain( 'mangle' , IPv4, $chain ) , ensure_chain( 'mangle' , $chain ) ,
NO_RESTRICT , NO_RESTRICT ,
do_proto( $proto, $ports, $sports) . do_test( $testval, $mask ) . do_tos( $tos ) , do_proto( $proto, $ports, $sports) . do_test( $testval, $mask ) . do_tos( $tos ) ,
$source , $source ,
@ -556,12 +556,12 @@ sub setup_tc() {
my $first_entry = 1; my $first_entry = 1;
if ( $capabilities{MANGLE_ENABLED} ) { if ( $capabilities{MANGLE_ENABLED} ) {
ensure_mangle_chain IPv4, 'tcpre'; ensure_mangle_chain 'tcpre';
ensure_mangle_chain IPv4, 'tcout'; ensure_mangle_chain 'tcout';
if ( $capabilities{MANGLE_FORWARD} ) { if ( $capabilities{MANGLE_FORWARD} ) {
ensure_mangle_chain IPv4, 'tcfor'; ensure_mangle_chain 'tcfor';
ensure_mangle_chain IPv4, 'tcpost'; ensure_mangle_chain 'tcpost';
} }
my $mark_part = ''; my $mark_part = '';
@ -570,21 +570,21 @@ sub setup_tc() {
$mark_part = $config{HIGH_ROUTE_MARKS} ? '-m mark --mark 0/0xFF00' : '-m mark --mark 0/0xFF'; $mark_part = $config{HIGH_ROUTE_MARKS} ? '-m mark --mark 0/0xFF00' : '-m mark --mark 0/0xFF';
for my $interface ( @routemarked_interfaces ) { for my $interface ( @routemarked_interfaces ) {
add_rule $mangle_table->{1}{PREROUTING} , "-i $interface -j tcpre"; add_rule $mangle_table->{PREROUTING} , "-i $interface -j tcpre";
} }
} }
add_rule $mangle_table->{1}{PREROUTING} , "$mark_part -j tcpre"; add_rule $mangle_table->{PREROUTING} , "$mark_part -j tcpre";
add_rule $mangle_table->{1}{OUTPUT} , "$mark_part -j tcout"; add_rule $mangle_table->{OUTPUT} , "$mark_part -j tcout";
if ( $capabilities{MANGLE_FORWARD} ) { if ( $capabilities{MANGLE_FORWARD} ) {
add_rule $mangle_table->{1}{FORWARD} , '-j tcfor'; add_rule $mangle_table->{FORWARD} , '-j tcfor';
add_rule $mangle_table->{1}{POSTROUTING} , '-j tcpost'; add_rule $mangle_table->{POSTROUTING} , '-j tcpost';
} }
if ( $config{HIGH_ROUTE_MARKS} ) { if ( $config{HIGH_ROUTE_MARKS} ) {
for my $chain qw(INPUT FORWARD POSTROUTING) { for my $chain qw(INPUT FORWARD POSTROUTING) {
insert_rule $mangle_table->{1}{$chain}, 1, '-j MARK --and-mark 0xFF'; insert_rule $mangle_table->{$chain}, 1, '-j MARK --and-mark 0xFF';
} }
} }
} }
@ -618,10 +618,9 @@ sub setup_tc() {
clear_comment; clear_comment;
} }
if ( @deferred_rules ) { for ( @deferred_rules ) {
my $chainref = ensure_chain( 'mangle' , IPv4, 'tcpost' ); add_rule ensure_chain( 'mangle' , 'tcpost' ), $_;
add_rule $chainref, $_ for ( @deferred_rules );
} }
} }

View File

@ -82,9 +82,9 @@ sub setup_tunnels() {
unless ( $gatewayzones eq '-' ) { unless ( $gatewayzones eq '-' ) {
for my $zone ( split /,/, $gatewayzones ) { for my $zone ( split /,/, $gatewayzones ) {
my $type = zone_type( $zone ); my $type = zone_type( $zone );
fatal_error "Invalid zone ($zone) for GATEWAY ZONE" if $type == ZT_FIREWALL || $type & ZT_BPORT; fatal_error "Invalid zone ($zone) for GATEWAY ZONE" if $type eq 'firewall' || $type eq 'bport4';
$inchainref = ensure_filter_chain IPv4, "${zone}2${fw}", 1; $inchainref = ensure_filter_chain "${zone}2${fw}", 1;
$outchainref = ensure_filter_chain IPv4, "${fw}2${zone}", 1; $outchainref = ensure_filter_chain "${fw}2${zone}", 1;
unless ( $capabilities{POLICY_MATCH} ) { unless ( $capabilities{POLICY_MATCH} ) {
add_rule $inchainref, "-p 50 $source -j ACCEPT"; add_rule $inchainref, "-p 50 $source -j ACCEPT";
@ -228,10 +228,10 @@ sub setup_tunnels() {
my $zonetype = zone_type( $zone ); my $zonetype = zone_type( $zone );
fatal_error "Invalid zone ($zone) for tunnel ZONE" if $zonetype == ZT_FIREWALL || $zonetype & ZT_BPORT; fatal_error "Invalid zone ($zone) for tunnel ZONE" if $zonetype eq 'firewall' || $zonetype eq 'bport4';
my $inchainref = ensure_filter_chain IPv4, "${zone}2${fw}", 1; my $inchainref = ensure_filter_chain "${zone}2${fw}", 1;
my $outchainref = ensure_filter_chain IPv4, "${fw}2${zone}", 1; my $outchainref = ensure_filter_chain "${fw}2${zone}", 1;
my $source = match_source_net $gateway; my $source = match_source_net $gateway;
my $dest = match_dest_net $gateway; my $dest = match_dest_net $gateway;

View File

@ -37,16 +37,6 @@ our @EXPORT = qw( NOTHING
IPSECPROTO IPSECPROTO
IPSECMODE IPSECMODE
ZT_IPV4
ZT_IPSEC
ZT_BPORT
ZT_IPV6
ZT_IPSEC4
ZT_IPSEC6
ZT_BPORT4
ZT_BPORT6
ZT_FIREWALL
numeric_value numeric_value
determine_zones determine_zones
zone_report zone_report
@ -55,11 +45,7 @@ our @EXPORT = qw( NOTHING
firewall_zone firewall_zone
defined_zone defined_zone
zone_type zone_type
zone_ipv
all_zones all_zones
all_ipv4_zones
all_ipv6_zones
all_ipvN_zones
complex_zones complex_zones
non_firewall_zones non_firewall_zones
single_interface single_interface
@ -95,7 +81,7 @@ use constant { NOTHING => 'NOTHING',
# #
# @zones contains the ordered list of zones with sub-zones appearing before their parents. # @zones contains the ordered list of zones with sub-zones appearing before their parents.
# #
# %zones{<zone1> => {type = > <zone type> (see above). # %zones{<zone1> => {type = > <zone type> 'firewall', 'ipv4', 'ipsec4', 'bport4';
# options => { complex => 0|1 # options => { complex => 0|1
# in_out => < policy match string > # in_out => < policy match string >
# in => < policy match string > # in => < policy match string >
@ -130,28 +116,6 @@ our %reservedName = ( all => 1,
DEST => 1 ); DEST => 1 );
# #
# Zone Types
#
use constant { ZT_IPV4 => 1,
ZT_IPV6 => 2,
ZT_FIREWALL => 3, #ZT_IPV4 + ZT_IPV6
ZT_IPSEC => 4,
ZT_IPSEC4 => 5, #ZT_IPV4 + ZT_IPSEC
ZT_IPSEC6 => 6, #ZT_IPV6 + ZT_IPSEC
ZT_BPORT => 8,
ZT_BPORT4 => 9, #ZT_IPV4 + ZT_BPORT
ZT_BPORT6 => 10, #ZT_IPV6 + ZT_BPORT
};
our %zonetypes = ( 1 => 'ipv4' ,
2 => 'ipv6' ,
3 => 'firewall' ,
5 => 'ipsec4' ,
6 => 'ipsec6' ,
9 => 'bport4' ,
10 => 'bport6' ,
);
#
# Interface Table. # Interface Table.
# #
# @interfaces lists the interface names in the order that they appear in the interfaces file. # @interfaces lists the interface names in the order that they appear in the interfaces file.
@ -259,7 +223,7 @@ sub parse_zone_option_list($$)
if ( $key{$e} ) { if ( $key{$e} ) {
$h{$e} = $val; $h{$e} = $val;
} else { } else {
fatal_error "The \"$e\" option may only be specified for ipsec zones" unless ( $zonetype & ZT_IPSEC ); fatal_error "The \"$e\" option may only be specified for ipsec zones" unless $zonetype eq 'ipsec4';
$options .= $invert; $options .= $invert;
$options .= "--$e "; $options .= "--$e ";
$options .= "$val "if defined $val; $options .= "$val "if defined $val;
@ -301,7 +265,7 @@ sub determine_zones()
for my $p ( @parents ) { for my $p ( @parents ) {
fatal_error "Invalid Parent List ($2)" unless $p; fatal_error "Invalid Parent List ($2)" unless $p;
fatal_error "Unknown parent zone ($p)" unless $zones{$p}; fatal_error "Unknown parent zone ($p)" unless $zones{$p};
fatal_error 'Subzones of firewall zone not allowed' if $zones{$p}{type} == ZT_FIREWALL; fatal_error 'Subzones of firewall zone not allowed' if $zones{$p}{type} eq 'firewall';
push @{$zones{$p}{children}}, $zone; push @{$zones{$p}{children}}, $zone;
} }
} }
@ -313,25 +277,20 @@ sub determine_zones()
$type = "ipv4" unless $type; $type = "ipv4" unless $type;
if ( $type =~ /ipv4/i ) { if ( $type =~ /ipv4/i ) {
$type = ZT_IPV4; $type = 'ipv4';
} elsif ( $type =~ /^ipsec4?$/i ) { } elsif ( $type =~ /^ipsec4?$/i ) {
$type = ZT_IPSEC4; $type = 'ipsec4';
} elsif ( $type =~ /^ipsec6$/i ) {
$type = ZT_IPSEC6;
} elsif ( $type =~ /^bport4?$/i ) { } elsif ( $type =~ /^bport4?$/i ) {
warning_message "Bridge Port zones should have a parent zone" unless @parents; warning_message "Bridge Port zones should have a parent zone" unless @parents;
$type = ZT_BPORT4; $type = 'bport4';
} elsif ( $type =~ /^bport6$/i ) {
warning_message "Bridge Port zones should have a parent zone" unless @parents;
$type = ZT_BPORT6;
} elsif ( $type eq 'firewall' ) { } elsif ( $type eq 'firewall' ) {
fatal_error 'Firewall zone may not be nested' if @parents; fatal_error 'Firewall zone may not be nested' if @parents;
fatal_error "Only one firewall zone may be defined ($zone)" if $firewall_zone; fatal_error "Only one firewall zone may be defined ($zone)" if $firewall_zone;
$firewall_zone = $zone; $firewall_zone = $zone;
$ENV{FW} = $zone; $ENV{FW} = $zone;
$type = ZT_FIREWALL; $type = "firewall";
} elsif ( $type eq '-' ) { } elsif ( $type eq '-' ) {
$type = ZT_IPV4; $type = 'ipv4';
} else { } else {
fatal_error "Invalid zone type ($type)" ; fatal_error "Invalid zone type ($type)" ;
} }
@ -347,7 +306,7 @@ sub determine_zones()
options => { in_out => parse_zone_option_list( $options || '', $type ) , options => { in_out => parse_zone_option_list( $options || '', $type ) ,
in => parse_zone_option_list( $in_options || '', $type ) , in => parse_zone_option_list( $in_options || '', $type ) ,
out => parse_zone_option_list( $out_options || '', $type ) , out => parse_zone_option_list( $out_options || '', $type ) ,
complex => ( ( $type & ZT_IPSEC ) || $options || $in_options || $out_options ? 1 : 0) } , complex => ($type eq 'ipsec4' || $options || $in_options || $out_options ? 1 : 0) } ,
interfaces => {} , interfaces => {} ,
children => [] , children => [] ,
hosts => {} hosts => {}
@ -382,7 +341,7 @@ sub determine_zones()
# #
sub haveipseczones() { sub haveipseczones() {
for my $zoneref ( values %zones ) { for my $zoneref ( values %zones ) {
return 1 if ( $zoneref->{type} & ZT_IPSEC ); return 1 if $zoneref->{type} eq 'ipsec4';
} }
0; 0;
@ -402,7 +361,7 @@ sub zone_report()
my $type = $zoneref->{type}; my $type = $zoneref->{type};
my $optionref = $zoneref->{options}; my $optionref = $zoneref->{options};
progress_message " $zone ($zonetypes{$type})"; progress_message " $zone ($type)";
my $printed = 0; my $printed = 0;
@ -426,8 +385,8 @@ sub zone_report()
} }
unless ( $printed ) { unless ( $printed ) {
fatal_error "No bridge has been associated with zone $zone" if ( $type & ZT_BPORT ) && ! $zoneref->{bridge}; fatal_error "No bridge has been associated with zone $zone" if $type eq 'bport4' && ! $zoneref->{bridge};
warning_message "*** $zone is an EMPTY ZONE ***" unless $type == ZT_FIREWALL; warning_message "*** $zone is an EMPTY ZONE ***" unless $type eq 'firewall';
} }
} }
@ -442,9 +401,9 @@ sub dump_zone_contents()
my $type = $zoneref->{type}; my $type = $zoneref->{type};
my $optionref = $zoneref->{options}; my $optionref = $zoneref->{options};
my $exclusions = $zoneref->{exclusions}; my $exclusions = $zoneref->{exclusions};
my $entry = "$zone $zonetypes{$type}"; my $entry = "$zone $type";
$entry .= ":$zoneref->{bridge}" if $type & ZT_BPORT; $entry .= ":$zoneref->{bridge}" if $type eq 'bport4';
if ( $hostref ) { if ( $hostref ) {
for my $type ( sort keys %$hostref ) { for my $type ( sort keys %$hostref ) {
@ -519,7 +478,7 @@ sub add_group_to_zone($$$$$)
} }
unless ( $switched ) { unless ( $switched ) {
if ( $type == $zonetype ) { if ( $type eq $zonetype ) {
fatal_error "Duplicate Host Group ($interface:$host) in zone $zone" if $ifacezone eq $zone; fatal_error "Duplicate Host Group ($interface:$host) in zone $zone" if $ifacezone eq $zone;
$ifacezone = $zone if $host eq ALLIPv4; $ifacezone = $zone if $host eq ALLIPv4;
} }
@ -546,7 +505,7 @@ sub add_group_to_zone($$$$$)
push @{$arrayref}, { options => $options, push @{$arrayref}, { options => $options,
hosts => \@newnetworks, hosts => \@newnetworks,
ipsec => $type & ZT_IPSEC ? 'ipsec' : 'none' }; ipsec => $type eq 'ipsec4' ? 'ipsec' : 'none' };
} }
# #
@ -571,29 +530,12 @@ sub defined_zone( $ ) {
$zones{$_[0]}; $zones{$_[0]};
} }
sub zone_ipv( $ ) {
find_zone( $_[0] )->{type} & ZT_FIREWALL;
}
sub all_zones() { sub all_zones() {
@zones; @zones;
} }
sub all_ipv4_zones() {
grep ( $zones{$_}{type} & ZT_IPV4 , @zones );
}
sub all_ipv6_zones() {
grep ( $zones{$_}{type} & ZT_IPV4 , @zones );
}
sub all_ipvN_zones($) {
my $ipv = $_[0];
grep ( ( $zones{$_}{type} & ZT_FIREWALL ) == $ipv , @zones );
}
sub non_firewall_zones() { sub non_firewall_zones() {
grep ( $zones{$_}{type} != ZT_FIREWALL , @zones ); grep ( $zones{$_}{type} ne 'firewall' , @zones );
} }
sub complex_zones() { sub complex_zones() {
@ -689,7 +631,7 @@ sub validate_interfaces_file( $ )
$zoneref = $zones{$zone}; $zoneref = $zones{$zone};
fatal_error "Unknown zone ($zone)" unless $zoneref; fatal_error "Unknown zone ($zone)" unless $zoneref;
fatal_error "Firewall zone not allowed in ZONE column of interface record" if $zoneref->{type} == ZT_FIREWALL; fatal_error "Firewall zone not allowed in ZONE column of interface record" if $zoneref->{type} eq 'firewall';
} }
$networks = '' if $networks eq '-'; $networks = '' if $networks eq '-';
@ -706,7 +648,7 @@ sub validate_interfaces_file( $ )
require_capability( 'KLUDGEFREE', 'Bridge Ports', ''); require_capability( 'KLUDGEFREE', 'Bridge Ports', '');
fatal_error "Duplicate Interface ($port)" if $interfaces{$port}; fatal_error "Duplicate Interface ($port)" if $interfaces{$port};
fatal_error "$interface is not a defined bridge" unless $interfaces{$interface} && $interfaces{$interface}{options}{bridge}; fatal_error "$interface is not a defined bridge" unless $interfaces{$interface} && $interfaces{$interface}{options}{bridge};
fatal_error "Bridge Ports may only be associated with 'bport' zones" if $zone && ! ( $zoneref->{type} & ZT_BPORT ); fatal_error "Bridge Ports may only be associated with 'bport' zones" if $zone && $zoneref->{type} ne 'bport4';
if ( $zone ) { if ( $zone ) {
if ( $zoneref->{bridge} ) { if ( $zoneref->{bridge} ) {
@ -726,7 +668,7 @@ sub validate_interfaces_file( $ )
$interface = $port; $interface = $port;
} else { } else {
fatal_error "Duplicate Interface ($interface)" if $interfaces{$interface}; fatal_error "Duplicate Interface ($interface)" if $interfaces{$interface};
fatal_error "Zones of type 'bport' may only be associated with bridge ports" if $zone && $zoneref->{type} & ZT_BPORT; fatal_error "Zones of type 'bport' may only be associated with bridge ports" if $zone && $zoneref->{type} eq 'bport4';
$interfaces{$interface}{bridge} = $interface; $interfaces{$interface}{bridge} = $interface;
} }
@ -992,7 +934,7 @@ sub validate_hosts_file()
my $type = $zoneref->{type}; my $type = $zoneref->{type};
fatal_error "Unknown ZONE ($zone)" unless $type; fatal_error "Unknown ZONE ($zone)" unless $type;
fatal_error 'Firewall zone not allowed in ZONE column of hosts record' if $type == ZT_FIREWALL; fatal_error 'Firewall zone not allowed in ZONE column of hosts record' if $type eq 'firewall';
my $interface; my $interface;
@ -1005,7 +947,7 @@ sub validate_hosts_file()
fatal_error "Invalid HOST(S) column contents: $hosts"; fatal_error "Invalid HOST(S) column contents: $hosts";
} }
if ( $type & ZT_BPORT ) { if ( $type eq 'bport4' ) {
if ( $zoneref->{bridge} eq '' ) { if ( $zoneref->{bridge} eq '' ) {
fatal_error 'Bridge Port Zones may only be associated with bridge ports' unless $interfaces{$interface}{options}{port}; fatal_error 'Bridge Port Zones may only be associated with bridge ports' unless $interfaces{$interface}{options}{port};
$zoneref->{bridge} = $interfaces{$interface}{bridge}; $zoneref->{bridge} = $interfaces{$interface}{bridge};
@ -1023,7 +965,7 @@ sub validate_hosts_file()
for my $option ( @options ) for my $option ( @options )
{ {
if ( $option eq 'ipsec' ) { if ( $option eq 'ipsec' ) {
$type |= ZT_IPSEC; $type = 'ipsec4';
$zoneref->{options}{complex} = 1; $zoneref->{options}{complex} = 1;
$ipsec = 1; $ipsec = 1;
} elsif ( $validoptions{$option}) { } elsif ( $validoptions{$option}) {
@ -1066,7 +1008,7 @@ sub find_hosts_by_option( $ ) {
my $option = $_[0]; my $option = $_[0];
my @hosts; my @hosts;
for my $zone ( grep $zones{$_}{type} != ZT_FIREWALL , @zones ) { for my $zone ( grep $zones{$_}{type} ne 'firewall' , @zones ) {
while ( my ($type, $interfaceref) = each %{$zones{$zone}{hosts}} ) { while ( my ($type, $interfaceref) = each %{$zones{$zone}{hosts}} ) {
while ( my ( $interface, $arrayref) = ( each %{$interfaceref} ) ) { while ( my ( $interface, $arrayref) = ( each %{$interfaceref} ) ) {
for my $host ( @{$arrayref} ) { for my $host ( @{$arrayref} ) {