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:
- In a list:
APIC#acidiag fnvread | grep leaf | awk '{print $1}'
- 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:
- 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;
- 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:
- 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