pfSense Traffic Shaping: Part Three (Class Based Queuing and Priority Queuing)

Class-Based QueuingIn the last article, I covered traffic shaping with Hierarchical Fair Service Curve (HFSC). In this article, I cover the other two algorithms implemented in pfSense 2.0: Class Based Queuing (CBQ) and Priority Queuing (PRIQ).

Class Based Queuing (CBQ)

Class based queuing is a network router queuing method that allows traffic to share bandwidth equally, after being grouped by classes. It was developed by the Network Research Group at Lawrence Berkeley National Laboratory as an alternative to traditional router-based technology. Class based queuing divides user traffic into a hierarchy of queues, or classes, based on any combination of IP addresses, protocols and application types. It provides a means of implementing guaranteed service on a network.

Class based queuing enables you to generate several classes, and even classes within classes. As an example, you may have a 10 Gbps connection to the internet which is to be shared by your customers and for your company’s needs. You cannot allow a few people at the office to steal away large amounts of bandwidth which you should sell to your customers. On the other hand, your customers should not be able to drown out the traffic from your field offices to the customer database.


One way of solving this problem was to either use frame relay/ATM and create virtual circuits. This works, but frame relays are not very fine-grained and ATM is inefficient at carrying IP traffic. Moreover, neither have standardized ways to segregate different types of traffic into different virtual circuits. If you use ATM with Linux, then Linux can do traffic classification, which would help. Another way is to order separate connections, but this is not very practical and does not solve all your problems.

One possible solution is class based queuing. Clearly, you have two main classes, which we can call “ISP” and “Office”. We could further subdivide these classes, but for the moment we won’t. You decide the customers should always be guaranteed 8 Gbps of downstream traffic, and your office 2 Gbps. With CBQ, you can simply set up a root class and two subclasses, ISP and Office. The upper bound on ISP’s bandwidth is 8 Gbps, and the upper bound on Office’s is 2 Gbps. This is not the most sophisticated form of bandwidth management, but it will work.

In this example, you may find that there are times when ISP customers are mostly offline, but your office only gets 2 Gbps. You could make the Office class unbounded, so the office class can borrow bandwidth from the ISP class.

You can also go further than this, introducing subclasses. If employees at the office start using peer-to-peer software, for example, the database may run out of bandwidth. Therefore, you create two subclasses: “Human” and “Database”. In this scenario, you allocate 500 Mbps to Database and allocate the rest (1.5 Gbps) to Human.

Class based queuing assigns each queue a priority level. Queues with a higher priority are preferred during congestion over queues with a lower priority as long as both queues share the same parent (in other words, as long as both queues are on the same branch in the hierarchy). Queues with the same priority are processed in a round-robin fashion. For example, we could assign priorities in the above example like this:

  • Office (priority 1)
    • Human (priority 2)
    • Database (priority 3)
  • ISP (priority 1)

In this example, Office and ISP traffic will be processed in a round-robin fashion – they have the same priority level. But within the Office class/queue, Database gets preferential treatment because it has a higher priority level than Human. Notice that Database is not compared to Office or ISP for priority levels because Office and ISP are not on the same level of the hierarchy.


Priority Queuing (PRIQ)

Priority Queuing assigns multiple queues to a network interface with each queue being given a priority level. A queue with a higher priority is always processed ahead of a queue with a lower priority. If two or more queues are assigned the same priority then those queues are processed in a round-robin fashion.

Unlike class based queuing, which has a hierarchical queue structure, the queuing structure in PRIQ is flat – you cannot define queues within queues. The root queue is defined, which sets the total amount of bandwidth that is available, and then sub queues are defined under the root. Consider the following example:

Root Queue (2 Mbps)

  • Queue A (priority 1)
  • Queue B (priority 2)
  • Queue C (priority 3)

The root queue is defined as having 2 Mbps of bandwidth available to it and three subqueues are defined. The queue with the highest priority (the highest priority number) is served first. Once all the packets in that queue are processed, or if the queue is found to be empty, PRIQ moves onto the next highest priority. Within a given queue, packets are processes in a first in first out (FIFO) manner.

One attribute of PRIQ that should be noted is that PRIQ always processes a higher priority queue before a lower priority one. Consequently, it is possible for a high priority queue to cause packets in a lower priority queue to be delayed or dropped if the high priority queue is receiving a constant stream of packets. Therefore, if you use PRIQ, you want to plan your queues carefully.

External Links:

Class based queuing on Wikipedia

Packet Queuing and Prioritization

© 2013 David Zientara. All rights reserved. Privacy Policy