… updated on Tuesday, November 17, 2020 11:51 UTC
The most convoluted MIB I’ve seen
Jared Valentine sent me a really interesting problem: he would like to detect voice traffic and start shaping TCP traffic for the duration of the voice call. The ideal solution would be an EEM applet reacting to the changes in the CISCO-CLASS-BASED-QOS-MIB; one of its tables contains the amount of traffic for each class configured in a service policy.
The MIB navigation looks simple: you just read the values from the cbQosClassMapStats
table, indexed by policy ID and class ID. The real problem is finding the correct index values. I could walk the MIB manually with a MIB browser or snmp_getnext TCL calls, but this approach is obviously not scalable, so I wrote a script that walks through the cbQosServicePolicy
, cbQosObjects
, cbQosPolicyMapCfg
and cbQosClassMapCfg
tables and prints the index values you need.
This script traverses the Class-based QoS MIB and displays service policies and classes attached to individual interfaces. The policy index and class index values are printed next to the policy/class name to help the operator fetch the desired SNMP variable from the statistics tables of the CISCO-CLASS-BASED-QOS-MIB.
Installation
- Download the source file into flash:cbindex.tcl
- Configure alias exec cbindex tclsh flash:cbindex.tcl
- Configure persistent CBQoS indexes with the snmp mib persist cbqos (otherwise the indexes will change after the router reload).
Usage guidelines
Usage: cbindex community
Command line parameters:
- Community: SNMP community with R/O access to the CISCO-CLASS-BASED-QOS-MIB
Source code
#
# title: Displays MQC class map indexes
# name: cbindex.tcl
# desc: The script traverses the Class-based QoS MIB and
# displays service policies and classes attached to
# individual interfaces. The policy index and class
# index values are printed next to the policy/class
# name to help the operator fetch the desired SNMP
# variable from the statistics tables of the
# CISCO-CLASS-BASED-QOS-MIB.
#
proc snmpInit { oid } {
global snmpCommunity
set getResult [ snmp_getnext $snmpCommunity $oid ]
if { [ regexp {snmp error} $getResult ] } {
puts "SNMP calls with community $snmpCommunity fail"; return 0
}
if { [ regexp {oid='(.*)'} $getResult ignore nxtoid ] } {
if { [string first $oid $nxtoid] == 0 } { return 1 }
}
puts "MIB $oid not implemented in this IOS release"; return 0;
}
proc snmpGet { oid result } {
global snmpCommunity
upvar $result r
if { [info exists r] } { unset r }
set getResult [ snmp_getone $snmpCommunity $oid ]
if { [ regexp {snmp error.*text='(.*)'} $getResult ignore errtxt ] } {
error "snmpGet - $errtxt"; return 0
}
if { [ regexp {oid='(.*)'.*val='(.*)'} $getResult ignore oid result ] } {
if { ! [ string equal $result "NO_SUCH_INSTANCE_EXCEPTION" ] } {
set r(OID) $oid ;
set r(VALUE) $result ;
return 1;
}
}
return 0;
}
proc snmpGetNext { oid result } {
global snmpCommunity
upvar $result r
if { [info exists r] } { unset r }
set getResult [ snmp_getnext $snmpCommunity $oid ]
if { [ regexp {snmp error.*text='(.*)'} $getResult ignore errtxt ] } {
error "snmpGet - $errtxt"; return 0
}
if { [ regexp {oid='(.*)'.*val='(.*)'} $getResult ignore oid result ] } {
if { ! [ string equal $result "NO_SUCH_INSTANCE_EXCEPTION" ] } {
set r(OID) $oid ;
set r(VALUE) $result ;
set oidSplit [ split $oid "." ]
set r(NAME) [ lindex $oidSplit 0 ]
set r(INDEX) [ lreplace $oidSplit 0 0 ]
set r(IDXLIST) [ join $r(INDEX) "." ]
return 1;
}
}
return 0;
}
proc snmpGetInTable { oid result { parentoid "" }} {
global snmpCommunity
upvar $result r
snmpGetNext $oid r
if { ! [info exists r(OID)] } { return 0 }
if { [string equal $parentoid ""] } {
set oidSplit [ split $oid "." ]
set parentoid [lindex $oidSplit 0]
}
if { [string first $parentoid $r(OID)] != 0 } { return 0 }
return 1;
}
proc printQosClassIndex {} {
global snmpCommunity
set oid "cbQosIfIndex"
array set dirLookup { 1 in 2 out }
set cnt 0
while { [ snmpGetInTable $oid svcPolicy ] } {
if { [snmpGet "ifDescr.$svcPolicy(VALUE)" ifDescr] } {
snmpGet "cbQosPolicyDirection.$svcPolicy(INDEX)" svcDirection
snmpGetNext "cbQosConfigIndex.$svcPolicy(INDEX)" policyObject
snmpGet "cbQosPolicyMapName.$policyObject(VALUE)" policyName
puts "\n$ifDescr(VALUE) ($dirLookup($svcDirection(VALUE))): $policyName(VALUE) ($svcPolicy(INDEX))"
set coid "cbQosObjectsType.$svcPolicy(INDEX)"
set parentoid $coid
while { [ snmpGetInTable $coid svcClass $parentoid ] } {
if { $svcClass(VALUE) == 2 } {
snmpGet "cbQosConfigIndex.$svcClass(IDXLIST)" svcClassConfig
snmpGet "cbQosCMName.$svcClassConfig(VALUE)" svcClassName
puts " $svcClassName(VALUE) $svcClass(IDXLIST)"
}
set coid $svcClass(OID)
}
} else { error "Cannot get interface name for service policy $svcPolicy(VALUE)" }
set oid $svcPolicy(OID)
}
}
set snmpCommunity [lindex $argv 0]
if { [string equal $snmpCommunity ""] } { set snmpCommunity "public" }
if { ! [ snmpInit "cbQosObjectsType" ] } return
printQosClassIndex
Sample usage scenario
The following QoS classes and policies have been configured on the router:
class-map match-all Mail
match protocol smtp
!
class-map match-all Web
match protocol http
!
class-map match-all SecureWeb
match protocol secure-http
!
class-map match-any Surfing
match class-map Web
match class-map SecureWeb
!
class-map match-all Files
match protocol ftp
!
policy-map Internet
class Web
bandwidth 128
class SecureWeb
priority 64
class Mail
bandwidth 32
!
policy-map MailOrFtp
class Mail
set ip precedence 0
class Files
set ip precedence 0
class Surfing
police 16000
class class-default
police cir 8000
exceed-action drop
!
interface Serial1/0
service-policy input MailOrFtp
service-policy output Internet
!
interface Serial1/1
service-policy output MailOrFtp
The cbindex script reported the following SNMP indexes:
c7200#cbindex Test
Serial1/0 (in): MailOrFtp (48)
Web 48.383777
Surfing 48.1970017
Mail 48.4297921
Files 48.13110129
class-default 48.14779377
SecureWeb 48.15077857
Serial1/0 (out): Internet (50)
Mail 50.10516033
Web 50.14007809
SecureWeb 50.14520625
class-default 50.15008753
Serial1/1 (out): MailOrFtp (66)
Web 66.383777
Surfing 66.1584993
Files 66.4236097
Mail 66.11615889
SecureWeb 66.15077857
class-default 66.15082481
Based on these indexes, you could monitor the bit rate of the Web class in outbound policy configured on Serial 1/1 with SNMP variable cbQosCMPrePolicyBitRate.66.383777
.
c7200#tclsh
c7200(tcl)#snmp_getone Test cbQosCMPrePolicyBitRate.66.383777
{<obj oid='cbQosCMPrePolicyBitRate.66.383777' val='0'/>}
Certifications: a new barrier to entry
Recent blog posts indicate that, in at least some market segments, IT certifications are becoming a new barrier to entry: companies require a specific set of certifications in their job offerings and use those requirements to filter the candidates who are invited to the initial interview. Obviously, IT vendors pushing the certifications are getting some real traction. On the other hand, anecdotal evidence indicates that certification holders are sometimes able to memorize vast amounts of information without being able to put it to use (I don’t want to imply that they used other, less honest methods).
NAT translation logging
The ip nat log translations syslog command starts NAT logging: every NAT translation created on the router is logged in syslog (which can be sent to console, syslog host or internal buffer). You could use this command as a poor man’s reporting tool if you have to monitor the address translations on your edge routers (for example, due to security policy or auditing requirements). Obviously you should configure the no logging console first in a production environment; otherwise your router will hang a few moments after you’ve enabled NAT logging.
Online session poll results
Update interval for IOS MIB counters?
I'm trying to implement an EEM applet that would detect traffic rate change using CISCO-CLASS-BASED-QOS-MIB. Everything would work perfectly ... if only IOS wouldn't update the MIB counters approximately every 10 seconds, not in real-time. Is anyone aware of a configuration command that would force the router to update these counters any faster?
Random “Scenic Route Certification” thoughts
The “Sometimes the path is more important than the destination” post has generated numerous highly interesting comments. I already planned to write about some of the issues raised by the readers (certification grind mill) or wrote about others (knowledge or recipes), so I’ll skip those and focus on the other interesting bits-and-pieces (but please make sure you read the original post first).
Should VTP be disabled by default?
One of my readers sent me a question that triggered one of my old grudges:
In my experience, when you first add a new switch (having a NULL domain) on an existing VTP Domain, it inherits the domain name, regardless of it being a VTP Server. I was wondering if this is a feature (i.e. has proved to be a solution in most cases) or a bug (i.e. has proved to cause problems in most cases). I know it's proved to be the latter for us!
In my personal opinion Cisco at one point in time wanted too much plug-and-play and someone had a great idea that you can just plug another switch into your network and it would autoconfigure itself. We've been suffering because of that "insight" ever since (and the CCIE written test has material for a few more interesting questions :).
I strongly believe that VTP should be turned off by default and should generate a warning before being enabled, but it will probably not happen. What do you think?
Disclaimer: I am not a switching person and have no idea about anything below or above layer 3.
I’m Too Old … I Prefer CLI over GUI
I was delighted when I got access to Cisco’s Application Control Engine (ACE) XML Gateway/Web Application Firewall (WAF) box. This box is the perfect intersection of three fields that really interest me: networking, security and Web programming. To my huge disappointment, though, all the real configuration can only be done through the Web interface. I understand that casual users of a device prefer a graphical user interface (GUI) over text commands (and Generation Z has never seen a terminal window, DOS prompt or, God forbid, an actual terminal), but you can achieve so much more with a simple text-based configuration approach:
When Would an MPLS LSR Have Untagged Output Label?
This is a nice MPLS question I’ve received from one of the readers:
I have understood the Penultimate Hop Popping (PHP) process, but I don’t understand when a router would use UNTAGGED instead of POP TAG?
Instead of answering the question directly, let's walk through a series of simple Q&A pairs that will help you understand the whole process (remember: knowledge, not recipes!).
Sometimes the path is more important than the destination ...
I received an interesting comment on one of my knowledge/certification-related posts:
I used to think that certifications were a useful indicator of knowledge or at least initiative, but I’m changing my mind. [...] I feel like I’ve gotten a lot out of studying for certifications, especially CCIE, but I’m starting to wonder if that’s the exception.
I guess a lot of prospective internetworking engineers are thinking along the same lines, so here’s my personal perspective on this issue.
This is why I don’t trust “independent experts”
The Network World recently published a story describing the results of an independent security product testing lab, where they’ve discovered (surprise, surprise) that adding security features to Cisco routers “presents a tremendous bottleneck” and “can turn a 60G router into a 5G one or even a 100M bit/sec device”.
The test results haven’t been published yet; I’ve got all the quotes from the NW story, so they might be the result of an ambitious middleware.
We don’t need “independent experts” for that. Anyone who has ever configured VPNs in a high-speed environment can tell you how to kill the performance. The basics are always the same: make sure the dedicated silicon can’t handle the job, so the packets have to be passed to the CPU. Here are a few ideas:
Stuffing the polls: the adventures of a convoluted mind
You might remember that the last polls I did using Blogger all resulted in every option having exactly the same number of votes. At that time, I've blamed Google ... and I have to apologize. It was obviously someone who has nothing better to do in his life. The log files I've collected indicate he's coming from Poland and I would appreciate if my Polish readers could help me persuade this troubled individual that he should spend his time doing something else (details in the rest of the post).
An offer you should not refuse
Online sessions in December 2008: please vote!
The post describing my ideas about interactive online sessions resulted in a few comments and several off-line suggestions. Unfortunately most of the suggestions you’ve made in the comments are too generic. Remember, I was talking about 30-60 minute sessions and some suggestions would easily fill a week’s worth of training at the level of detail I’m aiming at. Running high-level introductory sessions is not my idea of fun; you could get as many of them as you want at Networkers.
Several suggestions are still “in the pipeline”: I have to envision how to structure them to make them manageable. In the meantime, the rest of the post lists the topics we can definitely cover. Please vote on them, the most popular one will be featured in December session.
How should I cover ACE XML Gateway and Web Application Firewall?
I was delighted when I got access to Cisco's ACE XML Gateway/Web Application Firewall (WAF) box. This box is the perfect intersection of three fields I'm really interested in: networking, security and web programming, so I'll work with it quite a lot in the future and post interesting tips and tricks about its usage.
As this blog is currently focused exclusive on Cisco IOS, I'm wondering how to cover these new products. I won't create another blog; it simply doesn't make sense to build another blog from the ground up, but there are a few other options. Please help me select the best one by voting in the poll.