Weighted fair queuing, or WFQ, is a different beast from PQ or CQ. You can’t define your own classes with WFQ. WFQ does the classification for you, by examining flows:
- Source IP
- Destination IP
- Transport layer protocol (TCP or UDP)
- TCP or UDP source port
- TCP or UDP destination port
- IP Precedence
WFQ places flows into their own queues, so there’s necessarily lots of queues. WFQ services the queues as follows:
- Flows with the same IP precedence are given the same amount of bandwidth, no matter how many bytes are being pushed through a flow. (Thus, flows pushing huge amounts of data may suffer a bit.) 5 flows with the same IPP each get 20% of the bandwidth. If a queue is empty, then that bandwidth will get allocated to other queues.
- Flows with higher IPP are given a proportionally higher amount of pipe, based on IPP+1. Precendence 3 flows would get 4x as much pipe as a precendence 0. (3+1)/(0+1) = 4.
- Thus, WFQ will end up favoring low-volume, high IPP flows.
The WFQ scheduler works by assigning serial numbers to a packet when it is added to a flow queue. The packet with the lowest serial number gets sent to the hardware queue. Simple enough in principle. The complicated part is how WFQ assigns the serial number. SN is calculated as Previous_SN + (weight * new_packet_length), where “weight” is 32,384 / (IPP+1). Thus, larger packets get higher serial numbers. Packets with higher IP precendence values get lower serial numbers. For packets with no previous serial number associated with a new flow, the serial number of the last packet to leave that queue is used as the “Previous_SN”.
WFQ uses what is called modified tail-drop to determine who’s getting dropped. This is a 2-step process.
- The “hold-queue limit” is the maximum number of packets that can be queued amongst all the queues. If the hold-queue limit has been exceeded, then the packet is dropped. Bye, bye packet.
- If the hold-queue limit has not been exceeded, then WFQ looks at the length of the specific queue where this packet is headed. If the congestive discard threshold has been exceeded, then WFQ will discard a packet, but not necessarily that packet. Rather, WFQ determines if there is any packet in any other queue with a higher SN. If there is, then that higher-SN packet will be discarded, and the packet that just came up will be queued instead.
WFQ uses up to 4096 dynamic queues. You can configure this between 16 and 4096, assuming what you set is a power of 2. The hash WFQ uses to classify traffic requires that the number of available queues is a value of 2. Beyond the dynamic queues, the router maintains 8 hidden queues used for router-originated traffic. This router-traffic is given a very low weight so that it is given preference. Also note that resource reservation protocol (RSVP) can reserve bandwidth; WFQ supports RSVP, as does CBWFQ and LLQ.
WFQ doesn’t require that you do much in the way of configuration. WFQ is on by default on E1 and slower links. There are command to be aware of:
- fair-queue [congestive-discard threshold [dynamic-queues] [reservable-queues]]] – this turns WFQ on and allows you to tweak CDT and queues.
- hold-queue <x> out – set the maximum number of packets that can be queued for the entire interface.
- show queue <interface> – show info about the packets waiting in a queue.
- show queueing [custom | fair | priority | random-detect] – show info regarding config and statistics about the chosen queuing tool.