diff --git a/Shorewall/Perl/Shorewall/Compiler.pm b/Shorewall/Perl/Shorewall/Compiler.pm index 31c0a81d1..bb93b9fb8 100644 --- a/Shorewall/Perl/Shorewall/Compiler.pm +++ b/Shorewall/Perl/Shorewall/Compiler.pm @@ -38,6 +38,8 @@ use Shorewall::IPAddrs; use Shorewall::Raw; use Shorewall::Misc; +use strict; + our @ISA = qw(Exporter); our @EXPORT = qw( compiler ); our @EXPORT_OK = qw( $export ); @@ -705,9 +707,13 @@ sub compiler { # enable_script; # + # Validate the TC files so that the providers will know what interfaces have TC + # + my $tcinterfaces = process_tc; + # # Generate a function to bring up each provider # - process_providers; + process_providers( $tcinterfaces ); # # [Re-]establish Routing # diff --git a/Shorewall/Perl/Shorewall/Proc.pm b/Shorewall/Perl/Shorewall/Proc.pm index 196325d9d..a236461f2 100644 --- a/Shorewall/Perl/Shorewall/Proc.pm +++ b/Shorewall/Perl/Shorewall/Proc.pm @@ -40,7 +40,7 @@ our @EXPORT = qw( setup_source_routing setup_forwarding ); -our @EXPORT_OK = qw( ); +our @EXPORT_OK = qw( setup_interface_proc ); our $VERSION = 'MODULEVERSION'; # @@ -277,4 +277,45 @@ sub setup_forwarding( $$ ) { } } +sub setup_interface_proc( $ ) { + my $interface = shift; + my $physical = get_physical $interface; + my $value; + my @emitted; + + if ( interface_has_option( $interface, 'arp_filter' , $value ) ) { + push @emitted, "echo $value > /proc/sys/net/ipv4/conf/$physical/arp_filter"; + } + + if ( interface_has_option( $interface, 'arp_ignore' , $value ) ) { + push @emitted, "echo $value > /proc/sys/net/ipv4/conf/$physical/arp_ignore"; + } + + if ( interface_has_option( $interface, 'routefilter' , $value ) ) { + push @emitted, "echo $value > /proc/sys/net/ipv4/conf/$physical/rp_filter"; + } + + if ( interface_has_option( $interface, 'logmartians' , $value ) ) { + push @emitted, "echo $value > /proc/sys/net/ipv4/conf/$physical/log_martians"; + } + + if ( interface_has_option( $interface, 'sourceroute' , $value ) ) { + push @emitted, "echo $value > /proc/sys/net/ipv4/conf/$physical/accept_source_route"; + } + + if ( interface_has_option( $interface, 'sourceroute' , $value ) ) { + push @emitted, "echo $value > /proc/sys/net/ipv4/conf/$physical/accept_source_route"; + } + + if ( @emitted ) { + emit( '', + 'if [ $COMMAND = enable ]; then' ); + push_indent; + emit "$_" for @emitted; + pop_indent; + emit "fi\n"; + } +} + + 1; diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index 753c5d970..35497d992 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -29,6 +29,7 @@ use Shorewall::Config qw(:DEFAULT :internal); use Shorewall::IPAddrs; use Shorewall::Zones; use Shorewall::Chains qw(:DEFAULT :internal); +use Shorewall::Proc qw( setup_interface_proc ); use strict; @@ -143,6 +144,8 @@ sub copy_table( $$$ ) { # my $filter = $family == F_IPV6 ? q(sed 's/ via :: / /' | ) : ''; + emit ''; + if ( $realm ) { emit ( "\$IP -$family -o route show table $duplicate | sed -r 's/ realm [[:alnum:]_]+//' | while read net route; do" ) } else { @@ -174,6 +177,8 @@ sub copy_and_edit_table( $$$$ ) { # Shell and iptables use a different wildcard character # $copy =~ s/\+/*/; + + emit ''; if ( $realm ) { emit ( "\$IP -$family -o route show table $duplicate | sed -r 's/ realm [[:alnum:]]+//' | while read net route; do" ) @@ -258,7 +263,9 @@ sub start_provider( $$$ ) { emit "echo \". \${VARDIR}/undo_${table}_routing\" >> \${VARDIR}/undo_routing"; } -sub add_a_provider( ) { +sub add_a_provider( $ ) { + + my $tcdevices = shift; my ($table, $number, $mark, $duplicate, $interface, $gateway, $options, $copy ) = split_line 6, 8, 'providers file'; @@ -290,7 +297,8 @@ sub add_a_provider( ) { fatal_error "A bridge port ($interface) may not be configured as a provider interface" if port_to_bridge $interface; my $physical = get_physical $interface; - my $base = uc chain_base $physical; + my $dev = chain_base $physical; + my $base = uc $dev; my $gatewaycase = ''; if ( $gateway eq 'detect' ) { @@ -438,7 +446,6 @@ sub add_a_provider( ) { } else { start_provider( $table, $number, "if interface_is_usable $physical; then" ); } - $provider_interfaces{$interface} = $table; if ( $gatewaycase eq 'none' ) { @@ -450,6 +457,8 @@ sub add_a_provider( ) { } } + setup_interface_proc( $interface ); + if ( $mark ne '-' ) { my $mask = have_capability 'FWMARK_RT_MASK' ? '/' . in_hex $globals{PROVIDER_MASK} : ''; @@ -491,7 +500,7 @@ sub add_a_provider( ) { } emit "run_ip route add default via $gateway src $address dev $physical ${mtu}table $number $realm"; - } + } balance_default_route $balance , $gateway, $physical, $realm if $balance; @@ -545,6 +554,7 @@ sub add_a_provider( ) { emit "\nadd_${table}_routing_rules"; emit "add_${table}_routes"; + emit "setup_${dev}_tc" if $tcdevices->{$interface}; emit( '', 'if [ $COMMAND = enable ]; then' @@ -594,7 +604,7 @@ sub add_a_provider( ) { pop_indent; - emit "} # End of start_provider_$table()"; + emit '}'; # End of start_provider_$table(); if ( $optional ) { emit( '', @@ -894,14 +904,16 @@ sub finish_providers() { } } -sub process_providers() { +sub process_providers( $ ) { + my $tcdevices = shift; + our $providers = 0; $lastmark = 0; if ( my $fn = open_file 'providers' ) { first_entry "$doing $fn..."; - add_a_provider, $providers++ while read_a_line; + add_a_provider( $tcdevices ), $providers++ while read_a_line; } if ( $providers ) { diff --git a/Shorewall/Perl/Shorewall/Tc.pm b/Shorewall/Perl/Shorewall/Tc.pm index 8a710a641..26cf6e400 100644 --- a/Shorewall/Perl/Shorewall/Tc.pm +++ b/Shorewall/Perl/Shorewall/Tc.pm @@ -38,7 +38,7 @@ use Shorewall::Providers; use strict; our @ISA = qw(Exporter); -our @EXPORT = qw( setup_tc ); +our @EXPORT = qw( process_tc setup_tc ); our @EXPORT_OK = qw( process_tc_rule initialize ); our $VERSION = 'MODULEVERSION'; @@ -151,8 +151,8 @@ my $ipp2p; # leaf => 0|1 # guarantee => # options => { tos => [ , , ... ]; -# tcp_ack => 1 , -# ... +# tcp_ack => 1 , +# filters => [ filter list ] # } # } # } @@ -504,6 +504,8 @@ sub process_simple_device() { my $physical = physical_name $device; my $dev = chain_base( $physical ); + push @tcdevices, $device; + if ( $type ne '-' ) { if ( lc $type eq 'external' ) { $type = 'nfct-src'; @@ -530,6 +532,15 @@ sub process_simple_device() { $in_bandwidth = rate_to_kbit( $in_bandwidth ); } + emit( '', + '#', + "# Setup Simple Traffic Shaping for $physical", + '#', + "setup_${dev}_tc() {" + ); + + push_indent; + emit "if interface_is_up $physical; then"; push_indent; @@ -607,7 +618,9 @@ sub process_simple_device() { emit qq(error_message "WARNING: Device $physical is not in the UP state -- traffic-shaping configuration skipped"); emit "${dev}_exists="; pop_indent; - emit "fi\n"; + emit 'fi'; + pop_indent; + emit "}\n"; progress_message " Simple tcdevice \"$currentline\" $done."; } @@ -711,7 +724,8 @@ sub validate_tc_device( ) { qdisc => $qdisc, guarantee => 0, name => $device, - physical => physical_name $device + physical => physical_name $device, + filters => [] } , push @tcdevices, $device; @@ -1018,6 +1032,8 @@ sub process_tc_filter() { my $tcref = $tcclasses{$device}; + my $filtersref = $devref->{filters}; + fatal_error "No Classes were defined for INTERFACE $device" unless $tcref; my $classnum = hex_value $class; @@ -1036,17 +1052,6 @@ sub process_tc_filter() { my $have_rule = 0; - if ( $devref->{physical} ne $lastdevice ) { - if ( $lastdevice ) { - pop_indent; - emit "fi\n"; - } - - $lastdevice = $devref->{physical}; - emit "if interface_is_up $lastdevice; then"; - push_indent; - } - my $rule = "filter add dev $devref->{physical} protocol $ip parent $devnum:0 prio $prio u32"; if ( $source ne '-' ) { @@ -1101,9 +1106,9 @@ sub process_tc_filter() { if ( $portlist eq '-' && $sportlist eq '-' ) { if ( $have_rule ) { - emit( "\nrun_tc $rule\\" , - " flowid $devnum:$class" , - '' ); + push @$filtersref , ( "\nrun_tc $rule\\" , + " flowid $devnum:$class" , + '' ); } else { warning_message "Degenerate tcfilter ignored"; } @@ -1129,17 +1134,17 @@ sub process_tc_filter() { $lasttnum = $tnum; $lastrule = $rule; - emit( "\nrun_tc filter add dev $devref->{physical} parent $devnum:0 protocol $ip prio $prio handle $tnum: u32 divisor 1" ); + push @$filtersref, ( "\nrun_tc filter add dev $devref->{physical} parent $devnum:0 protocol $ip prio $prio handle $tnum: u32 divisor 1" ); } # # And link to it using the current contents of $rule # if ( $family == F_IPV4 ) { - emit( "\nrun_tc $rule\\" , - " link $tnum:0 offset at 0 mask 0x0F00 shift 6 plus 0 eat" ); + push @$filtersref, ( "\nrun_tc $rule\\" , + " link $tnum:0 offset at 0 mask 0x0F00 shift 6 plus 0 eat" ); } else { - emit( "\nrun_tc $rule\\" , - " link $tnum:0 offset plus 40 eat" ); + push @$filtersref, ( "\nrun_tc $rule\\" , + " link $tnum:0 offset plus 40 eat" ); } # # The rule to match the port(s) will be inserted into the new table @@ -1165,9 +1170,9 @@ sub process_tc_filter() { $rule1 = "match u32 0x${sport}0000 0x${smask}0000 at nexthdr+0" , } - emit( "\nrun_tc $rule\\" , - " $rule1\\" , - " flowid $devnum:$class" ); + push @$filtersref, ( "\nrun_tc $rule\\" , + " $rule1\\" , + " flowid $devnum:$class" ); } } } else { @@ -1183,9 +1188,9 @@ sub process_tc_filter() { my $rule1 = " match icmp type $icmptype 0xff"; $rule1 .= "\\\n match icmp code $icmpcode 0xff" if defined $icmpcode; - emit( "\nrun_tc ${rule}\\" , - "$rule1\\" , - " flowid $devnum:$class" ); + push @$filtersref, ( "\nrun_tc ${rule}\\" , + "$rule1\\" , + " flowid $devnum:$class" ); } elsif ( $protonumber == IPv6_ICMP ) { fatal_error "IPv6 ICMP not allowed with IPv4" unless $family == F_IPV4; fatal_error "SOURCE PORT(S) are not allowed with IPv6 ICMP" if $sportlist ne '-'; @@ -1194,9 +1199,9 @@ sub process_tc_filter() { my $rule1 = " match icmp6 type $icmptype 0xff"; $rule1 .= "\\\n match icmp6 code $icmpcode 0xff" if defined $icmpcode; - emit( "\nrun_tc ${rule}\\" , - "$rule1\\" , - " flowid $devnum:$class" ); + push @$filtersref, ( "\nrun_tc ${rule}\\" , + "$rule1\\" , + " flowid $devnum:$class" ); } else { my @portlist = expand_port_range $protonumber , $portrange; @@ -1214,9 +1219,9 @@ sub process_tc_filter() { } if ( $sportlist eq '-' ) { - emit( "\nrun_tc ${rule}\\" , - " $rule1\\" , - " flowid $devnum:$class" ); + push @$filtersref, ( "\nrun_tc ${rule}\\" , + " $rule1\\" , + " flowid $devnum:$class" ); } else { for my $sportrange ( split_list $sportlist , 'port list' ) { my @sportlist = expand_port_range $protonumber , $sportrange; @@ -1234,10 +1239,10 @@ sub process_tc_filter() { $rule2 = "match u32 0x${sport}0000 0x${smask}0000 at nexthdr+0" , } - emit( "\nrun_tc ${rule}\\", - " $rule1\\" , - " $rule2\\" , - " flowid $devnum:$class" ); + push @$filtersref, ( "\nrun_tc ${rule}\\", + " $rule1\\" , + " $rule2\\" , + " flowid $devnum:$class" ); } } } @@ -1268,12 +1273,13 @@ sub process_tc_filter() { } +# +# Process the tcfilter file storing the compiled filters in the %tcdevices table +# sub process_tcfilters() { my $fn = open_file 'tcfilters'; - our $lastdevice = ''; - if ( $fn ) { my @family = ( $family ); @@ -1301,15 +1307,12 @@ sub process_tcfilters() { } Shorewall::IPAddrs::initialize( $family = pop @family ); - - if ( $lastdevice ) { - pop_indent; - emit "fi\n"; - } - } } +# +# Process a tcpri record +# sub process_tc_priority() { my ( $band, $proto, $ports , $address, $interface, $helper ) = split_line1 1, 6, 'tcpri'; @@ -1371,27 +1374,31 @@ sub process_tc_priority() { } } -sub setup_simple_traffic_shaping() { - my $interfaces; - - save_progress_message q("Setting up Traffic Control..."); +# +# Process tcinterfaces +# +sub process_tcinterfaces() { my $fn = open_file 'tcinterfaces'; if ( $fn ) { first_entry "$doing $fn..."; - process_simple_device, $interfaces++ while read_a_line; - } else { - $fn = find_file 'tcinterfaces'; + process_simple_device while read_a_line; } +} +# +# Process tcpri +# +sub process_tcpri() { + my $fn = find_file 'tcinterfaces'; my $fn1 = open_file 'tcpri'; if ( $fn1 ) { first_entry sub { progress_message2 "$doing $fn1..."; - warning_message "There are entries in $fn1 but $fn was empty" unless $interfaces || $family == F_IPV6; + warning_message "There are entries in $fn1 but $fn was empty" unless @tcdevices || $family == F_IPV6; }; process_tc_priority while read_a_line; @@ -1413,10 +1420,10 @@ sub setup_simple_traffic_shaping() { } } -sub setup_traffic_shaping() { - our $lastrule = ''; - - save_progress_message q("Setting up Traffic Control..."); +# +# Process the compilex traffic shaping files storing the configuration in %tcdevices and %tcclasses +# +sub process_traffic_shaping() { my $fn = open_file 'tcdevices'; @@ -1426,9 +1433,6 @@ sub setup_traffic_shaping() { validate_tc_device while read_a_line; } - my $sfq = 0; - my $sfqinhex; - $devnum = $devnum > 10 ? 10 : 1; $fn = open_file 'tcclasses'; @@ -1439,6 +1443,11 @@ sub setup_traffic_shaping() { validate_tc_class while read_a_line; } + process_tcfilters; + + my $sfq = 0; + my $sfqinhex; + for my $device ( @tcdevices ) { my $devref = $tcdevices{$device}; my $defmark = in_hexp ( $devref->{default} || 0 ); @@ -1451,6 +1460,14 @@ sub setup_traffic_shaping() { my $dev = chain_base( $device ); + emit( '', + '#', + "# Configure Traffic Shaping for $device", + '#', + "setup_${dev}_tc() {" ); + + push_indent; + unless ( $config{TC_ENABLED} eq 'Shared' ) { emit "if interface_is_up $device; then"; @@ -1500,116 +1517,132 @@ sub setup_traffic_shaping() { emit( "run_tc filter add dev $rdev parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev $device > /dev/null" ); } - save_progress_message_short qq(" TC Device $device defined."); + for my $class ( @tcclasses ) { + # + # The class number in the tcclasses array is expressed in decimal. + # + my ( $d, $decimalclassnum ) = split /:/, $class; - pop_indent; - emit 'else'; - push_indent; + next unless $d eq $device; + # + # For inclusion in 'tc' commands, we also need the hex representation + # + my $classnum = in_hexp $decimalclassnum; + # + # The decimal value of the class number is also used as the key for the hash at $tcclasses{$device} + # + my $tcref = $tcclasses{$device}{$decimalclassnum}; + my $mark = $tcref->{mark}; + my $devicenumber = in_hexp $devref->{number}; + my $classid = join( ':', $devicenumber, $classnum); + my $rate = "$tcref->{rate}kbit"; + my $quantum = calculate_quantum $rate, calculate_r2q( $devref->{out_bandwidth} ); - emit qq(error_message "WARNING: Device $device is not in the UP state -- traffic-shaping configuration skipped"); - emit "${dev}_exists="; - pop_indent; - emit "fi\n"; - } - } + $classids{$classid}=$device; + $device = physical_name $device; - my $lastdevice = ''; + my $priority = $tcref->{priority} << 8; + my $parent = in_hexp $tcref->{parent}; + + emit ( "[ \$${dev}_mtu -gt $quantum ] && quantum=\$${dev}_mtu || quantum=$quantum" ); - for my $class ( @tcclasses ) { - # - # The class number in the tcclasses array is expressed in decimal. - # - my ( $device, $decimalclassnum ) = split /:/, $class; - # - # For inclusion in 'tc' commands, we also need the hex representation - # - my $classnum = in_hexp $decimalclassnum; - my $devref = $tcdevices{$device}; - # - # The decimal value of the class number is also used as the key for the hash at $tcclasses{$device} - # - my $tcref = $tcclasses{$device}{$decimalclassnum}; - my $mark = $tcref->{mark}; - my $devicenumber = in_hexp $devref->{number}; - my $classid = join( ':', $devicenumber, $classnum); - my $rate = "$tcref->{rate}kbit"; - my $quantum = calculate_quantum $rate, calculate_r2q( $devref->{out_bandwidth} ); - - $classids{$classid}=$device; - $device = physical_name $device; - - unless ( $config{TC_ENABLED} eq 'Shared' ) { - my $dev = chain_base $device; - my $priority = $tcref->{priority} << 8; - my $parent = in_hexp $tcref->{parent}; - - if ( $lastdevice ne $device ) { - if ( $lastdevice ) { - pop_indent; - emit "fi\n"; - } - - emit qq(if [ -n "\$${dev}_exists" ]; then); - push_indent; - $lastdevice = $device; - } - - emit ( "[ \$${dev}_mtu -gt $quantum ] && quantum=\$${dev}_mtu || quantum=$quantum" ); - - if ( $devref->{qdisc} eq 'htb' ) { - emit ( "run_tc class add dev $device parent $devicenumber:$parent classid $classid htb rate $rate ceil $tcref->{ceiling}kbit prio $tcref->{priority} \$${dev}_mtu1 quantum \$quantum" ); - } else { - my $dmax = $tcref->{dmax}; - - if ( $dmax ) { - my $umax = $tcref->{umax} ? "$tcref->{umax}b" : "\${${dev}_mtu}b"; - emit ( "run_tc class add dev $device parent $devicenumber:$parent classid $classid hfsc sc umax $umax dmax ${dmax}ms rate $rate ul rate $tcref->{ceiling}kbit" ); - } else { - emit ( "run_tc class add dev $device parent $devicenumber:$parent classid $classid hfsc sc rate $rate ul rate $tcref->{ceiling}kbit" ); - } - } - - if ( $tcref->{leaf} && ! $tcref->{pfifo} ) { - 1 while $devnums[++$sfq]; - - $sfqinhex = in_hexp( $sfq); if ( $devref->{qdisc} eq 'htb' ) { - emit( "run_tc qdisc add dev $device parent $classid handle $sfqinhex: sfq quantum \$quantum limit $tcref->{limit} perturb 10" ); + emit ( "run_tc class add dev $device parent $devicenumber:$parent classid $classid htb rate $rate ceil $tcref->{ceiling}kbit prio $tcref->{priority} \$${dev}_mtu1 quantum \$quantum" ); } else { - emit( "run_tc qdisc add dev $device parent $classid handle $sfqinhex: sfq limit $tcref->{limit} perturb 10" ); + my $dmax = $tcref->{dmax}; + + if ( $dmax ) { + my $umax = $tcref->{umax} ? "$tcref->{umax}b" : "\${${dev}_mtu}b"; + emit ( "run_tc class add dev $device parent $devicenumber:$parent classid $classid hfsc sc umax $umax dmax ${dmax}ms rate $rate ul rate $tcref->{ceiling}kbit" ); + } else { + emit ( "run_tc class add dev $device parent $devicenumber:$parent classid $classid hfsc sc rate $rate ul rate $tcref->{ceiling}kbit" ); + } } + + if ( $tcref->{leaf} && ! $tcref->{pfifo} ) { + 1 while $devnums[++$sfq]; + + $sfqinhex = in_hexp( $sfq); + if ( $devref->{qdisc} eq 'htb' ) { + emit( "run_tc qdisc add dev $device parent $classid handle $sfqinhex: sfq quantum \$quantum limit $tcref->{limit} perturb 10" ); + } else { + emit( "run_tc qdisc add dev $device parent $classid handle $sfqinhex: sfq limit $tcref->{limit} perturb 10" ); + } + } + # + # add filters + # + unless ( $devref->{classify} ) { + emit "run_tc filter add dev $device protocol all parent $devicenumber:0 prio " . ( $priority | 20 ) . " handle $mark fw classid $classid" if $tcref->{occurs} == 1; + } + + emit "run_tc filter add dev $device protocol all prio 1 parent $sfqinhex: handle $classnum flow hash keys $tcref->{flow} divisor 1024" if $tcref->{flow}; + # + # options + # + emit "run_tc filter add dev $device parent $devicenumber:0 protocol ip prio " . ( $priority | 10 ) ." u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 flowid $classid" if $tcref->{tcp_ack}; + + for my $tospair ( @{$tcref->{tos}} ) { + my ( $tos, $mask ) = split q(/), $tospair; + emit "run_tc filter add dev $device parent $devicenumber:0 protocol ip prio " . ( $priority | 10 ) . " u32 match ip tos $tos $mask flowid $classid"; + } + + save_progress_message_short qq(" TC Class $classid defined."); + emit ''; + } - # - # add filters - # - unless ( $devref->{classify} ) { - emit "run_tc filter add dev $device protocol all parent $devicenumber:0 prio " . ( $priority | 20 ) . " handle $mark fw classid $classid" if $tcref->{occurs} == 1; - } - - emit "run_tc filter add dev $device protocol all prio 1 parent $sfqinhex: handle $classnum flow hash keys $tcref->{flow} divisor 1024" if $tcref->{flow}; - # - # options - # - emit "run_tc filter add dev $device parent $devicenumber:0 protocol ip prio " . ( $priority | 10 ) ." u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 flowid $classid" if $tcref->{tcp_ack}; - - for my $tospair ( @{$tcref->{tos}} ) { - my ( $tos, $mask ) = split q(/), $tospair; - emit "run_tc filter add dev $device parent $devicenumber:0 protocol ip prio " . ( $priority | 10 ) . " u32 match ip tos $tos $mask flowid $classid"; - } - - save_progress_message_short qq(" TC Class $classid defined."); - emit ''; - } - } + emit ''; - if ( $lastdevice ) { + emit "$_" for @{$devref->{filters}}; + + save_progress_message_short qq(" TC Device $device defined."); + + pop_indent; + emit 'else'; + push_indent; + + emit qq(error_message "WARNING: Device $device is not in the UP state -- traffic-shaping configuration skipped"); + emit "${dev}_exists="; pop_indent; emit "fi\n"; + + pop_indent; + emit "}\n"; + } +} + +# +# Validate the TC configuration storing basic information in %tcdevices and %tcdevices +# +sub process_tc() { + if ( $config{TC_ENABLED} eq 'Internal' || $config{TC_ENABLED} eq 'Shared' ) { + process_traffic_shaping; + } elsif ( $config{TC_ENABLED} eq 'Simple' ) { + process_tcinterfaces; + } + # + # The Providers module needs to know which devices are tc-enabled so that + # it can call the appropriate 'setup_x_tc" function when the device is + # enabled. + + \%tcdevices; +} + +# +# Call the setup_${dev}_tc functions +# +sub setup_traffic_shaping() { + save_progress_message q("Setting up Traffic Control..."); + + for my $device ( @tcdevices ) { + my $interfaceref = known_interface( $device ); + my $dev = chain_base( $interfaceref ? $interfaceref->{physical} : $device ); + + emit "setup_${dev}_tc"; } - process_tcfilters; } # @@ -1723,10 +1756,9 @@ sub setup_tc() { if ( $globals{TC_SCRIPT} ) { save_progress_message q('Setting up Traffic Control...'); append_file $globals{TC_SCRIPT}; - } elsif ( $config{TC_ENABLED} eq 'Internal' || $config{TC_ENABLED} eq 'Shared' ) { + } else { + process_tcpri if $config{TC_ENABLED} eq 'Simple'; setup_traffic_shaping; - } elsif ( $config{TC_ENABLED} eq 'Simple' ) { - setup_simple_traffic_shaping; } if ( $config{TC_ENABLED} ) { diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index dda524035..720b5e26a 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -73,6 +73,7 @@ our @EXPORT = qw( NOTHING find_interfaces_by_option find_interfaces_by_option1 get_interface_option + interface_has_option set_interface_option interface_zones verify_required_interfaces @@ -1409,6 +1410,22 @@ sub get_interface_option( $$ ) { } +# +# Return the value of an option for an interface +# +sub interface_has_option( $$\$ ) { + my ( $interface, $option, $value ) = @_; + + my $ref = $interfaces{$interface}; + + $ref = known_interface( $interface ) unless $ref; + + if ( exists $ref->{options}{$option} ) { + $$value = $ref->{options}{$option}; + 1; + } +} + # # Set an option for an interface #