The traffic control mechanism in the Linux kernel consists of the following components:
- queueing disciplines (qdisc)
Policers are used to make sure filters match only a certain rate of packets. Policers can be shared by different filters and on different interfaces. It can be used to bound certain incoming traffic, but it's not as powerful as shaping on the outgoing interface with cbq or htb.
Each NIC has one special queueing discipline associated with it: the root-qdisc. Normally this is a very basic one (a FIFO qdisc) that transmits the packets in the same order as they are entered into the queue and as fast as possible, but it's doing this unfairly. There are more complex queueing disciplines with classes which can hold a part of the traffic.
The root qdisc holds all the data that's transmitted. You can replace this root qdisc with another qdisc. So when you want to replace it with a SFQ qdisc, you can use this command:
tc qdisc add dev eth0 root handle 10: SFQ
- tc : command
- qdisc : we are changing a queueing discipline
- add : we are adding a new one
- dev eth0 : we are working on device eth0
- root : we are changing the root qdisc
- handle 10 : this qdisc gets the major number 10 assigned (must be unique per device)
- SFQ : we attach an SFQ qdisc
Classes are attached to qdiscs and hold a part of the traffic. Classes and qdiscs are very tied into each other. Normally, classes are not responsible for handling the packets themselves. They have a qdisc associated with them to do this and this is a standard FIFO qdisc. Of course you can change this and attach a new qdisc with classes, etc ... . Each time you can split the traffic to the different classes with filters. So filters are always attached to qdiscs.
The qdiscs CBQ, DS_MARK, CSZ and p-FIFO can contain classes. All the traffic that's been put in a class by a filter, enters also the qdisc that's attached to the class.
The classes attached to a qdisc can have a different priority and/or rate. So when one packet enters class A, 2 packets enter class B. So the rate of class B is twice the rate of class A.
It's possible that a qdisc has a built-in filter (wrr for example uses the mac-address or ip-address to put the traffic in classes so each address has it's own class). But normally you will have to attach a filter to a qdisc to put the traffic in classes.
Each class and qdisc has a unique number: "<major number:minor number>". For a qdisc the minor number is zero, or you give no number. The major number of a class is the same as the major number of the qdisc the class belongs to. So, pairs x:y are class handles and x:0 or x: are qdisc handles.
Each major number can be a number between 1 and 0x7fff. Major number 0x8000 - 0xffff is used for qdiscs with an unspecified major number. Numbers from ffff:fff0 to ffff:ffff are reserved or have a special meaning.
The major numbers are unique for each qdisc. The minor numbers are unique per major number. You can use hexadecimal numbers.
/* "Handles" --------- All the traffic control objects have 32bit identifiers, or "handles". They can be considered as opaque numbers from user API viewpoint, but actually they always consist of two fields: major and minor numbers, which are interpreted by kernel specially, that may be used by applications, though not recommended. F.e. qdisc handles always have minor number equal to zero, classes (or flows) have major equal to parent qdisc major, and minor uniquely identifying class inside qdisc. */