mirror of
https://gitlab.com/shorewall/code.git
synced 2024-12-27 00:29:02 +01:00
305 lines
13 KiB
XML
305 lines
13 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||
<article>
|
||
<!--$Id$-->
|
||
|
||
<articleinfo>
|
||
<title>Simple Traffic Shaping/Control</title>
|
||
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Tom</firstname>
|
||
|
||
<surname>Eastep</surname>
|
||
</author>
|
||
</authorgroup>
|
||
|
||
<pubdate><?dbtimestamp format="Y/m/d"?></pubdate>
|
||
|
||
<copyright>
|
||
<year>2009</year>
|
||
|
||
<year>2010</year>
|
||
|
||
<holder>Thomas M. Eastep</holder>
|
||
</copyright>
|
||
|
||
<legalnotice>
|
||
<para>Permission is granted to copy, distribute and/or modify this
|
||
document under the terms of the GNU Free Documentation License, Version
|
||
1.2 or any later version published by the Free Software Foundation; with
|
||
no Invariant Sections, with no Front-Cover, and with no Back-Cover
|
||
Texts. A copy of the license is included in the section entitled
|
||
<quote><ulink url="GnuCopyright.htm">GNU Free Documentation
|
||
License</ulink></quote>.</para>
|
||
</legalnotice>
|
||
</articleinfo>
|
||
|
||
<section>
|
||
<title>Introduction</title>
|
||
|
||
<para>Traffic shaping and control was originally introduced into Shorewall
|
||
in version 2.2.5. That facility was based on Arne Bernin's
|
||
<firstterm>tc4shorewall</firstterm> and is generally felt to be complex
|
||
and difficult to use.</para>
|
||
|
||
<para>In Shorewall 4.4.6, a second traffic shaping facility that is simple
|
||
to understand and to configure was introduced. This newer facility is
|
||
described in this document while the original facility is documented in
|
||
<ulink url="traffic_shaping.htm">Complex Traffic
|
||
Shaping/Control</ulink>.</para>
|
||
|
||
<para>In the absense of any traffic shaping, interfaces are configured
|
||
automatically with the pfifo_fast <firstterm>queuing
|
||
discipline</firstterm> (qdisc). From tc-pfifo_fast (8):</para>
|
||
|
||
<blockquote>
|
||
<para> The algorithm is very similar to that of the classful tc-prio(8)
|
||
qdisc. pfifo_fast is like three tc-pfifo(8) queues side by side, where
|
||
packets can be enqueued in any of the three bands based on their Type of
|
||
Service bits or assigned priority.</para>
|
||
|
||
<para>Not all three bands are dequeued simultaneously - as long as lower
|
||
bands have traffic, higher bands are never dequeued. This can be used to
|
||
prioritize interactive traffic or penalize ’lowest cost’ traffic.</para>
|
||
|
||
<para>Each band can be txqueuelen packets long, as configured with
|
||
ifconfig(8) or ip(8). Additional packets coming in are not enqueued but
|
||
are instead dropped.</para>
|
||
|
||
<para>See tc-prio(8) for complete details on how TOS bits are translated
|
||
into bands. </para>
|
||
</blockquote>
|
||
|
||
<para>In other words, if all you want is strict priority queuing, then do
|
||
nothing.</para>
|
||
|
||
<para>Shorewall's Simple Traffic Shaping configures the prio
|
||
qdisc(rx-prio(8)) on the designated interface then adds a
|
||
<firstterm>Stochastic Fair Queuing</firstterm> sfq (tc-sfq (8)) qdisc to
|
||
each of the classes that are implicitly created for the prio qdisc. The
|
||
sfq qdisc ensures fairness among packets queued in each of the classes
|
||
such that each <firstterm>flow</firstterm> (session) gets its turn to send
|
||
packets. The definition of flows can be altered to include all traffic
|
||
being sent <emphasis>by</emphasis> a given IP address (normally defined
|
||
for an external interface) or all traffic being sent
|
||
<emphasis>to</emphasis> a given IP address (internal interface).</para>
|
||
|
||
<para>Finally, Simple Traffic Shaping allows you to set a limit on the
|
||
total bandwidth allowed out of an interface. It does this by inserting a
|
||
Token Bucket Filter (tbf) qdisc ahead of the prio qdisc. Note that this
|
||
can have the effect of defeating the priority queuing provided by the prio
|
||
qdisc but seems to provide a benefit when the actual link output
|
||
temporarily drops below the limit imposed by tbf or when tbf allows a
|
||
burst of traffic to be released.</para>
|
||
</section>
|
||
|
||
<section>
|
||
<title>Enabling Simple Traffic Shaping</title>
|
||
|
||
<para>Simple traffic shaping is enabled by setting TC_ENABLED=Simple in
|
||
<ulink url="manpages/shorewall.conf.html">shorewall.conf</ulink>(5). You
|
||
then add an entry for your external interface to <ulink
|
||
url="manpages/shorewall-tcinterfaces.html">shorewall-tcinterfaces</ulink>(5)
|
||
(<filename>/etc/shorewall/tcinterfaces</filename>).</para>
|
||
|
||
<para>Assuming that your external interface is eth0:</para>
|
||
|
||
<programlisting>#INTERFACE TYPE IN-BANDWIDTH OUT-BANDWIDTH
|
||
eth0 External</programlisting>
|
||
|
||
<note>
|
||
<para>If you experience an error such as the following during
|
||
<command>shorewall start</command> or <command>shorewall
|
||
restart</command>, your kernel and iproute do not support the <emphasis
|
||
role="bold">flow</emphasis> classifier. In that case, you must leave the
|
||
TYPE column empty (or specify '-').</para>
|
||
|
||
<programlisting>Unknown filter "flow", hence option "hash" is unparsable
|
||
ERROR: Command "tc filter add dev eth0 protocol all prio 1 parent 11: handle 11 flow hash keys nfct-src divisor 1024" Failed</programlisting>
|
||
|
||
<para>RHEL5-based systems such as <trademark>CentOS</trademark> 5 and
|
||
<trademark>Foobar</trademark> 5 are known to experience this
|
||
error.</para>
|
||
|
||
<para><emphasis role="bold">Update</emphasis>: Beginning with Shorewall
|
||
4.4.7, Shorewall can determine that some environments, such as RHEL5 and
|
||
derivatives, are incapable of using the TYPE parameter and simply ignore
|
||
it.</para>
|
||
</note>
|
||
|
||
<para>With this simple configuration, packets to be sent through interface
|
||
eth0 will be assigned to a priority band based on the value of their TOS
|
||
field:</para>
|
||
|
||
<programlisting>TOS Bits Means Linux Priority BAND
|
||
------------------------------------------------------------
|
||
0x0 0 Normal Service 0 Best Effort 2
|
||
0x2 1 Minimize Monetary Cost 1 Filler 3
|
||
0x4 2 Maximize Reliability 0 Best Effort 2
|
||
0x6 3 mmc+mr 0 Best Effort 2
|
||
0x8 4 Maximize Throughput 2 Bulk 3
|
||
0xa 5 mmc+mt 2 Bulk 3
|
||
0xc 6 mr+mt 2 Bulk 3
|
||
0xe 7 mmc+mr+mt 2 Bulk 3
|
||
0x10 8 Minimize Delay 6 Interactive 1
|
||
0x12 9 mmc+md 6 Interactive 1
|
||
0x14 10 mr+md 6 Interactive 1
|
||
0x16 11 mmc+mr+md 6 Interactive 1
|
||
0x18 12 mt+md 4 Int. Bulk 2
|
||
0x1a 13 mmc+mt+md 4 Int. Bulk 2
|
||
0x1c 14 mr+mt+md 4 Int. Bulk 2
|
||
0x1e 15 mmc+mr+mt+md 4 Int. Bulk 2</programlisting>
|
||
|
||
<para>When dequeueing, band 1 is tried first and only if it did not
|
||
deliver a packet does the system try band 2, and so onwards. Maximum
|
||
reliability packets should therefore go to band 1, minimum delay to band 2
|
||
and the rest to band 3.</para>
|
||
|
||
<note>
|
||
<para>If you run both an IPv4 and an IPv6 firewall on your system, you
|
||
should define each interface in only one of the two
|
||
configurations.</para>
|
||
</note>
|
||
</section>
|
||
|
||
<section>
|
||
<title>Customizing Simple Traffic Shaping</title>
|
||
|
||
<para>The default mapping of TOS to bands can be changed using the
|
||
TC_PRIOMAP setting in <ulink
|
||
url="manpages/shorewall.conf.html">shorewall.conf</ulink>(5). The default
|
||
setting of this option is:</para>
|
||
|
||
<programlisting>TC_PRIOMAP="2 3 3 3 2 3 1 1 2 2 2 2 2 2 2 2"</programlisting>
|
||
|
||
<para>These entries map Linux Priority to priority BAND. So only entries
|
||
0, 1, 2, 4 and 6 in the map are relevant to TOS->BAND mapping.</para>
|
||
|
||
<para>Further customizations can be defined in <ulink
|
||
url="manpages/shorewall-tcpri.html">shorewall-tcpri</ulink>(5)
|
||
(<filename>/etc/shorewall/tcpri</filename>). Using that file, you
|
||
can:</para>
|
||
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Assign traffic entering the firewall on a particular interface
|
||
to a specific priority band:</para>
|
||
|
||
<programlisting>#BAND PROTO PORT(S) ADDRESS INTERFACE HELPER
|
||
2 - - - eth1</programlisting>
|
||
|
||
<para>In this example, traffic from eth1 will be assigned to priority
|
||
band 2.</para>
|
||
|
||
<note>
|
||
<para>When an INTERFACE is specified, the PROTO, PORT(S) and ADDRESS
|
||
column must contain '-'.</para>
|
||
</note>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Assign traffic from a particular IP address to a specific
|
||
priority band:</para>
|
||
|
||
<programlisting>#BAND PROTO PORT(S) ADDRESS INTERFACE HELPER
|
||
1 - - 192.168.1.44</programlisting>
|
||
|
||
<para>In this example, traffic from 192.168.1.44 will be assigned to
|
||
priority band 1.</para>
|
||
|
||
<note>
|
||
<para>When an ADDRESS is specified, the PROTO, PORT(S) and INTERFACE
|
||
columns must be empty.</para>
|
||
</note>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Assign traffic to/from a particular application to a specific
|
||
priority band:</para>
|
||
|
||
<programlisting>#BAND PROTO PORT(S) ADDRESS INTERFACE HELPER
|
||
1 udp 1194</programlisting>
|
||
|
||
<para>In that example, OpenVPN traffic is assigned to priority band
|
||
1.</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>Assign traffic that uses a particular Netfilter helper to a
|
||
particular priority band:</para>
|
||
|
||
<programlisting>#BAND PROTO PORT(S) ADDRESS INTERFACE HELPER
|
||
1 - - - - sip</programlisting>
|
||
|
||
<para>In this example, SIP and associated RTP traffic will be assigned
|
||
to priority band 1 (assuming that the nf_conntrack_sip helper is
|
||
loaded).</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
|
||
<para>It is suggested that entries specifying an INTERFACE be placed at
|
||
the top of the file. That way, the band assigned to a particular packet
|
||
will be the <emphasis role="bold">last</emphasis> entry matched by the
|
||
packet. Packets which match no entry in <ulink
|
||
url="manpages/shorewall-tcpri.html">shorewall-tcpri</ulink>(5) are
|
||
assigned to priority bands using their TOS field as previously
|
||
described.</para>
|
||
|
||
<para>One cause of high latency on interactive traffic can be that queues
|
||
are building up at your ISP's gateway router. If you suspect that is
|
||
happening in your case, you can try to eliminate the problem by using the
|
||
IN-BANDWIDTH setting in <ulink
|
||
url="manpages/shorewall-tcinterfaces.html">shorewall-tcinterfaces</ulink>(5).
|
||
The contents of the column are a <replaceable>rate</replaceable>. For
|
||
defining the rate, use <emphasis role="bold">kbit</emphasis> or <emphasis
|
||
role="bold">kbps</emphasis> (for Kilobytes per second) and make sure there
|
||
is NO space between the number and the unit (it is 100kbit not 100 kbit).
|
||
<emphasis role="bold">mbit</emphasis>, <emphasis
|
||
role="bold">mbps</emphasis> or a raw number (which means bytes) can be
|
||
used, but note that before Shorewall 4.4.13 only integer numbers were
|
||
supported (0.5 was not valid). To pick an appropriate setting, we
|
||
recommend that you start by setting IN-BANDWIDTH significantly below your
|
||
measured download bandwidth (20% or so). While downloading, measure the
|
||
ping response time from the firewall to the upstream router as you
|
||
gradually increase the setting. The optimal setting is at the point beyond
|
||
which the ping time increases sharply as you increase the setting.</para>
|
||
|
||
<para>Simple Traffic Shaping is only appropriate on interfaces where
|
||
output queuing occurs. As a consequence, you usually only use it on
|
||
extermal interfaces. There are cases where you may need to use it on an
|
||
internal interface (a VPN interface, for example). If so, just add an
|
||
entry to <ulink
|
||
url="manpages/shorewall-tcinterfaces.html">shorewall-tcinterfaces</ulink>(5):</para>
|
||
|
||
<programlisting>#INTERFACE TYPE IN-BANDWIDTH
|
||
tun0 Internal</programlisting>
|
||
|
||
<para>For fast lines, the actual download rate may be significantly less
|
||
than the specified IN-BANDWIDTH. Beginning with Shoreall 4.4.13, you can
|
||
specify an optional burst</para>
|
||
|
||
<para>Also beginning with Shorewall 4.4.13, an OUT-BANDWIDTH column is
|
||
available in <ulink
|
||
url="manpages/shorewall-tcpri.html">shorewall-tcpri</ulink>(5). Limiting
|
||
to outgoing bandwidth can have a positive effect on latency for
|
||
applications like VOIP. We recommend that you begin with a setting that is
|
||
at least 20% less than your measured upload rate and then gradually
|
||
increase it until latency becomes unacceptable. Then reduce it back to the
|
||
point where latency is acceptable.</para>
|
||
</section>
|
||
|
||
<section>
|
||
<title>Additional Reading</title>
|
||
|
||
<para>The PRIO(8) (tc-prio) manpage has additional information on the
|
||
facility that Shorewall Simple Traffic Shaping is based on.</para>
|
||
|
||
<caution>
|
||
<para>Please note that Shorewall numbers the bands 1-3 whereas PRIO(8)
|
||
refers to them as bands 0-2.</para>
|
||
</caution>
|
||
</section>
|
||
</article>
|