I admit that my practical experience with QoS configuration is not very extensive. I present here some examples that I have solved or found in the documentation and tried. I welcome your suggestions, personal experiences, and practical configurations. Or comments on the given examples. I have encountered several times that practice did not correspond to what I expected according to theory.
What can we do with QoS?
- limit traffic - that is, set the maximum bandwidth that can be used
- reserve traffic - set the minimum (and sometimes the same maximum) bandwidth that can be used
- prioritize traffic - prioritize some traffic over others to prevent delays
- classify traffic - divide traffic into categories according to a number of parameters
- fairly divide bandwidth - different traffic comes in and all of it has to leave through one (slower) port, we can ensure that one type of traffic doesn't occupy all the outgoing bandwidth and the rest is not just discarded, but that the bandwidth is fairly distributed
Where we use QoS
QoS is most used at network boundaries. Typically, we have a local network where switches and a central L3 switch are used, which handles routing. In LANs, relatively high speeds are used (100Mbps, 1Gbps) and the backbone is usually an order of magnitude faster (1Gbps, 10Gbps). We then connect this fast network to another network (branch, internet) via a single line that is an order of magnitude slower (e.g., 10Mbps).
Within the LAN, problems usually don't occur because the incoming speed is usually less than the possible outgoing speed. So here we mostly deal with speed limiting for some special purposes. The problem arises at the point of connection further, for example to the WAN. Here, data often comes in much faster than we can send it out. Therefore, we need to address issues with prioritization and reservation and division of bandwidth. Generally, it is said that QoS needs to be addressed most on links up to 768kbps. Then links up to 2Mbps and everything above.
We therefore perform QoS configuration mostly on the router (gateway) that connects our LAN to another network. And then on the access switch (access layer), where we divide incoming traffic into categories and mark it so that it can be better handled on the router.
Auto-QoS - configuration macros
Note: On the router, QoS is enabled by default. On the switch, it is disabled by default and must be enabled using the mls qos command. However, if we use Auto QoS, it will also enable QoS.
Cisco IP phone
Example configuration where a Cisco IP phone is connected to port g1/0/2 (its communication goes to VLAN 110) and a PC is connected behind it (communication is sorted into VLAN 100). Auto QoS sets all necessary QoS parameters, so when we subsequently look at the port configuration, there will be several additional commands (to cancel the configuration, just use no auto qos … and the other commands will be removed automatically). CDP needs to be enabled for this to work.
SWITCH(config)#interface g1/0/2 SWITCH(config-if)#switchport mode access SWITCH(config-if)#switchport access vlan 100 SWITCH(config-if)#switchport voice vlan 110 SWITCH(config-if)#auto qos voip cisco-phone SWITCH(config-if)#spanning-tree portfast SWITCH(config-if)#no shutdown
Trunk port on Cisco switch
Example configuration of a trunk port (uplink to core switch) using IEEE802.1q. Auto QoS ensures trust in values, meaning that traffic marking (for example for IP telephony) is passed on.
SWITCH(config)#interface te1/0/1 SWITCH(config-if)#switchport trunk encapsulation dot1q SWITCH(config-if)#switchport mode trunk SWITCH(config-if)#switchport nonegotiate SWITCH(config-if)#auto qos voip trust SWITCH(config-if)#no shutdown
Traffic Marking
Selecting traffic - router and switch
A simple example that marks http traffic. First, we create an ACL that will select http (port 80). Then we create a class-map http-class, in which we will select traffic using ACL. Then we create a policy-map http-policy, where for traffic selected by the class map, we set DSCP to AF22. At the end, we apply this policy-map to interface g1/0/1 on incoming communication.
Note: If we wanted to set COS values, it must be a trunk port.
SWITCH(config)#access-list 101 permit tcp any eq 80 any SWITCH(config)#access-list 101 permit tcp any any eq 80 SWITCH(config)#mls qos SWITCH(config)#class-map http-class SWITCH(config-cmap)#match access-group 101 SWITCH(config)#policy-map http-policy SWITCH(config-pmap)#class http-class SWITCH(config-pmap-c)#set dscp AF22 SWITCH(config)#interface gigabitEthernet1/0/1 SWITCH(config-if)#service-policy input http-policy
All traffic - switch
On the switch, we can set all incoming packets to be marked with a given value. The first command marks only packets without a tag, the second ensures overwriting for all.
SWITCH(config)#interface gigabitEthernet1/0/1 SWITCH(config-if)#mls qos cos 3 SWITCH(config-if)#mls qos cos override
Rate Limiting - Rate Management
Port speed
The simplest option, which has nothing to do with QoS, is setting the port speed. The port speed is set to auto by default, where the speed is negotiated according to the connected device. However, we can also set the speed manually. For a gigabit port, we have 10Mbps, 100Mbps, and 1000Mbps available.
SWITCH(config)#interface g1/0/30 SWITCH(config-if)#speed 10
On switch - srr-queue
A simple solution for switches, but it cannot be set very finely. Percentages of 10 - 90% of the maximum interface speed are set. So for Gigabit Ethernet, we reach a minimum of 100Mbps.
SWITCH(config)#mls qos SWITCH(config)#interface g1/0/30 SWITCH(config-if)#srr-queue bandwidth limit 10
We can also use a trick and combine srr-queue with setting the port speed to reach lower speeds. In the following example, we set a gigabit port to FastEthernet mode (100Mbps) and then limit it to 20% of the speed, i.e., 20Mbps.
SWITCH(config)#interface g1/0/30 SWITCH(config-if)#speed 100 SWITCH(config-if)#srr-queue bandwidth limit 20
Using policer on switch
Here we use a method called Class Based Policing. It limits the maximum bandwidth that traffic can consume. This is done by truncating what is above the specified bandwidth (packets are dropped - drop, it is also possible to only remark packets). However, it does not guarantee minimum bandwidth in any way.
On the switch, we can use an aggregate policer (in this example, configuration at the beginning), which we then apply in one policy-map to multiple class-maps (the same aggregate policer cannot be applied to multiple policy-maps!). The values we set are the maximum for the sum of all flows to which it is applied. Or we can use an individual policer (in the second example), which is inserted into each class-map and limits only this flow.
The policer configuration is quite detailed, but it's necessary to understand a bit about the used Token Bucket algorithm (described in the 3rd part of the series) or practically know what settings achieve what results. In the example, we set the average data rate and burst size. Even if we set the values correctly, the measured values for TCP will be significantly lower (therefore it is recommended to set 2x more than we require) due to TCP behavior when dropping packets (halving the window size and subsequent speed increase - traffic then looks like saw teeth).
The following example, which comes from the Cisco website, is intended for older switches (C3550), which have a number of limitations. Here we select all traffic using two ACLs for IP and non-IP traffic. We create two class-maps where we use ACL. Then we create a policy-map into which we insert both class-maps (we can apply only one policy-map for one direction on an interface) and use an aggregate policer, which should limit traffic to 1Mbps (for better performance we set burst-size to 16kB). Finally, we apply the policy-map to port Gi1/0/30.
SWITCH(config)#mls qos SWITCH(config)#mls qos aggregate-policer test-policer 1000000 16000 exceed-action drop SWITCH(config)#access-list 100 permit any any SWITCH(config)#mac access-list extended non-ip-acl SWITCH(config-ext-macl)#permit any any SWITCH(config)#class-map test-ip SWITCH(config-cmap)#match access-group 100 SWITCH(config)#class-map test-non-ip SWITCH(config-cmap)#match access-group name non-ip-acl SWITCH(config)#policy-map police-all-traffic SWITCH(config-pmap)#class test-ip SWITCH(config-pmap-c)#police aggregate test-policer SWITCH(config-pmap)#class test-non-ip SWITCH(config-pmap-c)#police aggregate test-policer SWITCH(config)#interface gi1/0/30 SWITCH(config-if)#service-policy input police-all-traffic
On newer switches (C3750), we can perform the previous configuration more simply. I tried to modify the previous example and practically test it on a Catalyst 3750. Here we have available commands match all and match interface g1/0/30, but unfortunately when we use this selection, we cannot apply the resulting policy-map to a L2 interface. I tried to use the fact that all traffic that we don't classify anywhere falls into the class-default class, so I limited this class.
SWITCH(config)#mls qos SWITCH(config)#policy-map police-all-traffic SWITCH(config-pmap)#class class-default SWITCH(config-pmap-c)#police 1m 16000 exceed-action drop SWITCH(config)#interface gi1/0/30 SWITCH(config-if)#service-policy input police-all-traffic
The configuration proceeded smoothly. My idea was to limit the port on which I set the policer. I had a station connected to it and tried to simply verify the speed. Using Total Commander, I copied a file over the network using the CIFS protocol (Windows share). And I was surprised, the traffic was slowed down (from the original 168Mbps), but to a speed of about 22Mbps and I expected something well below 1Mbps. I tried different settings and for example, for a 100kbps policer, I achieved values of 3.89Mbps. It took me a while to figure out why. Yet it's enough to think. I set the policy-map on the correct interface, but only in one direction and that was the opposite one.
When applying a policy-map to an interface, we can specify the direction input or output. It's stated everywhere that input is the direction into the interface and output is out (which is logical). But I couldn't find anywhere from which side. I assume it's similar to ACL, and we look at the direction from the switch/router's perspective, so what comes from outside into the port is input and what leaves the switch through the port is output. So in my example, I was limiting outgoing traffic, but measuring incoming.
There's nothing easier than setting the policy-map to the other direction, so I tried to do that.
S2NP01(config-if)#service-policy ? input Assign policy-map to the input of an interface output Assign policy-map to the output of an interface S2NP01(config-if)#service-policy output ? WORD policy-map name S2NP01(config-if)#service-policy output police-all-traffic police command is not supported for this interface Configuration failed! Warning: Assigning a policy map to the output side of an interface not supported
The help displays both options, but when we try it, we get an error message because policing is only possible for input ports (input). So we can't limit the download of data for one user connected to the port this way. We would either have to set limits on the port from which the data is coming. Or we can use the previously mentioned options.
Note: When I tried copying in the opposite direction, where the PC on the configured port was the data source, I achieved better results of about 370kbps (I would expect a bit more).
Using policer on router
I moved further testing to the router. I tried on a small model from the lowest series Cisco 871. Routers have more options for CB Policing. They also contain a Dual Token Bucket algorithm. Here we can already select all traffic using match any. On the router, it's necessary to have Cisco Express Forwarding (CEF) turned on, which is default on all newer models (CEF is also used on multilayer switches).
ROUTER(config)#ip cef ROUTER(config)#class-map all-traffic-class ROUTER(config-cmap)#match any ROUTER(config)#policy-map all-traffic-policy ROUTER(config-pmap)#class all-traffic-class ROUTER(config-pmap-c)#police 1000000 16000 conform-action transmit exceed-action drop ROUTER(config)#interface fastEthernet1 ROUTER(config-if)#service-policy output all-traffic-policy
The Router 871 (my version) has 4 FastEthernet ports, as a LAN switch and 1 WAN port (also FastEthernet). For testing, I connected two PCs to ports fa1 and fa2. I tried to apply the policy to the outgoing direction on port fa1 and everything went without error. But my setting had no effect, I tried a number of things (including changing to the inward direction), but still nothing. When I looked at the statistics, it's visible that data traffic is recorded, but ignored.
Router#show policy-map interface f1
FastEthernet1
Service-policy output: all-traffic-policy
Class-map: all-traffic-class (match-all)
24 packets, 1440 bytes
5 minute offered rate 0 bps, drop rate 0 bps
Match: any
police:
cir 1000000 bps, bc 16000 bytes
conformed 0 packets, 0 bytes; actions:
transmit
exceeded 0 packets, 0 bytes; actions:
drop
conformed 0 bps, exceed 0 bps
Class-map: class-default (match-any)
0 packets, 0 bytes
5 minute offered rate 0 bps, drop rate 0 bps
Match: any
After a series of tests, I tried to connect one computer to the WAN port fa4 and set the policy on it (here there's only the option for the incoming direction). And everything started working. When I used copying in the correct direction, I achieved a fluctuating speed around 360kbps.
ROUTER(config)#interface FastEthernet4 ROUTER(config-if)#ip address 192.168.10.1 255.255.255.0 ROUTER(config-if)#service-policy output all-traffic-policy
I tried setting different policer values and performed simple measurements with copying from the network, the results are in the following table. The measurement is very inaccurate, but it gives (I hope) a basic idea of the influence of the entered values on the real speed. According to theory, different burst size values should mainly affect burst flows (where some data is briefly transferred, then there's a pause, and then briefly data again) and not constant copying.
| average rate - CIR [kbps] | burst size - Bc [kB] | average copying speed [kbps] |
|---|---|---|
| not set | not set | 60,000 |
| 1,000 | 32 | 416 (relatively constant speed) |
| 1,000 | 16 | 360 (jumps from 320 to 390) |
| 1,000 | 8 | 180 (jumps from 160 to 216) |
| 1,000 | 1 | copying didn't even start |
| 100 | 32 | 88 |
| 100 | 16 | 85 |
| 100 | 8 | 83 |
Shaping on router
Class Based Shaping is a method similar to CB Policing, with the difference that excess packets are not immediately discarded, but are queued (and only when the queue is full are they discarded). It should therefore lead to better bandwidth utilization. CB Shaping is available only on high-end switches (C3750 doesn't contain it) or on routers (I tested again on 871).
I used the same example as last time and set shaping to the average value.
ROUTER(config)#class-map all-traffic-class ROUTER(config-cmap)#match any ROUTER(config)#policy-map shape-all-traffic ROUTER(config-pmap)#class all-traffic-class ROUTER(config-pmap-c)#shape average 1000000 ROUTER(config)#interface FastEthernet4 ROUTER(config-if)#service-policy output shape-all-traffic
The result was much better than policing, I achieved a constant data flow of 936kbps. I also tried using shaping on the peak value, where I measured 1792kbps.
ROUTER(config-pmap-c)#shape peak 1000000
Bandwidth Reservation and Traffic Prioritization
To demonstrate bandwidth reservation for certain traffic, along with an example of prioritizing certain traffic, I again used an example from the Cisco website. This concerns IP telephony. Using ACL, we select VoIP signaling (H.323, TCP port 1720) and RTP media stream (which is a large range of UDP ports 16384 to 32767). For signaling, we reserve a bandwidth of 8kbps. And for the voice itself, we reserve and prioritize 48kbps.
ROUTER(config)#access-list 102 permit udp any any range 16384 32767 ROUTER(config)#access-list 103 permit tcp any eq 1720 any ROUTER(config)#access-list 103 permit tcp any any eq 1720 ROUTER(config)#class-map voice-signaling ROUTER(config-cmap)#match access-group 103 ROUTER(config)#class-map voice-traffic ROUTER(config-cmap)#match access-group 102 ROUTER(config)#policy-map voice-policy ROUTER(config-pmap)#class voice-signaling ROUTER(config-pmap-c)#bandwidth 8 ROUTER(config-pmap)#class voice-traffic ROUTER(config-pmap-c)#priority 48 ROUTER(config)#interface fastEthernet4 ROUTER(config-if)#service-policy output voice-policy
Bandwidth Reservation
To guarantee certain bandwidth, queues are used. In this case, we will use Class Based Weighted Fair Queuing (CBWFQ), which allows reserving certain bandwidth for a class. In the above example, it is the following command.
ROUTER(config-pmap-c)#bandwidth 8
We can also combine it with a better method of dropping packets when queues are full (to avoid the effect described earlier - TCP reduces its window size and then increases it again), this is Weighted Random Early Detection (WRED). We can use WRED even with policing, but my small 871 router doesn't support it. WRED works by dropping less important traffic earlier before congestion occurs. The following command uses IP Precedence for division.
ROUTER(config-pmap-c)#random-detect
Traffic Prioritization
If we want to prioritize some traffic over others (for example, voice), we again use queues and a method called Low Latency Queuing (LLQ). This is based on CBWFQ, so we have traffic with guaranteed bandwidth and we prioritize it. It adds a strictly priority queue (low latency). In case of congestion, it also limits traffic to the given value. In the previous example, it was the command.
ROUTER(config-pmap-c)#priority 48
LLQ nejen i omezuje,ale ono hlavne omezuje - viz hard QoS.
Jinak by totiz neslo zabezpecit konstani zpozdeni. Obecne pokud je pouzito LLQ, melo by byt pouzito i CAC(call admision control),takze ikdyz neni zacpa, nemuzou aplikace v LLQ vyuzivat vic,nez maji prideleny(nutny predpoklad je, ze CAC i LLQ musi byt v souladu,jinak by to nemelo vyznam)
ale hezky napsane
slinti
Ahoj, máš vynikající články! Uplně jsem se vtom zapotal...
Mám tu na experimentování jeden starší router 1760 a chtěl jsem se zeptat když bych chtěl omezit rychlost linky na IP adresu jak se tohle udělá?
Dobrý den, mám switch c2950 s posledním IOSem a potřebuji omezit rychlost na jednotlivých portech, stačí s přesností + - třeba 5Mbit. Je nekdě nějaký návod ? Podle tohoto článku se mi nedaří.
Jinak Super stránky, již mi mnohokrát pomohly.
Předem Moc Děkuji. Petr.
respond to [3]Petr: Nemám s 2950 žádné zkušenosti, ale co jsem nahlédl do dokumentace, tak skoro nic nepodporuje :-(, takže to asi bude problém.
Ahoj,
`srr-queue bandwidth limit X` je mozne uplatnit iba v smere input. Testovane na catalyst 2960.
respond to [5]najt: Potvrzuji, bohužel je to tak. Lze jen input směr. Já to řeším tak, že nastavuji omezení linky mezi dvěma switchi stejnou konfigurací limitu na obou portech.
Omezit VOIP provoz na range portu 16384 az 32767 neni spatny napad ale pozor aby ti zamestnanci nezacali hrat napr. Call of Duty nebo Half - life :D
BTW. super popis QOS