Simple Traffic Shaping/Control

Tom Eastep

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 GNU Free Documentation License.

2010/02/08



Table of Contents

Introduction
Enabling Simple Traffic Shaping
Customizing Simple Traffic Shaping
Additional Reading

Introduction

Traffic shaping and control was originally introduced into Shorewall in version 2.2.5. That facility was based on Arne Bernin's tc4shorewall and is generally felt to be complex and difficult to use.

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 Complex Traffic Shaping/Control.

Enabling Simple Traffic Shaping

Simple traffic shaping is enabled by setting TC_ENABLED=Simple in shorewall.conf(5). You then add an entry for your external interface to shorewall-tcinterfaces(5) (/etc/shorewall/tcinterfaces).

Assuming that your external interface is eth0:

#INTERFACE             TYPE          IN-BANDWIDTH
eth0                   External

Note

If you experience an error such as the following during shorewall start or shorewall restart, your kernel and iproute do not support the flow classifier. In that case, you must leave the TYPE column empty (or specify '-').

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

RHEL5-based systems such as CentOS™ 5 and Foobar™ 5 are known to experience this error.

Update: 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.

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:

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

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.

Note

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.

Customizing Simple Traffic Shaping

The default mapping of TOS to bands can be changed using the TC_PRIOMAP setting in shorewall.conf(5). The default setting of this option is:

TC_PRIOMAP="2 3 3 3 2 3 1 1 2 2 2 2 2 2 2 2"

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.

Further customizations can be defined in shorewall-tcpri(5) (/etc/shorewall/tcpri). Using that file, you can:

  1. Assign traffic entering the firewall on a particular interface to a specific priority band:

    #BAND         PROTO         PORT(S)         ADDRESS             INTERFACE        HELPER
    2               -             -                -                eth1

    In this example, traffic from eth1 will be assigned to priority band 2.

    Note

    When an INTERFACE is specified, the PROTO, PORT(S) and ADDRESS column must contain '-'.

  2. Assign traffic from a particular IP address to a specific priority band:

    #BAND         PROTO         PORT(S)         ADDRESS             INTERFACE        HELPER
    1               -             -             192.168.1.44

    In this example, traffic from 192.168.1.44 will be assigned to priority band 1.

    Note

    When an ADDRESS is specified, the PROTO, PORT(S) and INTERFACE columns must be empty.

  3. Assign traffic to/from a particular application to a specific priority band:

    #BAND         PROTO         PORT(S)         ADDRESS             INTERFACE        HELPER
    1             udp           1194

    In that example, OpenVPN traffic is assigned to priority band 1.

  4. Assign traffic that uses a particular Netfilter helper to a particular priority band:

    #BAND         PROTO         PORT(S)         ADDRESS             INTERFACE        HELPER
    1               -             -             -                   -                sip

    In this example, SIP and associated RTP traffic will be assigned to priority band 1 (assuming that the nf_conntrack_sip helper is loaded).

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 last entry matched by the packet. Packets which match no entry in shorewall-tcpri(5) are assigned to priority bands using their TOS field as previously described.

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 shorewall-tcinterfaces(5). The contents of the column are a rate. For defining the rate, use kbit or kbps (for Kilobytes per second) and make sure there is NO space between the number and the unit (it is 100kbit not 100 kbit). mbit, mbps or a raw number (which means bytes) can be used, but note that only integer numbers are supported (0.5 is 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.

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 shorewall-tcinterfaces(5):

#INTERFACE             TYPE          IN-BANDWIDTH
tun0                   Internal

Additional Reading

The PRIO(8) (tc-prio) manpage has additional information on the facility that Shorewall Simple Traffic Shaping is based on.

Caution

Please note that Shorewall numbers the bands 1-3 whereas PRIO(8) refers to them as bands 0-2.