Categories

CUC (6) CUCM (26) Jabber (6) Python (2) Routing (2) Solarwinds Orion NPM (4) switching (1) Video (6) voice (2)

Monday, 21 August 2017

using SNMP to monitor class maps / interface policies as well as some solarwinds



Sometimes it is just plain useful to  get some insight into the traffic classes that you use on some police map of, yes, some interface. Many organisation will have some sort of net flow tool deployed in their network, but that does not really give you any details on bit rates and drop rates that take place on an interface, in times of congestion. Sure Cisco prime can quantify QoS, but using snmp pollers is much cheaper.  The trick is to find the right OID to poll. So let me get stuck right into it.


STEP 1:

From your Cisco device's, CLI issue the following:

EXECUTE:           show snmp mib ifmib ifindex

GigabitEthernet0/1.100: Ifindex = 14
GigabitEthernet0/1: Ifindex = 3
GigabitEthernet0/1.10: Ifindex = 20
GigabitEthernet0/1.9: Ifindex = 19
Backplane-GigabitEthernet0/3: Ifindex = 4
GigabitEthernet0/1.7: Ifindex = 17
Async0/0/3: Ifindex = 9
Async0/0/1: Ifindex = 7
GigabitEthernet0/1.5: Ifindex = 15
GigabitEthernet0/1.3: Ifindex = 13
Loopback0: Ifindex = 10
Embedded-Service-Engine0/0: Ifindex = 1
Null0: Ifindex = 5
GigabitEthernet0/0: Ifindex = 2    <-------this is the interface we are interested in
GigabitEthernet0/1.11: Ifindex = 11
GigabitEthernet0/1.8: Ifindex = 18
GigabitEthernet0/1.6: Ifindex = 16
Async0/0/2: Ifindex = 8
Async0/0/0: Ifindex = 6
GigabitEthernet0/1.2: Ifindex = 12



STEP 2:

Get the cbQosIfIndex (OID 1.3.6.1.4.1.9.9.166.1.1.1.1.4) for the ifindex you retrieved in Step 1 (ifindex=2 in this case).

EXECUTE: snmp walk: <1.3.6.1.4.1.9.9.166.1.1.1.1.4>

result:

.1.3.6.1.4.1.9.9.166.1.1.1.1.4.34 = INTEGER: 2
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.176 = INTEGER: 11
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.192 = INTEGER: 12
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.208 = INTEGER: 13
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.224 = INTEGER: 14
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.240 = INTEGER: 15
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.256 = INTEGER: 16
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.272 = INTEGER: 17
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.288 = INTEGER: 18
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.304 = INTEGER: 19
.1.3.6.1.4.1.9.9.166.1.1.1.1.4.320 = INTEGER: 20

The cbQosPolicyIndex (OID 1.3.6.1.4.1.9.9.166.1.1.1.1.1) value returned, in this example, is 34

This means that, on interface Gi0/0 (Integer=2)  the cbQosPolicyIndex  = 34

STEP 3:

Use the MIB Object cbQosCMName (1.3.6.1.4.1.9.9.166.1.7.1.1.1) to get the names of class-maps configured on the router.

Now, query the Class map configuration as follows:

snmp walk:  <.1.3.6.1.4.1.9.9.166.1.7.1.1.1>

.1.3.6.1.4.1.9.9.166.1.7.1.1.1.1593 = STRING: "class-default"
.1.3.6.1.4.1.9.9.166.1.7.1.1.1.1434177 = STRING: "cm-prec-2-out"
.1.3.6.1.4.1.9.9.166.1.7.1.1.1.2482753 = STRING: "cm-prec-3-out"
.1.3.6.1.4.1.9.9.166.1.7.1.1.1.8774209 = STRING: "cm-prec-1-out"
.1.3.6.1.4.1.9.9.166.1.7.1.1.1.12472097 = STRING: "cm-prec-4-5-out"
.1.3.6.1.4.1.9.9.166.1.7.1.1.1.14191553 = STRING: "cm-prec-2-in"
.1.3.6.1.4.1.9.9.166.1.7.1.1.1.14257089 = STRING: "cm-prec-3-in"
.1.3.6.1.4.1.9.9.166.1.7.1.1.1.14322625 = STRING: "cm-prec-4-in"
.1.3.6.1.4.1.9.9.166.1.7.1.1.1.14650305 = STRING: "cm-prec-1-in"

Suppose, we are interested in the QosConfig of "cm-prec-4-5-out". Make a note of the highlighted value 12472097, which is cbQosConfigIndex.

STEP 4:

Use cbQosConfigIndex to get the cbQosPolicyIndex (1.3.6.1.4.1.9.9.166.1.1.1.1.1) and cbQosObjectsIndex (1.3.6.1.4.1.9.9.166.1.5.1.1.1) for individual class-maps.



STEP 5:

In order to get the Object Identifier (OID), search for the cbQosConfigIndex value obtained in Step 3 (12472097) in the output below:



EXECUTE: snmp walk: <1.3.6.1.4.1.9.9.166.1.5.1.1.2>

output:

.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.34 = GAUGE32: 14151856
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.887811 = GAUGE32: 10273235
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.2089970 = GAUGE32: 5239858
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.2196705 = GAUGE32: 12472097    <_----cm-prec-4-5-out
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.3369731 = GAUGE32: 11175747
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.4481794 = GAUGE32: 855826
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.5649682 = GAUGE32: 1594
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.6726419 = GAUGE32: 13688019
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.  = GAUGE32: 1593
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.8493601 = GAUGE32: 8774209
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.9382035 = GAUGE32: 12112579
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.9422642 = GAUGE32: 1594
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.9953299 = GAUGE32: 9357059
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.13689184 = GAUGE32: 10583344
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.14664689 = GAUGE32: 1593
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.14754018 = GAUGE32: 5252402
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.14779570 = GAUGE32: 14230322
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.14785057 = GAUGE32: 2482753
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.15141170 = GAUGE32: 5276466
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.15833633 = GAUGE32: 1434177 <--cm-prec-2-out
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.34.15863043 = GAUGE32: 14812867
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.176.176 = GAUGE32: 1298848
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.176.2463202 = GAUGE32: 15444834
.1.3.6.1.4.1.9.9.166.1.5.1.1.2.176.2741826 = GAUGE32: 6784962

in the output above  The highlighted values are: cbQosConfigIndex (12472097), cbQosPolicyIndex (34), and cbQosObjectsIndex (2196705).


STEP 7:

Now let us pull some relevant information of the router; let find out how much traffic is in in the pm-prec-4-5--out


Router # show policy-map interface GigabitEthernet0/0

EXECUTE: snmp walk <1.3.6.1.4.1.9.9.166.1.15.1.1.11.34>  
.1.3.6.1.4.1.9.9.166.1.15.1.1.11.34.2196705 = GAUGE32: 0
all policy map classes:
.1.3.6.1.4.1.9.9.166.1.15.1.1.11.34.2196705 = GAUGE32: 0                    <-----4-5 out
.1.3.6.1.4.1.9.9.166.1.15.1.1.11.34.7871617 = GAUGE32: 119000                <-------------default  bps
.1.3.6.1.4.1.9.9.166.1.15.1.1.11.34.8493601 = GAUGE32: 0                     <-----1 out
.1.3.6.1.4.1.9.9.166.1.15.1.1.11.34.14664689 = GAUGE32: 163000
.1.3.6.1.4.1.9.9.166.1.15.1.1.11.34.14785057 = GAUGE32: 3000                <----3 out
.1.3.6.1.4.1.9.9.166.1.15.1.1.11.34.15833633 = GAUGE32: 29000               <-----2 out

x
Time to get into some practicalities. Once you have obtained the 3 values:
cbQosConfigIndex (12472097) 
cbQosPolicyIndex (34)
cbQosObjectsIndex (2196705)
To poll data from the Policy-map 
(in correlation with QosObjectsType=classmap)

Use the base: 1.3.6.1.4.1.9.9.166.1.15 , many options are available:
+-- -R-- Counter   cbQosCMPrePolicyPktOverflow(1)
+-- -R-- Counter   cbQosCMPrePolicyPkt(2)
+-- -R-- Counter64 cbQosCMPrePolicyPkt64(3)
+-- -R-- Counter   cbQosCMPrePolicyByteOverflow(4)
+-- -R-- Counter   cbQosCMPrePolicyByte(5)
+-- -R-- Counter64 cbQosCMPrePolicyByte64(6)
+-- -R-- Gauge     cbQosCMPrePolicyBitRate(7)
+-- -R-- Counter   cbQosCMPostPolicyByteOverflow(8)
+-- -R-- Counter   cbQosCMPostPolicyByte(9)
+-- -R-- Counter64 cbQosCMPostPolicyByte64(10)
+-- -R-- Gauge     cbQosCMPostPolicyBitRate(11)
+-- -R-- Counter   cbQosCMDropPktOverflow(12)
+-- -R-- Counter   cbQosCMDropPkt(13)
+-- -R-- Counter64 cbQosCMDropPkt64(14)
+-- -R-- Counter   cbQosCMDropByteOverflow(15)
+-- -R-- Counter   cbQosCMDropByte(16)
+-- -R-- Counter64 cbQosCMDropByte64(17)
+-- -R-- Gauge     cbQosCMDropBitRate(18)
+-- -R-- Counter   cbQosCMNoBufDropPktOverflow(19)
-- -R-- Counter   cbQosCMNoBufDropPkt(20)
-- -R-- Counter64 cbQosCMNoBufDropPkt64(21)

For example, cbQosCMPostPolicyBitRate  (1.3.6.1.4.1.9.9.166.1.15.1.1.11), 
polls the bit rate of the traffic after QoS policy execution, 
derived from 11 in the table above, so drop rate would be:
1.3.6.1.4.1.9.9.166.1.15.1.1.18

Solarwinds configuration.
Solarwinds NPM has the ability to poll certain OIDs through customized pollers.
Go to universal device pollers:

As you can see we are polling 1.3.6.1.4.1.9.9.166.1.15.1.1.11, to find the post policy bit rate. The oid will actually return a table will the traffic rates for all class maps on all applied interfaces.
The post policy bit rate poller can be summarised as per above. Now lets have a closer look in solarwinds npm at a device that we have assigned the poller to:

Picture above shows the dfjbit rate for a class map prec-4-5-out (yes exactly the same name as when querying 1.3.6.1.4.1.9.9.166.1.7.1.1.1 earlier on in this post). essentially the graph above depicts 1.3.6.1.4.1.9.9.166.1.15.1.1.11.18.11136785
in the graph above, go to EDIT:
<As can be seen above only 18.1136785 is graphed, which is cm-prec-4-5-out.
if you wanted to graph more class maps:
1.3.6.1.4.1.9.9.166.1.7.1.1.1.2482753 = STRING: "cm-prec-3-out"
1.3.6.1.4.1.9.9.166.1.5.1.1.2.18.11057649 = GAUGE32: 2482753
you could tick for instance: 18.11057649, in the devicepoller graph above, for cm-prec-3-out to be graphed source:https://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/119031-technote-router-00.html

Thursday, 27 July 2017

Raspberry pi Cron jobs

There really isn't much raspi specific about cron jobs but I started looking into how cron jobs work when I was trying to run a python script automatically. cron jobs can be very useful when wanting to execute looping python scripts, because the cronjob will restart your script for instance after your raspi has lost power and reboots.

Cron, is essentially a daemon, that starts up at boot.


On the raspi (and most CentOs/Linux distro's), the location of crontabs file is:   


\var\spool\cron

The crontab file is where you define all the executions that need to take place and at what time.

The crontab syntax is as per below




A crontab file has five fields for specifying day , date and time followed by the command to be run at that interval.


Commands:


crontab -e    Edit crontab file, or create one if it doesn’t already exist.
crontab -l    crontab list of cronjobs , display crontab file contents.
crontab -r    Remove your crontab file.
crontab -v    Display the last time you edited your crontab file. (This option is                        Only available on a few systems.)



so to start editing use crontab -e which will open the unedited crontab in Nano, add executions and then CONTROL+O to save, then exit 

For example:

The command line below in a crontab file deletes all files in a temp folder at 18:30 every day:

30     18     *     *     *         rm /home/trespasser/tmp/*

If you wanted to log the execution of the above crontab execution, point it to create a log file as per below:

30     18     *     *     *         rm /home/trespasser/tmp/* > /home/trespasser/cronlogs/clean_tmp_dir.log


Frequency/repetition.

You can edit crontab to execute a certain line at a certain interval, say every 5 minutes; all the time. In order to do that, and let me keep the previous python script execution as our example:

*/5 * * * * sudo python3 /home/pi/pythonscripts/dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.log

Here, the line is executed every 5 minutes, disregarding time of day.


You might want to run a python script in the back ground to run in a certain frequency. Now you could loop the script itself, but that would mean you would need to constantly have a session open to the raspi or start it up manually each time it lost power or got recycled, unless you run it with no hangup (I will discuss this in a separate post).

Of course none of this is any good if the cron daemon is not running. To verify if it is:

pi@raspberrypi:/var/log$ service cron status

cron is running.


Now what you have to remember, is that the HOME directory from which crontab works is /home.  This means if you want to run a script for instance from any other directory then /home so one of its subdirectories for instance, it is wise to do a cd line in crontab first to move to the directory from which to execute the script.

Now, before you rely on your crontab's execution, it is good to mock up the command line that you added to the crontab file from the command prompt to see if you did not make any syntax mistakes.

Multiple command lines to do the same execution, in general, is not a good idea as multiple lines do no reference each other. For example:

a crontab with:

01 15 * * * cd /home/pi/pythonscripts
01  15 * * *sudo python3 dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.log)

would not work as the first line, containing cd /home/pi/pythonscript does not actuall effect the excecution of the second crontab line. So it is better to merge these two commands (lines) into one crontab statement, merging them with &&


cd /home/pi/pythonscripts && sudo python3 dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.lo

alternatively point the execution of your python script, to its absolute path, as per below:



sudo python3 /home/pi/pythonscripts/dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.lo


One thing you have to make sure of is that your machine has the correct time and timezone, and the raspberry pi, you might need to run raspi-config (internalization options). 

If you want to trouble shoot the execution of Crontab, possibly because i, writes it's execution result to syslog, which can be found at : 

/var/log/syslog


for example:

ul 28 16:19:01 raspberrypi /usr/sbin/cron[1935]: (pi) RELOAD (crontabs/pi)
Jul 28 16:25:01 raspberrypi /USR/SBIN/CRON[2697]: (pi) CMD (cd /home/pi/pythonscripts )
Jul 28 16:25:01 raspberrypi /USR/SBIN/CRON[2698]: (pi) CMD (sudo python3 dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.log)

Jul 28 16:25:02 raspberrypi /USR/SBIN/CRON[2695]: (CRON) info (No MTA installed, discarding output)

checking your syslog, will also confirm the time your line in the crontab was executed.


Namaste! Folks

Monday, 10 July 2017

Python object indexing and slicing; lists, strings and tuples.

Wonder where this is leading to, anyway. Let's kick off.


Because lists are sequences, indexing and slicing work the same way for lists as they do for strings (which are essentially a definition of ordered collections of characters, so accessible by position). The key to slicing and indexing is the offset. Python starts at 0 and ends at on less than the length of the string or list. This is important, because the latest character in a string or object in a list is not addressable. You can also use negative offsets, think of this as counting backward from the end. The picture below shows how offsets can be used.





Consider the following string and let's pull the first and last character of that string:

>>> S="flyffy bunny"
>>> S[0],S[-1]
('f', 'y')
>>> 

and slicing (extracting a section):

>>> S[-5:-1]           #negative offset slicing, count from right
'bunn'
>>> S[0:3]
'fly'

another example:

>>> S[1:-1]
'lyffy bunn'

>>> S[0:-1]

'flyffy bunn'

or just apply it straight:

>>> 'flyffy bunny'[1:3]

'ly'

>>> 'flyffy bunny'[slice(1,30)]
'lyffy bunny'


Now consider the following list, containing 3 objects:

>>> L = ['spam', 'Spam', 'SPAM!']

>>> L[2]                #offset starts at 0, which is the object on the left 

'SPAM!'


>>> L[2]                  #Negative; count offset from the right
>>> L[1:]                 # Slicing fetches sections (1st offset from left)

['Spam', 'SPAM!']




Slices can be used to extract columns of data, and to prefix or remove leading and trailing text.


In short:


• S[1:3] fetches items at offsets 1 up to but not including 3.
• S[1:] fetches items at offset 1 through the end (the sequence length).
• S[:3] fetches items at offset 0 up to but not including 3.
• S[:−1] fetches items at offset 0 up to but not including the last item.
• S[:] fetches items at offsets 0 through the end—making a top-level copy of S.

Extended slicing:

As of python 2.3, splice expressions allow  a third, optional index:  the step/stride.  

>>> S="123456789012345567890"
>>> S[0:10:2]

'13579'

This extended slice, takes characters between offset 0 and 10 by steps of 2, so 1 3 5 7 and 9

You can also use a negative stride.

Wednesday, 7 June 2017

Play queue announcements and recordings using Unity Connection

I haven't posted anything on Unity Connection for a while. What has happened so far?  Another joker's in the White House, crude has gone up and London is in a shit state of affairs.  Back to unity connection.  This post is about how to play a recorded message before a call gets handed over to a queue, hunt group or reception console.

Scenarios

For example, let's say you have a queue for an IT service desk and in the event of a large outage you want to play out a message notifying users of a large scale outage "we are currently suffering issues with users connecting to the internet in the Kansas City area and are working to resolve this", before the call is handed over to the queues. Or maybe you want to play out a welcome message before handing a call over to a reception console "welcome to Dead meat Inc. All our meat is guaranteed 100% dead before it lands on your plate". anyway the scenarios are endless, but you can see what I am getting at.

Nuts and bolts

These pre-recorded messages,  are nothing more than recorded greetings in a call handler, it is that simple. So let us get started.

1. Create the call handler CTI route points. For this particular exercise, you need two CTI route points.I will explain later, why you need two and not one.  So the way to do this is to add a CTI RP in CUCM and do a call forward all to your voicemail pilot point.For this example I will use 900617 and 18 for the two call handlers.
2. Add the first call handler, I have called it IT outage notifications and assigned it extension 900617:

Fig 1



3. Go to CUCX and add the first forwarding rule to point the first CTI RP to the correct Call handler, point it to the call handler called "IT outage notification", made in the previous step:

  1. Fig. 2 

Make sure you set it to "go directly to greeting" (see above). This will make the call hitting the handler, go straight to the recorded message/greeting.

Also add the call forwarding condition:

Fig.3

(forwarding station=900617 which is the extension of the CTI RP).

At this stage you should be able to dial into 900617 and the Standard greeting should be played. So test this first before you proceed. If you get an announcement along the lines of "from a touch tone telephone dial any extension...blah blah", your call is not getting through to your call handler and you might be missing your forwarding rule.

4. Set the greetings in your call handler.

This is where you are actually going to define what message will be played when someone calls into your queue and what happens to the caller once the message has been played.  Go back to your call handler, called IT outage Notification (or whatever you have called it) and go to Greetings. 
Let's use the scenario where you want to use a welcome meeting all the time and then go to reception.  So this means, in your 900618 call handler, the standard greeting would need to always play.  Below is a picture of what this welcome message/standard greeting, needs to look like:

Fig. 4 

So you will need to record the standard greeting and personalize it. Don't allow caller input during the meetings and after the greeting send it to a second call handler (IT outage notification after greeting handler) and attempt transfer. I mentioned in the beginning that we needed two call handlers to play a recording before transferring the call and the reason for this is greeting "transfer rules".

There is some contradicting information on what is applied first, the playing of greetings or the application of transfer rules. And to be honest, I have had both set up work, but I prefer to use a second call handler that does not play any greetings, but only attempts the transfer to the reception or queue or wherever it needs to transfer to.  So below is a screenshot of my transfer rules for the first call handler, and is actually a combination of direct transfers and sending the call to a second call handler for transfer.

Fig. 5


The standard greeting on transfers to 33570, once the standard greeting has been played (see figure 4) , this could be your reception.  In the example above (Fig 5) the alternate greeting is sent to 900618, the second call handler.

5. set up a second call handler with a transfer rule

Now set up a second call handler in the same way as your first call handler that contains the welcome message/standard greeting

This second call handler invokes the standard greeting when receiving a call:

Fig. 6




The standard greeting of the second call handler plays nothing (by setting Callers hear Nothing, see fig. 6), it just invokes the standard greeting transfer rule, and transfer the call to 33670, as per Fig. 7


Fig. 7

if you wanted to record the greetings, it is probably easiest to use the greeting administrator, unless moving around wav files is your cuppa tea. The greeting administrator also allows you to easily turn on and off an alternative greeting on one of your call handlers. You can turn the alternate greeting on and off in case you have an extraordinary notification you want to play to your callers, before connecting the call to the queue.

I have done a separate post on how to set up greeting administrator in a separate post.

Namaste!


Sunday, 4 June 2017

Basic QoS verification



Most people would happily apply auto QoS on their Cisco kit and assume that somehow this will guarantee QoS is set up properly like a true self fulfilling prophecy. Of course, there is no such thing. I would argue that that QoS configuration is not an out of the box feature that you just turn on. QoS requires tweaking and a thorough understanding of the quality and quantity of the network traffic in your organisation. When you set it up for the first time, you will most likely not get it 100% right. Maybe you will never get any complaint about the performance of your organisation's applications, simply because you have an obscene amount of bandwidth, maybe there never is any contention on your WAN links, which would make you a pretty happy engineer. For all those, not working for a bank or an insurance company; your WAN links will be just enough to carry the business or branch's traffic, so a properly functioning QoS configuration is important. All the voice engineers reading this article, will tell you that degraded audio and video will be reported straight away by your users. This sort of degradation is almost always symptomatic. I.e. if your QoS is not set up properly your video and audio is the first to suffer.


Cisco uses its MQC (Modular Quality of service Command line interface), to implement QoS on its devices.  Yes its modular, but this is still not a mean feat to configure and verify it.  In this post I will be trying to break down the basics of MQC in an attempt to give it some structure in the way that you can verify its workings. 

MQC is essentially a way to achieve the following:

When traffic enters a router/layer3 switch or any device that needs to police traffic, it needs a way to break up the traffic and decides what priority to give it, access lists can typically do that in combination with DSCP values that have already been set (Phones and telepresence endpoint use af41 for video and ef for audio only, so you you will need to do is trust these values, but putting mls qos trust dscp statements on your access ports). All this is done on the ingress port and essentially you have now 'labelled' (through DSCP) all your interesting traffic. Everything that has not been explicitly labelled will be considered default traffic and will be the first type of traffic to be dropped if there is contention on your egress interface. So on the egress interface you will need to create class maps that match certain DSCP values and give that traffic a certain bandwidth (%). The give it a shape average containing the maximum available bandwidth, this is called a service policy. Finally this service policy is applied to your egress interfaces.

MQC can be roughly broken up into 4 distinct parts of configuration:

  1. Classify traffic using access lists.
  2. Mark traffic in accordance with access lists and or DSCP trust markings
  3. Prioritize and assign bandwidth to each class to create a service policy
  4. Apply the service policy to the interface

Verification commands:

Are my policies applied to the relevant interfaces?
Issue the following command, to find out what service policies are applied to what interfaces, keep in mind that the direction of traffic decides if the service policy is applied at all.

router#show policy-map interface brief
Service-policy output: pm-shape-queue-out
 GigabitEthernet0/0 
Service-policy input: pm-classify-in
 GigabitEthernet0/1.2 
 GigabitEthernet0/1.3 
 GigabitEthernet0/1.5 
 GigabitEthernet0/1.6 
 GigabitEthernet0/1.7 
 GigabitEthernet0/1.8 
 GigabitEthernet0/1.9 
 GigabitEthernet0/1.10 
 GigabitEthernet0/1.11 
 GigabitEthernet0/1.100 
router#


In the example above the service policy called "pm-classify-in" is applied to the router on the ingress ports on Gi0/1, this is where traffic gets marked and classed. On the egress interface Gi0/0 the traffic gets policed and queued/dropped if necessary, using "pm-shape-queue-out".

Is traffic getting dropped?
Once you have established what policy map is applied to what interface you can see its service policy. Look out for the allocated bandwidth for a particular class map and verify offered rate, drop rate and queue drops, these are typically an indication that traffic is being policed and prioritized:

router#show policy-map interface Gi0/0
 GigabitEthernet0/0 

  Service-policy output: pm-shape-queue-out

    Class-map: class-default (match-any)  
      561242536 packets, 233371823734 bytes
      5 minute offered rate 463000 bps, drop rate 0000 bps
      Match: any 
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/106307/0
      (pkts output/bytes output) 561136228/233229485989
      shape (average) cir 10000000, bc 40000, be 40000
      target shape rate 10000000

      Service-policy : pm-queue-mark-out

        queue stats for all priority classes:
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/0/0
          (pkts output/bytes output) 69567362/32277474836

        Class-map: cm-prec-4-5-out (match-any)  
          69567365 packets, 32277476457 bytes
          5 minute offered rate 228000 bps, drop rate 0000 bps
          Match:  dscp ef (46)
            104148 packets, 11066856 bytes
            5 minute rate 0 bps
          Match:  dscp af41 (34)
            69463217 packets, 32266409601 bytes
            5 minute rate 228000 bps
          Priority: 33% (3300 kbps), burst bytes 82500, b/w exceed drops: 0   (notice the PRIORITY: 33% which indicates Low latency queueing applies)
          

        Class-map: cm-prec-3-out (match-any)  
          28990699 packets, 7045511506 bytes
          5 minute offered rate 10000 bps, drop rate 0000 bps
          Match: ip precedence 3 
            28990699 packets, 7045511506 bytes
            5 minute rate 10000 bps
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/830/0
          (pkts output/bytes output) 28989869/7045236932
          bandwidth 5% (500 kbps)

        Class-map: cm-prec-2-out (match-any)  
          168340364 packets, 88941217174 bytes
          5 minute offered rate 85000 bps, drop rate 0000 bps
          Match: ip precedence 2 
            168340364 packets, 88941217174 bytes
            5 minute rate 85000 bps
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/31192/0
          (pkts output/bytes output) 168309172/88898900167
          bandwidth 27% (2700 kbps)

        Class-map: cm-prec-1-out (match-any)  
          1546262 packets, 2100799191 bytes
          5 minute offered rate 5000 bps, drop rate 0000 bps
          Match: ip precedence 1 
            1546262 packets, 2100799191 bytes
            5 minute rate 5000 bps
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/286/0
          (pkts output/bytes output) 1545976/2100399647
          bandwidth 5% (500 kbps)

        Class-map: class-default (match-any)  
          292797848 packets, 103006819352 bytes
          5 minute offered rate 112000 bps, drop rate 0000 bps
          Match: any 
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops/flowdrops) 0/73999/0/73999
          (pkts output/bytes output) 292723849/102907474407
          Fair-queue: per-flow queue limit 16 packets

Am I marking my traffic correctly?

Well, this is a bit harder to answer and you might need get wireshark out of your tool box for this and verify is certain interesting traffic has the correct DSCP vlaue once it is received by the far end (use a span port for this for instance).  You could start with looking at your ACLs that define your interesting traffic and see if their statements are getting hit. For example, consider the following access-list, defining traffic for IP precedence 1:

ip access-list extended acl-prec-1
 remark Bulk Traffic
 permit ip any any precedence priority
 permit tcp any any eq 143

 permit tcp any any eq 993


router#      sh ip access-list acl-prec-1         
Extended IP access list acl-prec-1
    10 permit ip any any precedence priority (30831037 matches)
    20 permit tcp any any eq 143 (304 matches)

    30 permit tcp any any eq 993 (52018 matches)



As you can see all the statements in ACL "acl-prec-1", have matches. If you are not seeing any matches on a certain statement, you might need to double check things like IP addresses and ports and change the ACL until it is getting matched.

Another example is an ACL that matches all packets that have DSCP value ef (IP Precedence critical):

ip access-list extended acl-prec-5

 permit ip any any precedence critical

router# sh ip access-list acl-prec-5
Extended IP access list acl-prec-5

    10 permit ip any any precedence critical (1856824595 matches)



This ACL is based on DSCP values being set by the phones and or Telepresence endpoint (that would probably set DSCP to af41), again using the  "mls qos trust DSCP" command on the access port where these endpoint are connected to.