3 Commits
Author SHA1 Message Date
etwen 9d61b1aa43 docs(status): Add TTL script status sheet 20260817 2026-08-17 16:32:44 +08:00
etwen 071244fde1 feat(traffic): Add SWB loopback line-speed traffic tool
Blanton_Script/blanton_traffic_linespeed.sh V0.3.2 drives the whole
loopback traffic run from the DUT shell via bcmcmd, for both switch
boards (unit 0 and 1):

- init  : vlan remove 1 pbm=cd, then create/add the 108 loopback
          pairs (VLAN 30..137, cdN <-> cdN+32)
- clear : clear c
- show  : show c (raw)
- start : tx <count> length=<len> VLantag=<vid> per VLAN
- stop  : remove the pairs, optional --destroy
- ps    : port status of the cabled ports
- report: parse the show c MIB_TPOK/MIB_RPOK counters and lay them
          out one pair per block with a cross-check verdict
          (cdA.TX == cdB.RX and cdA.RX == cdB.TX), PASS green /
          FAIL red / NA yellow, --tolerance for snapshot skew,
          --tsv, --raw and -f <log> for offline analysis; the raw
          capture is kept under /tmp
- run   : ps -> init -> clear -> start -> report

Options -u/-c/-l/-p/-T/-d/-n and a sourceable function API, in the
style of the other blanton_*.sh tools. Command output matches the
former Tera Term macros byte for byte; report output matches
tools/bcm_mibpair_report_V1.1.0.py, added here as the off-box
equivalent, together with the raw bcmcmd command lists under tools/.

ScriptA sources the tool, ScriptB runs ps/init/clear/show/start and
drops stress_hhmd and stress_pcie, ScriptC stops the traffic and
prints the pair counter report.
2026-08-17 16:32:43 +08:00
etwen 9bf4291d17 feat(fpga): Auto-detect CB FPGA BDF at source time
blanton_fpga_pcimem.sh V1.5.0.

The four FUNCT0..3_RES sysfs paths were hard-coded and had to be
edited for every DUT, because the CB FPGA's BDF changes with the
PCIe enumeration (0000:03:00.x / 0000:05:00.x seen so far).

Detection order at source time: FPGA_BDF override -> sysfs scan for
vendor 0x1590 with all four functions exposing resource0 -> lspci
-Dnn name/id match -> FPGA_BDF_FALLBACK. Adds fpga_rescan for a
DUT swap, FPGA_BDF / FPGA_VENDOR_ID / FPGA_LSPCI_MATCH overrides,
FPGA_BDF_ACTIVE reporting and FPGA_QUIET. Detection runs once, so
cb_fpga / pmc / icb / swb keep zero per-command overhead.
2026-08-17 16:32:42 +08:00
10 changed files with 1743 additions and 46 deletions
Binary file not shown.
+10 -1
View File
@@ -7,7 +7,14 @@
; Version History: ; Version History:
; V1.0.0 2026-08-13 Initial Version ; V1.0.0 2026-08-13 Initial Version
; V1.0.1 2026-08-14 Add CLEAR PCIE Error ; V1.0.1 2026-08-14 Add CLEAR PCIE Error
; V1.0.2 2026-08-17 utils/setup_pmon.ttl add Leakage Status ; V1.0.2 2026-08-17 utils/setup_pmon.ttl Add Leakage Status
; utils/traffic_loopback_vlan_setting.ttl Created
; utils/traffic_loopback_vlan_remove.ttl Created
; utils/traffic_loopback_start.ttl Created
; ScriptB Remove stress_hhmd, stress_pcie
; Blanton_Script Add blanton_traffic_linespeed.sh
; ScriptB/C Add Traffic Test
;
; ============================================================================= ; =============================================================================
include "config.ttl" include "config.ttl"
@@ -52,6 +59,8 @@ sendln "source ~/Blanton_Script/blanton_icb_vi2c.sh"
wait prompt_sonic_root wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_pwr_data.sh" sendln "source ~/Blanton_Script/blanton_pwr_data.sh"
wait prompt_sonic_root wait prompt_sonic_root
sendln "source ~/Blanton_Script/blanton_traffic_linespeed.sh"
wait prompt_sonic_root
sendln "source ~/Blanton_Script/LTC2980_Margin_Script/margin.sh" sendln "source ~/Blanton_Script/LTC2980_Margin_Script/margin.sh"
; ========== CLEAR PCIE Error ========== ; ========== CLEAR PCIE Error ==========
+15 -16
View File
@@ -1,13 +1,5 @@
; ============================================================================= ; =============================================================================
; Script B for Blanton ; Script B for Blanton
; Version : V1.0.2
; Date : 2026-08-17
; Author : ETWen
; =============================================================================
; Version History:
; V1.0.0 2026-08-13 Initial Version
; V1.0.1 2026-08-14 Add AMD CPU STRESS TEST
; V1.0.2 2026-08-17 utils/setup_pmon.ttl add Leakage Status
; ============================================================================= ; =============================================================================
include "config.ttl" include "config.ttl"
@@ -40,18 +32,10 @@ sendln "python ~/hammer/tools/stress_mem.py &"
wait prompt_sonic_root wait prompt_sonic_root
sendln "python ~/hammer/tools/stress_mem.py &" sendln "python ~/hammer/tools/stress_mem.py &"
; ========== I2C, LSB and PCIE read with unlimited loop ==========
wait prompt_sonic_root
sendln "python ~/hammer/tools/stress_hhmd.py &"
; ========== SSD read/write ========== ; ========== SSD read/write ==========
wait prompt_sonic_root wait prompt_sonic_root
sendln "python ~/hammer/tools/stress_ssd.py &" sendln "python ~/hammer/tools/stress_ssd.py &"
; ========== PCIe CPU <- PCIe -> ASIC by dumping portStatus ==========
wait prompt_sonic_root
sendln "python ~/hammer/tools/stress_pcie.py &"
; ========== USB read/write ========== ; ========== USB read/write ==========
wait prompt_sonic_root wait prompt_sonic_root
sendln "python ~/hammer/tools/stress_usb.py &" sendln "python ~/hammer/tools/stress_usb.py &"
@@ -62,6 +46,21 @@ sendln "jobs"
; ========== Take one round of eye measurement on uplink ports ========== ; ========== Take one round of eye measurement on uplink ports ==========
; ========== Traffic START ==========
wait prompt_sonic_root
sendln "blanton_traffic_linespeed ps -u 0"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed init -u 0"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed clear -u 0"
wait prompt_sonic_root
pause 3
sendln "blanton_traffic_linespeed show -u 0"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed start -u 0"
; ========== Get data every 10mins ========== ; ========== Get data every 10mins ==========
while 1 while 1
include "utils/setup_pmon.ttl" include "utils/setup_pmon.ttl"
+4 -10
View File
@@ -1,13 +1,5 @@
; ============================================================================= ; =============================================================================
; Script C for Blanton ; Script C for Blanton
; Version : V1.0.2
; Date : 2026-08-17
; Author : ETWen
; =============================================================================
; Version History:
; V1.0.0 2026-08-13 Initial Version
; V1.0.1 2026-08-14 Add Check PCIE error counters,CHECK Stress results
; V1.0.2 2026-08-17 utils/setup_pmon.ttl add Leakage Status
; ============================================================================= ; =============================================================================
include "config.ttl" include "config.ttl"
@@ -40,8 +32,10 @@ wait prompt_sonic_root
sendln "cat ~/hammer/tools/log.stress_ssd" sendln "cat ~/hammer/tools/log.stress_ssd"
; ========== CHECK Traffic counters ========== ; ========== CHECK Traffic counters ==========
;wait prompt_sonic_root wait prompt_sonic_root
;sendln "command" sendln "blanton_traffic_linespeed stop -u 0"
wait prompt_sonic_root
sendln "blanton_traffic_linespeed report -u 0"
messagebox 'GOOD JOB! Test Case DONE' 'teraterm' messagebox 'GOOD JOB! Test Case DONE' 'teraterm'
@@ -17,10 +17,21 @@
# V1.4.2 2026-08-10 Change: FUNCT0..3_RES BDF updated 0000:04:00.x -> 0000:03:00.x (current unit's enumeration). # V1.4.2 2026-08-10 Change: FUNCT0..3_RES BDF updated 0000:04:00.x -> 0000:03:00.x (current unit's enumeration).
# V1.4.3 2026-08-12 Change: FUNCT0..3_RES BDF updated 0000:03:00.x -> 0000:05:00.x (current unit's enumeration). # V1.4.3 2026-08-12 Change: FUNCT0..3_RES BDF updated 0000:03:00.x -> 0000:05:00.x (current unit's enumeration).
# V1.4.4 2026-08-12 Change: FUNCT0..3_RES BDF back to 0000:03:00.x for the DUT on COM36. # V1.4.4 2026-08-12 Change: FUNCT0..3_RES BDF back to 0000:03:00.x for the DUT on COM36.
# NOTE: this BDF is per-unit. Check with # V1.5.0 2026-08-17 Change: BDF is no longer hard-coded. FUNCT0..3_RES are now
# lspci -Dnn | grep -i fpga or # auto-detected at source time by scanning sysfs for the HPE
# ls -d /sys/bus/pci/devices/0000:*:00.3 # vendor id (0x1590) with all four functions .0-.3 present,
# and edit the four lines below if it differs. # falling back to `lspci -Dnn` name/id match, then to
# FPGA_BDF_FALLBACK. No more editing this file per DUT.
# Add: fpga_rescan (re-detect after DUT swap / re-enumeration),
# FPGA_BDF / FPGA_VENDOR_ID / FPGA_LSPCI_MATCH overrides,
# FPGA_BDF_ACTIVE reporting the BDF in use.
# Note: detection runs ONCE at source time (one INFO line on
# stdout, WARN/FAIL on stderr). FPGA_QUIET=1 silences the
# INFO line. cb_fpga/pmc/icb/swb never re-scan, so there is
# no per-command output and no per-command overhead.
# NOTE: the old per-unit NOTE ("edit the four lines below")
# no longer applies - detection handles it. To pin a BDF
# manually: FPGA_BDF=0000:05:00 fpga_rescan
# ============================================================================= # =============================================================================
# #
# SONiC hardware has no memtool / devmem, but it has pcimem. pcimem mmaps the PCI # SONiC hardware has no memtool / devmem, but it has pcimem. pcimem mmaps the PCI
@@ -42,26 +53,112 @@
# icb_fpga <addr> [data] # icb_fpga <addr> [data]
# swb0_fpga <addr> [data] # swb0_fpga <addr> [data]
# swb1_fpga <addr> [data] # swb1_fpga <addr> [data]
# fpga_rescan re-detect the CB FPGA BDF (after a DUT swap)
# #
# data present = write, absent = read. # data present = write, absent = read.
# Usage: source blanton_fpga_pcimem.sh # Usage: source blanton_fpga_pcimem.sh
# === CB FPGA PCIe resource file (sysfs) === # === CB FPGA PCIe resource file (sysfs) - AUTO-DETECTED ===
# Use lspci -D to find the BDF (domain:bus:dev.fn); resource0 is the sysfs mapping of BAR0. # The CB FPGA's BDF (domain:bus:dev.fn) changes per unit / per enumeration, so it is
# e.g. lspci -Dnn | grep -i fpga -> 0000:02:00.0 ... # detected at source time instead of being hard-coded. resource0 is the sysfs mapping
# memtool variant fills in the BAR value; pcimem variant fills in the resource file # of BAR0. (memtool variant fills in the BAR value; pcimem variant fills in the
# path instead (offset becomes relative to BAR). # resource file path instead, so offsets become relative to BAR.)
FUNCT0_RES=/sys/bus/pci/devices/0000:03:00.0/resource0 #
FUNCT1_RES=/sys/bus/pci/devices/0000:03:00.1/resource0 # Detection order:
FUNCT2_RES=/sys/bus/pci/devices/0000:03:00.2/resource0 # 1. FPGA_BDF override e.g. FPGA_BDF=0000:05:00 (domain:bus:dev, WITHOUT .fn)
FUNCT3_RES=/sys/bus/pci/devices/0000:03:00.3/resource0 # 2. sysfs vendor scan /sys/bus/pci/devices/*.0 whose vendor == FPGA_VENDOR_ID
# (0x1590 = Hewlett Packard Enterprise) and that has all
# four functions .0 .1 .2 .3 exposing resource0
# 3. lspci -Dnn fallback lines matching FPGA_LSPCI_MATCH
# ("Hewlett Packard Enterprise" or vendor id "[1590:")
# 4. FPGA_BDF_FALLBACK last-known BDF, only if 1-3 all fail
#
# Overrides (export before sourcing, or set and call fpga_rescan afterwards):
# FPGA_BDF=0000:05:00 pin a specific device, skip detection
# FPGA_VENDOR_ID=0x10ee different vendor (e.g. a Xilinx-branded board)
# FPGA_LSPCI_MATCH='...' custom lspci grep -iE pattern
FPGA_VENDOR_ID="${FPGA_VENDOR_ID:-0x1590}"
FPGA_LSPCI_MATCH="${FPGA_LSPCI_MATCH:-Hewlett Packard Enterprise|\[1590:}"
FPGA_BDF_FALLBACK="${FPGA_BDF_FALLBACK:-0000:03:00}"
# Auto-detect example (uncomment to use; needs the FPGA's BDF prefix): # True if all four functions of <bdf> exist and expose resource0.
# _BDF=0000:02:00 # Usage: _fpga_bdf_ok <domain:bus:dev>
# FUNCT0_RES=/sys/bus/pci/devices/${_BDF}.0/resource0 _fpga_bdf_ok() {
# FUNCT1_RES=/sys/bus/pci/devices/${_BDF}.1/resource0 local bdf="$1" fn
# FUNCT2_RES=/sys/bus/pci/devices/${_BDF}.2/resource0 for fn in 0 1 2 3; do
# FUNCT3_RES=/sys/bus/pci/devices/${_BDF}.3/resource0 [ -e "/sys/bus/pci/devices/${bdf}.${fn}/resource0" ] || return 1
done
return 0
}
# Print the detected FPGA BDF prefix (domain:bus:dev) on stdout; non-zero if none.
_fpga_detect_bdf() {
local cands="" bdf dir vend want
# 1. explicit override wins (tolerate a trailing ".fn" being included)
if [ -n "${FPGA_BDF:-}" ]; then
bdf="$FPGA_BDF"
case "$bdf" in *.[0-7]) bdf="${bdf%.*}" ;; esac
echo "$bdf"
return 0
fi
want=$(echo "$FPGA_VENDOR_ID" | tr 'A-Z' 'a-z')
# 2. sysfs vendor-ID scan (no lspci / pci.ids needed)
for dir in /sys/bus/pci/devices/*:*.0; do
[ -e "$dir/vendor" ] || continue
vend=$(tr 'A-Z' 'a-z' < "$dir/vendor" 2>/dev/null)
[ "$vend" = "$want" ] || continue
bdf="${dir##*/}"; bdf="${bdf%.0}"
_fpga_bdf_ok "$bdf" && cands="$cands $bdf"
done
# 3. lspci fallback (device name match, in case the vendor id differs)
if [ -z "$cands" ] && command -v lspci >/dev/null 2>&1; then
for bdf in $(lspci -Dnn 2>/dev/null | grep -iE "$FPGA_LSPCI_MATCH" \
| awk '{print $1}' | sed 's/\.[0-9a-f]*$//' | sort -u); do
_fpga_bdf_ok "$bdf" && cands="$cands $bdf"
done
fi
set -- $cands
[ $# -eq 0 ] && return 1
if [ $# -gt 1 ]; then
echo -e "[\033[33mWARN\033[0m] multiple candidate FPGAs found:$cands -> using $1" >&2
echo -e " set FPGA_BDF=<domain:bus:dev> and run fpga_rescan to pick another." >&2
fi
echo "$1"
}
# (Re)detect the FPGA BDF and refresh FUNCT0..3_RES. Called once at source time;
# call again by hand after swapping/re-enumerating a DUT.
# The one-line INFO goes to STDOUT (so wrappers that already do
# `source ... >/dev/null` stay silent); WARN/FAIL go to STDERR.
# Set FPGA_QUIET=1 to suppress the INFO line entirely.
fpga_rescan() {
local bdf
bdf=$(_fpga_detect_bdf)
if [ -z "$bdf" ]; then
bdf="$FPGA_BDF_FALLBACK"
echo -e "[\033[33mWARN\033[0m] no FPGA found (vendor $FPGA_VENDOR_ID / '$FPGA_LSPCI_MATCH');" >&2
echo -e " falling back to $bdf. Check with: lspci -Dnn | grep -iE 'Hewlett|fpga'" >&2
fi
FPGA_BDF_ACTIVE="$bdf"
FUNCT0_RES=/sys/bus/pci/devices/${bdf}.0/resource0
FUNCT1_RES=/sys/bus/pci/devices/${bdf}.1/resource0
FUNCT2_RES=/sys/bus/pci/devices/${bdf}.2/resource0
FUNCT3_RES=/sys/bus/pci/devices/${bdf}.3/resource0
if _fpga_bdf_ok "$bdf"; then
[ "${FPGA_QUIET:-0}" = "1" ] || \
echo -e "[\033[34mINFO\033[0m] CB FPGA BDF = \033[36m${bdf}.0-.3\033[0m (resource0)"
else
echo -e "[\033[31mFAIL\033[0m] ${bdf}.0-.3 resource0 not all present - register access will fail." >&2
return 1
fi
}
fpga_rescan
# === VSPI window base offset (relative to CB Function 2 resource0 start) === # === VSPI window base offset (relative to CB Function 2 resource0 start) ===
# NOTE: CB.F2 has TWO near-identical VSPI register blocks (see spec register map): # NOTE: CB.F2 has TWO near-identical VSPI register blocks (see spec register map):
@@ -268,6 +365,9 @@ blanton_fpga_help() {
echo -e " \033[33mswb0_fpga\033[0m <addr> [data] SWB0 FPGA via VSPI" echo -e " \033[33mswb0_fpga\033[0m <addr> [data] SWB0 FPGA via VSPI"
echo -e " \033[33mswb1_fpga\033[0m <addr> [data] SWB1 FPGA via VSPI" echo -e " \033[33mswb1_fpga\033[0m <addr> [data] SWB1 FPGA via VSPI"
echo -e " \033[33mfpga_debug\033[0m on|off Toggle debug mode (print commands and execute)" echo -e " \033[33mfpga_debug\033[0m on|off Toggle debug mode (print commands and execute)"
echo -e " \033[33mfpga_rescan\033[0m Re-detect CB FPGA BDF (after DUT swap / re-enum)"
echo ""
echo -e " Active CB FPGA BDF: \033[36m${FPGA_BDF_ACTIVE:-unknown}\033[0m .0-.3 (pin with: FPGA_BDF=0000:05:00 fpga_rescan)"
echo "" echo ""
echo -e " Omit [data] to \033[32mread\033[0m, provide [data] to \033[31mwrite\033[0m." echo -e " Omit [data] to \033[32mread\033[0m, provide [data] to \033[31mwrite\033[0m."
echo -e " Backend: \033[36mpcimem\033[0m (sysfs resource file + relative offset)." echo -e " Backend: \033[36mpcimem\033[0m (sysfs resource file + relative offset)."
@@ -0,0 +1,729 @@
#!/usr/bin/env bash
# =============================================================================
# blanton_traffic_linespeed.sh -- SWB loopback line-speed traffic via bcmcmd
# =============================================================================
# Version History:
# V0.1.0 2026-08-17 First version. Bash port of the three Tera Term macros
# utils/traffic_loopback_vlan_setting.ttl (VLAN 30..137,
# port pair cdN <-> cdN+32), utils/traffic_loopback_start.ttl
# (tx 100 length=512 VLantag=<vid>) and
# utils/traffic_loopback_vlan_remove.ttl.
# One DUT = two switch boards -> bcmcmd unit 0 and 1
# (bcmcmd -n <unit>), default both.
# V0.2.0 2026-08-17 Add: 'ps' (port status) subcommand -- 'ps <portlist>' with
# the cabled-port list as default ($TL_PS_PORTS), -p/--ports
# to override (or a bare port list after 'ps'), 'ps -p all'
# for every port. 'run' now shows port status first.
# V0.3.0 2026-08-17 Add: 'report' subcommand -- runs 'show c', keeps the raw
# log, and renders the MIB_TPOK/MIB_RPOK counters as a
# loopback-pair table with a PASS/FAIL cross-check
# (cdA.TX==cdB.RX and cdA.RX==cdB.TX), i.e. an on-DUT awk
# port of tools/bcm_mibpair_report_V1.1.0.py (same layout,
# same verdict rules, same summary lines, exit 2 on
# FAIL/NA). Options -T/-a/-g/-P/-q/--tsv/--raw and
# -f <log> to re-parse a captured console log offline.
# 'run' now ends with 'report' instead of a raw 'show c'.
# V0.3.1 2026-08-17 Fix: only the FIRST VLAN was configured -- bcmcmd inherited
# the while-loop's stdin (the pair-list here-string) and ate
# the remaining lines, so 'read' hit EOF after one pass.
# bcmcmd now always runs with </dev/null and the loops read
# on fd 3 (3<<< "$TL_PAIRS").
# Fix: bcmcmd exits 0 even when the BCM shell rejects the
# command ("VLAN: ERROR: Entry exists" / "Failed to execute
# the diagnostic command"), so failures were counted as OK.
# Output is now pattern-matched ($TL_ERR_PAT), with benign
# cases tolerated and counted separately: 'Entry exists' on
# 'vlan create' (re-run of init) and 'not found' on
# 'vlan remove/destroy' (stop before init).
# V0.3.2 2026-08-17 Add: report colours the verdict -- PASS green, FAIL red,
# NA yellow (also in the summary lines). Padding is applied
# to the plain text before colouring so the columns stay
# aligned. Auto-disabled when stdout is not a terminal or
# with --tsv; --color / --no-color / TL_COLOR force it.
# =============================================================================
#
# The VLAN/port table below is copied verbatim from
# utils/traffic_loopback_vlan_setting.ttl -- it is NOT generated, because the
# port map has gaps (cd15..19, cd47..51, cd79..83, cd111..115, cd139,
# cd148..151, cd171, cd180..183, cd203, cd212..215, cd235, cd244..247 are not
# cabled). Keep this file and the .ttl in sync if the loopback harness changes.
#
# Usage (run directly):
# ./blanton_traffic_linespeed.sh init # step 1: VLAN loopback setup
# ./blanton_traffic_linespeed.sh clear # step 2: clear c
# ./blanton_traffic_linespeed.sh show # step 3/6: show c
# ./blanton_traffic_linespeed.sh start # step 4: tx burst per VLAN
# ./blanton_traffic_linespeed.sh stop # step 5: remove VLAN members
# ./blanton_traffic_linespeed.sh ps # port status (link/speed) of
# # the cabled ports
# ./blanton_traffic_linespeed.sh report # step 6+: show c -> per-pair
# # TX/RX table + PASS/FAIL
# ./blanton_traffic_linespeed.sh run # ps -> 1 -> 2 -> 4 -> report
#
# Usage (sourced, like the other blanton_*.sh tools):
# source blanton_traffic_linespeed.sh
# blanton_traffic_linespeed init -u 1 -d
#
# Options (any order, after the subcommand):
# -u|--unit <0|1|all|0,1> bcmcmd unit(s). Default: $TL_UNITS ("0 1")
# -c|--count <n> tx packet count (default $TL_TX_COUNT)
# -l|--length <n> tx packet length (default $TL_TX_LENGTH)
# -p|--ports <list|all> ps: port list ('all' = plain 'ps', every port)
# -T|--tolerance <n> report: allowed |delta| in packets (default 0;
# -T 1 absorbs the normal snapshot skew)
# -a|--all report: also list pairs that have no counters
# -g|--grouped report: comma-group the values (1,234,567)
# -P|--with-port report: render cd1(2) instead of cd1
# -q|--quiet report: drop the trailing summary comments
# --tsv report: tab-separated (paste into Excel)
# --raw report: also print the raw 'show c' output
# --color|--no-color report: force / disable PASS-green FAIL-red colours
# (default: colour only when stdout is a terminal)
# -f|--file <log> report: parse a saved console log, do not touch DUT
# -d|--debug print every bcmcmd before running it
# -n|--dry-run print commands only, do not touch the DUT
# --destroy stop: also 'vlan destroy <vid>' after removing members
# -h|--help help
#
# Environment overrides:
# BCMCMD_CMD=bcmcmd TL_UNITS="0 1" TL_TX_COUNT=100 TL_TX_LENGTH=512
# TL_PS_PORTS="1-24,40-96,..." TL_TOLERANCE=0 TL_LOG_DIR=/tmp
# DEBUG_MODE=1
#
# Related: tools/bcm_mibpair_report_V1.1.0.py -- same report off-box (python3,
# richer options). 'report' is the awk equivalent so it runs on the SONiC DUT
# itself; both accept the same captured 'show c' log.
# =============================================================================
# === Config ==================================================================
BCMCMD_CMD="${BCMCMD_CMD:-bcmcmd}"
TL_UNITS="${TL_UNITS:-0 1}" # one DUT = two switch boards (0 and 1)
TL_TX_COUNT="${TL_TX_COUNT:-100}"
TL_TX_LENGTH="${TL_TX_LENGTH:-512}"
TL_DEFAULT_VLAN="${TL_DEFAULT_VLAN:-1}"
TL_DEFAULT_VLAN_PBM="${TL_DEFAULT_VLAN_PBM:-cd}"
# 'ps' port list: the cabled ports of the loopback harness, in bcm logical-port
# numbering (NOT the cdN names used by vlan add). Kept as one string so it can be
# pasted straight from/into a manual "bcmcmd -n 0 -c 'ps <list>'".
TL_PS_PORTS="${TL_PS_PORTS:-1-24,40-96,112-168,184-240,256-259,270-308,310-327,342-380,382-399,414-452,454-471,486-524,526-543,558-565}"
# --- report (pair cross-check) defaults -------------------------------------
TL_TOLERANCE="${TL_TOLERANCE:-0}" # allowed |delta| in packets before FAIL
TL_LOG_DIR="${TL_LOG_DIR:-/tmp}" # where the raw 'show c' capture is kept
TL_REPORT_ALL=${TL_REPORT_ALL:-0}
TL_REPORT_GROUPED=${TL_REPORT_GROUPED:-0}
TL_REPORT_WITHPORT=${TL_REPORT_WITHPORT:-0}
TL_REPORT_QUIET=${TL_REPORT_QUIET:-0}
TL_REPORT_TSV=${TL_REPORT_TSV:-0}
TL_REPORT_RAW=${TL_REPORT_RAW:-0}
TL_REPORT_FILE="" # -f <log>: parse this instead of the DUT
TL_COLOR="${TL_COLOR:-auto}" # auto|always|never -- PASS green / FAIL red / NA yellow
# Debug / dry-run (1 = on). DEBUG_MODE is shared with blanton_fpga_pcimem.sh.
DEBUG_MODE=${DEBUG_MODE:-0}
TL_DRY_RUN=${TL_DRY_RUN:-0}
TL_DESTROY=${TL_DESTROY:-0}
# === VLAN <-> loopback port pair table (from traffic_loopback_vlan_setting.ttl) ==
# format: <vid> <port_a> <port_b>
TL_PAIRS="\
30 cd0 cd32
31 cd1 cd33
32 cd2 cd34
33 cd3 cd35
34 cd4 cd36
35 cd5 cd37
36 cd6 cd38
37 cd7 cd39
38 cd8 cd40
39 cd9 cd41
40 cd10 cd42
41 cd11 cd43
42 cd12 cd44
43 cd13 cd45
44 cd14 cd46
45 cd20 cd52
46 cd21 cd53
47 cd22 cd54
48 cd23 cd55
49 cd24 cd56
50 cd25 cd57
51 cd26 cd58
52 cd27 cd59
53 cd28 cd60
54 cd29 cd61
55 cd30 cd62
56 cd31 cd63
57 cd64 cd96
58 cd65 cd97
59 cd66 cd98
60 cd67 cd99
61 cd68 cd100
62 cd69 cd101
63 cd70 cd102
64 cd71 cd103
65 cd72 cd104
66 cd73 cd105
67 cd74 cd106
68 cd75 cd107
69 cd76 cd108
70 cd77 cd109
71 cd78 cd110
72 cd84 cd116
73 cd85 cd117
74 cd86 cd118
75 cd87 cd119
76 cd88 cd120
77 cd89 cd121
78 cd90 cd122
79 cd91 cd123
80 cd92 cd124
81 cd93 cd125
82 cd94 cd126
83 cd95 cd127
84 cd128 cd160
85 cd129 cd161
86 cd130 cd162
87 cd131 cd163
88 cd132 cd164
89 cd133 cd165
90 cd134 cd166
91 cd135 cd167
92 cd136 cd168
93 cd137 cd169
94 cd138 cd170
95 cd140 cd172
96 cd141 cd173
97 cd142 cd174
98 cd143 cd175
99 cd144 cd176
100 cd145 cd177
101 cd146 cd178
102 cd147 cd179
103 cd152 cd184
104 cd153 cd185
105 cd154 cd186
106 cd155 cd187
107 cd156 cd188
108 cd157 cd189
109 cd158 cd190
110 cd159 cd191
111 cd192 cd224
112 cd193 cd225
113 cd194 cd226
114 cd195 cd227
115 cd196 cd228
116 cd197 cd229
117 cd198 cd230
118 cd199 cd231
119 cd200 cd232
120 cd201 cd233
121 cd202 cd234
122 cd204 cd236
123 cd205 cd237
124 cd206 cd238
125 cd207 cd239
126 cd208 cd240
127 cd209 cd241
128 cd210 cd242
129 cd211 cd243
130 cd216 cd248
131 cd217 cd249
132 cd218 cd250
133 cd219 cd251
134 cd220 cd252
135 cd221 cd253
136 cd222 cd254
137 cd223 cd255"
# === Logging =================================================================
_tl_info() { echo -e "[\033[34mINFO\033[0m] $*"; }
_tl_ok() { echo -e "[\033[32m OK \033[0m] $*"; }
_tl_warn() { echo -e "[\033[33mWARN\033[0m] $*" >&2; }
_tl_err() { echo -e "[\033[31mERR \033[0m] $*" >&2; }
_tl_dbg() { [ "$DEBUG_MODE" = "1" ] && echo -e "\033[90m[DEBG] $*\033[0m" >&2; return 0; }
traffic_debug() {
if [ "${1:-}" = "on" ]; then DEBUG_MODE=1
elif [ "${1:-}" = "off" ]; then DEBUG_MODE=0
else [ "$DEBUG_MODE" = "0" ] && DEBUG_MODE=1 || DEBUG_MODE=0; fi
_tl_info "DEBUG_MODE=$DEBUG_MODE"
}
# === bcmcmd wrapper ==========================================================
# IMPORTANT: bcmcmd is always run with stdin closed (</dev/null). Without it
# bcmcmd inherits the caller's stdin and eats the rest of the pair list that the
# while-loops read, so only the first VLAN got configured (fixed in V0.3.1).
#
# _tl_bcm <unit> <bcm shell command> -- streams the DUT output, returns bcmcmd rc
# Debug mode prints the full command line first; dry-run prints and skips it.
_tl_bcm() {
local unit="$1"; shift
local cmd="$*"
_tl_dbg "$BCMCMD_CMD -n $unit -c '$cmd'"
if [ "$TL_DRY_RUN" = "1" ]; then
echo "[DRY ] $BCMCMD_CMD -n $unit -c '$cmd'"
return 0
fi
"$BCMCMD_CMD" -n "$unit" -c "$cmd" </dev/null
}
# bcmcmd exits 0 even when the BCM shell itself refused the command
# ("VLAN: ERROR: Entry exists", "Failed to execute the diagnostic command"),
# so the captured output has to be pattern-matched as well.
TL_ERR_PAT="${TL_ERR_PAT:-ERROR|Failed to execute|Invalid|Syntax error|Unavailable|not found}"
TL_BENIGN_CREATE="${TL_BENIGN_CREATE:-Entry exists|already exist}"
TL_BENIGN_REMOVE="${TL_BENIGN_REMOVE:-Entry not found|not found|does not exist|no such}"
# _tl_bcm_run <unit> <benign_regex|""> <cmd...>
# 0 = ok, 2 = failed but benign (matches benign_regex), 1 = real failure
# Output is captured (shown in debug mode, or on a real failure) so the ~110
# vlan create/add lines do not flood the console.
_tl_bcm_run() {
local unit="$1" benign="$2"; shift 2
local cmd="$*" out rc
if [ "$TL_DRY_RUN" = "1" ]; then _tl_bcm "$unit" "$cmd" >/dev/null; return 0; fi
_tl_dbg "$BCMCMD_CMD -n $unit -c '$cmd'"
out=$("$BCMCMD_CMD" -n "$unit" -c "$cmd" </dev/null 2>&1); rc=$?
[ "$DEBUG_MODE" = "1" ] && [ -n "$out" ] && echo "$out"
if [ "$rc" -ne 0 ] || echo "$out" | grep -qiE "$TL_ERR_PAT"; then
if [ -n "$benign" ] && echo "$out" | grep -qiE "$benign"; then
_tl_dbg "benign: unit $unit '$cmd'"
return 2
fi
_tl_err "unit $unit: '$cmd' rc=$rc"
[ "$DEBUG_MODE" != "1" ] && [ -n "$out" ] && echo "$out" >&2
return 1
fi
return 0
}
# _tl_bcm_q <unit> <cmd> -- _tl_bcm_run with no benign pattern
_tl_bcm_q() { local unit="$1"; shift; _tl_bcm_run "$unit" "" "$@"; }
_tl_units_check() {
local u
for u in $TL_UNITS; do
case "$u" in
0|1) ;;
*) _tl_err "invalid unit '$u' (expect 0 or 1)"; return 1 ;;
esac
done
if [ "$TL_DRY_RUN" != "1" ] && ! command -v "$BCMCMD_CMD" >/dev/null 2>&1; then
_tl_err "$BCMCMD_CMD not found in PATH (run on the SONiC DUT, or set BCMCMD_CMD)"
return 1
fi
return 0
}
_tl_pair_count() { echo "$TL_PAIRS" | grep -c . ; }
# === Step 1: VLAN loopback setup (traffic_loopback_vlan_setting.ttl) =========
traffic_linespeed_init() {
_tl_units_check || return 1
local unit vid pa pb n fail exist rc
for unit in $TL_UNITS; do
n=0; fail=0; exist=0
_tl_info "unit $unit: VLAN loopback setup ($(_tl_pair_count) pairs, VLAN 30..137)"
_tl_bcm_q "$unit" "vlan remove $TL_DEFAULT_VLAN pbm=$TL_DEFAULT_VLAN_PBM" \
|| _tl_warn "unit $unit: clearing default VLAN $TL_DEFAULT_VLAN membership failed (continuing)"
# read on fd 3: bcmcmd must not be able to consume the pair list
while read -r vid pa pb <&3; do
[ -z "$vid" ] && continue
_tl_bcm_run "$unit" "$TL_BENIGN_CREATE" "vlan create $vid"; rc=$?
[ "$rc" = "1" ] && fail=$((fail+1))
[ "$rc" = "2" ] && exist=$((exist+1))
_tl_bcm_q "$unit" "vlan add $vid pbm=$pa,$pb" || fail=$((fail+1))
n=$((n+1))
done 3<<< "$TL_PAIRS"
if [ "$fail" -eq 0 ]; then
_tl_ok "unit $unit: $n VLANs configured$([ "$exist" -gt 0 ] && echo " ($exist already existed)"), port pairs added"
else
_tl_warn "unit $unit: $n VLANs processed, $fail command(s) failed$([ "$exist" -gt 0 ] && echo ", $exist already existed")"
fi
done
}
# === Step 2: clear counters ==================================================
traffic_linespeed_clear() {
_tl_units_check || return 1
local unit
for unit in $TL_UNITS; do
_tl_info "unit $unit: clear c"
_tl_bcm "$unit" "clear c" || { _tl_err "unit $unit: clear c failed"; return 1; }
_tl_ok "unit $unit: counters cleared"
done
}
# === Step 3 / 6: show counters ==============================================
traffic_linespeed_show() {
_tl_units_check || return 1
local unit
for unit in $TL_UNITS; do
echo "----- unit $unit : show c -----"
_tl_bcm "$unit" "show c" || { _tl_err "unit $unit: show c failed"; return 1; }
done
}
# === Step 4: start traffic (traffic_loopback_start.ttl) =====================
traffic_linespeed_start() {
_tl_units_check || return 1
local unit vid pa pb n fail
for unit in $TL_UNITS; do
n=0; fail=0
_tl_info "unit $unit: tx $TL_TX_COUNT length=$TL_TX_LENGTH per VLAN 30..137"
while read -r vid pa pb <&3; do
[ -z "$vid" ] && continue
_tl_bcm_q "$unit" "tx $TL_TX_COUNT length=$TL_TX_LENGTH VLantag=$vid" || fail=$((fail+1))
n=$((n+1))
done 3<<< "$TL_PAIRS"
if [ "$fail" -eq 0 ]; then
_tl_ok "unit $unit: $n bursts sent ($((n * TL_TX_COUNT)) packets, ${TL_TX_LENGTH}B each)"
else
_tl_warn "unit $unit: $n bursts attempted, $fail failed"
fi
done
}
# === Step 5: stop traffic (traffic_loopback_vlan_remove.ttl) ================
traffic_linespeed_stop() {
_tl_units_check || return 1
local unit vid pa pb n fail
for unit in $TL_UNITS; do
n=0; fail=0
_tl_info "unit $unit: removing loopback port pairs from VLAN 30..137"
while read -r vid pa pb <&3; do
[ -z "$vid" ] && continue
_tl_bcm_run "$unit" "$TL_BENIGN_REMOVE" "vlan remove $vid pbm=$pa,$pb"
[ "$?" = "1" ] && fail=$((fail+1))
if [ "$TL_DESTROY" = "1" ]; then
_tl_bcm_run "$unit" "$TL_BENIGN_REMOVE" "vlan destroy $vid"
[ "$?" = "1" ] && fail=$((fail+1))
fi
n=$((n+1))
done 3<<< "$TL_PAIRS"
if [ "$fail" -eq 0 ]; then
_tl_ok "unit $unit: $n VLANs cleaned$([ "$TL_DESTROY" = "1" ] && echo " and destroyed")"
else
_tl_warn "unit $unit: $n VLANs processed, $fail command(s) failed"
fi
done
}
# === Port status: ps <portlist> =============================================
# 'ps' shows link / speed / duplex / flow-control per port. Default list is the
# cabled ports ($TL_PS_PORTS); 'all' (or empty) runs a bare 'ps' = every port.
traffic_linespeed_ps() {
_tl_units_check || return 1
local unit cmd="ps"
case "${TL_PS_PORTS:-all}" in
all|ALL|"") cmd="ps" ;;
*) cmd="ps $TL_PS_PORTS" ;;
esac
for unit in $TL_UNITS; do
echo "----- unit $unit : $cmd -----"
_tl_bcm "$unit" "$cmd" || { _tl_err "unit $unit: $cmd failed"; return 1; }
done
}
# === Report: show c -> per-pair TX/RX table + PASS/FAIL =====================
# Mirrors tools/bcm_mibpair_report_V1.1.0.py, in awk so it runs on the DUT.
#
# Parses MIB_TPOK.cd1(2) : 723,629,081,133 +723,629,081,133
# MIB_RPOK.cd1(2) : 581,693,309,458 +581,693,309,458
# Verdict per pair: cdA.TPOK == cdB.RPOK and cdA.RPOK == cdB.TPOK
# PASS within tolerance / FAIL outside / NA when counters are missing
# (a cd port absent from 'show c' means the counter is zero or the
# console scrolled -- cross-check with 'ps' before blaming the port).
# _tl_pair_report <logfile> -> 0 all PASS, 2 any FAIL/NA, 1 parse error
_tl_pair_report() {
local log="$1" color=0
# PASS green / FAIL red / NA yellow. auto = only when stdout is a terminal,
# so redirecting to a file or piping into grep/diff stays plain text.
case "$TL_COLOR" in
always|1|yes) color=1 ;;
never|0|no) color=0 ;;
*) [ -t 1 ] && color=1 ;;
esac
[ "$TL_REPORT_TSV" = "1" ] && color=0
awk -v PAIRS="$TL_PAIRS" \
-v TOL="$TL_TOLERANCE" \
-v ALL="$TL_REPORT_ALL" \
-v GROUPED="$TL_REPORT_GROUPED" \
-v WITHPORT="$TL_REPORT_WITHPORT" \
-v QUIET="$TL_REPORT_QUIET" \
-v TSV="$TL_REPORT_TSV" \
-v COLOR="$color" '
function grp(v, s,out,l,i) {
s = sprintf("%d", v)
if (!GROUPED) return s
out = ""; l = length(s)
for (i = 1; i <= l; i++) {
out = out substr(s, i, 1)
if (((l - i) % 3) == 0 && i < l) out = out ","
}
return out
}
function pname(cd) { return (WITHPORT && (cd in LP)) ? cd "(" LP[cd] ")" : cd }
function absd(x) { return (x < 0) ? -x : x }
# colour the verdict token: PASS green, FAIL red, NA yellow
function vc(v) {
if (!COLOR) return v
if (v == "PASS") return "\033[32m" v "\033[0m"
if (v == "FAIL") return "\033[31m" v "\033[0m"
return "\033[33m" v "\033[0m"
}
function redl(s) { return COLOR ? "\033[31m" s "\033[0m" : s }
BEGIN {
NP = split(PAIRS, L, "\n")
for (i = 1; i <= NP; i++) { split(L[i], f, " "); VID[i] = f[1]; A[i] = f[2]; B[i] = f[3] }
MISSING = "-"
}
{
idx = index($0, "MIB_")
if (idx == 0) next
s = substr($0, idx)
kind = substr(s, 5, 4)
if (kind != "TPOK" && kind != "RPOK") next
p1 = index(s, "."); p2 = index(s, "("); p3 = index(s, ")"); p4 = index(s, ":")
if (p1 == 0 || p2 == 0 || p3 == 0 || p4 == 0 || p2 < p1 || p4 < p3) next
cd = substr(s, p1 + 1, p2 - p1 - 1)
if (cd !~ /^cd[0-9]+$/) next
lp = substr(s, p2 + 1, p3 - p2 - 1)
val = substr(s, p4 + 1)
sub(/^[ \t]+/, "", val)
if (val !~ /^[0-9,]/) next
sub(/[ \t].*$/, "", val)
gsub(/,/, "", val)
LP[cd] = lp
if (kind == "TPOK") { TX[cd] = val + 0; HTX[cd] = 1 } else { RX[cd] = val + 0; HRX[cd] = 1 }
seen++
}
END {
if (seen == 0) {
print "error: no MIB_TPOK/MIB_RPOK counter found in the log" > "/dev/stderr"
exit 1
}
npass = nfail = nna = 0; nrow = 0; nrep = 0; miss = ""; nf = 0
for (i = 1; i <= NP; i++) {
a = A[i]; b = B[i]
oka = (a in HTX) && (a in HRX); okb = (b in HTX) && (b in HRX)
if (!(oka && okb)) {
v = "NA"; nna++
miss = miss (miss == "" ? "" : " ") a "/" b
if (!ALL) continue
ta = oka ? grp(TX[a]) : MISSING; ra = oka ? grp(RX[a]) : MISSING
tb = okb ? grp(TX[b]) : MISSING; rb = okb ? grp(RX[b]) : MISSING
} else {
dtx = TX[a] - RX[b]; drx = RX[a] - TX[b]
d = absd(dtx); if (absd(drx) > d) d = absd(drx)
if (d <= TOL + 0) { v = "PASS"; npass++ }
else {
v = "FAIL"; nfail++
FL[++nf] = sprintf("# FAIL %s/%s: %s.TX-%s.RX=%+d %s.RX-%s.TX=%+d", \
a, b, a, b, dtx, a, b, drx)
}
ta = grp(TX[a]); ra = grp(RX[a]); tb = grp(TX[b]); rb = grp(RX[b])
}
nrep++
nrow++; C0[nrow] = pname(a); C1[nrow] = ta; C2[nrow] = ra; C3[nrow] = v
nrow++; C0[nrow] = pname(b); C1[nrow] = tb; C2[nrow] = rb; C3[nrow] = v
}
H0 = "Port"; H1 = "TX"; H2 = "RX"; H3 = "PASS/FAIL"
if (TSV) {
print H0 "\t" H1 "\t" H2 "\t" H3
for (r = 1; r <= nrow; r++) print C0[r] "\t" C1[r] "\t" C2[r] "\t" C3[r]
} else {
w0 = length(H0); w1 = length(H1); w2 = length(H2); w3 = length(H3)
for (r = 1; r <= nrow; r++) {
if (length(C0[r]) > w0) w0 = length(C0[r])
if (length(C1[r]) > w1) w1 = length(C1[r])
if (length(C2[r]) > w2) w2 = length(C2[r])
if (length(C3[r]) > w3) w3 = length(C3[r])
}
w0 += 2; w1 += 2; w2 += 2; w3 += 2
printf "%-*s%*s%*s%*s\n", w0, H0, w1, H1, w2, H2, w3, H3
for (r = 1; r <= nrow; r++) {
# pad on the plain text, then colour, so the columns stay aligned
printf "%-*s%*s%*s", w0, C0[r], w1, C1[r], w2, C2[r]
printf "%*s%s\n", w3 - length(C3[r]), "", vc(C3[r])
}
}
if (!QUIET) {
print ""
printf "# pairs in table : %d\n", NP
printf "# pairs reported : %d\n", nrep
printf "# %s %d %s %d %s %d (tolerance %d)\n", \
vc("PASS"), npass, vc("FAIL"), nfail, vc("NA"), nna, TOL + 0
if (miss != "") printf "# %s (no counters): %s\n", vc("NA"), miss
for (i = 1; i <= nf; i++) print redl(FL[i])
}
exit (nfail || nna) ? 2 : 0
}' "$log"
}
# traffic_linespeed_report -- 'show c' per unit, keep the raw log, render the table
traffic_linespeed_report() {
local unit log rc worst=0 stamp
# -f <log>: offline mode, no DUT access, no unit loop
if [ -n "$TL_REPORT_FILE" ]; then
[ -r "$TL_REPORT_FILE" ] || { _tl_err "cannot read log '$TL_REPORT_FILE'"; return 1; }
_tl_info "report from log: $TL_REPORT_FILE (tolerance $TL_TOLERANCE)"
_tl_pair_report "$TL_REPORT_FILE"; return $?
fi
_tl_units_check || return 1
if [ "$TL_DRY_RUN" = "1" ]; then
for unit in $TL_UNITS; do _tl_bcm "$unit" "show c" >/dev/null; done
return 0
fi
stamp=$(date +%Y%m%d_%H%M%S 2>/dev/null || echo now)
for unit in $TL_UNITS; do
log="$TL_LOG_DIR/showc_unit${unit}_${stamp}.log"
if ! _tl_bcm "$unit" "show c" > "$log" 2>&1; then
_tl_err "unit $unit: show c failed (see $log)"; return 1
fi
[ "$TL_REPORT_RAW" = "1" ] && { echo "----- unit $unit : raw show c -----"; cat "$log"; }
echo "===== unit $unit : loopback pair counter report (raw: $log) ====="
_tl_pair_report "$log"; rc=$?
[ "$rc" -gt "$worst" ] && worst=$rc
case "$rc" in
0) _tl_ok "unit $unit: all pairs PASS" ;;
2) _tl_warn "unit $unit: at least one pair FAIL/NA" ;;
*) _tl_err "unit $unit: report parse error" ;;
esac
done
return "$worst"
}
# === Convenience: full sequence ps -> 1 -> 2 -> 4 -> report ==================
traffic_linespeed_run() {
traffic_linespeed_ps || return 1
traffic_linespeed_init || return 1
traffic_linespeed_clear || return 1
traffic_linespeed_start || return 1
traffic_linespeed_report
local rc=$?
_tl_info "traffic done. 'stop' removes the loopback VLAN membership."
return $rc
}
# === Help ====================================================================
blanton_traffic_linespeed_help() {
echo -e "\033[1mblanton_traffic_linespeed.sh - SWB loopback line-speed traffic (bcmcmd)\033[0m"
echo ""
echo -e " Units: \033[36m$TL_UNITS\033[0m tx: \033[36m$TL_TX_COUNT pkt x ${TL_TX_LENGTH}B\033[0m"
echo -e " VLANs: 30..137 ($(_tl_pair_count) loopback pairs, cdN <-> cdN+32)"
echo ""
echo -e "\033[1mSubcommands\033[0m"
echo -e " \033[33minit\033[0m step 1 vlan remove 1 pbm=cd, vlan create/add each pair"
echo -e " \033[33mclear\033[0m step 2 clear c"
echo -e " \033[33mshow\033[0m step 3/6 show c (run before and after traffic)"
echo -e " \033[33mstart\033[0m step 4 tx <count> length=<len> VLantag=<vid> per VLAN"
echo -e " \033[33mstop\033[0m step 5 vlan remove <vid> pbm=<pair> [--destroy also destroys]"
echo -e " \033[33mps\033[0m ps <portlist> port status (link/speed) of the cabled ports"
echo -e " \033[33mreport\033[0m show c -> per-pair TX/RX table + PASS/FAIL cross-check"
echo -e " \033[33mrun\033[0m ps -> init -> clear -> start -> report"
echo -e " \033[33mhelp\033[0m"
echo ""
echo -e "\033[1mOptions\033[0m"
echo -e " \033[33m-u|--unit\033[0m <0|1|all> bcmcmd unit(s); 'all' = 0 1 (default: $TL_UNITS)"
echo -e " \033[33m-c|--count\033[0m <n> tx packet count (default $TL_TX_COUNT)"
echo -e " \033[33m-l|--length\033[0m <n> tx packet length (default $TL_TX_LENGTH)"
echo -e " \033[33m-p|--ports\033[0m <list> ps port list, or 'all' for every port"
echo -e " \033[33m-T|--tolerance\033[0m <n> report: allowed |delta| pkts (default $TL_TOLERANCE; -T 1 = snapshot skew)"
echo -e " \033[33m-a|--all\033[0m report: also list pairs with no counters"
echo -e " \033[33m-g|--grouped\033[0m report: comma-group values"
echo -e " \033[33m-P|--with-port\033[0m report: render cd1(2) instead of cd1"
echo -e " \033[33m-q|--quiet\033[0m report: no trailing summary"
echo -e " \033[33m--tsv\033[0m report: tab-separated (Excel)"
echo -e " \033[33m--raw\033[0m report: also dump the raw 'show c'"
echo -e " \033[33m--color|--no-color\033[0m report: force/disable \033[32mPASS\033[0m / \033[31mFAIL\033[0m / \033[33mNA\033[0m colouring"
echo -e " (default: colour only when stdout is a terminal)"
echo -e " \033[33m-f|--file\033[0m <log> report: parse a saved log, no DUT access"
echo -e " \033[33m-d|--debug\033[0m print every bcmcmd command line (stderr) and run it"
echo -e " \033[33m-n|--dry-run\033[0m print commands only, do not touch the DUT"
echo -e " \033[33m--destroy\033[0m stop: also 'vlan destroy' each VLAN"
echo ""
echo -e "\033[1mExamples\033[0m"
echo -e " blanton_traffic_linespeed ps -u 0"
echo -e " blanton_traffic_linespeed init -u 1"
echo -e " blanton_traffic_linespeed clear && blanton_traffic_linespeed start"
echo -e " blanton_traffic_linespeed report -u 1 -T 1"
echo -e " blanton_traffic_linespeed report -u 1 -q | grep -v PASS"
echo -e " blanton_traffic_linespeed report -f /tmp/showc_unit1_*.log -a"
echo -e " blanton_traffic_linespeed show -u 1 | grep -iE 'error|discard|drop'"
echo -e " blanton_traffic_linespeed start -c 1000 -l 9216 -d"
echo -e " blanton_traffic_linespeed stop --destroy"
echo ""
echo -e " report exit code: 0 = all pairs PASS, 2 = any FAIL/NA, 1 = parse error"
echo -e " Off-box equivalent: tools/bcm_mibpair_report_V1.1.0.py (python3)"
echo -e " ps ports: \033[36m$TL_PS_PORTS\033[0m"
echo -e " Table mirrors utils/traffic_loopback_vlan_{setting,remove}.ttl and"
echo -e " utils/traffic_loopback_start.ttl - keep them in sync."
}
# === Dispatcher ==============================================================
blanton_traffic_linespeed() {
local sub="${1:-help}"; shift 2>/dev/null || true
while [ $# -gt 0 ]; do
case "$1" in
-u|--unit)
case "$2" in
all|both|*,*) TL_UNITS=$(echo "$2" | sed 's/all\|both/0 1/; s/,/ /g') ;;
*) TL_UNITS="$2" ;;
esac
shift 2 ;;
-c|--count) TL_TX_COUNT="$2"; shift 2 ;;
-l|--length) TL_TX_LENGTH="$2"; shift 2 ;;
-p|--ports) TL_PS_PORTS="$2"; shift 2 ;;
-T|--tolerance) TL_TOLERANCE="$2"; shift 2 ;;
-f|--file) TL_REPORT_FILE="$2"; shift 2 ;;
-a|--all) TL_REPORT_ALL=1; shift ;;
-g|--grouped) TL_REPORT_GROUPED=1; shift ;;
-P|--with-port) TL_REPORT_WITHPORT=1; shift ;;
-q|--quiet) TL_REPORT_QUIET=1; shift ;;
--tsv) TL_REPORT_TSV=1; shift ;;
--raw) TL_REPORT_RAW=1; shift ;;
--color) TL_COLOR=always; shift ;;
--no-color) TL_COLOR=never; shift ;;
-d|--debug) DEBUG_MODE=1; shift ;;
-n|--dry-run) TL_DRY_RUN=1; shift ;;
--destroy) TL_DESTROY=1; shift ;;
-h|--help) blanton_traffic_linespeed_help; return 0 ;;
-*) _tl_err "unknown option '$1'"; return 1 ;;
*) # bare argument: only meaningful as the 'ps' port list
if [ "$sub" = "ps" ] || [ "$sub" = "status" ]; then
TL_PS_PORTS="$1"; shift
else
_tl_err "unexpected argument '$1'"; return 1
fi ;;
esac
done
case "$sub" in
init) traffic_linespeed_init ;;
clear) traffic_linespeed_clear ;;
show) traffic_linespeed_show ;;
start) traffic_linespeed_start ;;
stop) traffic_linespeed_stop ;;
ps|status) traffic_linespeed_ps ;;
report|rpt) traffic_linespeed_report ;;
run|all) traffic_linespeed_run ;;
debug) traffic_debug on ;;
help|-h|--help) blanton_traffic_linespeed_help ;;
*) _tl_err "unknown subcommand '$sub'"; blanton_traffic_linespeed_help; return 1 ;;
esac
}
# Executed directly -> dispatch. Sourced -> just expose the functions + help.
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
blanton_traffic_linespeed "$@"
else
blanton_traffic_linespeed_help
fi
+325
View File
@@ -0,0 +1,325 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
bcm_mibpair_report_V1.1.0.py
Author : ETWen
Date : 20260730
Purpose : Extract MIB_TPOK / MIB_RPOK counters from a Broadcom drivshell log
and lay them out horizontally, one loopback pair per block:
Port TX RX PASS/FAIL
cd1 723629081133 581693309458 PASS
cd33 581693309458 723629081133 PASS
Pair membership and pair order come from the
"vlan remove <vid> pbm=cdA,cdB" lines in the same log, so the report
always follows the order the test actually ran in.
Verdict per pair comes from the loopback cross-check: for a pair,
cdA.TPOK must equal cdB.RPOK and cdA.RPOK must equal cdB.TPOK.
PASS - both directions match (within --tolerance)
FAIL - at least one direction is off; delta is listed in the
trailing summary
NA - the pair has no counters in the log
Usage : ./bcm_mibpair_report_V1.1.0.py <drivshell.log> [options]
-a, --all also emit pairs that have no counters in the log
(values shown as "-")
-b, --block repeat the header and blank-separate each pair
-g, --grouped keep the SDK's comma grouping (1,234,567)
-p, --with-port render "cd1(2)" instead of "cd1"
-t, --tsv tab-separated output (for Excel / pandas)
-s, --no-status drop the PASS/FAIL column
-T, --tolerance N allowed |delta| in packets before a pair is FAIL
(default 0). A +/-1 skew is normal: the SDK reads
counters port-by-port while traffic still runs, so
-T 1 is a reasonable production setting.
-q, --quiet suppress the trailing summary comments
-o, --output write to a file instead of stdout
Notes : - The trailing "+delta" column printed by the SDK is stripped.
- A cd port missing from the dump usually means the console
scrolled or auto-logged out mid-"show c", NOT that the port was
down. Cross-check against "ps" before drawing conclusions.
- A +/-1 packet delta between a pair is normal snapshot skew: the
SDK reads counters port-by-port while traffic is still running.
Exit : 0 = every pair had counters and cross-checked clean
1 = usage / input error
2 = at least one pair is FAIL or NA (see summary)
Version History
V1.0.0 20260730 Initial Version (parity with bcm_mibpair_report_V1.2.0.sh)
V1.0.1 20260730 Handle BrokenPipeError quietly when piped into head
V1.1.0 20260730 Add PASS/FAIL/NA verdict column and --tolerance
"""
from __future__ import annotations
import argparse
import re
import sys
from dataclasses import dataclass, field
from pathlib import Path
from typing import Iterable, TextIO
EXIT_OK = 0
EXIT_USAGE = 1
EXIT_WARN = 2
# "vlan remove 31 pbm=cd1,cd33"
RE_PBM = re.compile(r"pbm=(cd\d+),(cd\d+)")
# "MIB_TPOK.cd1(2) : 723,629,081,133 +723,629,081,133"
RE_MIB = re.compile(
r"^MIB_(?P<kind>TPOK|RPOK)\.(?P<cd>cd\d+)\((?P<lport>\d+)\)\s*:\s*(?P<val>[\d,]+)"
)
MISSING = "-"
@dataclass
class PortCounters:
"""TPOK / RPOK for a single cd port."""
lport: int | None = None
tx: int | None = None
rx: int | None = None
@property
def complete(self) -> bool:
return self.tx is not None and self.rx is not None
@dataclass
class LogData:
"""Everything the report needs, extracted from one drivshell log."""
pairs: list[tuple[str, str]] = field(default_factory=list)
ports: dict[str, PortCounters] = field(default_factory=dict)
def counters(self, cd: str) -> PortCounters:
return self.ports.setdefault(cd, PortCounters())
def parse_log(lines: Iterable[str]) -> LogData:
"""Pull pbm pair definitions and TPOK/RPOK counters out of a drivshell log."""
data = LogData()
seen_pairs: set[tuple[str, str]] = set()
for raw in lines:
line = raw.rstrip("\r\n")
for a, b in RE_PBM.findall(line):
if (a, b) not in seen_pairs:
seen_pairs.add((a, b))
data.pairs.append((a, b))
# drivshell echoes commands, so a MIB line may be prefixed with
# "drivshell>" noise; anchor on the MIB_ token instead of the line start.
idx = line.find("MIB_")
if idx < 0:
continue
m = RE_MIB.match(line[idx:])
if not m:
continue
pc = data.counters(m.group("cd"))
pc.lport = int(m.group("lport"))
value = int(m.group("val").replace(",", ""))
if m.group("kind") == "TPOK":
pc.tx = value
else:
pc.rx = value
return data
def fmt_value(value: int | None, grouped: bool) -> str:
if value is None:
return MISSING
return f"{value:,}" if grouped else str(value)
def fmt_port(cd: str, pc: PortCounters, with_port: bool) -> str:
if with_port and pc.lport is not None:
return f"{cd}({pc.lport})"
return cd
PASS, FAIL, NA = "PASS", "FAIL", "NA"
def pair_deltas(data: LogData, a: str, b: str) -> tuple[int, int] | None:
"""(cdA.TX - cdB.RX, cdA.RX - cdB.TX), or None if counters are missing."""
pa, pb = data.counters(a), data.counters(b)
if not (pa.complete and pb.complete):
return None
return pa.tx - pb.rx, pa.rx - pb.tx
def verdict(data: LogData, a: str, b: str, tolerance: int) -> str:
d = pair_deltas(data, a, b)
if d is None:
return NA
return PASS if max(abs(d[0]), abs(d[1])) <= tolerance else FAIL
def render(data: LogData, args: argparse.Namespace, out: TextIO) -> int:
status = not args.no_status
rows: list[tuple[str, ...]] = []
blocks: list[list[tuple[str, ...]]] = []
missing: list[tuple[str, str]] = []
failed: list[tuple[str, str, int, int]] = []
tally = {PASS: 0, FAIL: 0, NA: 0}
for a, b in data.pairs:
pa, pb = data.counters(a), data.counters(b)
v = verdict(data, a, b, args.tolerance)
tally[v] += 1
if v == NA:
missing.append((a, b))
if not args.all:
continue
elif v == FAIL:
d_tx, d_rx = pair_deltas(data, a, b)
failed.append((a, b, d_tx, d_rx))
block = []
for cd, pc in ((a, pa), (b, pb)):
row = (
fmt_port(cd, pc, args.with_port),
fmt_value(pc.tx, args.grouped),
fmt_value(pc.rx, args.grouped),
)
block.append(row + (v,) if status else row)
blocks.append(block)
rows.extend(block)
header = ("Port", "TX", "RX", "PASS/FAIL") if status else ("Port", "TX", "RX")
if args.tsv:
if not args.block:
print("\t".join(header), file=out)
for block in blocks:
if args.block:
print("\t".join(header), file=out)
for row in block:
print("\t".join(row), file=out)
if args.block:
print(file=out)
else:
# size columns to the widest cell actually emitted
ncol = len(header)
width = [
max([len(r[i]) for r in rows] + [len(header[i])]) + 2
for i in range(ncol)
]
def line(row: tuple[str, ...]) -> str:
cells = [f"{row[0]:<{width[0]}}"]
cells += [f"{row[i]:>{width[i]}}" for i in range(1, ncol)]
return "".join(cells).rstrip()
if not args.block:
print(line(header), file=out)
for block in blocks:
if args.block:
print(line(header), file=out)
for row in block:
print(line(row), file=out)
if args.block:
print(file=out)
if not args.quiet:
if not args.block:
print(file=out)
print(f"# pairs in pbm list : {len(data.pairs)}", file=out)
print(f"# pairs reported : {len(blocks)}", file=out)
print(
f"# PASS {tally[PASS]} FAIL {tally[FAIL]} NA {tally[NA]}"
f" (tolerance {args.tolerance})",
file=out,
)
if missing:
joined = " ".join(f"{a}/{b}" for a, b in missing)
print(f"# NA (no counters): {joined}", file=out)
for a, b, d_tx, d_rx in failed:
print(
f"# FAIL {a}/{b}: {a}.TX-{b}.RX={d_tx:+d} {a}.RX-{b}.TX={d_rx:+d}",
file=out,
)
return EXIT_WARN if (tally[FAIL] or tally[NA]) else EXIT_OK
def build_parser() -> argparse.ArgumentParser:
p = argparse.ArgumentParser(
description="Render Broadcom drivshell MIB_TPOK/RPOK counters as a "
"loopback-pair table.",
epilog="Exit 2 means missing counters and/or a cross-check mismatch.",
)
p.add_argument("log", type=Path, help="drivshell log file ('-' for stdin)")
p.add_argument("-a", "--all", action="store_true",
help="also emit pairs with no counters")
p.add_argument("-b", "--block", action="store_true",
help="repeat header and blank-separate each pair")
p.add_argument("-g", "--grouped", action="store_true",
help="keep comma grouping in values")
p.add_argument("-p", "--with-port", action="store_true",
help="render cd1(2) instead of cd1")
p.add_argument("-t", "--tsv", action="store_true",
help="tab-separated output")
p.add_argument("-s", "--no-status", action="store_true",
help="drop the PASS/FAIL column")
p.add_argument("-T", "--tolerance", type=int, default=0, metavar="N",
help="allowed |delta| in packets before a pair is FAIL "
"(default 0; -T 1 absorbs normal snapshot skew)")
p.add_argument("-q", "--quiet", action="store_true",
help="suppress trailing summary comments")
p.add_argument("-o", "--output", type=Path, default=None,
help="write to a file instead of stdout")
return p
def main(argv: list[str] | None = None) -> int:
args = build_parser().parse_args(argv)
try:
if str(args.log) == "-":
data = parse_log(sys.stdin)
else:
# console captures are frequently not clean UTF-8
with args.log.open("r", encoding="utf-8", errors="replace") as fh:
data = parse_log(fh)
except OSError as exc:
print(f"error: cannot read log: {exc}", file=sys.stderr)
return EXIT_USAGE
if not data.pairs:
print("error: no 'pbm=cdA,cdB' pair definition found in log",
file=sys.stderr)
return EXIT_USAGE
try:
if args.output:
with args.output.open("w", encoding="utf-8", newline="\n") as fh:
return render(data, args, fh)
return render(data, args, sys.stdout)
except BrokenPipeError:
# downstream closed the pipe (e.g. "| head") - not an error
try:
sys.stdout.close()
except BrokenPipeError:
pass
return EXIT_OK
except OSError as exc:
print(f"error: cannot write output: {exc}", file=sys.stderr)
return EXIT_USAGE
if __name__ == "__main__":
sys.exit(main())
+108
View File
@@ -0,0 +1,108 @@
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=30'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=31'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=32'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=33'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=34'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=35'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=36'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=37'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=38'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=39'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=40'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=41'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=42'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=43'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=44'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=45'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=46'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=47'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=48'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=49'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=50'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=51'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=52'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=53'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=54'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=55'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=56'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=57'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=58'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=59'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=60'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=61'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=62'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=63'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=64'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=65'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=66'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=67'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=68'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=69'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=70'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=71'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=72'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=73'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=74'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=75'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=76'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=77'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=78'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=79'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=80'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=81'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=82'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=83'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=84'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=85'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=86'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=87'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=88'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=89'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=90'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=91'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=92'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=93'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=94'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=95'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=96'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=97'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=98'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=99'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=100'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=101'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=102'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=103'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=104'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=105'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=106'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=107'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=108'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=109'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=110'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=111'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=112'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=113'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=114'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=115'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=116'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=117'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=118'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=119'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=120'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=121'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=122'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=123'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=124'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=125'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=126'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=127'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=128'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=129'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=130'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=131'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=132'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=133'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=134'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=135'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=136'
bcmcmd -n 1 -c 'tx 100 length=512 VLantag=137'
+108
View File
@@ -0,0 +1,108 @@
bcmcmd -n 1 -c 'vlan remove 30 pbm=cd0,cd32'
bcmcmd -n 1 -c 'vlan remove 31 pbm=cd1,cd33'
bcmcmd -n 1 -c 'vlan remove 32 pbm=cd2,cd34'
bcmcmd -n 1 -c 'vlan remove 33 pbm=cd3,cd35'
bcmcmd -n 1 -c 'vlan remove 34 pbm=cd4,cd36'
bcmcmd -n 1 -c 'vlan remove 35 pbm=cd5,cd37'
bcmcmd -n 1 -c 'vlan remove 36 pbm=cd6,cd38'
bcmcmd -n 1 -c 'vlan remove 37 pbm=cd7,cd39'
bcmcmd -n 1 -c 'vlan remove 38 pbm=cd8,cd40'
bcmcmd -n 1 -c 'vlan remove 39 pbm=cd9,cd41'
bcmcmd -n 1 -c 'vlan remove 40 pbm=cd10,cd42'
bcmcmd -n 1 -c 'vlan remove 41 pbm=cd11,cd43'
bcmcmd -n 1 -c 'vlan remove 42 pbm=cd12,cd44'
bcmcmd -n 1 -c 'vlan remove 43 pbm=cd13,cd45'
bcmcmd -n 1 -c 'vlan remove 44 pbm=cd14,cd46'
bcmcmd -n 1 -c 'vlan remove 45 pbm=cd20,cd52'
bcmcmd -n 1 -c 'vlan remove 46 pbm=cd21,cd53'
bcmcmd -n 1 -c 'vlan remove 47 pbm=cd22,cd54'
bcmcmd -n 1 -c 'vlan remove 48 pbm=cd23,cd55'
bcmcmd -n 1 -c 'vlan remove 49 pbm=cd24,cd56'
bcmcmd -n 1 -c 'vlan remove 50 pbm=cd25,cd57'
bcmcmd -n 1 -c 'vlan remove 51 pbm=cd26,cd58'
bcmcmd -n 1 -c 'vlan remove 52 pbm=cd27,cd59'
bcmcmd -n 1 -c 'vlan remove 53 pbm=cd28,cd60'
bcmcmd -n 1 -c 'vlan remove 54 pbm=cd29,cd61'
bcmcmd -n 1 -c 'vlan remove 55 pbm=cd30,cd62'
bcmcmd -n 1 -c 'vlan remove 56 pbm=cd31,cd63'
bcmcmd -n 1 -c 'vlan remove 57 pbm=cd64,cd96'
bcmcmd -n 1 -c 'vlan remove 58 pbm=cd65,cd97'
bcmcmd -n 1 -c 'vlan remove 59 pbm=cd66,cd98'
bcmcmd -n 1 -c 'vlan remove 60 pbm=cd67,cd99'
bcmcmd -n 1 -c 'vlan remove 61 pbm=cd68,cd100'
bcmcmd -n 1 -c 'vlan remove 62 pbm=cd69,cd101'
bcmcmd -n 1 -c 'vlan remove 63 pbm=cd70,cd102'
bcmcmd -n 1 -c 'vlan remove 64 pbm=cd71,cd103'
bcmcmd -n 1 -c 'vlan remove 65 pbm=cd72,cd104'
bcmcmd -n 1 -c 'vlan remove 66 pbm=cd73,cd105'
bcmcmd -n 1 -c 'vlan remove 67 pbm=cd74,cd106'
bcmcmd -n 1 -c 'vlan remove 68 pbm=cd75,cd107'
bcmcmd -n 1 -c 'vlan remove 69 pbm=cd76,cd108'
bcmcmd -n 1 -c 'vlan remove 70 pbm=cd77,cd109'
bcmcmd -n 1 -c 'vlan remove 71 pbm=cd78,cd110'
bcmcmd -n 1 -c 'vlan remove 72 pbm=cd84,cd116'
bcmcmd -n 1 -c 'vlan remove 73 pbm=cd85,cd117'
bcmcmd -n 1 -c 'vlan remove 74 pbm=cd86,cd118'
bcmcmd -n 1 -c 'vlan remove 75 pbm=cd87,cd119'
bcmcmd -n 1 -c 'vlan remove 76 pbm=cd88,cd120'
bcmcmd -n 1 -c 'vlan remove 77 pbm=cd89,cd121'
bcmcmd -n 1 -c 'vlan remove 78 pbm=cd90,cd122'
bcmcmd -n 1 -c 'vlan remove 79 pbm=cd91,cd123'
bcmcmd -n 1 -c 'vlan remove 80 pbm=cd92,cd124'
bcmcmd -n 1 -c 'vlan remove 81 pbm=cd93,cd125'
bcmcmd -n 1 -c 'vlan remove 82 pbm=cd94,cd126'
bcmcmd -n 1 -c 'vlan remove 83 pbm=cd95,cd127'
bcmcmd -n 1 -c 'vlan remove 84 pbm=cd128,cd160'
bcmcmd -n 1 -c 'vlan remove 85 pbm=cd129,cd161'
bcmcmd -n 1 -c 'vlan remove 86 pbm=cd130,cd162'
bcmcmd -n 1 -c 'vlan remove 87 pbm=cd131,cd163'
bcmcmd -n 1 -c 'vlan remove 88 pbm=cd132,cd164'
bcmcmd -n 1 -c 'vlan remove 89 pbm=cd133,cd165'
bcmcmd -n 1 -c 'vlan remove 90 pbm=cd134,cd166'
bcmcmd -n 1 -c 'vlan remove 91 pbm=cd135,cd167'
bcmcmd -n 1 -c 'vlan remove 92 pbm=cd136,cd168'
bcmcmd -n 1 -c 'vlan remove 93 pbm=cd137,cd169'
bcmcmd -n 1 -c 'vlan remove 94 pbm=cd138,cd170'
bcmcmd -n 1 -c 'vlan remove 95 pbm=cd140,cd172'
bcmcmd -n 1 -c 'vlan remove 96 pbm=cd141,cd173'
bcmcmd -n 1 -c 'vlan remove 97 pbm=cd142,cd174'
bcmcmd -n 1 -c 'vlan remove 98 pbm=cd143,cd175'
bcmcmd -n 1 -c 'vlan remove 99 pbm=cd144,cd176'
bcmcmd -n 1 -c 'vlan remove 100 pbm=cd145,cd177'
bcmcmd -n 1 -c 'vlan remove 101 pbm=cd146,cd178'
bcmcmd -n 1 -c 'vlan remove 102 pbm=cd147,cd179'
bcmcmd -n 1 -c 'vlan remove 103 pbm=cd152,cd184'
bcmcmd -n 1 -c 'vlan remove 104 pbm=cd153,cd185'
bcmcmd -n 1 -c 'vlan remove 105 pbm=cd154,cd186'
bcmcmd -n 1 -c 'vlan remove 106 pbm=cd155,cd187'
bcmcmd -n 1 -c 'vlan remove 107 pbm=cd156,cd188'
bcmcmd -n 1 -c 'vlan remove 108 pbm=cd157,cd189'
bcmcmd -n 1 -c 'vlan remove 109 pbm=cd158,cd190'
bcmcmd -n 1 -c 'vlan remove 110 pbm=cd159,cd191'
bcmcmd -n 1 -c 'vlan remove 111 pbm=cd192,cd224'
bcmcmd -n 1 -c 'vlan remove 112 pbm=cd193,cd225'
bcmcmd -n 1 -c 'vlan remove 113 pbm=cd194,cd226'
bcmcmd -n 1 -c 'vlan remove 114 pbm=cd195,cd227'
bcmcmd -n 1 -c 'vlan remove 115 pbm=cd196,cd228'
bcmcmd -n 1 -c 'vlan remove 116 pbm=cd197,cd229'
bcmcmd -n 1 -c 'vlan remove 117 pbm=cd198,cd230'
bcmcmd -n 1 -c 'vlan remove 118 pbm=cd199,cd231'
bcmcmd -n 1 -c 'vlan remove 119 pbm=cd200,cd232'
bcmcmd -n 1 -c 'vlan remove 120 pbm=cd201,cd233'
bcmcmd -n 1 -c 'vlan remove 121 pbm=cd202,cd234'
bcmcmd -n 1 -c 'vlan remove 122 pbm=cd204,cd236'
bcmcmd -n 1 -c 'vlan remove 123 pbm=cd205,cd237'
bcmcmd -n 1 -c 'vlan remove 124 pbm=cd206,cd238'
bcmcmd -n 1 -c 'vlan remove 125 pbm=cd207,cd239'
bcmcmd -n 1 -c 'vlan remove 126 pbm=cd208,cd240'
bcmcmd -n 1 -c 'vlan remove 127 pbm=cd209,cd241'
bcmcmd -n 1 -c 'vlan remove 128 pbm=cd210,cd242'
bcmcmd -n 1 -c 'vlan remove 129 pbm=cd211,cd243'
bcmcmd -n 1 -c 'vlan remove 130 pbm=cd216,cd248'
bcmcmd -n 1 -c 'vlan remove 131 pbm=cd217,cd249'
bcmcmd -n 1 -c 'vlan remove 132 pbm=cd218,cd250'
bcmcmd -n 1 -c 'vlan remove 133 pbm=cd219,cd251'
bcmcmd -n 1 -c 'vlan remove 134 pbm=cd220,cd252'
bcmcmd -n 1 -c 'vlan remove 135 pbm=cd221,cd253'
bcmcmd -n 1 -c 'vlan remove 136 pbm=cd222,cd254'
bcmcmd -n 1 -c 'vlan remove 137 pbm=cd223,cd255'
+325
View File
@@ -0,0 +1,325 @@
bcmcmd -n 1 -c 'vlan remove 1 pbm=cd'
bcmcmd -n 1 -c 'vlan create 30'
bcmcmd -n 1 -c 'vlan add 30 pbm=cd0,cd32'
bcmcmd -n 1 -c 'vlan create 31'
bcmcmd -n 1 -c 'vlan add 31 pbm=cd1,cd33'
bcmcmd -n 1 -c 'vlan create 32'
bcmcmd -n 1 -c 'vlan add 32 pbm=cd2,cd34'
bcmcmd -n 1 -c 'vlan create 33'
bcmcmd -n 1 -c 'vlan add 33 pbm=cd3,cd35'
bcmcmd -n 1 -c 'vlan create 34'
bcmcmd -n 1 -c 'vlan add 34 pbm=cd4,cd36'
bcmcmd -n 1 -c 'vlan create 35'
bcmcmd -n 1 -c 'vlan add 35 pbm=cd5,cd37'
bcmcmd -n 1 -c 'vlan create 36'
bcmcmd -n 1 -c 'vlan add 36 pbm=cd6,cd38'
bcmcmd -n 1 -c 'vlan create 37'
bcmcmd -n 1 -c 'vlan add 37 pbm=cd7,cd39'
bcmcmd -n 1 -c 'vlan create 38'
bcmcmd -n 1 -c 'vlan add 38 pbm=cd8,cd40'
bcmcmd -n 1 -c 'vlan create 39'
bcmcmd -n 1 -c 'vlan add 39 pbm=cd9,cd41'
bcmcmd -n 1 -c 'vlan create 40'
bcmcmd -n 1 -c 'vlan add 40 pbm=cd10,cd42'
bcmcmd -n 1 -c 'vlan create 41'
bcmcmd -n 1 -c 'vlan add 41 pbm=cd11,cd43'
bcmcmd -n 1 -c 'vlan create 42'
bcmcmd -n 1 -c 'vlan add 42 pbm=cd12,cd44'
bcmcmd -n 1 -c 'vlan create 43'
bcmcmd -n 1 -c 'vlan add 43 pbm=cd13,cd45'
bcmcmd -n 1 -c 'vlan create 44'
bcmcmd -n 1 -c 'vlan add 44 pbm=cd14,cd46'
bcmcmd -n 1 -c 'vlan create 45'
bcmcmd -n 1 -c 'vlan add 45 pbm=cd20,cd52'
bcmcmd -n 1 -c 'vlan create 46'
bcmcmd -n 1 -c 'vlan add 46 pbm=cd21,cd53'
bcmcmd -n 1 -c 'vlan create 47'
bcmcmd -n 1 -c 'vlan add 47 pbm=cd22,cd54'
bcmcmd -n 1 -c 'vlan create 48'
bcmcmd -n 1 -c 'vlan add 48 pbm=cd23,cd55'
bcmcmd -n 1 -c 'vlan create 49'
bcmcmd -n 1 -c 'vlan add 49 pbm=cd24,cd56'
bcmcmd -n 1 -c 'vlan create 50'
bcmcmd -n 1 -c 'vlan add 50 pbm=cd25,cd57'
bcmcmd -n 1 -c 'vlan create 51'
bcmcmd -n 1 -c 'vlan add 51 pbm=cd26,cd58'
bcmcmd -n 1 -c 'vlan create 52'
bcmcmd -n 1 -c 'vlan add 52 pbm=cd27,cd59'
bcmcmd -n 1 -c 'vlan create 53'
bcmcmd -n 1 -c 'vlan add 53 pbm=cd28,cd60'
bcmcmd -n 1 -c 'vlan create 54'
bcmcmd -n 1 -c 'vlan add 54 pbm=cd29,cd61'
bcmcmd -n 1 -c 'vlan create 55'
bcmcmd -n 1 -c 'vlan add 55 pbm=cd30,cd62'
bcmcmd -n 1 -c 'vlan create 56'
bcmcmd -n 1 -c 'vlan add 56 pbm=cd31,cd63'
bcmcmd -n 1 -c 'vlan create 57'
bcmcmd -n 1 -c 'vlan add 57 pbm=cd64,cd96'
bcmcmd -n 1 -c 'vlan create 58'
bcmcmd -n 1 -c 'vlan add 58 pbm=cd65,cd97'
bcmcmd -n 1 -c 'vlan create 59'
bcmcmd -n 1 -c 'vlan add 59 pbm=cd66,cd98'
bcmcmd -n 1 -c 'vlan create 60'
bcmcmd -n 1 -c 'vlan add 60 pbm=cd67,cd99'
bcmcmd -n 1 -c 'vlan create 61'
bcmcmd -n 1 -c 'vlan add 61 pbm=cd68,cd100'
bcmcmd -n 1 -c 'vlan create 62'
bcmcmd -n 1 -c 'vlan add 62 pbm=cd69,cd101'
bcmcmd -n 1 -c 'vlan create 63'
bcmcmd -n 1 -c 'vlan add 63 pbm=cd70,cd102'
bcmcmd -n 1 -c 'vlan create 64'
bcmcmd -n 1 -c 'vlan add 64 pbm=cd71,cd103'
bcmcmd -n 1 -c 'vlan create 65'
bcmcmd -n 1 -c 'vlan add 65 pbm=cd72,cd104'
bcmcmd -n 1 -c 'vlan create 66'
bcmcmd -n 1 -c 'vlan add 66 pbm=cd73,cd105'
bcmcmd -n 1 -c 'vlan create 67'
bcmcmd -n 1 -c 'vlan add 67 pbm=cd74,cd106'
bcmcmd -n 1 -c 'vlan create 68'
bcmcmd -n 1 -c 'vlan add 68 pbm=cd75,cd107'
bcmcmd -n 1 -c 'vlan create 69'
bcmcmd -n 1 -c 'vlan add 69 pbm=cd76,cd108'
bcmcmd -n 1 -c 'vlan create 70'
bcmcmd -n 1 -c 'vlan add 70 pbm=cd77,cd109'
bcmcmd -n 1 -c 'vlan create 71'
bcmcmd -n 1 -c 'vlan add 71 pbm=cd78,cd110'
bcmcmd -n 1 -c 'vlan create 72'
bcmcmd -n 1 -c 'vlan add 72 pbm=cd84,cd116'
bcmcmd -n 1 -c 'vlan create 73'
bcmcmd -n 1 -c 'vlan add 73 pbm=cd85,cd117'
bcmcmd -n 1 -c 'vlan create 74'
bcmcmd -n 1 -c 'vlan add 74 pbm=cd86,cd118'
bcmcmd -n 1 -c 'vlan create 75'
bcmcmd -n 1 -c 'vlan add 75 pbm=cd87,cd119'
bcmcmd -n 1 -c 'vlan create 76'
bcmcmd -n 1 -c 'vlan add 76 pbm=cd88,cd120'
bcmcmd -n 1 -c 'vlan create 77'
bcmcmd -n 1 -c 'vlan add 77 pbm=cd89,cd121'
bcmcmd -n 1 -c 'vlan create 78'
bcmcmd -n 1 -c 'vlan add 78 pbm=cd90,cd122'
bcmcmd -n 1 -c 'vlan create 79'
bcmcmd -n 1 -c 'vlan add 79 pbm=cd91,cd123'
bcmcmd -n 1 -c 'vlan create 80'
bcmcmd -n 1 -c 'vlan add 80 pbm=cd92,cd124'
bcmcmd -n 1 -c 'vlan create 81'
bcmcmd -n 1 -c 'vlan add 81 pbm=cd93,cd125'
bcmcmd -n 1 -c 'vlan create 82'
bcmcmd -n 1 -c 'vlan add 82 pbm=cd94,cd126'
bcmcmd -n 1 -c 'vlan create 83'
bcmcmd -n 1 -c 'vlan add 83 pbm=cd95,cd127'
bcmcmd -n 1 -c 'vlan create 84'
bcmcmd -n 1 -c 'vlan add 84 pbm=cd128,cd160'
bcmcmd -n 1 -c 'vlan create 85'
bcmcmd -n 1 -c 'vlan add 85 pbm=cd129,cd161'
bcmcmd -n 1 -c 'vlan create 86'
bcmcmd -n 1 -c 'vlan add 86 pbm=cd130,cd162'
bcmcmd -n 1 -c 'vlan create 87'
bcmcmd -n 1 -c 'vlan add 87 pbm=cd131,cd163'
bcmcmd -n 1 -c 'vlan create 88'
bcmcmd -n 1 -c 'vlan add 88 pbm=cd132,cd164'
bcmcmd -n 1 -c 'vlan create 89'
bcmcmd -n 1 -c 'vlan add 89 pbm=cd133,cd165'
bcmcmd -n 1 -c 'vlan create 90'
bcmcmd -n 1 -c 'vlan add 90 pbm=cd134,cd166'
bcmcmd -n 1 -c 'vlan create 91'
bcmcmd -n 1 -c 'vlan add 91 pbm=cd135,cd167'
bcmcmd -n 1 -c 'vlan create 92'
bcmcmd -n 1 -c 'vlan add 92 pbm=cd136,cd168'
bcmcmd -n 1 -c 'vlan create 93'
bcmcmd -n 1 -c 'vlan add 93 pbm=cd137,cd169'
bcmcmd -n 1 -c 'vlan create 94'
bcmcmd -n 1 -c 'vlan add 94 pbm=cd138,cd170'
bcmcmd -n 1 -c 'vlan create 95'
bcmcmd -n 1 -c 'vlan add 95 pbm=cd140,cd172'
bcmcmd -n 1 -c 'vlan create 96'
bcmcmd -n 1 -c 'vlan add 96 pbm=cd141,cd173'
bcmcmd -n 1 -c 'vlan create 97'
bcmcmd -n 1 -c 'vlan add 97 pbm=cd142,cd174'
bcmcmd -n 1 -c 'vlan create 98'
bcmcmd -n 1 -c 'vlan add 98 pbm=cd143,cd175'
bcmcmd -n 1 -c 'vlan create 99'
bcmcmd -n 1 -c 'vlan add 99 pbm=cd144,cd176'
bcmcmd -n 1 -c 'vlan create 100'
bcmcmd -n 1 -c 'vlan add 100 pbm=cd145,cd177'
bcmcmd -n 1 -c 'vlan create 101'
bcmcmd -n 1 -c 'vlan add 101 pbm=cd146,cd178'
bcmcmd -n 1 -c 'vlan create 102'
bcmcmd -n 1 -c 'vlan add 102 pbm=cd147,cd179'
bcmcmd -n 1 -c 'vlan create 103'
bcmcmd -n 1 -c 'vlan add 103 pbm=cd152,cd184'
bcmcmd -n 1 -c 'vlan create 104'
bcmcmd -n 1 -c 'vlan add 104 pbm=cd153,cd185'
bcmcmd -n 1 -c 'vlan create 105'
bcmcmd -n 1 -c 'vlan add 105 pbm=cd154,cd186'
bcmcmd -n 1 -c 'vlan create 106'
bcmcmd -n 1 -c 'vlan add 106 pbm=cd155,cd187'
bcmcmd -n 1 -c 'vlan create 107'
bcmcmd -n 1 -c 'vlan add 107 pbm=cd156,cd188'
bcmcmd -n 1 -c 'vlan create 108'
bcmcmd -n 1 -c 'vlan add 108 pbm=cd157,cd189'
bcmcmd -n 1 -c 'vlan create 109'
bcmcmd -n 1 -c 'vlan add 109 pbm=cd158,cd190'
bcmcmd -n 1 -c 'vlan create 110'
bcmcmd -n 1 -c 'vlan add 110 pbm=cd159,cd191'
bcmcmd -n 1 -c 'vlan create 111'
bcmcmd -n 1 -c 'vlan add 111 pbm=cd192,cd224'
bcmcmd -n 1 -c 'vlan create 112'
bcmcmd -n 1 -c 'vlan add 112 pbm=cd193,cd225'
bcmcmd -n 1 -c 'vlan create 113'
bcmcmd -n 1 -c 'vlan add 113 pbm=cd194,cd226'
bcmcmd -n 1 -c 'vlan create 114'
bcmcmd -n 1 -c 'vlan add 114 pbm=cd195,cd227'
bcmcmd -n 1 -c 'vlan create 115'
bcmcmd -n 1 -c 'vlan add 115 pbm=cd196,cd228'
bcmcmd -n 1 -c 'vlan create 116'
bcmcmd -n 1 -c 'vlan add 116 pbm=cd197,cd229'
bcmcmd -n 1 -c 'vlan create 117'
bcmcmd -n 1 -c 'vlan add 117 pbm=cd198,cd230'
bcmcmd -n 1 -c 'vlan create 118'
bcmcmd -n 1 -c 'vlan add 118 pbm=cd199,cd231'
bcmcmd -n 1 -c 'vlan create 119'
bcmcmd -n 1 -c 'vlan add 119 pbm=cd200,cd232'
bcmcmd -n 1 -c 'vlan create 120'
bcmcmd -n 1 -c 'vlan add 120 pbm=cd201,cd233'
bcmcmd -n 1 -c 'vlan create 121'
bcmcmd -n 1 -c 'vlan add 121 pbm=cd202,cd234'
bcmcmd -n 1 -c 'vlan create 122'
bcmcmd -n 1 -c 'vlan add 122 pbm=cd204,cd236'
bcmcmd -n 1 -c 'vlan create 123'
bcmcmd -n 1 -c 'vlan add 123 pbm=cd205,cd237'
bcmcmd -n 1 -c 'vlan create 124'
bcmcmd -n 1 -c 'vlan add 124 pbm=cd206,cd238'
bcmcmd -n 1 -c 'vlan create 125'
bcmcmd -n 1 -c 'vlan add 125 pbm=cd207,cd239'
bcmcmd -n 1 -c 'vlan create 126'
bcmcmd -n 1 -c 'vlan add 126 pbm=cd208,cd240'
bcmcmd -n 1 -c 'vlan create 127'
bcmcmd -n 1 -c 'vlan add 127 pbm=cd209,cd241'
bcmcmd -n 1 -c 'vlan create 128'
bcmcmd -n 1 -c 'vlan add 128 pbm=cd210,cd242'
bcmcmd -n 1 -c 'vlan create 129'
bcmcmd -n 1 -c 'vlan add 129 pbm=cd211,cd243'
bcmcmd -n 1 -c 'vlan create 130'
bcmcmd -n 1 -c 'vlan add 130 pbm=cd216,cd248'
bcmcmd -n 1 -c 'vlan create 131'
bcmcmd -n 1 -c 'vlan add 131 pbm=cd217,cd249'
bcmcmd -n 1 -c 'vlan create 132'
bcmcmd -n 1 -c 'vlan add 132 pbm=cd218,cd250'
bcmcmd -n 1 -c 'vlan create 133'
bcmcmd -n 1 -c 'vlan add 133 pbm=cd219,cd251'
bcmcmd -n 1 -c 'vlan create 134'
bcmcmd -n 1 -c 'vlan add 134 pbm=cd220,cd252'
bcmcmd -n 1 -c 'vlan create 135'
bcmcmd -n 1 -c 'vlan add 135 pbm=cd221,cd253'
bcmcmd -n 1 -c 'vlan create 136'
bcmcmd -n 1 -c 'vlan add 136 pbm=cd222,cd254'
bcmcmd -n 1 -c 'vlan create 137'
bcmcmd -n 1 -c 'vlan add 137 pbm=cd223,cd255'