mirror of
https://gitlab.com/shorewall/code.git
synced 2024-12-27 00:29:02 +01:00
Merge branch 'EdW'
This commit is contained in:
commit
ed7d70e54b
@ -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
|
||||
#
|
||||
|
@ -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;
|
||||
|
@ -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 ) {
|
||||
|
@ -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 => <sum of rates of sub-classes>
|
||||
# options => { tos => [ <value1> , <value2> , ... ];
|
||||
# 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} ) {
|
||||
|
@ -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
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user