Traffic Control is the umbrella term for packet prioritizing, traffic shaping, bandwidth limiting, AQM (Active Queue Management), QoS (Quality of Service), etc. This HowTo will help you understand and set up traffic control on your router. It is one strategy to address problems caused by Network congestion.
Note: As of late 2016, the OpenWrt SQM-QoS algorithms using cake or fq_codel have nearly eliminated bufferbloat.
SQM frequently performs better in all cases - upload and download - than arduous manual QoS settings described below.
SQM is simple to set up, and if it solves your problems, you're done. Check out the SQM HOWTO.
| | You can control, i.e. prioritize and/or shape, ANY upload traffic, i.e. traffic being sent from your router to the Internet. Doing so will solve problems that occur with congestion, i.e. jitter and delay. |
| | You do NOT have the same level of control over download traffic, i.e. traffic arriving at your router from the Internet. Here, you can only drop packets but not rearrange them. The dropping of TCP packets causes the sending site to reduce its transmission rate. The dropping of UDP packets however, will only help to keep the buffer empty. |
tc commandtc (traffic control, program to configure the Linux packet scheduler)kmod-sched-core (dependency of tc), package containing most used or advanced (QDiscs) and classifierskmod-sched (optional), package containing other schedulers and classifiers (those not included in the previous)iptables-mod-ipopt optional! Contains some matches and TARGETs for iptables: CLASSIFY, dscp/DSCP, ecn/ECN, length, mac, mark/MARK, statistic, tcpmms, tos/TOS, ttl/TTL, uncleankmod-ipt-ipopt (module; dependency of corresponding user space module;iptables-mod-* optional! (modules for iptables)kmod-ipt-* (kernel modules for iptables)l7-protocols optional! If you want to match Layer 7 contentl7-protocols-testing optional! If you want to test. Check the projects own Homepage.As long as your ISP does not give you access to the DSL-AC so you can install a simple TC-script, you will have to settle with policing the download:
kmod-ifb and act_connmark| | In r25641 iptables-mod-imq (Intermediate Queueing Device) was removed and is not supported any longer. It's successor is kmod-ifb. See Intermediate Functional Block device |
opkg update
opkg install tc iptables-mod-ipopt
Since the description of kmod-sched-core (kmod-sched-core is a dependency of tc) does not contain any information regarding its content, after installation list the currently installed QDisc modules (try installing kmod-sched for other modules):
ls -lha /lib/modules/$(uname -r)/ | grep sch
To use a particular one, you need to load the kernel module into memory:
insmod sch_hfsc
You need to do this after every reboot. List of currently loaded kernel modules and to remove a module:
lsmod
rmmod sch_hfsc
After thoroughly reading this wiki page, you are going to write a shell script which will invoke tc a couple of times and configure the packet scheduler.
Please also see the available examples.
When everything works good enough, proceed with Start on boot and Hotplug.
There are two types of scheduling algorithms (QDiscs) - classful and classless. If you choose to employ a classful root QDisc, you will be able to tailor the configuration very closely to your needs, by constructing a hierarchy of “nesting entities” and then further tune each branch of the tree separately.
tc is the only user space program available to set up, maintain and inspect the configuration of the Linux packet scheduler. Where iptables, ip6tables are for netfilter, tc is for the Linux packet scheduler. Generally only one change is made to the packet scheduler each time tc is executed. A small shell script containing multiple invocations of tc is required to achieve a meaningful overall configuration.
| nesting | configuration | ||||||
|---|---|---|---|---|---|---|---|
| tc | what | command | interface | parent qdisc-id | classid | QDisc | QDisc specific parameters |
tc | qdisc | add | dev eth0 | root | handle 1: | hfsc | default 20 |
change | dev eth0 | root | handle 1: | hfsc | default 20 | ||
replace | dev eth0 | root | handle 1: | hfsc | default 20 | ||
link | dev eth0 | root | handle 1: | hfsc | default 20 | ||
class | add | dev eth0 | parent 1: | classid 1:1 | hfsc | ls rate 750kbit ul rate 1000kbit | |
change | dev eth0 | parent 1:1 | classid 1:10 | hfsc | ls rate 250kbit ul rate 1000kbit | ||
replace | dev eth0 | parent 1:1 | classid 1:20 | hfsc | ls rate 250kbit ul rate 1000kbit | ||
Once you decide what your entire configuration will look like, look up the specific configuration of the QDisc algorithm you intend to use. Each Qdisc aka Scheduling Algorithm gives you parameters to tune:
| Queueing Discipline | Classfull | Description | kmod-sched-core | kmod-sched | |
|---|---|---|---|---|---|
| → sch_atm | name | ?? | bla | ||
| → sch_blackhole | Black hole queue | ?? | bla | ||
| → sch_cbq | Class-Based Queueing discipline | ☑ | very complex | ||
| → sch_choke | CHOKe scheduler | ?? | bla | ||
| → sch_codel | The Controlled-Delay Active Queue Management | ?? | available since r31756 and r31757, mainlined in Kernel 3.5 | ☑ | |
| → sch_drr | Deficit Round Robin scheduler | ?? | can handle packets of variable size without knowing their mean size. | ||
| → sch_dsmark | Differentiated Services field marker | ?? | bla | ☑ | |
| → sch_esfq | Enhanced Stochastic Fairness Queueing | ?? | removed in mainline kernel, but still available in OpenWrt | ☑ | |
| → sch_fifo | The simplest FIFO queue | ?? | bla | ☑ | |
| → sch_fq_codel | Fair Queue CoDel discipline | ?? | available since r31756 and r31757, mainlined in Kernel 3.5 | ☑ | |
| → sch_generic | Generic packet scheduler routines | ?? | bla | ||
| → sch_gred | Generic Random Early Detection | ?? | bla | ☑ | |
| → sch_hfsc | Hierarchical Fair Service Curve | ☑ | link sharing and low delay at the same time | ☑ | |
| → sch_htb | Hierarchy Token Bucket | ☑ | easiest configuration of link sharing, derived from CBQ, high CPU usage | ☑ | |
| → sch_ingress | Ingress qdisc | ?? | bla | ☑ | |
| → sch_mq | Classful multiqueue dummy scheduler | ?? | bla | ||
| → sch_mqprio | name | ?? | bla | ||
| → sch_multiq | name | ?? | bla | ||
| → sch_netem | Network emulator | ☒ | Drop, delay, bla packets | ||
| → sch_pfifo_fast | FIFO with prioritizing | ☒ | DEFAULT, usually build-into the kernel | ||
| → sch_prio | Simple 3-band priority scheduler | ☒ | allows packet prioritization | ☑ | |
| → sch_qfq | Quick Fair Queueing Scheduler | ?? | bla | ||
| → sch_red | Random Early Detection | ☒ | bla | ☑ | |
| → sch_sfb | Stochastic Fair Blue | ?? | bla | ||
| → sch_sfq | Stochastic Fairness Queueing | ☒ | distibutes bandwidth for known tcp-connections fairly | ☑ | |
| → sch_sfqred | mixture of qfq and red | ? | |||
| → sch_tbf | Token Bucket Filter | ☒ | limit bandwidth, does not work above 1mbit | ☑ | |
| → sch_teql | True/Trivial Link Equalizer | ?? | bla | ☑ | |
Note: The PRIO QDisc does contain three classes, but since they cannot be configured further, PRIO is considered to be a classless QDisc. Its classes are sometimes called bands.
| Action | Description | kmod-sched-core | kmod-sched | |
|---|---|---|---|---|
| act_police | Input police filter | |||
| act_nat | Stateless NAT actions | |||
| act_mirred | packet mirroring and redirect actions | |||
| act_skbedit | ||||
This is where you configure which network packet belongs to which queue/bucket. A rule used to allocate a group of IP packets to a certain classid consists of a number of classifiers (match) and one connected action (TARGET or VERDICT).
| Filter (Classifier) | Description | kmod-sched-core | kmod-sched | |
|---|---|---|---|---|
| → cls_flow | flow classifier | bla | ☑ | |
| → cls_fw | firewall classifier | bla | ☑ | |
| → cls_route | route classifier | bla | ☑ | |
| → cls_tcindex | tcindex classifier | bla | ☑ | |
| → cls_u32 | u32 classifier | bla | ☑ | |
| → cls_basic | basic classifier | bla | ☑ | |
| → cls_cgroup | cgroups (Control Group) Classifier | |||
A filter is used by a classfull QDisc to determine in which bucket a packet will be enqueued. Whenever traffic arrives at a class with subclasses, it needs to be classified. Various methods may be used, one of which is filters. All filters attached to the class are called until one of them returns with a verdict. If no verdict is declared, other criteria may be considered. This behaviour varies between different QDiscs.
| location | match | verdict/target | |||||||
|---|---|---|---|---|---|---|---|---|---|
| tc | what | command | interface | target | priority | protocol | filtertype | [ filtertype specific parameters ] | flowid |
| tc | filter | add | dev eth0 | parent 1: | prio 10 | protocol ip | u32 | match ip dport 22 0xffff | classid 1:202 |
| change | dev eth0 | parent 1: | prio 20 | protocol ip | u32 | match ip dport 22 0xffff | classid 1:202 |
||
| replace | dev eth0 | parent 1: | prio 99 | protocol ip | handle | 202 fw | flowid 1:202 |
||
Rules:
Notes:
packet scheduler classifying is slower then netfilter classifying!
Using iptables and tc filter. deprecated? We first match wanted packets with netfilter and mark them, then match the mark (handle 202) and connect it with a certain classid (flowid 1:202):
iptables -t mangle -A POSTROUTING -j MARK --set-mark 202 -p udp --dport 22 tc filter add dev pppoe-dsl parent 1: prio 1 protocol ip handle 202 fw flowid 1:202
It is possible, more efficient and comes with the most options to use netfilter to match and then directly classify network packets:
iptables -t mangle -A POSTROUTING -j CLASSIFY --set-class 1:202 -p tcp --dport 22
Here we match the combination of source IP address, transport protocol, destination port and packet (not payload) length:
iptables -t mangle -A POSTROUTING -j CLASSIFY --set-class 1:303 -s 192.168.0.15 -p tcp --dport 80 -m length --length :512
Notes:
The configuration of the packet scheduler has to be tailored to your situation. Bear in mind what you are actually doing - controlling the behaviour of the packet scheduler managing the egress queue of a network interface.
We can:
So, let's check your situation and then let's configure your packet scheduler accordingly:
Note: The above examples do not make any use of UCI or anthing else, that is not OpenWrt-specific, so you can simply port them to any other Linux distributions and back.
If You are looking for Per IP/MAC Download Speed limiting, be sure to check this forum post.
To check on your results, use tc with or without the option -s (statistics):
tc -s qdisc show dev pppoe-dsl tc class show dev pppoe-dsl tc filter show dev pppoe-dsl iptables -nL -v -x -t mangle
Once you managed to set up a working configuration, you need to test it. Thoroughly! Failure to do so could produce unpredictable results and/or problems.
Ideally you should set up your own mini-network that allows you to monitor and control the source, destination and traffic in between.
Produce all kinds of outgoing traffic and measure the bandwidth distribution.
Then measure and compare latency in different situations:
If you successful please share your knowledge!
Make init restart your script every boot up.
cat << "EOF" > /etc/init.d/trafficc #!/bin/sh START=50 boot () { /etc/tc_hfsc.sh start } start() { /etc/tc_hfsc.sh start } stop() { /etc/tc_hfsc.sh stop } EOF chmod a+x /etc/init.d/traffic /etc/init.d/traffic start /etc/init.d/traffic enable
If you disconnect your dsl-connection, the device pppoe-dsl will close and so will its QDisc.
The following script will restart it whenever you reconnect:
cat << "EOF" > /etc/hotplug.d/iface/30-trafficc #!/bin/sh # This script is executed as part of the hotplug event with # HOTPLUG_TYPE=iface, triggered by various scripts when an interface # is configured (ACTION=ifup) or deconfigured (ACTION=ifdown). The # interface is available as INTERFACE, the real device as DEVICE. [ "$ACTION" = ifup -a "$INTERFACE" = "dsl" ] && /etc/init.d/trafficc enabled && /etc/tc_hfsc.sh EOF
Once your configuration is up and running, you may want to collect some statistical data:
tc and iptables dispense is of course not sooo well formated.Note: If you do not log only your own traffic data, please mind data privacy protection laws to prevent you from going to jail or paying a fine.
Queueing Discipline (QDisc) | An algorithm that manages the queue of a device, either incoming (ingress) or outgoing (egress). Also referred to as a packet scheduler. |
|---|---|
Root QDisc | Not an actual queuing discipline (QDisc), but rather the location where traffic control structures can be attached to an interface for egress (outbound traffic). It can contain any of the queuing disciplines (qdiscs) with potential classes and class structures. |
Ingress QDisc | The location where ingress (incoming traffic) filters can be attached. For practical purposes, the ingress qdisc is merely a convenient object onto which to attach a policer to limit the amount of traffic accepted on a network interface. |
Classless QDisc | A QDisc with no configurable internal subdivisions. |
Classful QDisc | Contains multiple classes. Some of these classes contain a further QDisc, which may again be classful, but need not be. |
Work-Conserving | A work-conserving QDisc never delays packets. It does NOT “shape” packets. |
Non-Work-Conserving | A non-work-conserving QDiscs may delay packets and “shape” them. This means that they sometimes refuse to pass a packet, even though they have one available. |
Tail drop Queue | See Tail drop. |
Classes | Classes are sub-QDiscs which allow the user to configure QoS in more detail. Classes can contain additional classes. Classes do not have a queue, do not contain any network packets and cannot contain filters. |
Leaf Class | End class without any child classes. Always contains a QDisc! In case one is not configure, the default pfifo_fast is used. Leaf classes give unused bandwidth back to their parent class. |
Inner Class | Classes which contain leaf-classes. |
Parent Class | Parent class can dynamically pass bandwidth to leaf-classes. |
Child Class | Class that has another class or a QDisc as parent and contains classes. |
Classifier | Determines which class to send a packet. |
Filter | Classification can be performed using filters. A filter contains a number of conditions which if matched, make the filter match. |
Scheduling | A QDisc may, with the help of a classifier, decide that some packets need to leave earlier than others. This process is called scheduling. |
Shaping | Traffic Shaping is the process of delaying packets to limit egress traffic to a maximum rate or smooth bursts. |
Policing | Traffic Policing is the practice of dropping, marking or ignoring ingress packets that don't comply with user-defined criteria. |
Filters | Filters are used by classful QDiscs to determine which class a packet will be queued to. |
TCP Turbo | Yet another Buzzword bingo term; means the prioritization of TCP ACK-packets on the upload-side. |