#!/bin/bash # ultimate.sh for duron # Based on Wonder Shaper v1.1a echo "/usr/sbin/ultimate.sh: " # Please read the README before filling out these values. # Set the following values to somewhat less than your actual download # and upload speed in kilobits. Also set the device that is to be shaped. # Run a speed test from netspeed.stanford.edu with no shaping enabled. # Multiply the reported rates in Kb/s by ~.95 and enter them here: # Example: DNLINK=4.76M*.95 = 4522 # UPLINK=444.26K*.95 = 422 # Run the stanford test again. Note: stanford uses high ports. # Tweak during heavy upload so that each affected class has a small backlog but # as few dropped packets as possible. Interactive must NEVER backlog! # If heavy downloads affect uploads, tweak IMQ so there is a small backlog but # as few dropped packets as possible. # Watch the logs for "some class has too small rate" even with quantum set. # Stanford is in class 30; egress rate 36% ceil 92%, ingress rate 57% ceil 92% # Download w/HTB is plenty (5.2x), don't tweak. # Upload w/UPLINK=470 -> range 416 - 420 = ~85% of uCEIL. Try for 90% - 91%.
Showing posts with label tc. Show all posts
Showing posts with label tc. Show all posts
Thursday, September 8, 2011
ultimate.sh
Traffic Control
Introduction
Linux's traffic control functionality offers a lot of capabilities related to influencing the rate of flow, as well as latency, of primarily outgoing but also in some cases incoming network traffic. It is designed to be a "construction kit" rather than a turn-key system, where complex network traffic policing and shaping decisions can be made using a variety of algorithms. The Linux traffic control code is also often used by academia for research purposes, where is it can be a useful mechanism to simulate and explore the impact of a variety of different network behaviors. See netem for an example of a simulation framework that can be used for this purpose.
Of course, Linux traffic control can also be extremely useful in an IT context, and this document is intended to focus on the practical, useful applications of Linux traffic control, where these capabilities can be applied to solve problems that are often experienced on modern networks.
Thursday, May 26, 2011
Manual Reference Pages - TC (8)
NAME
tc - show / manipulate traffic control settings
CONTENTS
Synopsis
Description
Qdiscs
Classes
Filters
Classless Qdiscs
Configuring Classless Qdiscs
Classful Qdiscs
Theory Of Operation
Naming
Units
Tc Commands
History
See Also
Author
SYNOPSIS
tc qdisc [ add | change | replace | link ] dev DEV [ parent qdisc-id | root ] [ handle qdisc-id ] qdisc [ qdisc specific parameters ]
tc class [ add | change | replace ] dev DEV parent qdisc-id [ classid class-id ] qdisc [ qdisc specific parameters ]
tc filter [ add | change | replace ] dev DEV [ parent qdisc-id | root ] protocol protocol prio priority filtertype [ filtertype specific parameters ] flowid flow-id
tc [-s | -d ] qdisc show [ dev DEV ]
tc [-s | -d ] class show dev DEV
tc filter show dev DEV
DESCRIPTION
Tc is used to configure Traffic Control in the Linux kernel. Traffic Control consists of the following:
Processing of traffic is controlled by three kinds of objects: qdiscs, classes and filters.
SHAPING When traffic is shaped, its rate of transmission is under control. Shaping may be more than lowering the available bandwidth - it is also used to smooth out bursts in traffic for better network behaviour. Shaping occurs on egress. SCHEDULING By scheduling the transmission of packets it is possible to improve interactivity for traffic that needs it while still guaranteeing bandwidth to bulk transfers. Reordering is also called prioritizing, and happens only on egress. POLICING Where shaping deals with transmission of traffic, policing pertains to traffic arriving. Policing thus occurs on ingress. DROPPING Traffic exceeding a set bandwidth may also be dropped forthwith, both on ingress and on egress.
QDISCS
qdisc is short for ’queueing discipline’ and it is elementary to understanding traffic control. Whenever the kernel needs to send a packet to an interface, it is enqueued to the qdisc configured for that interface. Immediately afterwards, the kernel tries to get as many packets as possible from the qdisc, for giving them to the network adaptor driver. A simple QDISC is the ’pfifo’ one, which does no processing at all and is a pure First In, First Out queue. It does however store traffic when the network interface can’t handle it momentarily.
CLASSES
Some qdiscs can contain classes, which contain further qdiscs - traffic may then be enqueued in any of the inner qdiscs, which are within the classes. When the kernel tries to dequeue a packet from such a classful qdisc it can come from any of the classes. A qdisc may for example prioritize certain kinds of traffic by trying to dequeue from certain classes before others.
FILTERS
A filter is used by a classful qdisc to determine in which class a packet will be enqueued. Whenever traffic arrives at a class with subclasses, it needs to be classified. Various methods may be employed to do so, one of these are the filters. All filters attached to the class are called, until one of them returns with a verdict. If no verdict was made, other criteria may be available. This differs per qdisc. It is important to notice that filters reside within qdiscs - they are not masters of what happens.
CLASSLESS QDISCS
The classless qdiscs are:
[p|b]fifo Simplest usable qdisc, pure First In, First Out behaviour. Limited in packets or in bytes. pfifo_fast Standard qdisc for ’Advanced Router’ enabled kernels. Consists of a three-band queue which honors Type of Service flags, as well as the priority that may be assigned to a packet. red Random Early Detection simulates physical congestion by randomly dropping packets when nearing configured bandwidth allocation. Well suited to very large bandwidth applications. sfq Stochastic Fairness Queueing reorders queued traffic so each ’session’ gets to send a packet in turn. tbf The Token Bucket Filter is suited for slowing traffic down to a precisely configured rate. Scales well to large bandwidths.
CONFIGURING CLASSLESS QDISCS
In the absence of classful qdiscs, classless qdiscs can only be attached at the root of a device. Full syntax: tc qdisc add dev DEV root QDISC QDISC-PARAMETERS
To remove, issue
tc qdisc del dev DEV root
The pfifo_fast qdisc is the automatic default in the absence of a configured qdisc.
CLASSFUL QDISCS
The classful qdiscs are:
CBQ Class Based Queueing implements a rich linksharing hierarchy of classes. It contains shaping elements as well as prioritizing capabilities. Shaping is performed using link idle time calculations based on average packet size and underlying link bandwidth. The latter may be ill-defined for some interfaces. HTB The Hierarchy Token Bucket implements a rich linksharing hierarchy of classes with an emphasis on conforming to existing practices. HTB facilitates guaranteeing bandwidth to classes, while also allowing specification of upper limits to inter-class sharing. It contains shaping elements, based on TBF and can prioritize classes. PRIO The PRIO qdisc is a non-shaping container for a configurable number of classes which are dequeued in order. This allows for easy prioritization of traffic, where lower classes are only able to send if higher ones have no packets available. To facilitate configuration, Type Of Service bits are honored by default.
THEORY OF OPERATION
Classes form a tree, where each class has a single parent. A class may have multiple children. Some qdiscs allow for runtime addition of classes (CBQ, HTB) while others (PRIO) are created with a static number of children. Qdiscs which allow dynamic addition of classes can have zero or more subclasses to which traffic may be enqueued.
Furthermore, each class contains a leaf qdisc which by default has pfifo behaviour though another qdisc can be attached in place. This qdisc may again contain classes, but each class can have only one leaf qdisc.
When a packet enters a classful qdisc it can be classified to one of the classes within. Three criteria are available, although not all qdiscs will use all three:
Each node within the tree can have its own filters but higher level filters may also point directly to lower classes. If classification did not succeed, packets are enqueued to the leaf qdisc attached to that class. Check qdisc specific manpages for details, however.
tc filters If tc filters are attached to a class, they are consulted first for relevant instructions. Filters can match on all fields of a packet header, as well as on the firewall mark applied by ipchains or iptables. See tc-filters(8). Type of Service Some qdiscs have built in rules for classifying packets based on the TOS field. skb->priority Userspace programs can encode a class-id in the ’skb->priority’ field using the SO_PRIORITY option.
NAMING
All qdiscs, classes and filters have IDs, which can either be specified or be automatically assigned. IDs consist of a major number and a minor number, separated by a colon.
QDISCS A qdisc, which potentially can have children, gets assigned a major number, called a ’handle’, leaving the minor number namespace available for classes. The handle is expressed as ’10:’. It is customary to explicitly assign a handle to qdiscs expected to have children. CLASSES Classes residing under a qdisc share their qdisc major number, but each have a separate minor number called a ’classid’ that has no relation to their parent classes, only to their parent qdisc. The same naming custom as for qdiscs applies. FILTERS Filters have a three part ID, which is only needed when using a hashed filter hierarchy, for which see tc-filters(8).
UNITS
All parameters accept a floating point number, possibly followed by a unit. Bandwidths or rates can be specified in:
kbps Kilobytes per second mbps Megabytes per second kbit Kilobits per second mbit Megabits per second bps or a bare number Bytes per second Amounts of data can be specified in: kb or k Kilobytes mb or m Megabytes mbit Megabits kbit Kilobits b or a bare number Bytes. Lengths of time can be specified in: s, sec or secs Whole seconds ms, msec or msecs Milliseconds us, usec, usecs or a bare number Microseconds.
TC COMMANDS
The following commands are available for qdiscs, classes and filter:
add Add a qdisc, class or filter to a node. For all entities, a parent must be passed, either by passing its ID or by attaching directly to the root of a device. When creating a qdisc or a filter, it can be named with the handle parameter. A class is named with the classid parameter. remove A qdisc can be removed by specifying its handle, which may also be ’root’. All subclasses and their leaf qdiscs are automatically deleted, as well as any filters attached to them. change Some entities can be modified ’in place’. Shares the syntax of ’add’, with the exception that the handle cannot be changed and neither can the parent. In other words, change cannot move a node. replace Performs a nearly atomic remove/add on an existing node id. If the node does not exist yet it is created. link Only available for qdiscs and performs a replace where the node must exist already.
HISTORY
tc was written by Alexey N. Kuznetsov and added in Linux 2.2.
SEE ALSO
tc-cbq(8), tc-htb(8), tc-sfq(8), tc-red(8), tc-tbf(8), tc-pfifo(8), tc-bfifo(8), tc-pfifo_fast(8), tc-filters(8)
AUTHOR
http://www.squarebox.co.uk/cgi-squarebox/manServer/tc.8
manipulate traffic control settings
TC(8) Linux TC(8)
NAME
tc - show / manipulate traffic control settings
SYNOPSIS
tc qdisc [ add | change | replace | link ] dev DEV [ par-
ent qdisc-id | root ] [ handle qdisc-id ] qdisc [ qdisc
specific parameters ]
tc class [ add | change | replace ] dev DEV parent qdisc-
id [ classid class-id ] qdisc [ qdisc specific parameters
]
tc filter [ add | change | replace ] dev DEV [ parent
qdisc-id | root ] protocol protocol prio priority filter-
type [ filtertype specific parameters ] flowid flow-id
tc [-s | -d ] qdisc show [ dev DEV ]
tc [-s | -d ] class show dev DEV
tc filter show dev DEV
DESCRIPTION
Tc is used to configure Traffic Control in the Linux ker-
nel. Traffic Control consists of the following:
SHAPING
When traffic is shaped, its rate of transmission is
under control. Shaping may be more than lowering
the available bandwidth - it is also used to smooth
out bursts in traffic for better network behaviour.
Shaping occurs on egress.
SCHEDULING
By scheduling the transmission of packets it is
possible to improve interactivity for traffic that
needs it while still guaranteeing bandwidth to bulk
transfers. Reordering is also called prioritizing,
and happens only on egress.
POLICING
Where shaping deals with transmission of traffic,
policing pertains to traffic arriving. Policing
thus occurs on ingress.
DROPPING
Traffic exceeding a set bandwidth may also be
dropped forthwith, both on ingress and on egress.
Processing of traffic is controlled by three kinds of
objects: qdiscs, classes and filters.
QDISCS
qdisc is short for 'queueing discipline' and it is elemen-
tary to understanding traffic control. Whenever the kernel
needs to send a packet to an interface, it is enqueued to
the qdisc configured for that interface. Immediately
afterwards, the kernel tries to get as many packets as
possible from the qdisc, for giving them to the network
adaptor driver.
A simple QDISC is the 'pfifo' one, which does no process-
ing at all and is a pure First In, First Out queue. It
does however store traffic when the network interface
can't handle it momentarily.
CLASSES
Some qdiscs can contain classes, which contain further
qdiscs - traffic may then be enqueued in any of the inner
qdiscs, which are within the classes. When the kernel
tries to dequeue a packet from such a classful qdisc it
can come from any of the classes. A qdisc may for example
prioritize certain kinds of traffic by trying to dequeue
from certain classes before others.
FILTERS
A filter is used by a classful qdisc to determine in which
class a packet will be enqueued. Whenever traffic arrives
at a class with subclasses, it needs to be classified.
Various methods may be employed to do so, one of these are
the filters. All filters attached to the class are called,
until one of them returns with a verdict. If no verdict
was made, other criteria may be available. This differs
per qdisc.
It is important to notice that filters reside within
qdiscs - they are not masters of what happens.
CLASSLESS QDISCS
The classless qdiscs are:
[p|b]fifo
Simplest usable qdisc, pure First In, First Out
behaviour. Limited in packets or in bytes.
pfifo_fast
Standard qdisc for 'Advanced Router' enabled ker-
nels. Consists of a three-band queue which honors
Type of Service flags, as well as the priority that
may be assigned to a packet.
red Random Early Detection simulates physical conges-
tion by randomly dropping packets when nearing con-
figured bandwidth allocation. Well suited to very
large bandwidth applications.
sfq Stochastic Fairness Queueing reorders queued traf-
fic so each 'session' gets to send a packet in
turn.
tbf The Token Bucket Filter is suited for slowing traf-
fic down to a precisely configured rate. Scales
well to large bandwidths.
CONFIGURING CLASSLESS QDISCS
In the absence of classful qdiscs, classless qdiscs can
only be attached at the root of a device. Full syntax:
tc qdisc add dev DEV root QDISC QDISC-PARAMETERS
To remove, issue
tc qdisc del dev DEV root
The pfifo_fast qdisc is the automatic default in the
absence of a configured qdisc.
CLASSFUL QDISCS
The classful qdiscs are:
CBQ Class Based Queueing implements a rich linksharing
hierarchy of classes. It contains shaping elements
as well as prioritizing capabilities. Shaping is
performed using link idle time calculations based
on average packet size and underlying link band-
width. The latter may be ill-defined for some
interfaces.
HTB The Hierarchy Token Bucket implements a rich
linksharing hierarchy of classes with an emphasis
on conforming to existing practices. HTB facili-
tates guaranteeing bandwidth to classes, while also
allowing specification of upper limits to inter-
class sharing. It contains shaping elements, based
on TBF and can prioritize classes.
PRIO The PRIO qdisc is a non-shaping container for a
configurable number of classes which are dequeued
in order. This allows for easy prioritization of
traffic, where lower classes are only able to send
if higher ones have no packets available. To facil-
itate configuration, Type Of Service bits are hon-
ored by default.
THEORY OF OPERATION
Classes form a tree, where each class has a single parent.
A class may have multiple children. Some qdiscs allow for
runtime addition of classes (CBQ, HTB) while others (PRIO)
are created with a static number of children.
Qdiscs which allow dynamic addition of classes can have
zero or more subclasses to which traffic may be enqueued.
Furthermore, each class contains a leaf qdisc which by
default has pfifo behaviour though another qdisc can be
attached in place. This qdisc may again contain classes,
but each class can have only one leaf qdisc.
When a packet enters a classful qdisc it can be classified
to one of the classes within. Three criteria are avail-
able, although not all qdiscs will use all three:
tc filters
If tc filters are attached to a class, they are
consulted first for relevant instructions. Filters
can match on all fields of a packet header, as well
as on the firewall mark applied by ipchains or ipt-
ables. See tc-filters(8).
Type of Service
Some qdiscs have built in rules for classifying
packets based on the TOS field.
skb->priority
Userspace programs can encode a class-id in the
'skb->priority' field using the SO_PRIORITY option.
Each node within the tree can have its own filters but
higher level filters may also point directly to lower
classes.
If classification did not succeed, packets are enqueued to
the leaf qdisc attached to that class. Check qdisc spe-
cific manpages for details, however.
NAMING
All qdiscs, classes and filters have IDs, which can either
be specified or be automatically assigned.
IDs consist of a major number and a minor number, sepa-
rated by a colon.
QDISCS A qdisc, which potentially can have children, gets
assigned a major number, called a 'handle', leaving
the minor number namespace available for classes.
The handle is expressed as '10:'. It is customary
to explicitly assign a handle to qdiscs expected to
have children.
CLASSES
Classes residing under a qdisc share their qdisc
major number, but each have a separate minor number
called a 'classid' that has no relation to their
parent classes, only to their parent qdisc. The
same naming custom as for qdiscs applies.
FILTERS
Filters have a three part ID, which is only needed
when using a hashed filter hierarchy, for which see
tc-filters(8).
UNITS
All parameters accept a floating point number, possibly
followed by a unit.
Bandwidths or rates can be specified in:
kbps Kilobytes per second
mbps Megabytes per second
kbit Kilobits per second
mbit Megabits per second
bps or a bare number
Bytes per second
Amounts of data can be specified in:
kb or k
Kilobytes
mb or m
Megabytes
mbit Megabits
kbit Kilobits
b or a bare number
Bytes.
Lengths of time can be specified in:
s, sec or secs
Whole seconds
ms, msec or msecs
Milliseconds
us, usec, usecs or a bare number
Microseconds.
TC COMMANDS
The following commands are available for qdiscs, classes
and filter:
add Add a qdisc, class or filter to a node. For all
entities, a parent must be passed, either by pass-
ing its ID or by attaching directly to the root of
a device. When creating a qdisc or a filter, it
can be named with the handle parameter. A class is
named with the classid parameter.
remove A qdisc can be removed by specifying its handle,
which may also be 'root'. All subclasses and their
leaf qdiscs are automatically deleted, as well as
any filters attached to them.
change Some entities can be modified 'in place'. Shares
the syntax of 'add', with the exception that the
handle cannot be changed and neither can the par-
ent. In other words, change cannot move a node.
replace
Performs a nearly atomic remove/add on an existing
node id. If the node does not exist yet it is cre-
ated.
link Only available for qdiscs and performs a replace
where the node must exist already.
HISTORY
tc was written by Alexey N. Kuznetsov and added in Linux
2.2.
SEE ALSO
tc-cbq(8), tc-htb(8), tc-sfq(8), tc-red(8), tc-tbf(8), tc-
pfifo(8), tc-bfifo(8), tc-pfifo_fast(8), tc-filters(8)
AUTHOR
Manpage maintained by bert hubert (ahu@ds9a.nl)
iproute2 16 December 2001 TC(8)http://yesican.chsoft.biz/lartc/tc.html
A Practical Guide to Linux Traffic Control
4. Class Structure Revealed
Paramount to creating a useful traffic control configuration is understanding how to manipulate the class hierarchy you can attach to each root hook. You configure all aspects of the actual shaping using the tc binary. (Traffic classification can be done with the tc binary as well, but we will instead look at a more powerful method later.)4.1. A Classless qdisc
Let us take an example, using the tc binary.tc qdisc add dev eth2 parent root handle 1:0 pfifo |
First, we specify that we want to work with a qdisc. Next, we indicate we wish to add a new qdisc to the Ethernet device eth2. (You can specify del in place of add to remove the qdisc in question.) Then, we specify the special parent root. We discussed the importance of the root hook earlier. It is the hook on the egress side of your Ethernet interface. The handle is the magic userspace way of naming a particular qdisc, but more on that later. Finally, we specify the qdisc we wish to add. Because pfifo is a classless qdisc, there is nothing more to do.
A graphical representation of the structure we just created is depicted below. The color blue is used to represent a qdisc. Later, you will see green used to represent a class.
It is important to discuss the naming convention for qdiscs before proceeding. qdiscs are always referred to using a combination of a major node number and a minor node number. For any given qdisc, the major node number has to be unique for the root hook for a given Ethernet interface. The minor number for any given qdisc will always be zero. By convention, the first qdisc created is named 1:0. You could, however, choose 7:0 instead. These numbers are actually in hexadecimal, so any values in within the range of 1 to ffff are also valid. For readability the digits 0 to 9 are generally used exclusively.
4.2. A Classful qdisc
Now, let us look at an example where we add a classful qdisc and a single class.tc qdisc add dev eth2 parent root handle 1:0 htb default 1 |
default is specified. It is an option for htb qdiscs described later. tc class add dev eth2 parent 1:0 classid 1:1 htb rate 1mbit |
The value for the parent parameter must be the major and minor node number of the qdisc or class you wish to attach to. Earlier, the identifier 1:0 was chosen for handle of the htb qdisc. That must be used as the argument to the parent parameter so tc knows where you are assigning this class.
The classid parameter serves the same purpose for classes that the handle parameter serves for qdiscs. It is the identifier for this specific class. The major node number has already been chosen for you. It must be the same as the major node number specified for the parent argument earlier. You are free to choose any minor node number you want for the classid parameter. Traditionally numbering starts at 1, but numbers from 1 to ffff are valid. For this class the classid 1:1 was chosen, because the qdisc it is being attached to has a major node number 1 for its handle parameter.
Finally we specify the type of class and any options that class requires. In this instance, the htb class was chosen, as the htb qdisc can only have htb classes assigned to it. (This is generally true of classful qdiscs.) The
rate option for htb is discussed later. Another graphical representation, this time of an htb qdisc and an associated class in a simple hierarchy, is shown below. The qdisc is blue and the class green.

4.3. A Combined Example
Finally, we can reveal a complete example using both classful and classless qdiscs.tc qdisc add dev eth2 parent root handle 1:0 htb default 20 tc class add dev eth2 parent 1:0 classid 1:1 htb rate 1000kbit tc class add dev eth2 parent 1:1 classid 1:10 htb rate 500kbit tc class add dev eth2 parent 1:1 classid 1:20 htb rate 500kbit tc qdisc add dev eth2 parent 1:20 handle 2:0 sfq |
A graphical representation of the class hierarchy just created should be beneficial.

Each of the three htb classes attached to the htb qdisc are assigned a major node number of 1 for the classid, as the qdisc they are attached to has a handle with 1 as the major node number. The minor node number for each classid must merely be a unique number between 1 and ffff in hexadecimal.
Finally, a sfq qdisc is attached to the leaf class with classid 1:20. Notice the qdisc is added nearly the same as the htb. However, instead of being assigned to the magic root hook, the target is 1:20. The handle is chosen based on the rules discussed earlier. Briefly, the major node number must be a unique number between 1 and ffff and the minor node must be 0.
Last, the whole structure can be deleted simply by deleting the root hook as demonstrated below.
tc qdisc del dev eth2 root |
4.4. Displaying qdisc and class Details
Now we can take a look at the details of the hierarchy we have created. Using the tc tool again the following output is produced.# tc -s -d qdisc show dev eth2 qdisc sfq 2: quantum 1514b limit 128p flows 128/1024 Sent 0 bytes 0 pkts (dropped 0, overlimits 0) qdisc htb 1: r2q 10 default 0 direct_packets_stat 0 ver 3.16 Sent 0 bytes 0 pkts (dropped 0, overlimits 0) |
# tc -s -d class show dev eth2 class htb 1:10 root leaf 2: prio 0 quantum 13107 rate 1Mbit ceil 1Mbit burst 2909b/8 mpu 0b cburst 2909b/8 mpu 0b level 0 Sent 0 bytes 0 pkts (dropped 0, overlimits 0) lended: 0 borrowed: 0 giants: 0 tokens: 28791 ctokens: 2879 |
Next, we will discuss some of the more interesting qdiscs available, including pfifo, sfq, tbf, prio, htb.
| Prev | Home | Next |
| Linux Traffic Control |
hfsc script
tc qdisc add dev $DEV root handle 1: hfsc default 10
tc class add dev $DEV parent 1: classid 1:1 hfsc sc rate 3072kbit ul rate 3072kbit
tc class add dev $DEV parent 1:1 classid 1:10 hfsc sc umax 1500b dmax 53ms rate 614kbit ul rate 3072kbit
tc class add dev $DEV parent 1:1 classid 1:11 hfsc sc umax 1500b dmax 30ms rate 2457kbit ul rate 3072kbit
iptables -t mangle --new-chain voip
iptables -t mangle --insert voip -o $DEV -j voip
tc filter add dev $DEV parent 1: prio 1 protocol ip handle 1 fw flowid 1:11
iptables -t mangle -A voip -p udp --sport 4569 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --dport 4569 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --sport 5060 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --dport 5060 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --sport 10000:20000 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --dport 10000:20000 -j MARK --set-mark 1
tc -s qdisc show eth0
qdisc hfsc 1: root refcnt 2 default 10
Sent 83509933 bytes 1029276 pkt (dropped 3, overlimits 6238 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
tc -s class show dev
class hfsc 1: root
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 0 level 2
class hfsc 1:11 parent 1:1 sc m1 0bit d 25.1ms m2 2457Kbit ul m1 0bit d 0us m2 3072Kbit
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 0 level 0
class hfsc 1:1 parent 1: sc m1 0bit d 0us m2 3072Kbit ul m1 0bit d 0us m2 3072Kbit
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 1029159 work 83510091 bytes level 1
class hfsc 1:10 parent 1:1 sc m1 0bit d 33.5ms m2 614000bit ul m1 0bit d 0us m2 3072Kbit
Sent 83510091 bytes 1029278 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 1029159 work 83510091 bytes rtwork 82189624 bytes level 0
tc -s filter show dev
filter parent 1: protocol ip pref 1 fw
filter parent 1: protocol ip pref 1 fw handle 0x1 classid 1:11
iptables -t mangle -L voip -v -x
Chain voip (1 references)
pkts bytes target prot opt in out source destination
0 0 MARK udp -- any any anywhere anywhere udp spt:sip MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp dpt:sip MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp spt:iax MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp dpt:iax MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp spts:10000:20000 MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp dpts:10000:20000 MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp spt:sip-tls MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp dpt:sip-tls MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any x.x.x.18 anywhere MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere x.x.x.18 MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any x.x.x.24 anywhere MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere x.x.x.24 MARK xset 0x1/0xffffffff
tc class add dev $DEV parent 1: classid 1:1 hfsc sc rate 3072kbit ul rate 3072kbit
tc class add dev $DEV parent 1:1 classid 1:10 hfsc sc umax 1500b dmax 53ms rate 614kbit ul rate 3072kbit
tc class add dev $DEV parent 1:1 classid 1:11 hfsc sc umax 1500b dmax 30ms rate 2457kbit ul rate 3072kbit
iptables -t mangle --new-chain voip
iptables -t mangle --insert voip -o $DEV -j voip
tc filter add dev $DEV parent 1: prio 1 protocol ip handle 1 fw flowid 1:11
iptables -t mangle -A voip -p udp --sport 4569 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --dport 4569 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --sport 5060 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --dport 5060 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --sport 10000:20000 -j MARK --set-mark 1
iptables -t mangle -A voip -p udp --dport 10000:20000 -j MARK --set-mark 1
tc -s qdisc show eth0
qdisc hfsc 1: root refcnt 2 default 10
Sent 83509933 bytes 1029276 pkt (dropped 3, overlimits 6238 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
tc -s class show dev
class hfsc 1: root
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 0 level 2
class hfsc 1:11 parent 1:1 sc m1 0bit d 25.1ms m2 2457Kbit ul m1 0bit d 0us m2 3072Kbit
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 0 level 0
class hfsc 1:1 parent 1: sc m1 0bit d 0us m2 3072Kbit ul m1 0bit d 0us m2 3072Kbit
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 1029159 work 83510091 bytes level 1
class hfsc 1:10 parent 1:1 sc m1 0bit d 33.5ms m2 614000bit ul m1 0bit d 0us m2 3072Kbit
Sent 83510091 bytes 1029278 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
period 1029159 work 83510091 bytes rtwork 82189624 bytes level 0
tc -s filter show dev
filter parent 1: protocol ip pref 1 fw
filter parent 1: protocol ip pref 1 fw handle 0x1 classid 1:11
iptables -t mangle -L voip -v -x
Chain voip (1 references)
pkts bytes target prot opt in out source destination
0 0 MARK udp -- any any anywhere anywhere udp spt:sip MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp dpt:sip MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp spt:iax MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp dpt:iax MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp spts:10000:20000 MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp dpts:10000:20000 MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp spt:sip-tls MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere anywhere udp dpt:sip-tls MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any x.x.x.18 anywhere MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere x.x.x.18 MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any x.x.x.24 anywhere MARK xset 0x1/0xffffffff
0 0 MARK udp -- any any anywhere x.x.x.24 MARK xset 0x1/0xffffffff
Bandwidth Shaping with Linux
On the router, the device, br0 is the bridged device that is in the internet side of things. We will use that device for shaping our internet traffic in and out of the router. I am using my home internet connection, which is Cox cable internet with 12Mbps download and 2Mbps upload or 12288 kilobits per second and 2048 kilobits per second, respectively.
First, lets setup some bash variables to point to the various commands we will use throughout the script. We will also set variables to indicate our maximum bandwidth in both directions.
First, lets setup some bash variables to point to the various commands we will use throughout the script. We will also set variables to indicate our maximum bandwidth in both directions.
TC="/usr/sbin/tc"IPT="/usr/sbin/iptables"IP="/usr/sbin/ip"INSMOD="/sbin/insmod"RMMOD="/sbin/rmmod"DNLD_BANDWIDTH="12288kbit"UPLD_BANDWIDTH="2048kbit"Next, lets setup the download shaping by adding a queuing discipline (qdisc) to device br0 and tell the qdisc the maximum throughput.
TCA="${TC} class add dev br0"TFA="${TC} filter add dev br0"TQA="${TC} qdisc add dev br0"${TQA} root handle 1: htb${TCA} parent 1: classid 1:1 htb rate ${DNLD_BANDWIDTH}Next, we are going to setup 2 classes. Each class will be setup with a guaranteed bandwidth and a maximum bandwidth if the other class is underutilized. The first class will have a guaranteed download bandwidth of 8Mbps. The second class will have a guaranteed download bandwidth of 4Mbps. Both classes will be able to utilize up to 12Mbps depending on how active the other class is.
{TCA} parent 1:1 classid 1:10 htb rate 8192kbit ceil ${DNLD_BANDWIDTH} prio 1{TCA} parent 1:1 classid 1:11 htb rate 4096kbit ceil ${DNLD_BANDWIDTH} prio 2{TQA} parent 1:10 handle 10: sfq perturb 10{TQA} parent 1:11 handle 11: sfq perturb 10Now we need to setup a filter for each class. This is ensure only packets marked with the filter’s tag will be restricted. The mark is denoted by the ip handle. Here we will use 10 and 11, to match the classids of the classes we just defined.
${TFA} parent 1:0 prio 2 protocol ip handle 10 fw flowid 1:10${TFA} parent 1:0 prio 2 protocol ip handle 11 fw flowid 1:11Now to setup the upload shaping, we have to create a imq device.
${INSMOD} imq${INSMOD} ipt_IMQ${IP} link set imq0 upNext, we need to setup a qdisc, classes, and filters for our 2 classes. Just like we did for download, only this time using the imq0 device and the upload bandwidths. The first class will have a guaranteed upload bandwidth of ~1.3Mbps and the second class will have a guaranteed upload bandwidth of 700Kbps.
TCAU="${TC} class add dev imq0"TFAU="${TC} filter add dev imq0"TQAU="${TC} qdisc add dev imq0"${TQAU} root handle 1: htb${TCAU} parent 1: classid 1:1 htb rate ${UPLD_BANDWIDTH}${TCAU} parent 1:1 classid 1:10 htb rate 1348kbit ceil ${UPLD_BANDWIDTH} prio 1${TCAU} parent 1:1 classid 1:11 htb rate 700kbit ceil ${UPLD_BANDWIDTH} prio 2${TQAU} parent 1:10 handle 10: sfq perturb 10${TQAU} parent 1:11 handle 11: sfq perturb 10${TFAU} parent 1:0 prio 2 protocol ip handle 10 fw flowid 1:10${TFAU} parent 1:0 prio 2 protocol ip handle 11 fw flowid 1:11Finally, now that all our shaping is setup, we need to use iptables to mark packets to indicate which packets to shape. My internal network is 192.168.1.0/24. So we only mark packets headed for the internet and leave internal traffic alone. The first class will be restricted to a single IP address. The second class will be restrict to a group of IPs using CIDR notation (32 DHCP addresses from the router).
# download${IPT} -t mangle -A POSTROUTING -s ! 192.168.1.0/24 -d 192.168.1.2 -j MARK --set-mark 10${IPT} -t mangle -A POSTROUTING -s ! 192.168.1.0/24 -d 192.168.1.128/27 -j MARK --set-mark 11# upload${IPT} -t mangle -A PREROUTING -j IMQ --todev 0${IPT} -t mangle -A PREROUTING -d ! 192.168.1.0/24 -s 192.168.1.2 -j MARK --set-mark 10${IPT} -t mangle -A PREROUTING -d ! 192.168.1.0/24 -s 192.168.1.128/27 -j MARK --set-mark 11Note: I would really like to use iptables range of address notation (e.g. -m iprange –src-range 192.168.1.3-192.168.1.254), but current builds of DD-WRT do not seem to work with that notation. I posted to the DD-WRT forums and I’ll I got was IP ranges are not supported. So for my own purposes, I just have giant script with many iptables commands, one for each IP address I want to shape.
To make it easy to start, stop, restart, I wrote an init.d style script for the above. I use it as part of the DD-WRT custom firewall script.
To make it easy to start, stop, restart, I wrote an init.d style script for the above. I use it as part of the DD-WRT custom firewall script.
#!/bin/bashTC="/usr/sbin/tc"IPT="/usr/sbin/iptables"IP="/usr/sbin/ip"INSMOD="/sbin/insmod"RMMOD="/sbin/rmmod"DNLD_BANDWIDTH="12228kbit"UPLD_BANDWIDTH="2048kbit"DNLD_CLASS10_BANDWIDTH="8192kbit"DNLD_CLASS11_BANDWIDTH="4096kbit"UPLD_CLASS10_BANDWIDTH="1348kbit"UPLD_CLASS11_BANDWIDTH="700kbit"[ -x ${TC} ] || exit 1[ -x ${IPT} ] || exit 1[ -x ${IP} ] || exit 1[ -x ${INSMOD} ] || exit 1[ -x ${RMMOD} ] || exit 1case "${1}" in start) echo -n "Starting bandwidth shaping service ... " # download TCA="${TC} class add dev br0" TFA="${TC} filter add dev br0" TQA="${TC} qdisc add dev br0" ${TQA} root handle 1: htb ${TCA} parent 1: classid 1:1 htb rate ${DNLD_BANDWIDTH} ${TCA} parent 1:1 classid 1:10 htb rate ${DNLD_CLASS10_BANDWIDTH} ceil ${DNLD_BANDWIDTH} prio 1 ${TCA} parent 1:1 classid 1:11 htb rate ${DNLD_CLASS11_BANDWIDTH} ceil ${DNLD_BANDWIDTH} prio 2 ${TQA} parent 1:10 handle 10: sfq perturb 10 ${TQA} parent 1:11 handle 11: sfq perturb 10 ${TFA} parent 1:0 prio 2 protocol ip handle 10 fw flowid 1:10 ${TFA} parent 1:0 prio 2 protocol ip handle 11 fw flowid 1:11 # upload ${INSMOD} imq ${INSMOD} ipt_IMQ ${IP} link set imq0 up TCAU="${TC} class add dev imq0" TFAU="${TC} filter add dev imq0" TQAU="${TC} qdisc add dev imq0" ${TQAU} root handle 1: htb ${TCAU} parent 1: classid 1:1 htb rate ${UPLD_BANDWIDTH} ${TCAU} parent 1:1 classid 1:10 htb rate ${UPLD_CLASS10_BANDWIDTH} ceil ${UPLD_BANDWIDTH} prio 1 ${TCAU} parent 1:1 classid 1:11 htb rate ${UPLD_CLASS11_BANDWIDTH} ceil ${UPLD_BANDWIDTH} prio 2 ${TQAU} parent 1:10 handle 10: sfq perturb 10 ${TQAU} parent 1:11 handle 11: sfq perturb 10 ${TFAU} parent 1:0 prio 2 protocol ip handle 10 fw flowid 1:10 ${TFAU} parent 1:0 prio 2 protocol ip handle 11 fw flowid 1:11 # download ${IPT} -t mangle -A POSTROUTING -s ! 192.168.1.0/24 -d 192.168.1.2 -j MARK --set-mark 10 ${IPT} -t mangle -A POSTROUTING -s ! 192.168.1.0/24 -d 192.168.1.128/27 -j MARK --set-mark 11 # upload ${IPT} -t mangle -A PREROUTING -j IMQ --todev 0 ${IPT} -t mangle -A PREROUTING -d ! 192.168.1.0/24 -s 192.168.1.2 -j MARK --set-mark 10 ${IPT} -t mangle -A PREROUTING -d ! 192.168.1.0/24 -s 192.168.1.128/27 -j MARK --set-mark 11 echo "done" ;; stop) echo -n "Stopping bandwidth shaping service ... " # download ${IPT} -t mangle -D POSTROUTING -s ! 192.168.1.0/24 -d 192.168.1.2 -j MARK --set-mark 10 ${IPT} -t mangle -D POSTROUTING -s ! 192.168.1.0/24 -d 192.168.1.128/27 -j MARK --set-mark 11 # upload ${IPT} -t mangle -D PREROUTING -d ! 192.168.1.0/24 -s 192.168.1.2 -j MARK --set-mark 10 ${IPT} -t mangle -D PREROUTING -d ! 192.168.1.0/24 -s 192.168.1.128/27 -j MARK --set-mark 11 ${IPT} -t mangle -D PREROUTING -j IMQ --todev 0 ${TC} qdisc del dev br0 root ${TC} qdisc del dev imq0 root ${IP} link set imq0 down ${RMMOD} ipt_IMQ ${RMMOD} imq echo "done" ;; restart) ${0} stop sleep 1 ${0} start ;; status) ${TC} qdisc show dev br0 ${TC} class show dev br0 ${TC} filter show dev br0 ${TC} qdisc show dev imq0 ${TC} class show dev imq0 ${TC} filter show dev imq0 ;; *) echo "Usage: ${0} {start|stop|restart|status}" exit 1 ;;esacexit 0http://roback.cc/wp/2009/09/bandwidth-shaping-with-linux/#Introduction Traffic shaping with tc
Sometimes it's necessary to limit traffic bandwidth from and to a container. You can do it using ordinary
Here
tc tool. Contents[hide] |
[edit] Packet routes
First of all, a few words about how packets travel from and to a container. Suppose we have Hardware Node (HN) with a container (CT) on it, and this container talks to some Remote Host (RH). HN has one "real" network interface eth0 and, thanks to OpenVZ, there is also "virtual" network interface venet0. Inside the container we have interface venet0:0.venet0:0 venet0 eth0
CT >------------->-------------> HN >--------->--------> RH
venet0:0 venet0 eth0
CT <-------------<-------------< HN <---------<--------< RH[edit] Limiting outgoing bandwidth
We can limit container outgoing bandwidth by setting the tc filter on eth0.DEV=eth0 tc qdisc del dev $DEV root tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 100mbit tc class add dev $DEV parent 1: classid 1:1 cbq rate 256kbit allot 1500 prio 5 bounded isolated tc filter add dev $DEV parent 1: protocol ip prio 16 u32 match ip src X.X.X.X flowid 1:1 tc qdisc add dev $DEV parent 1:1 sfq perturb 10X.X.X.X is an IP address of container.
[edit] Limiting incoming bandwidth
This can be done by setting thetc filter on venet0: DEV=venet0 tc qdisc del dev $DEV root tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 100mbit tc class add dev $DEV parent 1: classid 1:1 cbq rate 256kbit allot 1500 prio 5 bounded isolated tc filter add dev $DEV parent 1: protocol ip prio 16 u32 match ip dst X.X.X.X flowid 1:1 tc qdisc add dev $DEV parent 1:1 sfq perturb 10Note that
X.X.X.X is an IP address of container. [edit] Limiting CT to HN talks
As you can see, two filters above don't limit container to HN talks. I mean a container can emit as much traffic as it wishes. To make such a limitation from the HN, it is necessary to use tc police on venet0:DEV=venet0 tc filter add dev $DEV parent 1: protocol ip prio 20 u32 match u32 1 0x0000 police rate 2kbit buffer 10k drop flowid :1
[edit] Limiting packets per second rate from container
To prevent dos atacks from the container you can limit packets per second rate using iptables.DEV=eth0 iptables -I FORWARD 1 -o $DEV -s X.X.X.X -m limit --limit 200/sec -j ACCEPT iptables -I FORWARD 2 -o $DEV -s X.X.X.X -j DROP
X.X.X.X is an IP address of container. [edit] An alternate approch using HTB
For details refer to the HTB Home Page#!/bin/sh # # Incoming traffic control # CT_IP1=$1 CT_IP2=$2 DEV=venet0 # tc qdisc del dev $DEV root # tc qdisc add dev $DEV root handle 1: htb default 10 # tc class add dev $DEV parent 1: classid 1:1 htb rate 100mbit burst 15k tc class add dev $DEV parent 1:1 classid 1:10 htb rate 10mbit ceil 10mbit burst 15k tc class add dev $DEV parent 1:1 classid 1:20 htb rate 20mbit ceil 20mbit burst 15k tc class add dev $DEV parent 1:1 classid 1:30 htb rate 30mbit ceil 30mbit burst 15k # tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10 tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10 # if [ ! -z $CT_IP1 ]; then tc filter add dev $DEV protocol ip parent 1:0 prio 1 u32 match ip dst "$CT_IP1" flowid 1:20 fi if [ ! -z $CT_IP2 ]; then tc filter add dev $DEV protocol ip parent 1:0 prio 1 u32 match ip dst "$CT_IP2" flowid 1:30 fi # echo;echo "tc configuration for $DEV:" tc qdisc show dev $DEV tc class show dev $DEV tc filter show dev $DEV # # Outgoing traffic control # DEV=eth0 # tc qdisc del dev $DEV root # tc qdisc add dev $DEV root handle 1: htb default 10 # tc class add dev $DEV parent 1: classid 1:1 htb rate 100mbit burst 15k tc class add dev $DEV parent 1:1 classid 1:10 htb rate 10mbit ceil 10mbit burst 15k tc class add dev $DEV parent 1:1 classid 1:20 htb rate 20mbit ceil 20mbit burst 15k tc class add dev $DEV parent 1:1 classid 1:30 htb rate 30mbit ceil 30mbit burst 15k # tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10 tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10 # if [ ! -z $CT_IP1 ]; then tc filter add dev $DEV protocol ip parent 1:0 prio 1 u32 match ip src "$CT_IP1" flowid 1:20 fi if [ ! -z $CT_IP2 ]; then tc filter add dev $DEV protocol ip parent 1:0 prio 1 u32 match ip src "$CT_IP2" flowid 1:30 fi # echo;echo "tc configuration for $DEV:" tc qdisc show dev $DEV tc class show dev $DEV tc filter show dev $DEV
http://wiki.openvz.org/Traffic_shaping_with_tc HIERARCHICAL FAIR SERVICE CURVE
HISTORY & INTRODUCTION
HFSC - Hierarchical Fair Service Curve was first presented at SIGCOMM'97. Developed as a part of ALTQ (ALTernative Queuing) on NetBSD, found its way quickly to other BSD systems, and then a few years ago became part of the linux kernel. Still, it's not the most popular scheduling algorithm - especially if compared to HTB - and it's not well documented from enduser's perspective. This introduction aims to explain how HFSC works without going to deep into math side of things (although some if it will be inevitable). In short HFSC aims to:
-
- 1)
- guarantee precise bandwidth and delay allocation for all leaf classes (realtime criterion)
- 2)
- allocate excess bandwidth fairly as specified by class hierarchy (linkshare & upperlimit criterion)
- 3)
- minimize any discrepancy between the service curve and the actual amount of service provided during linksharing
Feature (2) is well, obvious - any algorithm featuring class hierarchy (such as HTB or CBQ) strives to achieve that. HFSC does that well, although you might end with unusual situations, if you define service curves carelessly - see section CORNER CASES for examples.
Feature (3) is mentioned due to the nature of the problem. There may be situations where it's either not possible to guarantee service of all curves at the same time, and/or it's impossible to do so fairly. Both will be explained later. Note that this is mainly related to interior (aka aggregate) classes, as the leafs are already handled by (1). Still - it's perfectly possible to create a leaf class w/o realtime service, and in such case - the caveats will naturally extend to leaf classes as well.
TC STAB
NAME
tc-stab - Generic size table manipulationsSYNOPSIS
tc qdisc add ... stab \
- [ mtu BYTES ] [ tsize SLOTS ] \ [ mpu BYTES ] [ overhead BYTES ] [ linklayer TYPE ] ...
- mtu
- maximum packet size we create size table for, assumed 2048 if not specified explicitly
- tsize
- required table size, assumed 512 if not specified explicitly
- mpu
- minimum packet size used in computations
- overhead
- per-packet size overhead (can be negative) used in computations
- linklayer
- required linklayer adaptation.
DESCRIPTION
Size tables allow manipulation of packet size, as seen by whole scheduler framework (of course, the actual packet size remains the same). Adjusted packet size is calculated only once - when a qdisc enqueues the packet. Initial root enqueue initializes it to the real packet's size. Each qdisc can use different size table, but the adjusted size is stored in area shared by whole qdisc hierarchy attached to the interface (technically, it's stored in skb). The effect is, that if you have such setup, the last qdisc with a stab in a chain "wins". For example, consider HFSC with simple pfifo attached to one of its leaf classes. If that pfifo qdisc has stab defined, it will override lengths calculated during HFSC's enqueue, and in turn, whenever HFSC tries to dequeue a packet, it will use potentially invalid size in its calculations. Normal setups will usually include stab defined only on root qdisc, but further overriding gives extra flexibility for less usual setups.Initial size table is calculated by tc tool using mtu and tsize parameters. The algorithm sets each slot's size to the smallest power of 2 value, so the whole mtu is covered by the size table. Neither tsize, nor mtu have to be power of 2 value, so the size table will usually support more than is required by mtu.
For example, with mtu~=~1500 and tsize~=~128, a table with 128 slots will be created, where slot 0 will correspond to sizes 0-16, slot 1 to 17~-~32, ..., slot 127 to 2033~-~2048. Note, that the sizes are shifted 1 byte (normally you would expect 0~-~15, 16~-~31, ..., 2032~-~2047). Sizes assigned to each slot depend on linklayer parameter.
Stab calculation is also safe for an unusual case, when a size assigned to a slot would be larger than 2^16-1 (you will lose the accuracy though).
During kernel part of packet size adjustment, overhead will be added to original size, and after subtracting 1 (to land in the proper slot - see above about shifting by 1 byte) slot will be calculated. If the size would cause overflow, more than 1 slot will be used to get the final size. It of course will affect accuracy, but it's only a guard against unusual situations.
Currently there're two methods of creating values stored in the size table - ethernet and atm (adsl):
- ethernet
- This is basically 1-1 mapping, so following our example from above (disregarding mpu for a moment) slot 0 would have 8, slot 1 would have 16 and so on, up to slot 127 with 2048. Note, that mpu~>~0 must be specified, and slots that would get less than specified by mpu, will get mpu instead. If you don't specify mpu, the size table will not be created at all, although any overhead value will be respected during calculations.
- atm, adsl
- ATM linklayer consists of 53 byte cells, where each of them provides 48 bytes for payload. Also all the cells must be fully utilized, thus the last one is padded if/as necessary. When size table is calculated, adjusted size that fits properly into lowest amount of cells is assigned to a slot. For example, a 100 byte long packet requires three 48-byte payloads, so the final size would require 3 ATM cells - 159 bytes. For ATM size tables, 16~bytes sized slots are perfectly enough. The default values of mtu and tsize create 4~bytes sized slots.
TYPICAL OVERHEADS
The following values are typical for different adsl scenarios (based on [1] and [2]):LLC based:
- PPPoA - 14 (PPP - 2, ATM - 12) PPPoE - 40+ (PPPoE - 8, ATM - 18, ethernet 14, possibly FCS - 4+padding) Bridged - 32 (ATM - 18, ethernet 14, possibly FCS - 4+padding) IPoA - 16 (ATM - 16)
- PPPoA - 10 (PPP - 2, ATM - 8) PPPoE - 32+ (PPPoE - 8, ATM - 10, ethernet 14, possibly FCS - 4+padding) Bridged - 24+ (ATM - 10, ethernet 14, possibly FCS - 4+padding
- IPoA - 8 (ATM - 8)
There're few important things regarding the above overheads:
- *
- IPoA in LLC case requires SNAP, instead of LLC-NLPID (see rfc2684) - this is the reason, why it actually takes more space than PPPoA.
- *
- In rare cases, FCS might be preserved on protocols that include ethernet frame (Bridged and PPPoE). In such situation, any ethernet specific padding guaranteeing 64 bytes long frame size has to be included as well (see rfc2684). In the other words, it also guarantees that any packet you send will take minimum 2 atm cells. You should set mpu accordingly for that.
- *
- When size table is consulted, and you're shaping traffic for the sake of another modem/router, ethernet header (without padding) will already be added to initial packet's length. You should compensate for that by subtracting 14 from the above overheads in such case. If you're shaping directly on the router (for example, with speedtouch usb modem) using ppp daemon, layer2 header will not be added yet. For more thorough explanations, please see [1] and [2]. http://www.linuxhowtos.org/manpages/8/tc-stab.htm
Subscribe to:
Posts (Atom)