By default, a QoS policy applied in IOS will only reserve up to 75% of a link's available bandwidth. The motivation behind this is to leave a bit of headroom for routing protocols and other critical traffic which might not otherwise be accounted for in a QoS policy. While this is effective for low-speed links, it leaves potential for a large amount of wasted bandwidth on high-speed links, particularly when policing is applied. For example, on a 10 Mbps Ethernet link, only 7.5 Mbps is available for CBWFQ or LLQ allocation.
This can present problems if you want to reserve, say, 90% of a link's bandwidth for RTP.
class-map match-all RTP match protocol rtp ! ! policy-map VOIP class RTP priority 9000
We can see the 75% limitation manifest itself when applying the policy to an interface. We receive the following error:
R1(config-if)# service-policy output VOIP I/f FastEthernet0/0 class RTP requested bandwidth 9000 (kbps), available only 7500 (kbps)
Oddly, at least on IOS 12.4(9)T1, a fair-queue configuration is applied as an apparent fallback:
fair-queue 64 256 256
. Not quite what we wanted. One way to fix this would be to artificially increase the bandwidth of the interface to make the router think it has more than it does. To reserve a full 9 Mbps, we could set the interface bandwidth to 12 Mbps; 75% of 12 Mbps is 9 Mbps, so we stay within the 75% ceiling.R1(config-if)# no fair-queue R1(config-if)# bandwidth 12000 R1(config-if)# service-policy output VOIP
This time our policy is applied without incident, as we're only reserving 75% of the supposed bandwidth. While our QoS goal has been achieved, we've inadvertently broken something else: routing. Consider a simple lab running a single OSPF area across all routers. Our QoS policy is applied outbound on R1's link to R2. R4 is advertising a default route into the area.
With all equal-cost links, R1 should load-balance traffic following the default route across both of its uplinks toward R4. Here's what the OSPF interface table looks like before our bandwidth modification on FastEthernet0/0:
R1# show ip ospf int brief Interface PID Area IP Address/Mask Cost State Nbrs F/C Fa0/1 1 0 10.0.13.1/24 10 BDR 1/1 Fa0/0 1 0 10.0.12.1/24 10 BDR 1/1
But increasing the observed bandwidth of FastEthernet0/0 to 12 Mbps lowers its OSPF cost from 10 to 8, resulting in a lower overall metric to R4:
R1# show ip ospf int brief Interface PID Area IP Address/Mask Cost State Nbrs F/C Fa0/1 1 0 10.0.13.1/24 10 BDR 1/1 Fa0/0 1 0 10.0.12.1/24 8 BDR 1/1
What we've done is killed our equal-cost load balancing; all traffic from R1 to R4 will now flow over the link via R2, effectively cutting our actual available bandwidth in half.
Fortunately IOS provides a much more elegant solution to this problem: max-reserved-bandwidth. This command allows us to change the default limit of 75% to something better suited to our needs. We can lower the configured bandwidth on FastEthernet0/0 to match its actual bandwidth, and increase the maximum QoS-reserved bandwidth to 90%.
R1(config-if)# bandwidth 10000 CBWFQ: Not enough available bandwidth for all classes Available 7500 (kbps) Needed 9000 (kbps) CBWFQ: Removing service policy on FastEthernet0/0 R1(config-if)# max-reserved-bandwidth 90 R1(config-if)# service-policy output VOIP
With this solution, we can leave the bandwidth settings where they should be while still getting efficient use out of our links.
R1# show interface f0/0 FastEthernet0/0 is up, line protocol is up Hardware is Gt96k FE, address is c201.4188.0000 (bia c201.4188.0000) Internet address is 10.0.12.1/24 MTU 1500 bytes, BW 10000 Kbit, DLY 1000 usec, ... R1# show policy-map interface f0/0 FastEthernet0/0 Service-policy output: VOIP Class-map: RTP (match-all) 0 packets, 0 bytes 5 minute offered rate 0 bps, drop rate 0 bps Match: protocol rtp Queueing Strict Priority Output Queue: Conversation 264 Bandwidth 9000 (kbps) Burst 225000 (Bytes) (pkts matched/bytes matched) 0/0 (total drops/bytes drops) 0/0 Class-map: class-default (match-any) 7 packets, 522 bytes 5 minute offered rate 0 bps, drop rate 0 bps Match: any