Several readers told me that the Hierarchical Queuing Framework introduced in IOS releases 12.4(20)T and 15.0 (why do I always have the urge to write 12.5?) works much better than CB-WFQ. After spending several hours trying to break HQF, I have to concur with them: Cisco’s engineers did a splendid job. However, the HQF behavior might be slightly counterintuitive to those that became too familiar with CB-WFQ.
For example, faced with this configuration …
policy-map WAN class P5001 bandwidth percent 20 fair-queue class P5003 bandwidth percent 30 class class-default fair-queue
… one might assume that all three classes will get a proportional part of the remaining bandwidth (50%). Not true. An HQF class with a bandwidth allocation gets as much as it’s asked for. It might get more, but if all classes are fully congested, the remaining bandwidth is distributed equally between classes without explicit bandwidth allocation.
When I ran 30 parallel TCP sessions across a 2 Mbps link (10 TCP sessions in each class), I’ve got these results:
a1#show policy-map interface serial 0/1/0 | include map|bps Class-map: P5001 (match-all) 30 second offered rate 418000 bps, drop rate 21000 bps bandwidth 20% (400 kbps) Class-map: P5003 (match-all) 30 second offered rate 613000 bps, drop rate 15000 bps bandwidth 30% (600 kbps) Class-map: class-default (match-any) 30 second offered rate 997000 bps, drop rate 0 bps
As you can see, all the remaining bandwidth was used by the best-effort class-default.
I was performing the QoS tests on a 2Mbps PPP link between two 2800-series routers running IOS release 15.0(1)M. The relevant parts of the router configuration are shown below.
Access lists permit TCP and UDP traffic to the same port. I needed a mix of TCP and UDP to test intra-class queuing behavior.
ip access-list extended P5001 permit tcp any any eq 5001 permit tcp any eq 5001 any permit udp any any eq 5001 permit udp any eq 5001 any ip access-list extended P5002 permit tcp any any eq 5002 permit tcp any eq 5002 any permit udp any any eq 5002 permit udp any eq 5002 any ip access-list extended P5003 permit tcp any any eq 5003 permit tcp any eq 5003 any permit udp any any eq 5003 permit udp any eq 5003 any
class-map match-all P5001 match access-group name P5001 class-map match-all P5003 match access-group name P5003 class-map match-all P5002 match access-group name P5002
interface Serial0/1/0 bandwidth 2000 ip address 10.0.1.1 255.255.255.252 encapsulation ppp ip ospf 1 area 0 load-interval 30 ! service-policy output WAN
I used iperf to generate TCP load and my own flood.pl to generate UDP load. The following command was used to start iperf:
$ iperf -c host -t 3600 -p port -i 60 -P 10