Tuesday, September 9, 2014

cbQosCMDropPkt demystified

It is very difficult to get stats on QOS drops from a Cisco router via snmp. There are multiple nested OIDs that eventually will get you the proper index and class-map. But following the bread crumb trail of OIDs is not straightforward. Sure it is documented by Cisco, but the trail is very confusing

My project required that I grab the QOS drops from the different class-maps on multiple routers and then feed them into a Splunk dashboard.  Scripting the multiple snmpwalks and outputting to CSV for ingestion by Splunk was the best way I had at my disposal.

Introducing get_qos-v3.sh

Usage : get_qos-v3.sh Customer Host_IP Host_Name Priv_Proto(DES/AES)

> get_qos-v3.sh Cust1 10.10.10.4 USA-Winslow "DES"

This script will output the following:

> cat /nsm/snmp/customer/Cust1/Cust1-10.10.10.4-qos.log

07-03-2014 17:00:01,Cust1,10.10.10.4,Winslow,class-default,sla,0
07-03-2014 17:00:01,Cust1,10.10.10.4,Winslow,class-default,class-default,0
07-03-2014 17:00:01,Cust1,10.10.10.4,Winslow,class-default,control,0
07-03-2014 17:00:01,Cust1,10.10.10.4,Winslow,class-default,media-ports,25
07-03-2014 17:00:01,Cust1,10.10.10.4,Winslow,MAP-QoSParentPolicy,class-default,25

My requirements dictated that I had customer separation as well as individual sites listed separately. Remove them if you dont need! (Or ask me to edit them out of the code)

Before you run the script you will need to edit the top part of the script to match your SNMPv3 settings, and log file locations. User, auth_passwd, priv_passwd and log_file are the only variables you should need to set. Please note that user and auth_passwd need the single (') quotes around them, while priv_passwd does not.. It was extremely frustrating troubleshooting those quotes.

This script assumes SNMPv3. If you need SNMPv2 functionality, write me and we can work up a new command line.

> cat get_qos-v3.sh 
#/bin/sh

# http://www.activexperts.com/admin/mib/Cisco/CISCO-CLASS-BASED-QOS-MIB/
# ftp://ftp.cisco.com/pub/mibs/oid/CISCO-CLASS-BASED-QOS-MIB.oid

if [ "$2x" = "x" ];
        then
        echo "Usage : $0 Customer Host_IP Host_Name Priv_Proto(DES/AES)"
        echo " "
        exit 1
fi

customer=$1
host=$2
host_name=$3
version=3
#add user here - keep the quotes
user='SNMPv3 user'
auth_mode=authPriv
auth_proto=SHA
#add auth_password - keep the quotes
auth_passwd='auth_password'
priv_proto=$4
#add priv_password here - no quotes this time
priv_passwd=priv_password 
mibs_dir=/usr/share/mibs/
cmd_variables="-v $version -M $mibs_dir -m ALL -u $user -l $auth_mode -a $auth_proto -A $auth_passwd -x $priv_proto -X $priv_passwd " 
#change log location - keep quotes
log_file="/nsm/snmp/customer/$customer/$customer-$host-qos.log"

##
#Should not have to edit below this line!!
##

#Save Field Seperator
OldFS=$IFS

# Get cbQosCMDropPkt with snmpwalk
OID=1.3.6.1.4.1.9.9.166.1.15.1.1.13
timestamp=$(date +"%m-%d-%Y %T")
cbQosCMDropPkt_WALK=$(snmpwalk $cmd_variables $host $OID)

#New Field seperator to parse the SNMPWALK
IFS=$'\n'

#For each line in cbQosCMDropPkt_WALK determine index and QOS drops
i=1
for I in $cbQosCMDropPkt_WALK;
        do
cbQosCMDropPkt_index=`echo $I | awk 'BEGIN {FS="."} {print $16}' | awk 'BEGIN {FS="="} {print $1}'`
CM_parent_index=`echo $I | awk 'BEGIN {FS="."} {print $15}' | awk 'BEGIN {FS="="} {print $1}'`
cbQosCMDropPkt=`echo $I  | awk '{print $4}'`

#Set Field seperator back to original
IFS=$OldFS

### Get class-map name
#Match up the index from cbQosCMDropPkt to cbQosConfigIndex
   OID="1.3.6.1.4.1.9.9.166.1.5.1.1.2.$CM_parent_index.$cbQosCMDropPkt_index"
   cbQosConfigIndex=`snmpget $cmd_variables $host $OID | cut -d" " -f4`

   OID="1.3.6.1.4.1.9.9.166.1.7.1.1.1.$cbQosConfigIndex"
   cbQosCMName_classmap=`snmpget $cmd_variables $host $OID | sed 's/\"//g' | awk '{print $4}'`
### 

#Clear variables
cbQosParentObjectsIndex1=
cbQosParentObjectsIndex2=
cbQosConfigIndex2=
cbQosCMName_parent=

#What site does this class-map belong too (double query to cbQosParentObjectsIndex)
OID="1.3.6.1.4.1.9.9.166.1.5.1.1.4.$CM_parent_index.$cbQosCMDropPkt_index"
cbQosParentObjectsIndex1=`snmpget $cmd_variables $host $OID |awk '{print $4}'`

if [ $cbQosParentObjectsIndex1 -ne $CM_parent_index ]; then

   OID="1.3.6.1.4.1.9.9.166.1.5.1.1.4.$CM_parent_index.$cbQosParentObjectsIndex1"
   cbQosParentObjectsIndex2=`snmpget $cmd_variables $host $OID |awk '{print $4}'`

   OID="1.3.6.1.4.1.9.9.166.1.5.1.1.2.$CM_parent_index.$cbQosParentObjectsIndex2"
   cbQosConfigIndex2=`snmpget $cmd_variables $host $OID |awk '{print $4}'`

   OID="1.3.6.1.4.1.9.9.166.1.7.1.1.1.$cbQosConfigIndex2"
   cbQosCMName_parent=`snmpget $cmd_variables $host $OID |sed 's/\"//g' | awk '{print $4}'`

else

   OID="1.3.6.1.4.1.9.9.166.1.5.1.1.2.$CM_parent_index.$cbQosParentObjectsIndex1"
   cbQosParentObjectsIndex2=`snmpget $cmd_variables $host $OID |awk '{print $4}'`

   OID="1.3.6.1.4.1.9.9.166.1.6.1.1.1.$cbQosParentObjectsIndex2"
   cbQosCMName_parent=`snmpget $cmd_variables $host $OID | sed 's/\"//g' | awk '{print $4}'`

fi

        echo $timestamp,$customer,$host,$host_name,$cbQosCMName_parent,$cbQosCMName_classmap,$cbQosCMDropPkt >> $log_file

 i=`echo $i+1|bc`
done