Previous section   Next section

Recipe 11.4 Using Custom Queueing

11.4.1 Problem

You want to configure custom queueing on an interface to give different traffic streams a share of the bandwidth according to their IP Precedence levels.

11.4.2 Solution

Implementing Custom Queueing on a router is a two-step procedure. First you must define the traffic types that will populate your queues. And then you apply the queueing method to an interface:

Router#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#access list 103 permit ip any any precedence 5
Router(config)#access list 104 permit ip any any precedence 4
Router(config)#access list 105 permit ip any any precedence 3
Router(config)#access list 106 permit ip any any precedence 2
Router(config)#access list 107 permit ip any any precedence 1
Router(config)#queue-list 1 protocol ip 3 list 103
Router(config)#queue-list 1 protocol ip 4 list 104
Router(config)#queue-list 1 protocol ip 5 list 105
Router(config)#queue-list 1 queue 5 byte-count 3000 limit 55
Router(config)#queue-list 1 protocol ip 6 list 106
Router(config)#queue-list 1 protocol ip 7 list 107
Router(config)#queue-list 1 default 8
Router(config)#interface HSSI0/0
Router(config-if)#custom-queue-list 1
Router(config-if)#end
Router#

11.4.3 Discussion

When you enable Custom Queueing, the router automatically creates 16 queues for application traffic plus one more for system requirements. You can look at the queues with a normal show interface command:

Router#show interface Ethernet0
Ethernet0 is up, line protocol is up
  Hardware is Lance, address is 0000.0cf0.8460 (bia 0000.0cf0.8460)
  Internet address is 192.168.1.201/24
  MTU 1500 bytes, BW 10000 Kbit, DLY 1000 usec,
     reliability 255/255, txload 2/255, rxload 1/255
  Encapsulation ARPA, loopback not set, keepalive set (10 sec)
  ARP type: ARPA, ARP Timeout 04:00:00
  Last input 00:00:00, output 00:00:00, output hang never
  Last clearing of "show interface" counters never
  Input queue: 2/75/0 (size/max/drops); Total output drops: 0
  Queueing strategy: custom-list 1
  Output queues: (queue #: size/max/drops)
     0: 0/20/0 1: 0/20/0 2: 0/20/0 3: 0/20/0 4: 0/20/0
     5: 0/55/3 6: 5/20/0 7: 0/20/0 8: 0/20/0 9: 0/20/0
     10: 0/20/0 11: 0/20/0 12: 0/20/0 13: 0/20/0 14: 0/20/0
     15: 0/20/0 16: 0/20/0
  5 minute input rate 5000 bits/sec, 12 packets/sec
  5 minute output rate 106000 bits/sec, 24 packets/sec
     132910 packets input, 14513345 bytes, 0 no buffer
     Received 109570 broadcasts, 0 runts, 0 giants, 0 throttles
     9 input errors, 0 CRC, 0 frame, 0 overrun, 9 ignored, 0 abort
     0 input packets with dribble condition detected
     1028116 packets output, 85603681 bytes, 0 underruns
     1 output errors, 42 collisions, 8 interface resets
     0 babbles, 0 late collision, 4 deferred
     1 lost carrier, 0 no carrier
     0 output buffer failures, 0 output buffers swapped out
Router#

In this output you can see that queue number 6 currently has five packets queued and waiting for delivery (6: 5/20/0), while queue number 5 has had to drop three packets due to congestion (5: 0/55/3).

The example assigns queue number 3 for all packets with the highest application IP Precedence value of 5. Similarly, packets with Precedence 4 use queue number 4, Precedence 3 use queue 5, Precedence 2 use queue 6, Precedence 1 use queue 7, and everything else uses queue number 8.

Custom Queueing does not assign a default queue for unclassified traffic, so you must remember to do this. The command in the example defines the default as queue number 8:

Router(config)#queue-list 1 default 8

Note that if there is another non-IP protocol such as IPX configured on this interface, it will also use the default queue. If you prefer to give this other protocol its own set of queues, you can use define them using access lists for that protocol. The configuration is nearly identical to the IP example we have shown, except for the exact access list syntax, which naturally depends on the protocol.

By default, the Custom Queueing scheduler visits all queues in order and takes an average of 1500 bytes from each, and each queue can hold up to 20 packets. In the example, we changed these default values for queue number 5:

Router(config)#queue-list 1 queue 5 byte-count 3000 limit 55

This tells the scheduler to take an average of 3000 bytes from this queue on each pass, and to store up to 55 packets in the queue. Increasing the number of bytes will effectively increase the share of the bandwidth that this queue receives. Increasing the queue depth decreases the probability of tail drops. But it also increases the amount of time that a packet could theoretically spend in the queue, which may increase latency and jitter.

In this example, all of the traffic types are selected by the IP Precedence value. It is also possible to select based on specific applications. You can do this either with an access list or, in some cases, using keywords in the queue-list command. For example, if you wanted to select all DLSw traffic and send it to queue number 9, you could create an access list:

Router(config)#access list 117 permit ip any eq 2065 any 
Router(config)#access list 117 permit ip any any eq 2065
Router(config)#access list 117 permit ip any eq 2067 any 
Router(config)#access list 117 permit ip any any eq 2067
Router(config)#queue-list 1 protocol ip 9 list 117

Or you could do it like this:

Router(config)#queue-list 1 protocol dlsw 9 

This second method is clearly easier, but the number of protocol types that can be defined this way is unfortunately rather limited.

We have three important final notes on Custom Queueing that you should bear in mind. The first point is that if traffic from all of these streams is present, the router will share traffic between them. In this example, we have used six different queues: one for each of the five application precedence levels plus a default. By default, each will receive a roughly equal share of the total bandwidth. So you may be surprised to find that, despite imposing different queues for the different traffic-only types, the important traffic still doesn't get a large enough share of the bandwidth. You can affect this with the byte-count keyword, as we discussed earlier. Note that the queues are serviced by byte count rather than packet count. So suppose you have two queues, one of which supports an interactive session with many short packets, while the other contains a bulk transfer with a few large packets. If you configure the router to service these queues with the same byte-count, it will tend to forward a lot more of the small packets. But the net share of the bandwidth will be roughly equal on average.

Secondly, in Custom Queueing, the traffic within each queue competes directly with all other traffic in the same queue. So, for example, if one user sends a burst of application traffic that fills one of the queues, this will cause tail drops for other users whose traffic uses the same queue. This will cause a smaller version of the global problem of a FIFO queue that we discuss in Appendix B.

The third point is that the more queues you define, the smaller the share of the total bandwidth each queue receives. Further, having more queues increases the amount of processing the router has to do to segregate the traffic.

The second and third points compete with one another. The second one tends to point toward increasing the number of queues to limit the competition within each queue. But the third point should convince you that there is a point of diminishing returns where more queues will not help the situation. In practice, the third rule tends to win out. It rarely turns out to be beneficial to have more than five or six Custom Queues unless some of those queues are only used very lightly.

Custom Queueing is an older QoS mechanism on Cisco routers. In most cases, you will likely find that a newer algorithm such as CBWFQ will be more flexible and give better results.


  Previous section   Next section
Top