Tweak and document HFSC implementation

This commit is contained in:
Tom Eastep 2009-05-24 10:06:36 -07:00
parent d97a96b350
commit a0071a21e8
9 changed files with 189 additions and 57 deletions

View File

@ -664,6 +664,7 @@ sub validate_tc_class( ) {
# #
my $parentref = $tcref->{$parentclass}; my $parentref = $tcref->{$parentclass};
fatal_error "Unknown Parent class ($parentclass)" unless $parentref && $parentref->{occurs} == 1; fatal_error "Unknown Parent class ($parentclass)" unless $parentref && $parentref->{occurs} == 1;
fatal_error "The parent class ($parentclass) specifies UMAX and/or DMAX; it cannot serve as a parent" if $parentref->{dmax};
$parentref->{leaf} = 0; $parentref->{leaf} = 0;
} }
@ -677,7 +678,7 @@ sub validate_tc_class( ) {
$rate = convert_rate ( $full, $trate, 'RATE' ); $rate = convert_rate ( $full, $trate, 'RATE' );
$dmax = convert_delay( $dmax ); $dmax = convert_delay( $dmax );
$umax = convert_size( $umax ); $umax = convert_size( $umax );
fatal_error "A umax or dmax value must be specified for an hfsc class" unless $umax || $dmax; fatal_error "DMAX must be specified when UMAX is specified" if $umax && ! $dmax;
} else { } else {
$rate = convert_rate ( $full, $rate, 'RATE' ); $rate = convert_rate ( $full, $rate, 'RATE' );
} }
@ -1008,7 +1009,7 @@ sub setup_traffic_shaping() {
emit ( "run_tc qdisc add dev $device root handle $devnum: htb default $defmark r2q $r2q" , emit ( "run_tc qdisc add dev $device root handle $devnum: htb default $defmark r2q $r2q" ,
"run_tc class add dev $device parent $devnum: classid $devnum:1 htb rate $devref->{out_bandwidth} \$${dev}_mtu1" ); "run_tc class add dev $device parent $devnum: classid $devnum:1 htb rate $devref->{out_bandwidth} \$${dev}_mtu1" );
} else { } else {
emit ( "run_tc qdisc add dev $device root handle $devnum: hfsc default $defmar r2q $r2qk" , emit ( "run_tc qdisc add dev $device root handle $devnum: hfsc default $defmark" ,
"run_tc class add dev $device parent $devnum: classid $devnum:1 hfsc sc rate $devref->{out_bandwidth} ul rate $devref->{out_bandwidth}" ); "run_tc class add dev $device parent $devnum: classid $devnum:1 hfsc sc rate $devref->{out_bandwidth} ul rate $devref->{out_bandwidth}" );
} }
@ -1097,29 +1098,15 @@ sub setup_traffic_shaping() {
if ( $devref->{qdisc} eq 'htb' ) { if ( $devref->{qdisc} eq 'htb' ) {
emit ( "run_tc class add dev $device parent $devref->{number}:$parent classid $classid htb rate $rate ceil $tcref->{ceiling}kbit prio $tcref->{priority} \$${dev}_mtu1 quantum \$quantum" ); emit ( "run_tc class add dev $device parent $devref->{number}:$parent classid $classid htb rate $rate ceil $tcref->{ceiling}kbit prio $tcref->{priority} \$${dev}_mtu1 quantum \$quantum" );
} else { } else {
my $umax = $tcref->{umax};
my $dmax = $tcref->{dmax}; my $dmax = $tcref->{dmax};
unless ( $dmax ) { if ( $dmax ) {
# my $umax = $tcref->{umax} ? "$tcref->{umax}b" : "\${${dev}_mtu}b";
# We must calculate the dmax but we know that umax has been specified emit ( "run_tc class add dev $device parent $devref->{number}:$parent classid $classid hfsc sc umax $umax dmax ${dmax}ms rate $rate ul rate $tcref->{ceiling}kbit" );
# } else {
my $packetbits = 8 * $umax; warning_message "Leaf HFSC class $classid does not specify UMAX or DMAX" if $tcref->{leaf};
my $rateinbits = 1000 * $tcref->{rate}; emit ( "run_tc class add dev $device parent $devref->{number}:$parent classid $classid hfsc sc rate $rate ul rate $tcref->{ceiling}kbit" );
my $fullinbytes = $devref->{out_bandwidth};
$fullinbytes =~ s/kbit//;
my $fullinbits = 1000 * $fullinbytes;
my $packetspersecond = $rateinbits / $packetbits;
my $totaldelayinms = 1000 * ( 1 - ( $rateinbits / $fullinbits ) );
#
# In this calculation, '3' is a magic number. We can adjust it as necessary as we learn about this QDISC
#
$dmax = int( 3 * $totaldelayinms / $packetspersecond );
} }
$umax = $umax ? "${umax}b" : "\$${dev}_mtu";
emit ( "run_tc class add dev $device parent $devref->{number}:$parent classid $classid hfsc sc umax $umax dmax ${dmax}ms rate $rate ul rate $tcref->{ceiling}kbit" );
} }
emit( "run_tc qdisc add dev $device parent $classid handle ${classnum}: sfq quantum \$quantum limit 127 perturb 10" ) if $tcref->{leaf} && ! $tcref->{pfifo}; emit( "run_tc qdisc add dev $device parent $classid handle ${classnum}: sfq quantum \$quantum limit 127 perturb 10" ) if $tcref->{leaf} && ! $tcref->{pfifo};

View File

@ -2,6 +2,8 @@ Changes in Shorewall 4.3.12
1) Eliminate 'large quantum' warnings. 1) Eliminate 'large quantum' warnings.
2) Add HFSC support.
Changes in Shorewall 4.3.11 Changes in Shorewall 4.3.11
1) Reduce the number of arguments passed in may cases. 1) Reduce the number of arguments passed in may cases.

View File

@ -6,5 +6,6 @@
# See http://shorewall.net/traffic_shaping.htm for additional information. # See http://shorewall.net/traffic_shaping.htm for additional information.
# #
############################################################################### ###############################################################################
#INTERFACE:CLASS MARK RATE CEIL PRIORITY OPTIONS #INTERFACE:CLASS MARK RATE: CEIL PRIORITY OPTIONS
# DMAX:UMAX
#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE

View File

@ -11,31 +11,40 @@ released late in 2009.
has been combined with Shorewall-common to produce a single has been combined with Shorewall-common to produce a single
Shorewall package. Shorewall package.
2) The Shorewall documentation and man pages have been purged of 2) Support for the "Hierarchical Fair Service Curve" (HFSC) queuing
discipline has been added. HFSC is superior to the "Hierarchical
Token Bucket" queuing discipline where realtime traffic such as
VOIP is being used.
3) Support for the "flow" traffic classifier has been added. This
classifier can help prevent multi-connection applications such as
BitTorrent from using an unfair amount of bandwidth.
4) The Shorewall documentation and man pages have been purged of
information about earlier Shorewall releases. The documentation information about earlier Shorewall releases. The documentation
describes only the behavior of Shorewall 4.3 and later versions. describes only the behavior of Shorewall 4.3 and later versions.
3) The interfaces file OPTIONs have been extended to largely remove the 5) The interfaces file OPTIONs have been extended to largely remove the
need for the hosts file. need for the hosts file.
4) It is now possible to define PREROUTING and OUTPUT marking rules 6) It is now possible to define PREROUTING and OUTPUT marking rules
that cause new connections to use the same provider as an existing that cause new connections to use the same provider as an existing
connection of the same kind. connection of the same kind.
5) Dynamic Zone support is once again available for IPv4; ipset support is 7) Dynamic Zone support is once again available for IPv4; ipset support is
required in your kernel and in iptables. required in your kernel and in iptables.
6) A new AUTOMAKE option has been added to shorewall.conf and 8) A new AUTOMAKE option has been added to shorewall.conf and
shorewall6.conf. Setting this option will allow Shorewall to skip shorewall6.conf. Setting this option will allow Shorewall to skip
the compilation phase during start/restart if no configuration the compilation phase during start/restart if no configuration
changes have occurred since the last start/restart. changes have occurred since the last start/restart.
7) The LIMIT:BURST column in /etc/shorewall/policy 9) The LIMIT:BURST column in /etc/shorewall/policy
(/etc/shorewall6/policy) and the RATE LIMIT column in (/etc/shorewall6/policy) and the RATE LIMIT column in
/etc/shorewall/rules (/etc/shorewall6/rules) may now be used to /etc/shorewall/rules (/etc/shorewall6/rules) may now be used to
limit on a per source IP or per destination IP basis. limit on a per source IP or per destination IP basis.
8) Support for per-IP traffic shaping classes has been added. 10) Support for per-IP traffic shaping classes has been added.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
M I G R A T I O N I S S U E S M I G R A T I O N I S S U E S
@ -97,7 +106,49 @@ None.
N E W F E A T U R E S I N 4 . 3 . 12 N E W F E A T U R E S I N 4 . 3 . 12
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
None. 1) Support for the "Hierarchical Fair Service Curve" (HFSC) queuing
discipline has been added. HFSC is superior to the "Hierarchical
Token Bucket" queuing discipline where realtime traffic such as
VOIP is being used.
An excellent overview of HFSC on Linux may be found at
http://linux-ip.net/articles/hfsc.en/.
To use HFSC, several changes need to be made to your traffic
shaping configuration:
- To use HFSC on an interface rather than HTB, specify the
'hfsc' option in the OPTIONS column in the interfaces's
entry in /etc/shorewall/tcdevices.
- Modify the RATE colum for each 'leaf' class (class with no
parent class specified) defined for the interface.
When using HFSC, the RATE column may specify 1, 2 or 3
pieces of information separated by colons (":").
1. The Guaranteed bandwidth (as always).
2. The Maximum delay (DMAX) that the first queued packet
in the class should experience. The delay is expressed
in milliseconds and may be followed by 'ms' (e.g.,
10ms. Note that there may be no white space between the
number and 'ms').
3. The maximum transmission unit (UMAX) for this class of
traffic. If not specified, the MTU of the interface is
used. The length is specified in bytes and may be
followed by 'b' (e.g., 800b. Note that there may be no
white space between the number and 'b').
DMAX should be specified for each leaf class. The Shorewall
compiler will issue a warning if DMAX is omitted.
Example:
full/2:10ms:1500b
Guaranteed bandwidth is 1/2 of the devices
OUT-BANDWIDTH. Maximum delay is 10ms. Maximum packet
size is 1500 bytes.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
N E W F E A T U R E S IN 4 . 3 N E W F E A T U R E S IN 4 . 3

View File

@ -64,15 +64,20 @@
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para>The LARTC HOWTO: <ulink <para><emphasis>The LARTC HOWTO</emphasis>: <ulink
url="http://www.lartc.org">http://www.lartc.org</ulink></para> url="http://www.lartc.org">http://www.lartc.org</ulink></para>
</listitem> </listitem>
<listitem> <listitem>
<para>The HTB User's Guide: <ulink <para>T<emphasis>he HTB User's Guide</emphasis>: <ulink
url="http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm">http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm</ulink></para> url="http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm">http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm</ulink></para>
</listitem> </listitem>
<listitem>
<para><emphasis>HFSC Scheduling with Linux</emphasis>: <ulink
url="http://linux-ip.net/articles/hfsc.en/">http://linux-ip.net/articles/hfsc.en/</ulink></para>
</listitem>
<listitem> <listitem>
<para>Some of the documents listed at <ulink <para>Some of the documents listed at <ulink
url="http://www.netfilter.org/documentation/index.html#documentation-howto">http://www.netfilter.org/documentation/index.html#documentation-howto</ulink>. url="http://www.netfilter.org/documentation/index.html#documentation-howto">http://www.netfilter.org/documentation/index.html#documentation-howto</ulink>.
@ -117,15 +122,17 @@
your bandwidth, this queuing algorithm will not stop it from doing your bandwidth, this queuing algorithm will not stop it from doing
so.</para> so.</para>
<para>For Shorewall traffic shaping we use two algorithms, one is called <para>For Shorewall traffic shaping we use three algorithms: HTB
HTB (Hierarchical Token Bucket) and SFQ (Stochastic Fairness Queuing). SFQ (Hierarchical Token Bucket), HFSC (Hierarchical Fair Service Curves) and
is easy to explain: it just tries to track your connections (tcp or udp SFQ (Stochastic Fairness Queuing). SFQ is easy to explain: it just tries
streams) and balances the traffic between them. This normally works well. to track your connections (tcp or udp streams) and balances the traffic
HTB allows you to define a set of classes, and you can put the traffic you between them. This normally works well. HTB and HFSC allow you to define a
want into these classes. You can define minimum and maximum bandwidth set of classes, and you can put the traffic you want into these classes.
settings for those classes and order them hierarchically (the less You can define minimum and maximum bandwidth settings for those classes
prioritized classes only get bandwidth if the more important have what and order them hierarchically (the less prioritized classes only get
they need). Shorewall builtin traffic shaping allows you to define these bandwidth if the more important have what they need). Additionally, HFSC
allows you to specify the maximum queuing delay that a packet may
experience. Shorewall builtin traffic shaping allows you to define these
classes (and their bandwidth limits), and it uses SFQ inside these classes classes (and their bandwidth limits), and it uses SFQ inside these classes
to make sure, that different data streams are handled equally. If SFQ's to make sure, that different data streams are handled equally. If SFQ's
default notion of a 'stream' doesn't work well for you, you can change it default notion of a 'stream' doesn't work well for you, you can change it
@ -308,7 +315,9 @@
<para>This file allows you to define the incoming and outgoing bandwidth <para>This file allows you to define the incoming and outgoing bandwidth
for the devices you want traffic shaping to be enabled. That means, if for the devices you want traffic shaping to be enabled. That means, if
you want to use traffic shaping for a device, you have to define it you want to use traffic shaping for a device, you have to define it
here.</para> here. For additional information, see <ulink
url="manpages/shorewall-tcdevices.html">shorewall-tcdevices</ulink>
(5).</para>
<para>Columns in the file are as follows:</para> <para>Columns in the file are as follows:</para>
@ -378,6 +387,18 @@
will be associated with classes on this interface.</para> will be associated with classes on this interface.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>hfsc</term>
<listitem>
<para>Shorewall normally uses the <firstterm>Hierarchical
Token Bucket</firstterm> queuing discipline. When
<option>hfsc</option> is specified, the
<firstterm>Hierarchical Fair Service Curves</firstterm>
discipline is used instead.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</listitem> </listitem>
@ -411,7 +432,9 @@ ppp0 6000kbit 500kbit</programlisting>
<title>/etc/shorewall/tcclasses</title> <title>/etc/shorewall/tcclasses</title>
<para>This file allows you to define the actual classes that are used to <para>This file allows you to define the actual classes that are used to
split the outgoing traffic.</para> split the outgoing traffic. For additional information, see <ulink
url="manpages/shorewall-tcclasses.html">shorewall-tcclasses</ulink>
(5).</para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
@ -453,6 +476,12 @@ ppp0 6000kbit 500kbit</programlisting>
role="bold">If the sum of the RATEs for all classes assigned to an role="bold">If the sum of the RATEs for all classes assigned to an
INTERFACE exceed that interfaces's OUT-BANDWIDTH, then the INTERFACE exceed that interfaces's OUT-BANDWIDTH, then the
OUT-BANDWIDTH limit will not be honored.</emphasis></para> OUT-BANDWIDTH limit will not be honored.</emphasis></para>
<para>When using HFSC, this column may contain 1, 2 or 3 pieces of
information separated by colons (":"). In addition to the minimum
bandwidth, leaf classes must specify DMAX (maximum delay in
milliseconds) and may optionally specify UMAX (the largest packet
expected in the class).</para>
</listitem> </listitem>
<listitem> <listitem>
@ -1315,6 +1344,31 @@ ppp0 4 90kbit 200kbit 3 default</pro
instructions.</para> instructions.</para>
</section> </section>
<section>
<title>An HFSC Example</title>
<para>As mentioned at the top of this article, there is an excellent
introduction to HFSC at <ulink
url="http://linux-ip.net/articles/hfsc.en/">http://linux-ip.net/articles/hfsc.en/</ulink>.
At the end of that article are 'tc' commands that implement the
configuration in the article. Those tc commands correspond to the
following Shorewall traffic shaping configuration.</para>
<para><filename>/etc/shorewall/tcdevices</filename>:</para>
<programlisting>#INTERFACE IN-BANDWITH OUT-BANDWIDTH OPTIONS
eth0 - 1000kbit hfsc</programlisting>
<para><filename>/etc/shorewall/tcclasses</filename>:</para>
<programlisting>#INTERFACE:CLASS MARK RATE: CEIL PRIORITY OPTIONS
# DMAX:UMAX
1:10 1 500kbit full 1
1:20 2 500kbit full 1
1:10:11 3 400kbit:53ms:1500b full 2
1:10:12 4 100kbit:30ms:1500b full 2</programlisting>
</section>
<section id="Downloads"> <section id="Downloads">
<title>Shaping Download Traffic</title> <title>Shaping Download Traffic</title>

View File

@ -170,7 +170,7 @@
<varlistentry> <varlistentry>
<term><emphasis role="bold">RATE</emphasis> - <term><emphasis role="bold">RATE</emphasis> -
<emphasis>rate</emphasis></term> <emphasis>rate</emphasis>[:<emphasis>dmax</emphasis>[:<emphasis>umax</emphasis>]]</term>
<listitem> <listitem>
<para>The minimum bandwidth this class should get, when the traffic <para>The minimum bandwidth this class should get, when the traffic
@ -179,6 +179,19 @@
honored. Similarly, if the sum of the rates of sub-classes of a honored. Similarly, if the sum of the rates of sub-classes of a
class exceed the CEIL of the parent class, things don't work class exceed the CEIL of the parent class, things don't work
well.</para> well.</para>
<para>When using the HFSC queuing discipline, leaf classes should
specify <replaceable>dmax</replaceable>, the maximum delay in
milliseconds that the first queued packet for this class should
experience. May be expressed as an integer, optionally followed by
'ms' with no intervening white space (e.g., 10ms).</para>
<para>HFSC leaf classes may also specify
<replaceable>umax</replaceable>, the largest packet expected in this
class. May be expressed as an integer. The unit of measure is
<emphasis>bytes</emphasis> and the integer may be optionally
followed by 'b' with no intervening white space (e.g., 800b).
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -388,7 +401,7 @@
<para>Those that begin with "nfct-" are Netfilter connection <para>Those that begin with "nfct-" are Netfilter connection
tracking fields. As shown above, we recommend flow=nfct-src; tracking fields. As shown above, we recommend flow=nfct-src;
that means that we want to use the source IP address that means that we want to use the source IP address
<emphasis>before NAT</emphasis> as the key. </para> <emphasis>before NAT</emphasis> as the key.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>

View File

@ -156,13 +156,18 @@
<varlistentry> <varlistentry>
<term><emphasis role="bold">OPTIONS</emphasis> - {<emphasis <term><emphasis role="bold">OPTIONS</emphasis> - {<emphasis
role="bold">-</emphasis>|<emphasis role="bold">-</emphasis>|<emphasis
role="bold">classify</emphasis>}</term> role="bold">{classify</emphasis>|hfsc} ,...}</term>
<listitem> <listitem>
<para>classify ― When specified, Shorewall will not generate tc or <para><option>classify</option> ― When specified, Shorewall will not
Netfilter rules to classify traffic based on packet marks. You must generate tc or Netfilter rules to classify traffic based on packet
do all classification using CLASSIFY rules in <ulink marks. You must do all classification using CLASSIFY rules in <ulink
url="shorewall-tcrules.html">shorewall-tcrules</ulink>(5).</para> url="shorewall-tcrules.html">shorewall-tcrules</ulink>(5).</para>
<para><option>hfsc</option> - Shorewall normally uses the
<firstterm>Hierarchical Token Bucket</firstterm> queuing discipline.
When <option>hfsc</option> is specified, the <firstterm>Hierarchical
Fair Service Curves</firstterm> discipline is used instead.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -166,13 +166,27 @@
<varlistentry> <varlistentry>
<term><emphasis role="bold">RATE</emphasis> - <term><emphasis role="bold">RATE</emphasis> -
<emphasis>rate</emphasis></term> <emphasis>rate</emphasis>[:<emphasis>dmax</emphasis>[:<emphasis>umax</emphasis>]]</term>
<listitem> <listitem>
<para>The minimum bandwidth this class should get, when the traffic <para>The minimum bandwidth this class should get, when the traffic
load rises. If the sum of the rates in this column exceeds the load rises. If the sum of the rates in this column exceeds the
INTERFACE's OUT-BANDWIDTH, then the OUT-BANDWIDTH limit may not be INTERFACE's OUT-BANDWIDTH, then the OUT-BANDWIDTH limit may not be
honored.</para> honored. Similarly, if the sum of the rates of sub-classes of a
class exceed the CEIL of the parent class, things don't work
well.</para>
<para>When using the HFSC queuing discipline, leaf classes should
specify <replaceable>dmax</replaceable>, the maximum delay in
milliseconds that the first queued packet for this class should
experience. May be expressed as an integer, optionally followed by
'ms' with no intervening white space (e.g., 10ms).</para>
<para>HFSC leaf classes may also specify
<replaceable>umax</replaceable>, the largest packet expected in this
class. May be expressed as an integer. The unit of measure is
<emphasis>bytes</emphasis> and the integer may be optionally
followed by 'b' with no intervening white space (e.g., 800b).</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -156,13 +156,18 @@
<varlistentry> <varlistentry>
<term><emphasis role="bold">OPTIONS</emphasis> - {<emphasis <term><emphasis role="bold">OPTIONS</emphasis> - {<emphasis
role="bold">-</emphasis>|<emphasis role="bold">-</emphasis>|<emphasis
role="bold">classify</emphasis>}</term> role="bold">{classify</emphasis>|hfsc} ,...}</term>
<listitem> <listitem>
<para>classify ― When specified, Shorewall6 will not generate tc or <para><option>classify</option> ― When specified, Shorewall will not
Netfilter rules to classify traffic based on packet marks. You must generate tc or Netfilter rules to classify traffic based on packet
do all classification using CLASSIFY rules in <ulink marks. You must do all classification using CLASSIFY rules in <ulink
url="shorewall6-tcrules.html">shorewall6-tcrules</ulink>(5).</para> url="shorewall-tcrules.html">shorewall-tcrules</ulink>(5).</para>
<para><option>hfsc</option> - Shorewall normally uses the
<firstterm>Hierarchical Token Bucket</firstterm> queuing discipline.
When <option>hfsc</option> is specified, the <firstterm>Hierarchical
Fair Service Curves</firstterm> discipline is used instead.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>