Exploring the SNMP-MIB for Class-based QoS

Discover the OIDs representing the counter-values of all active traffic-classes

Ciscos „SNMP Object Navigator“ (http://mibs.cloudapps.cisco.com/ITDIT/MIBS/servlet/index) is our friend to get the base-OID when you know the name of the MIB:

  • Object-NAME <=> Object-ID (OID)
  • „cbQosCMStatsEntry“ <=> „1.3.6.1.4.1.9.9.166.1.15.1.1“

Each object is a set of all counters from „show policy-map interface“-command, the Object Navigator documents the ID of these counters, too.
„Exploring the SNMP-MIB for Class-based QoS“ weiterlesen

Refresher: RMON @ Cisco IOS

RMON Refresher
Think about this given Router-Configuration:

class-map match-all CM_VOIP_CTRL
 match dscp af31
class-map match-all CM_VOIP_RTP
 match dscp ef

policy-map PM_OUT
 class CM_VOIP_RTP
  priority percent 10
 class CM_VOIP_CTRL
  bandwidth percent 1
 class class-default
  fair-queue
!
interface GigabitEthernet1
 ip address 192.168.2.72 255.255.255.0
 service-policy output PM_OUT

Three Queues at interface Gig1:

  • CM_VOIP_RTP
  • CM_VOIP_CTRL
  • class-default

with per-Queue-Statistics:

  • Packet counters
  • Drop-counters
  • etc.

In these first examples, i don’t want to wait for queue-drops, i’ll just generate DSCP=EF-Traffic by the ping-command and watch the Queue-Packet-Counters, not Drops.
Configure RMON Alarms and Events
I’ll add two RMON-Events

rmon event 10 log owner RMONevent
rmon event 11 log owner RMONevent

event #10 = rising-threshold – in my example: >1 Packet has been dropped forwarded
event #11 = the falling-threshold – no packets have been…

Than, instruct the Router to have a look at a QoS-counter:

rmon alarm 10001 enterprises.9.9.166.1.15.1.1.2.18.65536 300 delta rising-threshold 1 11 falling-threshold 0 10 owner RMONevent

In the upcoming post I’ll discover the RMON-MIB to illustrate where the „enterprise.9….65536“-Parameter comes from.

This alarm #10001 monitors:

  • the value the QoS-counter with OID „enterprises.9.9.166.1.15.1.1.2.18.65536“ (Pkt-Counter of the RTP-Queue).
  • every 300s
  • watch for delta-values (not for absolute counters which might be interesting when monitoring temperatures, fan-speed etc…)
  • define a hysteresis:
    • rising: if the last counter-delta „was <1" and "is now >=1″ – it raises event#11.
    • falling: if the last counter-delta „was >=1“ and „is now <1" - it raises event#10.

Both events instruct the router to generate a syslog-message.
In production event 10 will be configured without the „log“-option [to do nothing]. This config is for demonstration purpose.

Forward some Traffic

Generate some Traffic (TOS 184 = DSCP 46 = Expedited Forwarding (EF).

IOS-RTR#ping 192.168.2.1 tos 184
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.2.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/5 ms

So – the Queue wasn’t used before:

  • the old-counter has been „0“
  • now 5 Packets have been forwarded

This delta-counter „5“ has exceeded rising-threshold „1“:

  • event#11 should be raised.

When?

  • we’ll have to wait between 0..300s for the cyclic 300s-alarm-interval to fire
IOS-RTR#
*Nov 20 14:54:39.015: %RMON-5-RISINGTRAP: Rising threshold has been crossed because the value of cbQosCMStatsEntry.2.18.65536 exceeded the rising-threshold value 1

The current counter is „5“:

  • whithout rtp-data, the next delta-counter will be 0.

Wait for the next 300s interval:

  • the falling-event#10 should get raised.
IOS-RTR#
*Nov 20 14:59:38.837: %RMON-5-FALLINGTRAP: Falling threshold has been crossed because the value of cbQosCMStatsEntry.2.18.65536 has fallen below the falling-threshold value 0

Works, perfect!

Linux: SNMP with Python

Background: I plan to design and implement a controller-based QoS-Solution with distributed control-plane using SNMP and RMON.

How to send SNMP-Requests in Python?

Why Python? It’s an arbitrary decision, every programming language might be sufficient. For the moment, I prefer Python for new projects.

I decided to try Easy-SNMP, since good performance and a nice python-programming-interface seem to be killer-features for me.

EasySNMP homepage
EasySNMP documentation

A development environment

  1. clone an ubuntu-server VM

https://allones.de/2017/11/17/linux-quick-and-…ab-vm-deployment/

  1. install net-snmp

sudo apt-get install libsnmp-dev snmp-mibs-downloader

  1. install gcc, python

sudo apt-get install gcc python-dev python-pip

  1. install EasySNMP

pip install easysnmp

Enable SNMP on a Router
Never ever enable SNMP-Access for everybody, don’t even think about it.
Use an ACL permitting only the SNMP-Manager.

ip access-list standard ACL_SNMP
    permit host 192.168.2.89

snmp-server community READ ro ACL_SNMP

! just as an example System-Variable
snmp-server location allones.de

Access the Router via SNMP
The router’s LAN-IP is 192.168.2.72.

I like the „Session“-Interface:

user@snmp-server:~$ python
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from easysnmp import Session
>>>
>>> session = Session(hostname='192.168.2.72', community='READ', version=2)

Be aware to poll the Object-Instance, not the Object-Tree-Position.
Wrong

>>> location = session.get('sysLocation')
>>> print location
<SNMPVariable value='NOSUCHINSTANCE' (oid='sysLocation', oid_index='', snmp_type='NOSUCHINSTANCE')>

Correct: Specify an Instance-ID

>>>
>>> location = session.get('sysLocation.0')
>>> print location
<SNMPVariable value='allones.de' (oid='sysLocation', oid_index='0', snmp_type='OCTETSTR')>

Works!

How to access the return-value?
How to verify the Datatype?

I’ve been using the Cisco-developed TCL-Interface for years, the „snmp_getone“-command there, where you had to parse the return-value (a string similar to the „location“-Variable above) applying regular expressions… Weird.

Just remembering the blog post, which motivated me to learn TCL… Ten years old, how time flies!
Read: „SNMP with TCL“ by Ivan Pepelnjak

Might this be easy with EasySNMP?

>>> print location.value
allones.de

>>> print location.oid
sysLocation
>>> print location.oid_index
0

>>> print location.snmp_type
OCTETSTR

Isn’t EasySNMP beautiful!? 🙂

Linux: Quick and Clean Lab-VM Deployment

I often need for quick tests a clean Linux Server, a VM nowadays.

I decided to save DRAM in my virtualization host and to:

  • not use a GUI
  • SSH with standard text-editor are quite fine for me.

Ubuntu 16.04 seems to be a good choice to start with.

  1. Apply Updates,

sudo apt-get update && sudo apt-get upgrade -y

  1. install a text-editor //I like joe since it remembers me of turbo-pascal/wordstar 😉

sudo apt-get install joe

  1. change the hostname of the server-vm
sudo joe /etc/hostname
sudo joe /etc/hosts
  1. add a reliable (static) IP-Address
sudo joe /etc/network/interfaces
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto ens160
iface ens160 inet static
address 192.168.2.89
netmask 255.255.255.0
gateway 192.168.2.1
dns-nameservers 192.168.2.1
dns-search lab.local
  1. reboot the VM

There are other possibilities, but just ifdown/ifup won’t stop the dhcpd-client – the easiest way [but uncoolest, who cares?] is to reboot the VM, takes half a second…

sudo reboot

 

Todo: Create an UCSD-Workflow for this

Todo: Fix the buggy „always 1“ section-numbering