Contents

Introduction

Prerequisites

Requirements

Components Used

Background Information

Tools used to grab the information

List of all single line command

Get only the node IDs of the LEAFs within the fabric:

Verify if there are interface resets:

Check for the Highest rated interface:

Find all STP topology changes:

Ensure if there are multicast RPF drops:

Verify if there are too many packets getting Glean:

QoS drop stats:

Interface Drops:

FCS Errors (non-stomped CRC errors)

FCS + Stomped CRC Errors

Output Buffer Drops

Output Errors

Clear all interface counters

BGP session issues:

OSPF session issues:

Primarypackets that are punted to the CPU

Check fabric-wide from apic where all a specific contract relationship is deployed

Check where an encap is already deployed and get corresponding epg

Memory Utilization of All nodes in Fabric:

Verify drops on istack (exception packets get punted)

Contract Validation

Introduction

This document describes different ways we can detect an overall issue on the fabric.

Prerequisites

Requirements

- Cisco recommends knowledge of ACI

- Basic knowledge of bash

Components Used

This document is not restricted to specific software and hardware versions.

Devices used:

- Cisco ACI running version 4.2(3)

The information in this document was created from the devices in a specific lab environment. All of the devices used in this document started with a cleared (default) configuration. If your network is live, ensure that you understand the potential impact of any command.

Background Information

Tools used to grab the information

- Sed to substitute: sed  “s/<oldword >/<new wordk>/g” g defines that it is done more than once.

- Sed to grab lines from start to end: sed “/<beginning/,/end/p>”. Combine the -n (noprint) option with the /p print flag for duplicates of the functionality of grep.

- Sed can used more than once by using ‘;’ for example: would : sed  “s/<oldword >/<new wordk>/g; s/<oldword2 >/<new wordk2>/g”

- awk -F '<field_separator>' '{print $2}' In this specific example, you split the line by the defined FIELD_SEPARATOR and print the 2nd delimited chunk. Both syntaxes do exactly the same thing.

- awk '{ print $1, $2 }' prints the first two fields of each input record, with a space between them.

- sort | uniq Reports the repeated lines. Using -c  prefix lines by the number of occurrences.

- sort -nrk <column> sorts the lines highest. -n for a numeric sort, -k for a key so we can modify the column and if you want to define lowest you can remove -r

- python -m json.tool Shows JSON in a pretty format.

List of all single line command

Get only the node IDs of the LEAFs within the fabric:

1. In a list:

APIC#acidiag fnvread | grep leaf | awk '{print $1}'

2. In a line with commas as separators:

APIC#acidiag fnvread | grep leaf | awk '{print $1}' | sed -z 's/\n/,/g;s/,$/\n/'

Verify if there are interface resets:

The information is sorted on the interfaces with highest number of resets.

APIC#moquery -c ethpm.PhysIf | egrep "dn|lastLinkStChg|resetCtr" | tr -d "\n" | sed "s/dn/\ndn/g;s/lastLinkStChg/\tlastLinkStChg/g;s/resetCtr/\tresetCtr/g" | sort -nrk 9 | more

slower option

APIC#for leaf in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo " -> leaf ID: $leaf  "; fabric $leaf  show interface  | sed -n '/net[0-9]\/[0-9]\+ is up/,/Tx pause/p'  | egrep "is up|Last link flapped|interface resets" | grep -v Dedicated | tr -d "\n" | sed "s/resets/rests\n/g" | sort -nrk 9   ; done;

Check for the Highest rated interface:

In order to find where the most traffic is received:

Query the fabric for all interfaces with output throughput over specific value (b). The value of m defines whether b is gb, mb, or kb.

To filter on gb set m to 125000000. To filter on mb set m to 125000. To filter on kb set m to 125.

APIC#bash

APIC#b=1; m=125000;b=$((b*m)); printf "%-65s %25s\n", "Node/Interface" "Bits/Second"; icurl 'http://localhost:7777/api/class/eqptEgrTotal5min.json?query-target-filter=gt(eqptEgrTotal5min.bytesRateLast,"'$b'")&order-by=eqptEgrTotal5min.bytesRateLast|desc' 2>/dev/null | python -m json.tool | egrep "dn|bytesRateLast" | sed -e 's/\s\+//g' | tr -d '\n' | sed -e 's/\"bytesRateLast\"/\n\"bytesRateLast\"/g' | sed -r '/^\s*$/d' | awk -F "\"" '{ printf "%-65s %25.2f\n", $8,$4*8}'

APIC#for leaf in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo " -> leaf ID: $leaf  "; fabric $leaf  show int | sed -n '/net[0-9]\/[0-9]\+ is up/,/Tx pause/p' | egrep -i '[0-9]+ is up|30 seconds input' | tr -d '\n' | sed 's/packets\/sec/\n/g' | sort -n -r -k 10 ; done;

Find all STP topology changes:

1. The command goes into each leaf and verifies if there are any recent topology changes and in which interfaces:

APIC#for node in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo "node ID: $node "; fabric $node  show mcp internal info vlan all |  grep -A 2 -B 4 "Last TC flush at"  | sed -z 's/\n/ /g' | sed 's/--/\n/g;s/  $/\n/' | sort -n -r -k 22  ; done;

2. The command goes into each leaf and verifies the highest count on PVRSTP changes and which interfaces are seen:

APIC#for node in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo "node ID: $node "; fabric $node  show mcp internal info vlan all |  grep -A 2 -B 4 "Last TC flush at"  | sed -z 's/\n/ /g' | sed 's/--/\n/g;s/  $/\n/' | sort -n -r -k 11 ; done;

Ensure if there are multicast RPF drops:

This needs to be for the individual leaf at the time and it verifies all the enabled pim VRF for any RPF drops:

APIC#for vrf in `show ip mroute summary vrf all | grep 'IP Multicast Routing Table for VR' | awk '{print $7}' | sed 's/"//g' `  ; do echo; echo -e "VRF  id: $vrf: \n" ; show ip mroute summary rpf-failed vrf $vrf | egrep "Source count: [1-9][0-9]*|[1-9]\.[0-9]{3}|LEAF|leaf" | sed -n '/Group.*count: [1-9][0-9]*/,/bps  [0-9]*/p' | awk '{print $1, $2}' | sed 's/,/ - SRC \/ pckt:\n/g' ; done;

Verify if there are too many packets getting Glean:

1. Fabric ARP gleans :

APIC#for leaf in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo " -> leaf ID: $leaf  "; fabric $leaf show ip arp internal event-history event | grep glean | grep "Received pkt Fabric-Glean" | awk -F 'log_collect_arp_glean;' '{print $2}' | awk -F 'info =' '{print $1}' | sort | uniq -c ; done;

2. ARP glean Received packets:

APIC#for leaf in `acidiag fnvread | grep leaf | awk '{print $1}'`; do echo; echo " -> leaf ID: $leaf  "; fabric $leaf show ip arp internal event-history event | grep "Received glean packet" | awk -F 'log_collect_arp_glean;' '{print $2}' | awk -F 'info =' '{print $1}' | sort | uniq -c ; done;

QoS drop stats:

Verify QoS received drops for the entire fabric :

APIC#moquery -c qosmIfClass -f 'qosm.IfClass.RxDropPacketsCount!="0"' | egrep "RxDropPacketsCount|dn" | awk '{print $3}' | tr -d "\n" | sed 's/level[0-9]/level\t\n/g'| sed 's/plane/plane\n/g' | awk -F 'topology/' '{print $2}'

Verify QoS transmit drops for the entire fabric :

APIC#moquery -c qosmIfClass -f 'qosm.IfClass.TxDropPacketsCount!="0"' | egrep "TxDropPacketsCount|dn" | awk '{print $3}' | tr -d "\n" | sed 's/level[0-9]/level\t\n/g'| sed 's/plane/plane\n/g' | awk -F 'topology/' '{print $2}'

Interface Drops:

FCS Errors (non-stomped CRC errors)

APIC#moquery -c rmonDot3Stats -f 'rmon.Dot3Stats.fCSErrors>="1"' | egrep "dn|fCSErrors"

FCS + Stomped CRC Errors

APIC#moquery -c rmonEtherStats -f 'rmon.EtherStats.cRCAlignErrors>="1"' | egrep "dn|cRCAlignErrors"

Output Buffer Drops

APIC#moquery -c rmonEgrCounters -f 'rmon.EgrCounters.bufferdroppkts>="1"' | egrep "dn|bufferdroppkts"

Output Errors

APIC#moquery -c rmonIfOut -f 'rmon.IfOut.errors>="1"' | egrep "dn|errors"

Clear all interface counters

Command to get a list of fabric nodes

APIC# acidiag fnvread | egrep " active" | egrep "leaf|spine" | awk '{print $1}' | sed -e 'H;${x;s/\n/,/g;s/^,//;p;};d'

101,102,103,204,205,206,301,1001,1002,2001,2002

Command to clear counters for previous list

APIC# fabric 101,102,103,204,205,206,301,1001,1002,2001,2002 clear counters interface all

BGP session issues:

In order to check if there are any BGP sessions having issues on the fabric underlay

APIC#moquery -c bgpPeerEntry -f 'bgp.PeerEntry.operSt!="established" and  bgp.PeerEntry.dn*"overlay-1"' | egrep "dn|operSt" | tr -d "\n" | sed "s/dn/\ndn/g;s/operSt/\t-\toperSt/g"

In order to check any BGP session

APIC#moquery -c bgpPeerEntry -f 'bgp.PeerEntry.operSt!="established" | egrep "dn|operSt" | tr -d "\n" | sed "s/dn/\ndn/g;s/operSt/\t-\toperSt/g"

OSPF session issues:

Identify sessions that are not on full state.

APIC#moquery -c ospfAdjEp -f 'ospf.AdjEp.operSt!="full"' | egrep "dn|peerIp" | tr -d '\n' | sed "s/dn           : topology\//\nNode : /g;s/peerIp/\tpeerIp/g;s/       //g" | sed "s/\/sys.*dom-/ VRF: /g;s/\/if-\[/ Interface : /g;s/\]\/adj-/ Adj: /g"

Identify sessions that flap constantly and sort the information on the highest count:

APIC#moquery -c ospfAdjStats -f 'ospf.AdjStats.stChgCnt!="0"' | egrep "dn|stChgCnt" | tr -d "\n" | tr -d " " | sed "s/dn:topology\//\nNode: /g;s/\/adjstatsstChgCnt:/\tADJ changes: /g;s/\/if-\[/ Interface: /g;s/\]\/adj-/ Adj /g" | sed "s/\/sys.*dom-/ VRF: /g" | sort -nrk 11

Primary packets that are punted to the CPU

Take into account: this command debugs 500 packets. For lower amount, modify the number after -c.

lEAF#tcpdump -i kpm_inb -c 500 > /tmp/cpu-dp.txt

LEAF#cat /tmp/cpu-dp.txt | grep IP | awk '{print $3 , $4 , $5}' | grep -v $HOSTNAME | awk -F ':' '{print $1}' | sort | uniq -c | sort -nrk 1

Direct without creating a brand new file:

LEAF#tcpdump -i kpm_inb -c 500 | grep IP | awk '{print $3 , $4 , $5}' | grep -v $HOSTNAME | awk -F ':' '{print $1}' | sort | uniq -c | sort -nrk 1

Check fabric-wide from apic where all a specific contract relationship is deployed

APIC#moquery -c actrlRule -f 'actrl.Rule.sPcTag=="32783" and actrl.Rule.dPcTag=="46" and actrl.Rule.scopeId=="2818048"'

Check where an encap is already deployed and get corresponding epg

APIC#moquery -c l2CktEp -f 'l2.CktEp.encap=="vlan-3018"'

Memory Utilization of All nodes in Fabric:

APIC#bash

APIC# clear ; echo -e "Node ID\t\tFree Memory\tUsed Memory" ; moquery -c procSysMemHist15min -f 'proc.SysMemHist15min.index=="1"' | grep dn | awk -F " " '{print $3}' | xargs -n 1 -I {} sh -c 'freeAvg=`moquery -d {} | grep freeAvg | sed -E -e "s/[[:blank:]]+/ /g" | cut -d " " -f3` ; usedAvg=`moquery -d {} | grep usedAvg | sed -E -e "s/[[:blank:]]+/ /g" | cut -d " " -f3` ; totalAvg=`moquery -d {} | grep totalAvg | sed -E -e "s/[[:blank:]]+/ /g" | cut -d " " -f3` ; node=`echo {} | cut -d "/" -f3` ; freeAdj=$(( freeAvg * 100 )) ; usedAdj=$(( usedAvg * 100 )) ; percFree=$(( freeAdj / totalAvg )) ; percUtil=$(( usedAdj / totalAvg )) ; echo -e "$node\tFree% : $percFree\tUsed% : $percUtil"'

Verify drops on istack (exception packets get punted)

Review TX drops. Use the command with sort -nk 6 -r :

APIC# cat istack_debug | egrep "Protocol:|x_pkts_dropped" | tr -d "\n" | sed "s/Protocol/\nProtocol/g" | sort -nk 6 -r | more

Contract Validation

Review all the relationships for a specific contract. Use the script replacing the name of the contract and tenant:

APIC# CONTRACT='brc-<contract-name>'

APIC# TN='<tenant>'

#CHECK CONSUMERS

#To get the count of epgs consuming a contract (excluding vzany consumer):

APIC#icurl -g 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=subtree&target-subtree-class=vzRtCons,vzConsDef&rsp-subtree-include=count&query-target-filter=or(eq(vzRtCons.tCl,"fvAEPg"),eq(vzRtCons.tCl,"l2extInstP"),eq(vzRtCons.tCl,"l3extInstP"),wcard(vzConsDef.dn,"uni/tn-'.*'/inherited-\[uni/tn-"))'

#To list all epg objects consuming a contract (excluding vzany consumers):

APIC#icurl -g 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=subtree&target-subtree-class=vzRtCons,vzConsDef&query-target-filter=or(eq(vzRtCons.tCl,"fvAEPg"),eq(vzRtCons.tCl,"l2extInstP"),eq(vzRtCons.tCl,"l3extInstP"),wcard(vzConsDef.dn,"uni/tn-'.*'/inherited-\[uni/tn-"))' | python -m json.tool

#To get the count of vzanys consuming a contract:

APIC#icurl 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=children&target-subtree-class=vzRtAnyToCons&rsp-subtree-include=count'

#To list all vzany objects consuming a contract:

APIC#icurl 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=children&target-subtree-class=vzRtAnyToCons' | python -m json.tool

#CHECK PROVIDERS

#To get the count of epgs providing a contract (excluding vzany consumer):

APIC#icurl -g 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=subtree&target-subtree-class=vzRtProv,vzProvDef&rsp-subtree-include=count&query-target-filter=or(eq(vzRtProv.tCl,"fvAEPg"),eq(vzRtProv.tCl,"l2extInstP"),eq(vzRtProv.tCl,"l3extInstP"),wcard(vzProvDef.dn,"uni/tn-'.*'/inherited-\[uni/tn-"))'

#To list all epg objects providing a contract (excluding vzany consumers):

APIC#icurl -g 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=subtree&target-subtree-class=vzRtProv,vzProvDef&query-target-filter=or(eq(vzRtProv.tCl,"fvAEPg"),eq(vzRtProv.tCl,"l2extInstP"),eq(vzRtProv.tCl,"l3extInstP"),wcard(vzProvDef.dn,"uni/tn-'.*'/inherited-\[uni/tn-"))' | python -m json.tool

#To get the count of vzanys providing a contract:

APIC#icurl 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=children&target-subtree-class=vzRtAnyToProv&rsp-subtree-include=count'

#To list all vzany objects providing a contract:

APIC#icurl 'http://localhost:7777/api/node/mo/uni/tn-'$TN'/'$CONTRACT'.json?query-target=children&target-subtree-class=vzRtAnyToProv' | python -m json.tool