Here is how the CBWFQ (Class-Based Weighted Fair Queueing) allocation mechanism is described on Cisco website : “If excess bandwidth is available, the excess bandwidth is divided amongst the traffic classes in proportion to their configured bandwidths. If not all of the bandwidth is allocated, the remaining bandwidth is proportionally allocated among the classes, based on their configured bandwidth.”
How Is Unused Bandwidth Allocated?
In this example, policy-map “TOP” guarantees 20 percent of the bandwidth to class aaa and 40 percent of the bandwidth to class bbb.
policy-map TOP
class C1
bandwidth percent 20
class C2
bandwidth percent 40
If we apply this policy to a 100 Mbps link, it means that 20 Mbps is the minimum guaranteed to class aaa, and 40 Mbps is minimum guaranteed to class bbb. Importantly, 40 Mbps is leftover for class-default.
Should both classes C1 and C2 require bandwidth simultaneously, they proportionally share the unused bandwith 40 Mbps based on the configured rates.
The sharing ratio, in this case, is set at 20:40 or 1:2 so they share it in proportion to the configured rates, reflecting the respective allocations to class aaa and class bbb.
Now, let’s explore the scenarios where we explicitly specify the class-default and those where we don’t
Test environment :
We can conduct the tests using EVE-NG and iperf as follow :
From the client, we initiate two flows as follows:
└─# iperf -c 5.5.5.2 -u -P 1 -i 1 -p 5000 -f k -b 1.0M -t 0
└─# iperf -c 5.5.5.2 -u -P 1 -i 1 -p 5001 -f k -b 1.0M -t 0
On the server, we simultaneously listen to both UDP ports:
└─# iperf -s -u -P 0 -i 1 -p 5001 -f k
└─# iperf -s -u -P 0 -i 1 -p 5000 -f k
We use a Cisco CSR1K router, and we match the port UDP 5000 to class CM1 (so 5001 will go to class-default) :
class-map match-all CM1
match access-group name ACL1
ip access-list extended ACL1
permit udp any any eq 5000
Without Explicitly Allocating Bandwidth on class-default:
We configure the CSR Cisco router as follow :
policy-map TEST
class CM1
bandwidth percent 20
class class-default
policy-map SHAPE
class class-default
shape average 1000000
service-policy TEST
interface GigabitEthernet5
service-policy output SHAPE
In the Cisco output, implicitly, the class-default has been allocated 80%.
Router#show policy-map interface gigabitEthernet 5
GigabitEthernet5
Service-policy output: SHAPE
Class-map: class-default (match-any)
441009 packets, 666677500 bytes
5 minute offered rate 2157000 bps, drop rate 1162000 bps
Match: any
Queueing
queue limit 64 packets
(queue depth/total drops/no-buffer drops) 0/228229/0
(pkts output/bytes output) 213515/322756330
shape (average) cir 1000000, bc 4000, be 4000
target shape rate 1000000
Service-policy : TEST
Class-map: CM1 (match-all)
212393 packets, 321138216 bytes
5 minute offered rate 1078000 bps, drop rate 878000 bps
Match: access-group name ACL1
Queueing
queue limit 64 packets
(queue depth/total drops/no-buffer drops) 64/166765/0
(pkts output/bytes output) 46862/70855344
bandwidth 20% (200 kbps)
Class-map: class-default (match-any)
226849 packets, 342867580 bytes
5 minute offered rate 1079000 bps, drop rate 285000 bps
Match: any
Queueing
queue limit 64 packets
(queue depth/total drops/no-buffer drops) 63/61464/0
(pkts output/bytes output) 166653/251900986
bandwidth 80% (800 kbps)
Now, let’s launch the trafic from the iPerf and see what we’ve got :
As observed, the default class did not receive the entire 80% of the remaining share. Instead, the excess share was proportionally divided. In our case, with only the CM1 class having a 20% minimum guaranteed, it received 20 + (20 * 80%) = 36%
without explicitly assigning bandwidth to the default class, it operates on a best-effort basis. All classes will contend for the remaining bandwidth after claiming their designated shares.
With Explicitly Allocating Bandwidth on Default-Class:
Now, let’s explicitly define the allocation for the class-default :
policy-map TEST
class CM1
bandwidth percent 20
class class-default
bandwidth percent 80
When bandwidth is explicitly allocated to the default class (80% in this example), it ensures that default traffic will receive its designated share, even when CM1 attempts to utilize the entire link.
In summary
In situations where non-default classes saturate the bandwidth, it becomes crucial to explicitly allocate bandwidth for the default-class. This explicit assignment ensures that unclassified or traffic not specified by other classes receives a dedicated share.
Failure to assign a specific bandwidth percentage to the default-class under such saturation scenarios may lead to potential capacity starvation for critical business applications or essential traffic falling within the default class (if there is), particularly when not explicitly identified and classified.
Leveraging ChatGPT3’s assistance, I’ve crafted a tool for pasting the class-map configuration and monitoring the dynamic distribution behavior 🙂
Feel free to make use of it (https://lastopinion.io/public/QoS_CBWFQ_proportion.html)
You can download the Lab here
Hope this helps !
Are you currently evaluating the adoption of a new Quality of Service (QoS) strategy for your network and seeking a professional second opinion to address any uncertainties?
We can assist you. Please don’t hesitate to reach out to us through the CONTACT-US page or by emailing us at [email protected] for advise assistance.