A customer has several WAN lines to remote offices and has QoS implemented on the routers. Of course I wanted to monitor what really happens on the line. Which packets are classified? And how? How many packets are queued and how many bytes are dropped. And the customer was interested if QoS really worked as described in the documentation.
So I read the CISCO-CLASS-BASED-QOS-MIB (ciscoMgmt.166) and developed some templates to monitor QoS.
Cisco's QoS MIB
Cisco's QoS MIB is one of the most complicated I have ever seen. The MIB's header describes its structure quite accurate, but the problem is that you have several configuration objects like class maps, policies or traffic shaping that can be used on all interfaces.
So all entries in the SNMP tables will be double indexed. First by the interface the entry belongs to and then, the second time, by a run-time object that you want to monitor. The run-time object is linked to the configuration object by a separate table.
If you want to understand a entry in a table you have to understand both indices that explain exactly what this object is and where it is used.
First of all you have to find out what is the index of your outgoing interface because you are shaping on that interface. Cisco uses different indices in the CLASS-BASED-QOS MIB than in the ifTable. They are mapped in the cbQosIfIndex table. Here is a sample of both tables:
IF-MIB::ifDescr.2 = STRING: FastEthernet0/0 CISCO-CLASS-BASED-QOS-MIB::cbQosIfIndex.34 = INTEGER: 2
If your outgoing interface is Fa0/0 with the index 2 the interesting entries in the QOS MIB are those with the first index 34.
Indices of Run-Time Class Map Objects
With this information you can start exploring your MIB. If you know how many bytes after policing where delivered to what classes you walk the cbQosCMPostPolicyByte64.<interface-index> table. You will have to use SNMPv2 since this is a 64bit Counter and SNMPv1 does not know that data type. A sample walking that table is here:
# snmpwalk -v2c router cbQosCMPostPolicyByte64.34 CISCO-CLASS-BASED-QOS-MIB::cbQosCMPostPolicyByte64.34.1614705 = Counter64: 362240190 CISCO-CLASS-BASED-QOS-MIB::cbQosCMPostPolicyByte64.34.4411937 = Counter64: 7076947746 CISCO-CLASS-BASED-QOS-MIB::cbQosCMPostPolicyByte64.34.5790449 = Counter64: 34669114128 CISCO-CLASS-BASED-QOS-MIB::cbQosCMPostPolicyByte64.34.14664689 = Counter64: 681538196464 CISCO-CLASS-BASED-QOS-MIB::cbQosCMPostPolicyByte64.34.14967201 = Counter64: 11603295588 CISCO-CLASS-BASED-QOS-MIB::cbQosCMPostPolicyByte64.34.15546257 = Counter64: 627826581024
As you can see all objects in that table are indexed by two indices. The first one (34) we already know. This is the outgoing interface. The second index gives the run-time QoS object. These run-time objects are linked to the configuration objects through the cbQosConfigIndex table.
So the first entry in the table above (1614705) is linked to a configration object:
# snmpget router cbQosConfigIndex.34.1614705 CISCO-CLASS-BASED-QOS-MIB::cbQosConfigIndex.34.1614705 = Gauge32: 13387249
Now it is very simple to find the name of the according config object:
#snmpget router cbQosCMName.13387249 CISCO-CLASS-BASED-QOS-MIB::cbQosCMName.13387249 = STRING: BULK-DATA
Please note that the PostPolicy table uses Class Map objects so we are searching for a cbQosCMName configuration object. Other run-time objects have configuration objects of different type so you would have to request a different table (i.e. cbQosPolicyMapName, ...).
For monitoring I found the cbQosCMDropByte64 and cbQosCMPostPolicyByte64 tables interesting. They count the bytes that were dropped or forwared in the different Class Maps. Your monitoring system just has to calculate the differences between two measurement points to get the traffic rate.
Traffic Shaping Objects
The other interesting table is ths cbQosTSStats (read: Traffic Shaping Statistics). Get all objects in that table by walking it and searching for the right interface:
# snmpwalk -v2c router cbQosTSStats | grep <interfaceindex> CISCO-CLASS-BASED-QOS-MIB::cbQosTSStatsDelayedByte64.34.887811 = Counter64: 3145575695 octets CISCO-CLASS-BASED-QOS-MIB::cbQosTSStatsDelayedPkt64.34.887811 = Counter64: 260625807 packets CISCO-CLASS-BASED-QOS-MIB::cbQosTSStatsDropByte64.34.887811 = Counter64: 73293628 octets CISCO-CLASS-BASED-QOS-MIB::cbQosTSStatsDropPkt64.34.887811 = Counter64: 70718 packets CISCO-CLASS-BASED-QOS-MIB::cbQosTSStatsActive.34.887811 = INTEGER: false(2) CISCO-CLASS-BASED-QOS-MIB::cbQosTSStatsCurrentQSize.34.887811 = Gauge32: 0 packets
For monitoring I use the cbQosTSStatsCurrentQSize, cbQosTSStatsDelayedByte64, and cbQosTSStatsDropByte64. Please note that the cbQosTSStatsActive that shows if traffic shaping is active at the moment or not is broken in IOS 15 and will only be fixed in versions 15.2(1)T and 15.2(4)M.
To check if everything is correct you could search for the configuration object that the index of the run-time object in the TS MIB refers to.
# snmpget router cbQosConfigIndex.34.887811 CISCO-CLASS-BASED-QOS-MIB::cbQosConfigIndex.34.887811 = Gauge32: 6910963
Now you search for the Traffic Shaping configuration object that has the index 6910963. The rate table will tell you the speed the output stream is shaped to:
# snmpget router cbQosTSCfgRate.6910963 CISCO-CLASS-BASED-QOS-MIB::cbQosTSCfgRate.6910963 = INTEGER: 512000 bits/second
If the rate is 512 kbit/s.
Problems with Templates
Now you have all the information to collect the data from your routers and to print nice graphs about the state of QoS on your WAN lines. The only problem remaining is all the interface and run-time object indices will differ on all routers.
This makes it quite difficult to write templates for monitoring the QoS statistics on all routers. The only solution I found for now is writing scripts on your own.
I wrote a script to create templates for the Zabbix monitoring system. It takes the outgoing interface name as a parameter and gives me a template that collects all the parameters described above. The template also creates nice graphs where all the throughput data of the traffic classes are displayed stacked.