mirror of
https://gitlab.com/shorewall/code.git
synced 2025-02-21 20:21:19 +01:00
fq_codel
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
51deec115b
commit
6d9cca1cff
@ -1129,6 +1129,17 @@ my %validredoptions = ( min => RED_INTEGER,
|
||||
ecn => RED_NONE,
|
||||
);
|
||||
|
||||
use constant { CODEL_INTEGER => 1, CODEL_INTERVAL => 2, CODEL_NONE => 3 };
|
||||
|
||||
my %validcodeloptions = ( flows => CODEL_INTEGER,
|
||||
target => CODEL_INTERVAL,
|
||||
interval => CODEL_INTERVAL,
|
||||
limit => CODEL_INTEGER,
|
||||
ecn => CODEL_NONE,
|
||||
noecn => CODEL_NONE,
|
||||
quantum => CODEL_INTEGER
|
||||
);
|
||||
|
||||
sub validate_filter_priority( $$ ) {
|
||||
my ( $priority, $kind ) = @_;
|
||||
|
||||
@ -1303,6 +1314,7 @@ sub validate_tc_class( ) {
|
||||
fatal_error "RATE ($rate) exceeds CEIL ($ceil)" if $rate && $ceil && $rate > $ceil;
|
||||
|
||||
my ( $red, %redopts ) = ( 0, ( avpkt => 1000 ) );
|
||||
my ( $codel, %codelopts ) = ( 0, ( ) );
|
||||
|
||||
unless ( $options eq '-' ) {
|
||||
for my $option ( split_list1 "\L$options", 'option' ) {
|
||||
@ -1352,8 +1364,9 @@ sub validate_tc_class( ) {
|
||||
fatal_error "The 'flow' option is not allowed with 'red'" if $tcref->{red};
|
||||
$tcref->{flow} = process_flow $1;
|
||||
} elsif ( $option eq 'pfifo' ) {
|
||||
fatal_error "The 'pfifo' option is not allowed with 'flow='" if $tcref->{flow};
|
||||
fatal_error "The 'pfifo' option is not allowed with 'red='" if $tcref->{red};
|
||||
fatal_error "The 'pfifo' option is not allowed with 'flow='" if $tcref->{flow};
|
||||
fatal_error "The 'pfifo' option is not allowed with 'red='" if $tcref->{red};
|
||||
fatal_error "The 'pfifo' option is not allowed with 'fq_codel='" if $tcref->{fq_codel};
|
||||
$tcref->{pfifo} = 1;
|
||||
} elsif ( $option =~ /^occurs=(\d+)$/ ) {
|
||||
my $val = $1;
|
||||
@ -1375,8 +1388,9 @@ sub validate_tc_class( ) {
|
||||
fatal_error "Invalid limit ($1)" if $1 < 3 || $1 > 128;
|
||||
$tcref->{limit} = $1;
|
||||
} elsif ( $option =~ s/^red=// ) {
|
||||
fatal_error "The 'red=' option is not allowed with 'flow='" if $tcref->{flow};
|
||||
fatal_error "The 'red=' option is not allowed with 'pfifo'" if $tcref->{pfifo};
|
||||
fatal_error "The 'red=' option is not allowed with 'flow='" if $tcref->{flow};
|
||||
fatal_error "The 'red=' option is not allowed with 'pfifo'" if $tcref->{pfifo};
|
||||
fatal_error "The 'pfifo' option is not allowed with 'fq_codel='" if $tcref->{fq_codel};
|
||||
$tcref->{red} = 1;
|
||||
my $opttype;
|
||||
|
||||
@ -1425,6 +1439,61 @@ sub validate_tc_class( ) {
|
||||
fatal_error "The 'limit' red option must be at least 2 * 'max'" unless $redopts{limit} >= 2 * $redopts{min};
|
||||
$redopts{ecn} = 1 if exists $redopts{ecn};
|
||||
$tcref->{redopts} = \%redopts;
|
||||
} elsif ( $option =~ /^fq_codel(?:=.+)?$/ ) {
|
||||
fatal_error "The 'fq_codel' option is not allowed with 'red='" if $tcref->{red};
|
||||
fatal_error "The 'fq_codel' option is not allowed with 'pfifo'" if $tcref->{pfifo};
|
||||
$tcref->{fq_codel} = 1;
|
||||
my $opttype;
|
||||
|
||||
$option =~ s/fq_codel=?//;
|
||||
|
||||
for my $codelopt ( split_list( $option , q('fq_codel' option list) ) ) {
|
||||
#
|
||||
# $2 --------------------
|
||||
# $1 ------ | $3 ----------- |
|
||||
# | | | | | |
|
||||
if ( $codelopt =~ /^([a-z]+) (?:= ((?:\d+)(ms)?))?$/x )
|
||||
{
|
||||
fatal_error "Invalid CODEL option ($1)" unless $opttype = $validcodeloptions{$1};
|
||||
if ( $2 ) {
|
||||
#
|
||||
# '=<value>' supplied
|
||||
#
|
||||
fatal_error "The $1 option does not take a value" if $opttype == CODEL_NONE;
|
||||
if ( $3 ) {
|
||||
#
|
||||
# Rate
|
||||
#
|
||||
fatal_error "The $1 option requires an integer value" if $opttype == CODEL_INTEGER;
|
||||
} else {
|
||||
#
|
||||
# Interval value
|
||||
#
|
||||
fatal_error "The $1 option requires an interval value" if $opttype == CODEL_INTERVAL;
|
||||
}
|
||||
} else {
|
||||
#
|
||||
# No value supplied
|
||||
#
|
||||
fatal_error "The $1 option requires a value" unless $opttype == CODEL_NONE;
|
||||
}
|
||||
|
||||
$codelopts{$1} = $2;
|
||||
} else {
|
||||
fatal_error "Invalid fq_codel option specification ($codelopt)";
|
||||
}
|
||||
}
|
||||
|
||||
if ( exists $codelopts{ecn} ) {
|
||||
fatal_error "The 'ecn' and 'noecn' fq_codel options are mutually exclusive" if exists $codelopts{noecn};
|
||||
$codelopts{ecn} = 1;
|
||||
} elsif ( exists $codelopts{noecn} ) {
|
||||
$codelopts{noecn} = 1;
|
||||
} else {
|
||||
$codelopts{ecn} = 1;
|
||||
}
|
||||
|
||||
$tcref->{codelopts} = \%codelopts;
|
||||
} else {
|
||||
fatal_error "Unknown option ($option)";
|
||||
}
|
||||
@ -1443,19 +1512,21 @@ sub validate_tc_class( ) {
|
||||
while ( --$occurs ) {
|
||||
fatal_error "Duplicate class number ($classnumber)" if $tcclasses{$device}{++$classnumber};
|
||||
|
||||
$tcclasses{$device}{$classnumber} = { tos => [] ,
|
||||
rate => $tcref->{rate} ,
|
||||
ceiling => $tcref->{ceiling} ,
|
||||
priority => $tcref->{priority} ,
|
||||
mark => 0 ,
|
||||
markprio => $markprio ,
|
||||
flow => $tcref->{flow} ,
|
||||
pfifo => $tcref->{pfifo},
|
||||
occurs => 0,
|
||||
parent => $parentclass,
|
||||
limit => $tcref->{limit},
|
||||
red => $tcref->{red},
|
||||
redopts => $tcref->{redopts},
|
||||
$tcclasses{$device}{$classnumber} = { tos => [] ,
|
||||
rate => $tcref->{rate} ,
|
||||
ceiling => $tcref->{ceiling} ,
|
||||
priority => $tcref->{priority} ,
|
||||
mark => 0 ,
|
||||
markprio => $markprio ,
|
||||
flow => $tcref->{flow} ,
|
||||
pfifo => $tcref->{pfifo},
|
||||
occurs => 0,
|
||||
parent => $parentclass,
|
||||
limit => $tcref->{limit},
|
||||
red => $tcref->{red},
|
||||
redopts => $tcref->{redopts},
|
||||
fq_codel => $tcref->{fq_codel},
|
||||
codelopts => $tcref->{codelopts},
|
||||
};
|
||||
push @tcclasses, "$device:$classnumber";
|
||||
};
|
||||
@ -2063,8 +2134,25 @@ sub process_traffic_shaping() {
|
||||
}
|
||||
|
||||
emit( "run_tc qdisc add dev $device parent $classid handle $sfqinhex: red${options}" );
|
||||
} elsif ( $tcref->{fq_codel} ) {
|
||||
1 while $devnums[++$sfq];
|
||||
$sfqinhex = in_hexp( $sfq);
|
||||
|
||||
} elsif ( $tcref->{leaf} && ! $tcref->{pfifo} ) {
|
||||
my ( $options, $codelopts ) = ( '', $tcref->{codelopts} );
|
||||
|
||||
while ( my ( $option, $type ) = each %validcodeloptions ) {
|
||||
if ( my $value = $codelopts->{$option} ) {
|
||||
if ( $type == CODEL_NONE ) {
|
||||
$options = join( ' ', $options, $option );
|
||||
} else {
|
||||
$options = join( ' ', $options, $option, $value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit( "run_tc qdisc add dev $device parent $classid handle $sfqinhex: fq_codel${options}" );
|
||||
|
||||
} elsif ( ! $tcref->{pfifo} ) {
|
||||
1 while $devnums[++$sfq];
|
||||
|
||||
$sfqinhex = in_hexp( $sfq);
|
||||
|
@ -501,7 +501,8 @@
|
||||
Detection) queuing discipline rather than SFQ. See tc-red (8)
|
||||
for additional information.</para>
|
||||
|
||||
<para>Allowable redoptions are:</para>
|
||||
<para>Allowable <replaceable>redoptions</replaceable>
|
||||
are:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
@ -605,6 +606,94 @@
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>fq_codel[=(<replaceable>codeloption</replaceable>=<replaceable>value</replaceable>,
|
||||
...)]</term>
|
||||
|
||||
<listitem>
|
||||
<para>Added in Shorewall 4.5.12. When specified for a leaf
|
||||
class, causes the class to use the FQ_CODEL (Fair-queuing
|
||||
Controlled Delay) queuing discipline rather than SFQ. See
|
||||
tc-fq_codel (8) for additional information.</para>
|
||||
|
||||
<para>Allowable <replaceable>codeloptions</replaceable>
|
||||
are:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>limit</term>
|
||||
|
||||
<listitem>
|
||||
<para>hard limit on the real queue size. When this limit
|
||||
is reached, incoming packets are dropped. If the value
|
||||
is lowered, packets are dropped so that the new limit is
|
||||
met. Default is 1000 packets.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>flows</term>
|
||||
|
||||
<listitem>
|
||||
<para>is the number of flows into which the incoming
|
||||
packets are classified. Due to the stochastic nature of
|
||||
hashing, multiple flows may end up being hashed into the
|
||||
same slot. Newer flows have priority over older ones.
|
||||
This parameter can be set only at load time since memory
|
||||
has to be allocated for the hash table. Default value is
|
||||
1024.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>target</term>
|
||||
|
||||
<listitem>
|
||||
<para>is the acceptable minimum standing/persistent
|
||||
queue delay. This minimum delay is identified by
|
||||
tracking the local minimum queue delay that packets
|
||||
experience. Default and recommended value is 5ms.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>interval</term>
|
||||
|
||||
<listitem>
|
||||
<para>is used to ensure that the measured minimum delay
|
||||
does not become too stale. The minimum delay must be
|
||||
experienced in the last epoch of length interval. It
|
||||
should be set on the order of the worst-case RTT through
|
||||
the bottleneck to give endpoints sufficient time to
|
||||
react. Default value is 100ms.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>quantum</term>
|
||||
|
||||
<listitem>
|
||||
<para>is the number of bytes used as 'deficit' in the
|
||||
fair queuing algorithm. Default is set to 1514 bytes
|
||||
which corresponds to the Ethernet MTU plus the hardware
|
||||
header length of 14 bytes.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>ecn | noecn</term>
|
||||
|
||||
<listitem>
|
||||
<para>can be used to mark packets instead of dropping
|
||||
them. If ecn has been enabled, noecn can be used to turn
|
||||
it off and vice-a-versa. By default, ecn is
|
||||
enabled.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -557,6 +557,94 @@
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>fq_codel[=(<replaceable>codeloption</replaceable>=<replaceable>value</replaceable>,
|
||||
...)]</term>
|
||||
|
||||
<listitem>
|
||||
<para>Added in Shorewall 4.5.12. When specified for a leaf
|
||||
class, causes the class to use the FQ_CODEL (Fair-queuing
|
||||
Controlled Delay) queuing discipline rather than SFQ. See
|
||||
tc-fq_codel (8) for additional information.</para>
|
||||
|
||||
<para>Allowable <replaceable>codeloptions</replaceable>
|
||||
are:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>limit</term>
|
||||
|
||||
<listitem>
|
||||
<para>hard limit on the real queue size. When this limit
|
||||
is reached, incoming packets are dropped. If the value
|
||||
is lowered, packets are dropped so that the new limit is
|
||||
met. Default is 1000 packets.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>flows</term>
|
||||
|
||||
<listitem>
|
||||
<para>is the number of flows into which the incoming
|
||||
packets are classified. Due to the stochastic nature of
|
||||
hashing, multiple flows may end up being hashed into the
|
||||
same slot. Newer flows have priority over older ones.
|
||||
This parameter can be set only at load time since memory
|
||||
has to be allocated for the hash table. Default value is
|
||||
1024.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>target</term>
|
||||
|
||||
<listitem>
|
||||
<para>is the acceptable minimum standing/persistent
|
||||
queue delay. This minimum delay is identified by
|
||||
tracking the local minimum queue delay that packets
|
||||
experience. Default and recommended value is 5ms.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>interval</term>
|
||||
|
||||
<listitem>
|
||||
<para>is used to ensure that the measured minimum delay
|
||||
does not become too stale. The minimum delay must be
|
||||
experienced in the last epoch of length interval. It
|
||||
should be set on the order of the worst-case RTT through
|
||||
the bottleneck to give endpoints sufficient time to
|
||||
react. Default value is 100ms.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>quantum</term>
|
||||
|
||||
<listitem>
|
||||
<para>is the number of bytes used as 'deficit' in the
|
||||
fair queuing algorithm. Default is set to 1514 bytes
|
||||
which corresponds to the Ethernet MTU plus the hardware
|
||||
header length of 14 bytes.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>ecn | noecn</term>
|
||||
|
||||
<listitem>
|
||||
<para>can be used to mark packets instead of dropping
|
||||
them. If ecn has been enabled, noecn can be used to turn
|
||||
it off and vice-a-versa. By default, ecn is
|
||||
enabled.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
Loading…
Reference in New Issue
Block a user