TRex Network Monitoring and Performance Test Platform

Concept, Implementation Plan and Operations Guide for the LVR-InfoKom data centres Kalk (RZK) and Chorweiler (RZC) - HPE FlexFabric 5950 EVPN-VXLAN fabric
Document status
Draft v0.9 for review (content to be ironed out before PDF release)
Date
12 October 2026
Customer
Landschaftsverband Rheinland - LVR-InfoKom, Team Netzwerk/TK
Scope
RZK (Rechenzentrum Kalk) and RZC (Rechenzentrum Chorweiler); RZD (Deutz) out of scope
Platform under test
HPE FlexFabric 5950 Comware 7.1.070 R6301 / R6301P03 (sw-rzc-L21: R6205P03), Check Point firewalls CPF-ZV01/02 (Enterprise FW) and CPF-ZV05/06 (DC FW)
Tooling
Cisco TRex v3.08 (stateless + ASTF), TRex EMU, custom orchestrator trexctl, InfluxDB OSS 2.x, Grafana
Language
English (project language); source documents partly German

Document control

VersionDateAuthorChanges
0.92026-10-12Secured NetworksFirst complete draft based on the 2025-02-17 diagnostic files, the "Big Picture-Rechenzentren-RZKC" topology (15.05.2024), the reference design "man_trex_documentation_v1.3" and the customer decisions recorded in section 2.3.
1.0tbdIncorporate review comments, fill open items (section 12.5), release as PDF.

Conventions used in this document

MarkerMeaning
VALIDATEDCommand or behaviour verified against output of the same device family and release (diagnostic files of 2025-02-17) or against the HPE FlexFabric 5950 R630x documentation (cited by PDF file and PDF page number), or against the official TRex / InfluxDB / Grafana documentation.
CONFIRMSyntactically plausible and consistent with the documentation, but one or more values (port numbers, IP addresses, FW object names) or a behaviour must be confirmed on the live system before execution. Use contextual ? help on the CLI first.
DECISIONDesign proposal that requires a customer decision or confirmation (IP plan, naming, FW zone design, procurement).
TBDValue not yet known; collected in the open items list (section 12.5).
<UPPER-CASE>Placeholder to be replaced with a real value (e.g. <MGMT-IP>).
pre.cli (blue bar)Comware CLI (switch). pre.sh (grey): Linux shell. pre.py (yellow): Python. pre.yaml (purple): YAML. pre.flux (cyan): Flux/InfluxQL.
Naming used throughout TX switch = dedicated TRex distribution switch (one per DC: sw-rzk-TX1, sw-rzc-TX1). AP = attachment point (a physical link from a TX switch into a production device: Leaf, Border Leaf or firewall). S-VLAN = outer 802.1Q tag used only on the TX switches to identify an AP (QinQ). C-VLAN = inner tag = production VLAN ID. Stream = one unidirectional TRex packet flow with its own statistics (packet group id, pg_id). Class = traffic class (L2, L3-BL, L3-DCFW, L3-ENTFW, DSCP, LAB).

Table of contents

1. Executive summary

LVR-InfoKom operates an HPE FlexFabric 5950 EVPN-VXLAN fabric spanning the data centres Kalk (RZK, BGP AS 65001) and Chorweiler (RZC, BGP AS 65002). The fabric has no built-in way to measure end-to-end delay, jitter and packet loss between arbitrary points, across the inter-DC link, across the Border Leaf routing functions or across the Check Point firewalls. This document describes a permanent, low-footprint measurement platform based on the open-source traffic generator Cisco TRex, plus an on-demand performance test capability, with all results stored in InfluxDB and visualised in Grafana.

The core design decisions are:

The expected monitoring footprint is below 50 Mbit/s and 50 kpps in total (roughly 180 streams at 50-200 pps each, 128-byte packets), i.e. negligible for the fabric and the firewalls. Sections 7 and 8 contain step-by-step configuration and installation procedures, section 11 the test and operations procedures, and section 12 the phased implementation plan with acceptance criteria and open items.

2. Requirements, scope and decisions

2.1 Customer requirements (as stated)

  1. TRex server with several NICs.
  2. Send traffic inside multiple production VLANs to measure delay permanently and to run occasional performance tests.
  3. Traffic types: Layer 2 (inside one VLAN); Layer 3 within a single VRF (default routing table or a single vpn-instance); Layer 3 between different VRFs (vpn-instances); traffic through the firewall.
  4. The TRex server is connected to one of two dedicated switches; the two switches are in different DCs (RZK, RZC), one per DC, each with physical connections to every Leaf, Border Leaf and FW in its DC.
  5. Integration with Grafana for visualisation.
  6. Reference: the MAN Truck & Bus TRex documentation v1.3 (German) as inspiration, not a 1:1 copy.

2.2 Interpretation against the real fabric

The diagnostic files show that the fabric uses centralised Layer 3: the Leafs are pure Layer 2 VTEPs (VLAN to VSI mapping via Ethernet service instances), and all vpn-instance gateways live on the Border Leafs. Most server VLANs do not have a switch gateway at all - their default gateway is the DC firewall (CPF-ZV05/06). The default routing table (public instance) carries only the underlay (loopbacks, OSPF 172, BGP EVPN), so "L3 in the default routing table" has no end-system meaning in this fabric. The requirement list therefore maps to these measurable paths:

RequirementPath in this fabricTraffic class in this document
L2 inside one VLANLeaf - Spine - Leaf (VXLAN), intra-DC and inter-DC via the Border-Leaf DCI link (RAGG1, 2 x 40G, MACsec)L2
L3 within a single VRFVLAN with a Border-Leaf gateway in VPN-CORE to another such VLAN (e.g. 1314 to 1315), routed on sw-rzk-BLL3-BL
L3 between VLANs whose gateway is the DC firewallVLAN A - Leaf - BL - DC-FW (CPF-ZV05/06, "Vlan-all" channel) - BL - Leaf - VLAN BL3-DCFW
L3 between VRFs / through the firewallVPN-CORE - Border Leaf - transfer VSI 4002 - Enterprise FW (CPF-ZV01/02) - new TRex firewall zone (dedicated FW interface on the TX switches). Other VRFs (VPN-WAN, VPN-WLAN) can be added later with the same pattern.L3-ENTFW
QoS verificationAny of the above with different DSCP markingsDSCP
Performance testsAny AP pair, stateless line-rate (hardware assisted) or stateful TCP through the Enterprise FWLAB

2.3 Decisions taken with the customer (12 October 2026)

TopicDecisionStatus
TX switch platformHPE FlexFabric 5950 spare units (Comware 7, R630x syntax)DECIDED
Inter-DC connection of the TX switchesDedicated dark fibre / DWDM channel (not through the production fabric)DECIDED
TRex serversOne server in RZK; hardware not yet purchased, BoM in section 5DECIDED
TRex NIC speed10G SFP+ (Intel X710)DECIDED
TX switch to Leaf/BL links1 x 10G per Leaf/BL IRF pair (single member)DECIDED
Direct firewall linkEnterprise FW (CPF-ZV01/02) test interface = dedicated TRex zoneDECIDED
Firewall productCheck Point (Gaia, ClusterXL)DECIDED
Addresses in production VLANsReserve a small range per monitored VLAN (16 addresses, see 4.6)DECIDED
VRF scopeOnly VPN-CORE (plus the FW zone); VPN-WAN/VPN-WLAN out of scope for nowDECIDED
Visualisation stackAll-in-one on the TRex server: InfluxDB OSS 2.x + GrafanaDECIDED
OrchestrationCustom Python orchestrator (trexctl) built on the TRex STL/EMU/ASTF APIsDECIDED
Stateful testsIn scope (TRex ASTF, firewall)DECIDED
Server OSRHEL 9 / Rocky Linux 9 / AlmaLinux 9DECIDED
Additional scopeQoS/DSCP per-class measurements. Not in scope: IPv6, multicast, RZD (Deutz)DECIDED
Monitoring packet ratePer stream type (section 4.5)DECIDED

2.4 Assumptions

3. Environment analysis (as found)

Sources: diag_*_20250217/18.txt for sw-rzk-S1/S2, sw-rzk-L11, sw-rzk-BL, SW-RZC-S1/S2, SW-RZC-L21, sw-rzc-BL, sw-rzd-BL; "Big Picture-Rechenzentren-RZKC.pdf" (page 1); "LVR-InfoKom - Comware Switch Analysis v1.0.xlsx".

3.1 Devices and roles

DeviceRole / DCModelReleaseLoopback0ManagementNotes
sw-rzk-S1 / S2Spine RZK5950 32QSFP28 (JH321A)R6301172.31.0.252 / .25310.112.118.37 / .34OSPF 172 area 0.0.0.172 underlay, iBGP EVPN route reflection within AS 65001
sw-rzk-L11, L12, L21, L31, L41Leaf RZK (IRF pairs)5950 4-slot (JH404A)R6301 (L11)172.31.0.241, .245, .242, .243, .24410.112.118.39, 10.112.117.11, .40, .35, .41L2-only VTEPs; ~550 VSIs; access via service-instance/xconnect vsi
sw-rzk-BLBorder Leaf RZK (IRF)5950 4-slot + MACsec moduleR6301P03172.31.0.25410.0.31.224 (mon 10.9.0.17)All L3 gateways; VRFs VPN-CORE/WAN/WLAN/MGMT; DCI RAGG1 2x40G to sw-rzc-BL; eBGP EVPN to AS 65002/65003
sw-rzc-S1 / S2Spine RZC5950 32QSFP28R6301172.31.1.252 / .25310.112.118.18 / .17
sw-rzc-L11, L12, L13, L21, L22, L23Leaf RZC (IRF pairs)5950 4-slotR6205P03 (L21)172.31.1.241 ... .24610.0.31.237, 10.112.118.29, 10.0.31.238, .31, .30, .28sw-rzc-L21 runs an older release (upgrade recommended in the switch analysis)
sw-rzc-BLBorder Leaf RZC (IRF)5950 4-slot + MACsecR6301P03172.31.1.25410.0.31.228 (mon 10.9.0.18)Transfer VSIs only (20/21/30/31/40/41/44/50); no server-VLAN gateways
CPF-ZV01 / ZV02Enterprise FW RZK / RZCCheck Point---Hub between VPN-CORE, VPN-WAN, VPN-WLAN (transfer VSIs 4000-4002), OSPF neighbour 10.9.0.22 in VPN-CORE
CPF-ZV05 / ZV06DC FW RZK / RZCCheck Point---Default gateway of most server VLANs (BAGG31 "Vlan-all": VLANs 32 ... 1000-1399, 4033); transfer VSI 4004 to VPN-CORE (10.9.0.33/.34, FW 10.9.0.35)

3.2 Layer 2 / Layer 3 model relevant for TRex

3.3 Lessons taken from the reference design (MAN, man_trex_documentation_v1.3)

Reference design elementAdopted?Comment
Dedicated "TRex switch" between server and network, dot1q-tunnel (QinQ) per attachment pointYesSame principle, implemented with Comware qinq enable. In addition the inter-DC fibre extends the RZC attachment points to the server in RZK.
One TRex port per attachment point (12 ports)PartlyMonitoring uses two multiplexed (double-tagged) ports for all 14 APs; four "lab" ports are pinned 1:1 to selectable APs for hardware-assisted line-rate tests.
TRex in --software --emu mode for multi-VLAN ARPYes (monitoring instance)Required for QinQ flow statistics (TRex stateless guide, "Flow statistics - Limitations").
Proprietary trex_client.py (ncurses) with setup/profile YAMLConcept onlyNot available to LVR. trexctl is specified from scratch (section 9) with a similar inventory/profile split and tagging model for Grafana.
InfluxDB 1.8 + Grafana 7, 1-second samplingModernisedInfluxDB OSS 2.x (Flux/InfluxQL), Grafana current LTS, 2-second sampling by default, downsampling task for long-term retention.
1000 pps per stream = 1 ms outage resolutionPer class200 pps for fabric classes (5 ms resolution), 50 pps for firewall classes; configurable, can be raised for convergence tests.
trex_daemon_server under systemdReplacedTwo static systemd units (monitor, lab) are simpler and deterministic; the daemon remains optional for remote restarts.

4. Solution concept

4.1 Components and overall architecture

RZK - Rechenzentrum Kalk (AS 65001) RZC - Rechenzentrum Chorweiler (AS 65002) TRex server trex-rzk-01 HPE ProLiant, RHEL/Rocky 9 NIC1 X710-DA4: p0 p1 p2 p3 instance trex-mon STL --software --emu p0/p1 double-tagged, all APs NIC2 X710-DA4: p4 p5 p6 p7 instance trex-lab STL hardware mode / ASTF single-tagged, pinned 1:1 to an AP mgmt NIC trexctl, InfluxDB, Grafana (HTTPS), SSH Network team Grafana dashboards / alerts, trexctl CLI sw-rzk-TX1 (HPE 5950) no STP, no production VLANs p0-p3: XGE1/1/21-24 trunk, all S-VLANs p4-p7: XGE1/1/9-12 QinQ access, PVID = pinned AP AP ports XGE1/1/1-6: QinQ access, PVID = S-VLAN XGE1/1/7: QinQ access, S-VLAN 3300 (FW zone) HGE1/2/1: trunk to sw-rzc-TX1 S-VLANs 3201-3210, 3300 one isolated bridge domain per AP 4 x 10G DAC 4 x 10G DAC sw-rzk-L11 (IRF)AP K-L11, S-VLAN 3101 sw-rzk-L12 (IRF)AP K-L12, S-VLAN 3102 sw-rzk-L21 (IRF)AP K-L21, S-VLAN 3103 sw-rzk-L31 (IRF)AP K-L31, S-VLAN 3104 sw-rzk-L41 (IRF)AP K-L41, S-VLAN 3105 sw-rzk-BL (IRF)AP K-BL, S-VLAN 3110 CPF-ZV01 (ENT-FW member)AP FW, S-VLAN 3300 (stretched) EVPN-VXLAN fabric sw-rzk-S1/S2 spines VSIs, VPN-CORE gateways on BL DC-FW CPF-ZV05 (Vlan-all) ENT-FW transfer VSI 4002 BL DCI RAGG1 2 x 40G MACsec sw-rzc-TX1 (HPE 5950) no STP, no production VLANs AP ports XGE1/1/1-7: QinQ access, PVID = S-VLAN XGE1/1/8: QinQ access, S-VLAN 3300 (FW zone) HGE1/2/1: trunk to sw-rzk-TX1 S-VLANs 3201-3210, 3300 no TRex ports in RZC dedicated dark fibre / DWDM TX-to-TX trunk, 10G/40G/100G, QinQ frames sw-rzc-L11AP C-L11, S-VLAN 3201 sw-rzc-L12AP C-L12, S-VLAN 3202 sw-rzc-L13AP C-L13, S-VLAN 3203 sw-rzc-L21AP C-L21, S-VLAN 3204 sw-rzc-L22AP C-L22, S-VLAN 3205 sw-rzc-L23AP C-L23, S-VLAN 3206 sw-rzc-BLAP C-BL, S-VLAN 3210 CPF-ZV02 (ENT-FW member)AP FW, S-VLAN 3300 (stretched) EVPN-VXLAN fabric sw-rzc-S1/S2 spines VSIs stretched from RZK DC-FW CPF-ZV06 ENT-FW transfer VSI 4002
Figure 1 - Overall architecture. The TRex server sits in RZK; every attachment point (AP) in both DCs is reachable through an isolated QinQ domain on the TX switches; the RZC APs are extended to the server over the dedicated TX-to-TX fibre.
ComponentFunctionTechnology / product
TRex server trex-rzk-01Generates and receives all test traffic; hosts the orchestrator, InfluxDB and GrafanaHPE ProLiant DL380 Gen11 (or DL360), 1 CPU, 128 GB RAM, 2 x Intel X710-DA4, RHEL/Rocky 9, TRex v3.08
TX switches sw-rzk-TX1, sw-rzc-TX1Transparent QinQ "patch panel" from TRex ports to attachment points; extension of RZC APs over the inter-DC fibreHPE FlexFabric 5950 (spare units), Comware 7 R630x
Attachment points1 x 10G trunk port on each Leaf pair and Border Leaf (production VLANs under test mapped via service instances); 1 x 10G per Enterprise-FW cluster member (TRex firewall zone)Leaf/BL: existing free SFP+ ports; FW: free 10G interface per member
Inter-DC TX linkCarries S-VLANs 3201-3210 and 3300 between the TX switchesDedicated fibre pair or DWDM channel, 10G LR/ER or 40G/100G LR4 optics
TRex monitoring instance trex-monPermanent streams, latency/jitter/loss per stream, up to 1023 streams, QinQ frames, EMU for ARP/ICMPTRex STL, --software --emu, NIC1
TRex lab instance trex-labOn-demand line-rate stateless tests (hardware flow statistics, 127 streams) or stateful ASTF testsTRex STL (hardware mode) or ASTF, NIC2
Orchestrator trexctlInventory/profile YAML to streams, EMU provisioning, start/stop, test runners, statistics exportPython 3.12 virtual environment, TRex Python APIs (STL, EMU, ASTF), InfluxDB client
Time-series databaseStores per-stream and per-port statistics; retention and downsamplingInfluxDB OSS 2.x (currently 2.9.x), Flux + InfluxQL
Visualisation / alertingDashboards, alert rules, annotations for maintenance windowsGrafana (current LTS, 12.4.x; 13.x also supported)

4.2 Attachment-point model: QinQ on the TX switches

The TX switch must connect a small number of TRex ports to many production devices without ever bridging production VLANs between two attachment points (which would create a loop through the stretched VXLAN VLANs). Comware QinQ solves this elegantly: a QinQ-enabled port adds the port PVID as an outer tag to every incoming frame, tagged or untagged, and removes it on egress (Layer 2 Configuration Guide, "Configuring QinQ", PDF pp. 219-222). By giving every AP-facing port its own PVID (S-VLAN), each AP becomes an isolated two-port bridge domain: {AP port, TRex port(s)}.

TRex port p0 EMU client 02:54:52:01:05:22 10.3.14.101/24 sw-rzk-TX1 XGE1/1/21 port link-type trunk permit 3101-3110, 3201-3210, 3300 S-tag kept on wire XGE1/1/1 port access vlan 3101 qinq enable in: push S=3101 out: pop S=3101 S-VLAN 3101 sw-rzk-L11 XGE1/3/1 port link-type trunk port trunk permit vlan 1314 1315 ... service-instance 1314 encapsulation s-vid 1314 xconnect vsi VPN-1314 -> VXLAN 1314, EVPN Frame on TRex link (double-tagged) DA SA S 3101 C 1314 IP tos / UDP pg_id / timestamp Frame on Leaf link (single-tagged) DA SA C 1314 IP tos / UDP pg_id / timestamp Return direction: Leaf sends single-tagged (C 1314) -> XGE1/1/1 pushes S 3101 -> XGE1/1/21 forwards double-tagged -> TRex p0 (promiscuous) -> EMU / flow statistics Pinned lab ports (XGE1/1/9-12) are themselves QinQ access ports: TRex sends single-tagged C 1314, the switch pushes/pops the S-tag; the TRex side never sees the S-tag.
Figure 2 - QinQ frame handling between a multiplexed TRex port, the TX switch and a Leaf attachment point (example AP K-L11, VLAN 1314).

Two kinds of TRex-facing ports exist on sw-rzk-TX1:

TRex-facing port typeTX switch configurationFrame on TRex sideUsed byPros / cons
Multiplexed (p0, p1; p2, p3 reserved)802.1Q trunk permitting all S-VLANsDouble-tagged: outer S-VLAN = AP, inner = production VLANtrex-mon (permanent monitoring, most tests)Any AP from any port, no re-cabling or re-configuration; requires TRex --software mode (QinQ flow statistics), 1023 streams, software RX processing
Pinned (p4-p7)QinQ access port, PVID = S-VLAN of the chosen APSingle-tagged production VLANtrex-lab (line rate, ASTF)Hardware flow statistics on X710 ("IPv4 with one VLAN tag"), full line rate; re-pinning = one CLI command (port access vlan); 127 concurrent streams in hardware mode
Why the TX switch runs without STP and without production VLANs Each S-VLAN contains exactly one AP port and the TRex-facing ports. The TRex server does not bridge between its ports (DPDK ports have no kernel stack), so no Layer 2 loop can form and no BPDU interaction with the fabric is wanted. STP is disabled globally on the TX switches (undo stp global enable, L2 Configuration Guide PDF p. 306; it is the default when the device starts with initial settings). BPDUs received from a Leaf on a QinQ port are flooded as data within that S-VLAN only, i.e. to the TRex ports, where TRex discards them CONFIRM (to be observed in the lab phase; if undesired, bpdu-drop any can be added to the AP ports). The Leaf AP ports are configured as edge ports so that they forward immediately (PVST VLANs otherwise wait 30 s).

4.3 Traffic classes and paths

4.3.1 Class L2 - Layer 2 inside one VLAN

Source and destination TRex clients are in the same production VLAN (C-VLAN) at two different APs. The destination MAC is the MAC of the remote TRex client (known from the inventory - no ARP needed; EMU gratuitous ARP keeps the remote MAC learned in the fabric). Path: TX switch - Leaf A - Spine - Leaf B (VXLAN) - TX switch. Inter-DC variant: Leaf A - Spine - sw-rzk-BL - RAGG1 (MACsec) - sw-rzc-BL - Spine - Leaf B - sw-rzc-TX1 - fibre - sw-rzk-TX1. Measures fabric forwarding, VXLAN encapsulation, DCI link and IRF behaviour.

4.3.2 Class L3-BL - Layer 3 within VPN-CORE routed on the Border Leaf

Source in VLAN 1314 (gateway 10.3.14.1 on sw-rzk-BL Vsi-interface914), destination in VLAN 1315 (10.3.15.1, Vsi-interface915), both bound to VPN-CORE. Destination MAC = gateway MAC resolved by EMU ARP. Path: Leaf A - fabric - sw-rzk-BL (routing, VXLAN re-encapsulation) - fabric - Leaf B. Sources in RZC also cross RAGG1 twice (gateway only in Kalk). Measures the centralised routing hop and its asymmetry.

4.3.3 Class L3-DCFW - Layer 3 between production VLANs routed by the DC firewall

Source in production VLAN A and destination in production VLAN B, both with their default gateway on CPF-ZV05/06 (VIP). Path: Leaf - fabric - sw-rzk-BL/sw-rzc-BL - BAGG31 "Vlan-all" - DC-FW (active member) - BAGG31 - fabric - Leaf. Requires a DC-FW rule permitting the TRex UDP port range between the TRex host objects. Measures firewall forwarding latency and its cluster state (active member location changes the path).

4.3.4 Class L3-ENTFW - VPN-CORE through the Enterprise firewall into the TRex firewall zone

Source in VLAN 1314 (VPN-CORE); destination TRex client in the new TRex firewall zone (VLAN 1420, 10.9.90.0/24, proposal) which is a dedicated interface of the Enterprise-FW cluster connected through AP "FW" (S-VLAN 3300, stretched over both TX switches so that both cluster members see the same Layer 2 domain). Path: Leaf - fabric - sw-rzk-BL (VPN-CORE) - Vsi40 transfer (10.9.0.16/29) - ENT-FW active member - zone interface - TX switch - TRex. The firewall advertises 10.9.90.0/24 into OSPF 1 (it is already an OSPF neighbour of both Border Leafs in VPN-CORE); alternatively a static route on both Border Leafs. This is the inter-VRF/firewall path requested; extending it to VPN-WAN/VPN-WLAN later only requires TRex clients in those VRFs.

TRex p0client 10.3.14.101[S 3101][C 1314] sw-rzk-TX1S-VLAN 3101pop S-tag sw-rzk-L11VSI VPN-1314VXLAN 1314 sw-rzk-BLVsi914 10.3.14.1VPN-CORE -> Vsi40 ENT-FW cluster10.9.0.22 (Vsi40)zone TRex 10.9.90.1 sw-rzk/rzc-TX1AP FW, S-VLAN 3300push S-tag TRex p1client 10.9.90.101[S 3300][C 1420] Class L3-ENTFW forward direction; the reverse stream (p1 -> p0) is a separate pg_id. If the active member is CPF-ZV02, the FW hop crosses the DCI link and the return crosses the TX fibre.
Figure 3 - Firewall class path through the Enterprise firewall into the dedicated TRex zone.

4.3.5 Firewall zone design options

OptionWhenTX switch designFW design
A - stretched zone (default)CPF-ZV01/ZV02 form one ClusterXLS-VLAN 3300 on both TX switches and on the inter-DC trunk; FW member ports are QinQ access ports with PVID 3300One cluster VLAN interface (e.g. eth1-05.1420), VIP 10.9.90.1, member IPs .2/.3, anti-spoofing topology "internal, this network"
B - two zonesIndependent clusters per DCS-VLAN 3300 (RZK) and 3310 (RZC), each localTwo interfaces/subnets 10.9.90.0/24 and 10.9.91.0/24, two VIPs

4.3.6 Class DSCP - QoS verification

Selected L2 and L3 pairs are duplicated with different TOS bytes (EF = 0xB8, AF41 = 0x88, CS1 = 0x20, BE = 0x00). Because the fabric configuration contains no QoS trust or scheduling policy, equal treatment is expected; differences in latency or loss under load (lab tests) would indicate a (re)marking or queuing effect, e.g. on the firewalls. On the TX switches the 802.1p value of the S-tag is copied from the C-tag only when qos trust dot1p is configured (L2 Configuration Guide PDF p. 224); this is irrelevant for the measurement and not configured.

4.3.7 Class LAB - performance tests

4.4 Measurement methodology

4.5 Permanent monitoring matrix and packet budget

ClassPairs (default profile)Streamspps / streamSizeTotal ppsResolution
L2 intra-DCEach Leaf AP <-> BL AP of its DC, per monitored VLAN (5 RZK + 6 RZC pairs, 2 directions)22 per VLAN200128 B4 400 per VLAN5 ms
L2 inter-DCK-L11<->C-L11, K-L12<->C-L12, K-L21<->C-L21, K-L31<->C-L22, K-L41<->C-L23, K-BL<->C-BL, per monitored VLAN12 per VLAN200128 B2 400 per VLAN5 ms
L3-BLVLAN 1314 <-> 1315: K-L11<->K-L21, K-L31<->K-BL, C-L21<->C-L22, C-L13<->C-BL (2 directions)8200128 B1 6005 ms
L3-DCFWProduction VLAN A <-> B: K-L11<->K-L41, K-L21<->K-L31, C-L12<->C-L23, C-L11<->C-L22 (2 directions)850128 B40020 ms
L3-ENTFWVLAN 1314 at K-L11, K-BL, C-L21, C-BL <-> FW zone850128 B40020 ms
DSCPK-L11<->C-L21 L2 and L3-ENTFW with EF, AF41, CS1 (both directions)12100256 B1 20010 ms
Total with 4 monitored VLANs (1314, 1315 + 2 production VLANs)172~31 000 pps, ~35 Mbit/s

Hard budget for the permanent profile: not more than 600 streams, 50 kpps and 50 Mbit/s in total; not more than 100 pps per stream through a firewall. The profile is a YAML file (section 9.4), so pairs and rates are adjusted without code changes.

4.6 Addressing, VLAN and naming plan

4.6.1 Attachment points and S-VLANs

APDCDeviceDevice port (proposal, re-verify)TX switch portS-VLANAP index
K-L11RZKsw-rzk-L11XGE1/3/1 (free 2025-02-17)sw-rzk-TX1 XGE1/1/131011
K-L12RZKsw-rzk-L12TBD free SFP+ portsw-rzk-TX1 XGE1/1/231022
K-L21RZKsw-rzk-L21TBDsw-rzk-TX1 XGE1/1/331033
K-L31RZKsw-rzk-L31TBDsw-rzk-TX1 XGE1/1/431044
K-L41RZKsw-rzk-L41TBDsw-rzk-TX1 XGE1/1/531055
K-BLRZKsw-rzk-BLXGE1/3/6 (free 2025-02-17)sw-rzk-TX1 XGE1/1/631106
FW (member ZV01)RZKCPF-ZV01TBD free 10G portsw-rzk-TX1 XGE1/1/7330014
C-L11RZCsw-rzc-L11TBDsw-rzc-TX1 XGE1/1/132017
C-L12RZCsw-rzc-L12TBDsw-rzc-TX1 XGE1/1/232028
C-L13RZCsw-rzc-L13TBDsw-rzc-TX1 XGE1/1/332039
C-L21RZCSW-RZC-L21XGE1/4/4 (free 2025-02-18)sw-rzc-TX1 XGE1/1/4320410
C-L22RZCsw-rzc-L22TBDsw-rzc-TX1 XGE1/1/5320511
C-L23RZCsw-rzc-L23TBDsw-rzc-TX1 XGE1/1/6320612
C-BLRZCsw-rzc-BLXGE1/3/14 (free 2025-02-17)sw-rzc-TX1 XGE1/1/7321013
FW (member ZV02)RZCCPF-ZV02TBD free 10G portsw-rzc-TX1 XGE1/1/8330014

4.6.2 VLANs under test and TRex address pools

VLANVSISubnetGatewayGateway ownerTRex pool (16 addresses)Purpose
1314VPN-131410.3.14.0/2410.3.14.1sw-rzk-BL, VPN-CORE10.3.14.101-116 (AP index 1-14 => .101-.114) DECISIONPrimary monitoring carrier, L3-BL, L3-ENTFW, lab
1315VPN-131510.3.15.0/2410.3.15.1sw-rzk-BL, VPN-CORE10.3.15.101-116Second carrier, L3-BL
<PROD-VLAN-A>VPN-A<SUBNET-A><GW-A>DC-FW CPF-ZV05/06<POOL-A> e.g. .236-.251L2 production, L3-DCFW
<PROD-VLAN-B>VPN-B<SUBNET-B><GW-B>DC-FW CPF-ZV05/06<POOL-B>L2 production, L3-DCFW
1420 (new, proposal)-10.9.90.0/24 DECISION10.9.90.1 (VIP)ENT-FW cluster, zone "TRex"10.9.90.101-116L3-ENTFW target, ASTF server side
(ASTF only) routed ranges-10.9.92.0/24 clients, 10.9.93.0/24 servers DECISION-static routes (7.4.3)-Scalable stateful tests

Candidate production VLANs seen in the configurations that are already test-oriented and therefore low-risk: 176 ("DC-Testnetz RZ Deutz/RZ-Chorweiler", 10.180/24-DC), 171 ("Server Testnetz und Altnetz von Deutz"), 724 ("Test Server Netz"), 1395/1396 ("t3_139x_ngfw-test"). Their subnets and gateways are not visible in the switch configurations (gateway on the DC firewall) and must be supplied by LVR. TBD

4.6.3 Deterministic TRex client addressing

For VLAN V with pool start P and attachment point index i (table 4.6.1): IP = P + (i - 1). MAC = 02:54:52:<ii>:<VV>:<VV> where ii is the AP index and VVVV the VLAN id in hex (locally administered, unique per AP and VLAN). Example: AP K-L11 (1) in VLAN 1314 (0x0522): 10.3.14.101, 02:54:52:01:05:22. Clients attached to the lab instance use index offset 50 (02:54:52:33.., IP pool second half) so that monitoring and lab clients never collide.

4.6.4 UDP port and pg_id plan

ItemPlan
UDP destination port32000 + class id: 32001 L2, 32002 L3-BL, 32003 L3-DCFW, 32004 L3-ENTFW, 32005 DSCP, 32009 LAB. Firewall rules permit UDP 32000-32099 between TRex objects.
UDP source port40000 + stream index (unique per stream, stable across restarts; keeps one firewall session per stream and diversifies ECMP hashing)
pg_idtrex-mon: 1-899 allocated by trexctl and persisted in /etc/trexctl/pgid-map.json so that ids stay stable; trex-lab: 1000-1126
TOS byte0x00 default; DSCP class uses 0xB8 (EF), 0x88 (AF41), 0x20 (CS1)
TTL64

4.6.5 Names and management addresses

ObjectNameManagement IPNote
TRex servertrex-rzk-01<MGMT-IP-SERVER> (server management network), iLO <ILO-IP>Grafana at https://trex-rzk-01/
TX switch RZKsw-rzk-TX1<MGMT-IP-TX-K> via M-GigabitEthernet0/0/0 (switch management network 10.112.118.x / 10.0.31.x as used today)Loopback not required
TX switch RZCsw-rzc-TX1<MGMT-IP-TX-C>

4.7 Two TRex instances on one server

trex-montrex-lab
NIC / portsNIC1, p0-p3 (p0, p1 active)NIC2, p4-p7
TRex modeSTL interactive, --software --emuSTL interactive hardware mode (default) or --astf; switched by stopping/starting the systemd unit
Frame format to TX switchDouble-taggedSingle-tagged
ARP handlingEMU clients (ARP, ICMP, gratuitous ARP), promiscuous portsPort L3 mode (service + arp) or ASTF topology, one VLAN per port per test
Streamsup to 1023 latency streams127 hardware flow-stat streams, line rate
IsolationSeparate prefix, zmq_pub_port/zmq_rpc_port, limit_memory and CPU threads in two configuration files (TRex manual, platform configuration); separate systemd units
Console./trex-console -p 4501 --async_port 4500 --emu./trex-console -p 4601 --async_port 4600

4.8 Security and operational impact

5. Bill of materials

5.1 TRex server

ItemRecommendationRationale
ChassisHPE ProLiant DL380 Gen11 (2U) - alternatively DL360 Gen11 if two full-height PCIe slots on the populated CPU are guaranteedPCIe Gen5 slots, HPE support, iLO 6; 2U gives riser flexibility for a third NIC later
CPU1 x Intel Xeon Gold 6426Y (16 cores / 32 threads, 2.5 GHz base) or 6444Y (16 cores, 3.6 GHz)Single socket avoids NUMA pitfalls; DPDK benefits from clock speed; 16 cores cover both TRex instances plus InfluxDB/Grafana
Memory128 GB (8 x 16 GB DDR5, one DIMM per channel)TRex recommends all memory channels populated; InfluxDB benefits from RAM; hugepages 8 GB
Storage2 x 480 GB SSD (RAID 1, OS) + 2 x 1.92 TB SSD (RAID 1, /data for InfluxDB, TRex, logs); HPE MR controller or NS204i boot device for OSRaw statistics at 2 s sampling grow about 1-2 GB per month; 90-day raw retention plus multi-year downsampled data fits easily
Data NICs2 x Intel X710-DA4 (4 x 10G SFP+) PCIe Gen3 x8, HPE-branded variant for Gen11 if available (check current HPE adapter QuickSpecs) or Intel retail X710DA4FHBLKX710 is the TRex reference 10G NIC ("preferred", hardware flow statistics). Both NICs must be of the same type; mixing NIC types in one TRex instance is not supported. E810-XXVDA4 (25G) is a possible alternative (hardware mode supported since TRex v3.07, but not part of the TRex regression)
Management NICOn-board OCP 4 x 1GbE (Broadcom) or 2 x 10GBase-TKept under Linux kernel control: SSH, Grafana, InfluxDB API, NTP
Cabling server to TX switch8 x SFP+ passive DAC 1-3 m (HPE X240 10G SFP+ to SFP+ DAC, e.g. JD096C 1.2 m / JD097C 3 m)Intel X710 accepts Intel-coded optics only, but passive DAC is generally accepted; validate one cable first. Fallback: HPE X130 10G SFP+ LC SR on the switch, Intel E10GSFPSR on the NIC, OM3/OM4 patch
Power / rack2 x PSU, 2U in the RZK rack hosting sw-rzk-TX1
SoftwareRHEL 9 (subscription) or Rocky Linux 9 / AlmaLinux 9; TRex v3.08; InfluxDB OSS 2.9.x; Grafana 12.4.x LTS; Python 3.9+ (RHEL 9 ships 3.9; 3.11/3.12 available as AppStream)All open source apart from the OS subscription
PCIe slot to CPU mapping On the DL380 Gen11 some riser slots are wired to CPU 2. With a single CPU, order a riser configuration that exposes at least two x8 (or x16) slots on CPU 1, or populate two CPUs and keep both NICs on the same socket (dual_if ... socket in the TRex configuration). Check with lspci -vv / cat /sys/bus/pci/devices/<pci>/numa_node after installation.

5.2 TX switches and attachment links

ItemQuantityNotes
HPE FlexFabric 5950 (spare)2 (one per DC)Factory-reset, R6301P03 recommended (same as Border Leafs). 4-slot chassis: one 24-port SFP+ module (JH180A) is sufficient for all 10G ports; one QSFP28/QSFP+ module for the inter-DC link. 32QSFP28 chassis: 100G ports split with using tengige and QSFP28-to-4xSFP+ breakout cables
10G SR optics, TX switch side (AP links)RZK: 7 (5 Leafs, BL, FW member); RZC: 8 (6 Leafs, BL, FW member)HPE X130 10G SFP+ LC SR (JD092B) or DAC where the TX switch is in the same rack row
10G SR optics, Leaf / BL sideRZK: 6; RZC: 7HPE X130 10G SFP+ LC SR (JD092B) - transceivers in the production switches must be HPE-coded
10G optics, firewall side2 (one per member)Check Point certified SFP+ SR
Inter-DC link optics2Depends on fibre: 10G LR (10 km, JD094B) / ER (40 km, JG234A) or 40G/100G LR4 (JL275A 100G QSFP28 LR4 for up to 10 km), or DWDM transponder client ports. 40G/100G recommended if RZC performance tests above 10 Gbit/s aggregate are wanted
Fibre patching~16 LC-LC OM3/OM4 patches, 1 inter-DC pathDistances within the DCs are short; inter-DC path is the customer's dark fibre/DWDM

6. Physical design and cabling

6.1 Port assignment sw-rzk-TX1 (RZK)

Port names assume a 5950 4-slot chassis with a 24-port SFP+ module in slot 1 and a QSFP28 module in slot 2 CONFIRM. Adjust if the module layout differs.

sw-rzk-TX1 portRoleRemote endS-VLAN / modeMedia
XGE1/1/1AP K-L11sw-rzk-L11 XGE1/3/13101, QinQ accessSR / OM4
XGE1/1/2AP K-L12sw-rzk-L12 <PORT>3102, QinQ accessSR
XGE1/1/3AP K-L21sw-rzk-L21 <PORT>3103, QinQ accessSR
XGE1/1/4AP K-L31sw-rzk-L31 <PORT>3104, QinQ accessSR
XGE1/1/5AP K-L41sw-rzk-L41 <PORT>3105, QinQ accessSR
XGE1/1/6AP K-BLsw-rzk-BL XGE1/3/63110, QinQ accessSR
XGE1/1/7AP FW (member ZV01)CPF-ZV01 <FW-PORT>3300, QinQ accessSR
XGE1/1/8, XGE1/1/13-20spare-shutdown
XGE1/1/21TRex p0 (trex-mon)trex-rzk-01 NIC1 port 0trunk, all S-VLANsDAC
XGE1/1/22TRex p1 (trex-mon)NIC1 port 1trunk, all S-VLANsDAC
XGE1/1/23TRex p2 (trex-mon, reserve)NIC1 port 2trunk, all S-VLANs (shutdown until used)DAC
XGE1/1/24TRex p3 (trex-mon, reserve)NIC1 port 3trunk, all S-VLANs (shutdown until used)DAC
XGE1/1/9TRex p4 (trex-lab)NIC2 port 0QinQ access, PVID = pinned AP (default 3101)DAC
XGE1/1/10TRex p5 (trex-lab)NIC2 port 1QinQ access, PVID = pinned AP (default 3110)DAC
XGE1/1/11TRex p6 (trex-lab)NIC2 port 2QinQ access, PVID = pinned AP (default 3300)DAC
XGE1/1/12TRex p7 (trex-lab)NIC2 port 3QinQ access, PVID = pinned AP (default 3204)DAC
HGE1/2/1 (or FGE / XGE)Inter-DC trunksw-rzc-TX1 HGE1/2/1trunk, S-VLANs 3201-3210, 3300LR4 / DWDM
M-GE0/0/0Managementmanagement switch-copper

6.2 Port assignment sw-rzc-TX1 (RZC)

sw-rzc-TX1 portRoleRemote endS-VLAN / modeMedia
XGE1/1/1AP C-L11sw-rzc-L11 <PORT>3201, QinQ accessSR
XGE1/1/2AP C-L12sw-rzc-L12 <PORT>3202, QinQ accessSR
XGE1/1/3AP C-L13sw-rzc-L13 <PORT>3203, QinQ accessSR
XGE1/1/4AP C-L21SW-RZC-L21 XGE1/4/43204, QinQ accessSR
XGE1/1/5AP C-L22sw-rzc-L22 <PORT>3205, QinQ accessSR
XGE1/1/6AP C-L23sw-rzc-L23 <PORT>3206, QinQ accessSR
XGE1/1/7AP C-BLsw-rzc-BL XGE1/3/143210, QinQ accessSR
XGE1/1/8AP FW (member ZV02)CPF-ZV02 <FW-PORT>3300, QinQ accessSR
HGE1/2/1Inter-DC trunksw-rzk-TX1 HGE1/2/1trunk, S-VLANs 3201-3210, 3300LR4 / DWDM
M-GE0/0/0Managementmanagement switch-copper

6.3 Cabling and labelling rules

7. Switch and firewall configuration

All Comware commands in this section follow the 5950 R630x documentation and the configuration style found in the diagnostic files. Commands marked VALIDATED use syntax already present on the customer's 5950s or documented in the cited guides; values marked CONFIRM depend on the physical port layout of the spare units or on live state.

7.1 TX switch sw-rzk-TX1

7.1.1 Preparation

  1. Factory-reset the spare 5950 (restore factory-default, reboot) and upgrade to R6301P03 (same release as the Border Leafs) using the HPE release notes HPE5950CMW710R6301P03RN.pdf. CONFIRM file names on the flash.
  2. Confirm the module layout (display device) and derive the interface names. The configuration below assumes a 24-port SFP+ module in slot 1 (Ten-GigabitEthernet1/1/x) and a QSFP28 module in slot 2 (HundredGigE1/2/x).
  3. Connect the management port to the switch management network and apply the base configuration via console.

7.1.2 Base configuration

# --- system -------------------------------------------------------------
system-view
 sysname sw-rzk-TX1
 clock timezone COLOGNE add 01:00:00
 clock summer-time MEST 02:00:00 March last Sunday 02:00:00 October last Sunday 01:00:00
 clock protocol ntp
# management VRF, same pattern as the production switches
ip vpn-instance MGMT
 route-distinguisher 10:1
 description MGMT/Monitoring
 vpn-target 10:1 import-extcommunity
 vpn-target 10:1 export-extcommunity
quit
interface M-GigabitEthernet0/0/0
 description mgmt_oobm
 ip binding vpn-instance MGMT
 ip address <MGMT-IP-TX-K> <MASK>
quit
 ip route-static vpn-instance MGMT 0.0.0.0 0 <MGMT-GW> description mgmt-DEFAULT-GATEWAY
 ntp-service enable
 ntp-service source M-GigabitEthernet0/0/0
 ntp-service unicast-server 10.0.31.21 vpn-instance MGMT
 ntp-service unicast-server 10.0.31.23 vpn-instance MGMT
 info-center loghost 10.0.61.10 vpn-instance MGMT
# SNMPv3 / SSH / local users: copy the LVR standard from an existing Leaf
# (prefer SNMPv3 as recommended in the switch analysis)
 ssh server enable
 lldp global enable
# --- no spanning tree on the TX switch (see 4.2) -------------------------
 undo stp global enable
# --- S-VLANs: one per attachment point, plus the stretched FW zone -------
 vlan 3101 to 3110
 vlan 3201 to 3210
# (bulk creation stays in system view; naming requires VLAN view)
vlan 3101
 name TRX-AP-K-L11
 quit
vlan 3102
 name TRX-AP-K-L12
 quit
vlan 3103
 name TRX-AP-K-L21
 quit
vlan 3104
 name TRX-AP-K-L31
 quit
vlan 3105
 name TRX-AP-K-L41
 quit
vlan 3110
 name TRX-AP-K-BL
 quit
vlan 3300
 name TRX-AP-FW-ZONE-stretched
 quit

QinQ, STP and VLAN commands: 5950 Layer 2 Configuration Guide R630x, PDF pp. 219-222 (QinQ), p. 306 (undo stp global enable); VPN/NTP/mgmt pattern identical to sw-rzk-L11 running configuration. VALIDATED

7.1.3 Attachment-point ports (QinQ access)

# one isolated S-VLAN per attachment point; QinQ pushes the PVID on ingress and pops it on egress
interface Ten-GigabitEthernet1/1/1
 description TRX AP K-L11 --> sw-rzk-L11 XGE1/3/1
 port link-type access
 port access vlan 3101
 qinq enable
quit
interface Ten-GigabitEthernet1/1/2
 description TRX AP K-L12 --> sw-rzk-L12 <PORT>
 port link-type access
 port access vlan 3102
 qinq enable
quit
interface Ten-GigabitEthernet1/1/3
 description TRX AP K-L21 --> sw-rzk-L21 <PORT>
 port link-type access
 port access vlan 3103
 qinq enable
quit
interface Ten-GigabitEthernet1/1/4
 description TRX AP K-L31 --> sw-rzk-L31 <PORT>
 port link-type access
 port access vlan 3104
 qinq enable
quit
interface Ten-GigabitEthernet1/1/5
 description TRX AP K-L41 --> sw-rzk-L41 <PORT>
 port link-type access
 port access vlan 3105
 qinq enable
quit
interface Ten-GigabitEthernet1/1/6
 description TRX AP K-BL --> sw-rzk-BL XGE1/3/6
 port link-type access
 port access vlan 3110
 qinq enable
quit
interface Ten-GigabitEthernet1/1/7
 description TRX AP FW-ZONE --> CPF-ZV01 <FW-PORT>
 port link-type access
 port access vlan 3300
 qinq enable
quit
# unused ports administratively down
interface range Ten-GigabitEthernet1/1/8 Ten-GigabitEthernet1/1/13 to Ten-GigabitEthernet1/1/20
 shutdown
quit

7.1.4 TRex-facing ports

# multiplexed monitoring ports: plain 802.1Q trunk, frames stay double-tagged towards TRex
interface Ten-GigabitEthernet1/1/21
 description TRX p0 trex-mon (double-tagged, all APs)
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 3101 to 3110 3201 to 3210 3300
quit
interface Ten-GigabitEthernet1/1/22
 description TRX p1 trex-mon (double-tagged, all APs)
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 3101 to 3110 3201 to 3210 3300
quit
interface Ten-GigabitEthernet1/1/23
 description TRX p2 trex-mon reserve
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 3101 to 3110 3201 to 3210 3300
 shutdown
quit
interface Ten-GigabitEthernet1/1/24
 description TRX p3 trex-mon reserve
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 3101 to 3110 3201 to 3210 3300
 shutdown
quit
# pinned lab ports: QinQ access, PVID selects the attachment point; TRex sends single-tagged frames
interface Ten-GigabitEthernet1/1/9
 description TRX p4 trex-lab pinned [K-L11]
 port link-type access
 port access vlan 3101
 qinq enable
quit
interface Ten-GigabitEthernet1/1/10
 description TRX p5 trex-lab pinned [K-BL]
 port link-type access
 port access vlan 3110
 qinq enable
quit
interface Ten-GigabitEthernet1/1/11
 description TRX p6 trex-lab pinned [FW-ZONE]
 port link-type access
 port access vlan 3300
 qinq enable
quit
interface Ten-GigabitEthernet1/1/12
 description TRX p7 trex-lab pinned [C-L21]
 port link-type access
 port access vlan 3204
 qinq enable
quit
Re-pinning a lab port to another attachment point interface Ten-GigabitEthernet1/1/9 / port access vlan 3204 / description TRX p4 trex-lab pinned [C-L21]. No other change is needed; the TRex side keeps sending single-tagged production VLAN frames. Update the trexctl inventory (lab_ports.p4.ap) accordingly.

7.1.5 Inter-DC trunk

interface HundredGigE1/2/1
 description TRX inter-DC --> sw-rzc-TX1 HGE1/2/1 (dark fibre)
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 3201 to 3210 3300
quit
save force

If the inter-DC path is 10G, use a Ten-GigabitEthernet port with the same VLAN configuration. If 40G is used on a QSFP28 port, no breakout is needed (FortyGigE transceiver in a 100G port is supported on the 8-port QSFP28 module; confirm with the installation guide for the module in use CONFIRM).

7.1.6 Variant: spare units are 5950 32QSFP28 (JH321A)

Split 100G ports into four 10G breakout ports with a QSFP28-to-4xSFP+ breakout cable (Layer 2 Configuration Guide R630x, "Splitting a 100-GE interface and combining 10-GE breakout interfaces", PDF pp. 37-38). The resulting interfaces are named Ten-GigabitEthernet1/0/N:1 ... :4 and support the same QinQ configuration. VALIDATED (syntax) / CONFIRM (cable type per installation guide).

interface HundredGigE1/0/1
 using tengige
quit
interface Ten-GigabitEthernet1/0/1:1
 description TRX AP K-L11 --> sw-rzk-L11 XGE1/3/1
 port link-type access
 port access vlan 3101
 qinq enable
quit

7.2 TX switch sw-rzc-TX1

Identical base configuration with sysname sw-rzc-TX1, its own management address and the RZC S-VLANs:

 vlan 3201 to 3210
vlan 3201
 name TRX-AP-C-L11
 quit
vlan 3202
 name TRX-AP-C-L12
 quit
vlan 3203
 name TRX-AP-C-L13
 quit
vlan 3204
 name TRX-AP-C-L21
 quit
vlan 3205
 name TRX-AP-C-L22
 quit
vlan 3206
 name TRX-AP-C-L23
 quit
vlan 3210
 name TRX-AP-C-BL
 quit
vlan 3300
 name TRX-AP-FW-ZONE-stretched
 quit
interface Ten-GigabitEthernet1/1/1
 description TRX AP C-L11 --> sw-rzc-L11 <PORT>
 port link-type access
 port access vlan 3201
 qinq enable
quit
# ... XGE1/1/2-6 analogously with 3202-3206 ...
interface Ten-GigabitEthernet1/1/4
 description TRX AP C-L21 --> SW-RZC-L21 XGE1/4/4
 port link-type access
 port access vlan 3204
 qinq enable
quit
interface Ten-GigabitEthernet1/1/7
 description TRX AP C-BL --> sw-rzc-BL XGE1/3/14
 port link-type access
 port access vlan 3210
 qinq enable
quit
interface Ten-GigabitEthernet1/1/8
 description TRX AP FW-ZONE --> CPF-ZV02 <FW-PORT>
 port link-type access
 port access vlan 3300
 qinq enable
quit
interface HundredGigE1/2/1
 description TRX inter-DC --> sw-rzk-TX1 HGE1/2/1 (dark fibre)
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 3201 to 3210 3300
quit
interface range Ten-GigabitEthernet1/1/9 to Ten-GigabitEthernet1/1/24
 shutdown
quit
save force

7.3 Leaf attachment ports

The Leaf port is configured exactly like an existing server trunk: 802.1Q trunk, one Ethernet service instance per VLAN under test, cross-connected to the existing VSI. The pattern is taken from sw-rzk-L11 Ten-GigabitEthernet1/3/3 (running configuration 2025-02-17). VALIDATED Only the VLAN list differs per AP and is generated by trexctl inventory render-leaf (section 9.6).

7.3.1 Template

interface <LEAF-PORT>
 port link-mode bridge
 description TRX AP <AP-CODE> --> <TX-SWITCH> <TX-PORT> (TRex attachment point)
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 1314 to 1315 <PROD-VLAN-A> <PROD-VLAN-B>
 stp edged-port
 #
 service-instance 1314
  encapsulation s-vid 1314
  xconnect vsi VPN-1314
 #
 service-instance 1315
  encapsulation s-vid 1315
  xconnect vsi VPN-1315
 #
 service-instance <PROD-VLAN-A>
  encapsulation s-vid <PROD-VLAN-A>
  xconnect vsi VPN-<PROD-VLAN-A>
 #
 service-instance <PROD-VLAN-B>
  encapsulation s-vid <PROD-VLAN-B>
  xconnect vsi VPN-<PROD-VLAN-B>

stp edged-port (L2 Configuration Guide PDF p. 294) makes the port forward immediately in the PVST-enabled VLANs. It is not used on the existing server ports; if the team prefers to stay consistent, omit it and accept a 30 s forwarding delay after link-up. Do not enable BPDU guard on these ports unless the BPDU behaviour of the TX switch has been confirmed (section 4.2).

7.3.2 Example: sw-rzk-L11 (AP K-L11)

system-view
interface Ten-GigabitEthernet1/3/1
 port link-mode bridge
 description TRX AP K-L11 --> sw-rzk-TX1 XGE1/1/1 (TRex attachment point)
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 1314 to 1315
 stp edged-port
 #
 service-instance 1314
  encapsulation s-vid 1314
  xconnect vsi VPN-1314
 #
 service-instance 1315
  encapsulation s-vid 1315
  xconnect vsi VPN-1315
quit
save force

Prerequisite check before configuring: the VSIs exist on the Leaf (display l2vpn vsi name VPN-1314 verbose) and the port is really unused (display interface Ten-GigabitEthernet1/3/1, display current-configuration interface Ten-GigabitEthernet1/3/1). CONFIRM

7.3.3 Example: SW-RZC-L21 (AP C-L21)

interface Ten-GigabitEthernet1/4/4
 port link-mode bridge
 description TRX AP C-L21 --> sw-rzc-TX1 XGE1/1/4 (TRex attachment point)
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 1314 to 1315
 stp edged-port
 #
 service-instance 1314
  encapsulation s-vid 1314
  xconnect vsi VPN-1314
 #
 service-instance 1315
  encapsulation s-vid 1315
  xconnect vsi VPN-1315
quit
save force

SW-RZC-L21 runs R6205P03. The commands are identical on that release (its own running configuration uses the same service-instance/xconnect vsi syntax), but the switch analysis recommends upgrading it to R6301P03 anyway.

7.4 Border Leaf attachment ports and optional routes

7.4.1 sw-rzk-BL (AP K-BL)

interface Ten-GigabitEthernet1/3/6
 port link-mode bridge
 description TRX AP K-BL --> sw-rzk-TX1 XGE1/1/6 (TRex attachment point)
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 1314 to 1315
 stp edged-port
 #
 service-instance 1314
  encapsulation s-vid 1314
  xconnect vsi VPN-1314
 #
 service-instance 1315
  encapsulation s-vid 1315
  xconnect vsi VPN-1315
quit

sw-rzk-BL already uses this access style (e.g. BAGG11 "CPF-ZV01 - MAIN - DMZ" with service instances 125, 137, ...). VALIDATED Note that the BL runs hardware-resource vxlan border; adding two more service instances is far below any resource limit.

7.4.2 sw-rzc-BL (AP C-BL)

interface Ten-GigabitEthernet1/3/14
 port link-mode bridge
 description TRX AP C-BL --> sw-rzc-TX1 XGE1/1/7 (TRex attachment point)
 port link-type trunk
 undo port trunk permit vlan 1
 port trunk permit vlan 1314 to 1315
 stp edged-port
 #
 service-instance 1314
  encapsulation s-vid 1314
  xconnect vsi VPN-1314
 #
 service-instance 1315
  encapsulation s-vid 1315
  xconnect vsi VPN-1315
quit

7.4.3 Optional: static routes for scalable ASTF tests (sw-rzk-BL only)

Only required for the stateful test variant with routed client ranges (section 11.7, option B). The TRex ASTF client port (lab port p4 pinned to a VLAN-1314 AP) gets 10.3.14.151; the client range 10.9.92.0/24 is routed to it. OSPF 1 already redistributes static routes (import-route static), so the Enterprise firewall learns the return path automatically.

 ip route-static vpn-instance VPN-CORE 10.9.92.0 24 10.3.14.151 description TRex-ASTF-clients

Syntax identical to the existing VPN-CORE static routes on both Border Leafs. VALIDATED Remove the route after the test campaign (undo ip route-static vpn-instance VPN-CORE 10.9.92.0 24 10.3.14.151).

7.5 Firewall requirements (Check Point)

Firewall configuration is performed by the LVR firewall team in SmartConsole/Gaia; this section lists the required objects and rules. Object names are proposals.

7.5.1 Enterprise firewall cluster CPF-ZV01/ZV02 - TRex zone

ItemRequirement
Physical interfaceOne free 10G port per cluster member, connected to sw-rzk-TX1 XGE1/1/7 (ZV01) and sw-rzc-TX1 XGE1/1/8 (ZV02)
VLAN interfaceVLAN 1420 on that port on both members (e.g. eth1-05.1420) DECISION
AddressesMember ZV01 10.9.90.2/24, member ZV02 10.9.90.3/24, cluster VIP 10.9.90.1/24 DECISION
Topology / anti-spoofingInternal, "network defined by the interface IP and net mask"; anti-spoofing enabled (prevent + log)
RoutingAdvertise 10.9.90.0/24 into the existing OSPF process towards 10.9.0.16/29 (VPN-CORE transfer, neighbours sw-rzk-BL 10.9.0.17 and sw-rzc-BL 10.9.0.18) by redistributing connected/interface routes; alternatively ask the switch team for ip route-static vpn-instance VPN-CORE 10.9.90.0 24 10.9.0.22 on both Border Leafs (same syntax as the existing statics; import-route static into OSPF 1 is already configured)
Host objectsTRX-mon-1314 (10.3.14.101-116 as address range), TRX-mon-1315 (10.3.15.101-116), TRX-mon-<VLAN> per production VLAN pool, TRX-fwzone (10.9.90.101-116), groups TRX-inside and TRX-fwzone
ServicesTRX-udp = UDP 32000-32099; TRX-tcp = TCP 80, 443, 8080 (ASTF); ICMP echo
Access rules1) TRX-inside -> TRX-fwzone: TRX-udp, icmp - Accept, Log. 2) TRX-fwzone -> TRX-inside: TRX-udp, icmp - Accept, Log. 3) (ASTF) TRX-astf-clients (10.9.92.0/24 or 10.3.14.151) -> TRX-astf-servers (10.9.93.0/24 or 10.9.90.151): TRX-tcp - Accept. Place above any cleanup/drop rules.
NATNo NAT for TRex objects (explicit "no NAT" rule if automatic hide NAT exists for the inside networks)
InspectionDecide whether Threat Prevention/IPS should inspect TRex traffic. Default: exclude (measure forwarding), optional profile with inspection for lab tests. DECISION
TimeoutsDefault UDP virtual session timeout (40 s) is fine for continuous streams at 50 pps; for ASTF increase TCP start timeout only if connection rates above 10 000 cps are tested

7.5.2 DC firewall cluster CPF-ZV05/ZV06 - inter-VLAN streams

Class L3-DCFW needs rules between the TRex pools of the selected production VLANs: TRX-mon-<VLAN-A> <-> TRX-mon-<VLAN-B>, services TRX-udp and ICMP, Accept, Log; no NAT. No interface changes are needed on the DC firewall.

7.6 Verification commands

WhereCommandExpectedStatus
TX switchdisplay qinqLists all QinQ-enabled ports (AP ports and pinned lab ports)VALIDATED L2 CR PDF p. 277
TX switchdisplay vlan 3101Untagged member XGE1/1/1 (and pinned port if any), tagged members XGE1/1/21-22VALIDATED
TX switchdisplay mac-address vlan 3101TRex client MACs (02:54:52:01:...) on XGE1/1/21/22, Leaf-side MACs (gateway, remote TRex clients) on XGE1/1/1VALIDATED
TX switchdisplay interface brief, display counters rate inbound interfaceLinks up at 10G, rates matching the profileVALIDATED (present in diag files)
TX switchdisplay lldp neighbor-information listLeaf/BL seen on AP ports; TRex server not visible (DPDK)VALIDATED
Leaf / BLdisplay interface Ten-GigabitEthernet1/3/1Up, 10G, no input errorsVALIDATED
Leaf / BLdisplay l2vpn mac-address vsi VPN-1314Local TRex MAC on the AP port, remote TRex MACs via VXLAN tunnelsVALIDATED VXLAN CR PDF p. 13
Leaf / BLdisplay evpn route macType-2 routes for TRex MACsVALIDATED (in diag)
sw-rzk-BLdisplay arp vpn-instance VPN-COREARP entries 10.3.14.1xx / 10.3.15.1xx on Vsi914/915VALIDATED L3 Services CR PDF p. 33
sw-rzk-BL / sw-rzc-BLdisplay ip routing-table vpn-instance VPN-CORE 10.9.90.0 24OSPF (or static) route to 10.9.0.22VALIDATED L3 Routing CR PDF p. 26
sw-rzk-BLdisplay ospf 1 peerNeighbour 10.9.0.22 FullVALIDATED (in diag as display ospf peer)
TRextrex-console --emu > emu_show_allClients with resolved default-gateway MAC (dgw.resolve = true)VALIDATED TRex EMU guide

7.7 Rollback

8. TRex server installation

Target: Rocky Linux 9 / RHEL 9 (minimal), TRex v3.08, two TRex instances, Python 3.12 virtual environment for trexctl. Commands are shown for Rocky 9; RHEL 9 is identical apart from subscription handling. Everything in this section runs as root unless stated otherwise.

8.1 Firmware and BIOS (iLO / RBSU)

SettingValueWhy
Workload profileLow Latency (or Custom with the settings below)Deterministic DPDK polling
Power regulator / C-statesStatic High Performance; C6 disabled; Energy/Performance bias = max performanceAvoids latency jitter from power transitions
Intel VT-d (IOMMU)EnabledRequired for the vfio-pci DPDK driver (preferred over igb_uio on Secure-Boot systems)
Hyper-ThreadingEnabledTRex uses sibling threads for data-plane cores
MemoryAll channels populated, NUMA memory interleaving offTRex recommends 4+ channels per socket
BootUEFI, Secure Boot may stay on if vfio-pci is usedigb_uio is an unsigned out-of-tree module and would need Secure Boot off
iLODedicated iLO port, NTP, syslogOut-of-band access

8.2 Operating system installation

8.3 Base configuration

# time, NTP (same servers as the switches), tuned profile for low latency
dnf -y update
dnf -y install chrony tuned pciutils numactl tmux git wget tar bzip2 vim-enhanced \
    python3.12 python3.12-pip kernel-devel-$(uname -r) kernel-headers gcc make \
    elfutils-libelf-devel zlib-devel firewalld policycoreutils-python-utils
sed -i 's/^pool .*/server 10.0.31.21 iburst\nserver 10.0.31.23 iburst/' /etc/chrony.conf
systemctl enable --now chronyd
tuned-adm profile network-latency

# firewall: management access only (adjust the management prefix)
firewall-cmd --permanent --new-zone=mgmt
firewall-cmd --permanent --zone=mgmt --add-source=<MGMT-PREFIX>
firewall-cmd --permanent --zone=mgmt --add-service=ssh --add-service=https
firewall-cmd --permanent --zone=public --remove-service=ssh --remove-service=cockpit --remove-service=dhcpv6-client
firewall-cmd --reload

# kernel parameters: IOMMU passthrough + 8 GB of 2 MB hugepages (TRex allocates from them)
grubby --update-kernel=ALL --args="intel_iommu=on iommu=pt default_hugepagesz=2M hugepagesz=2M hugepages=4096"
# optional CPU isolation for the TRex data-plane threads (threads 6-15 and 28-31 in the example layout of 8.5)
grubby --update-kernel=ALL --args="isolcpus=6-15,28-31 nohz_full=6-15,28-31 rcu_nocbs=6-15,28-31"
reboot
# after reboot: verify
grep -E 'HugePages_(Total|Free)' /proc/meminfo
cat /proc/cmdline
dmesg | grep -i -E 'DMAR|IOMMU' | head
lspci -nn | grep -i ethernet
for d in $(lspci -n | awk '/8086:1572/{print $1}'); do
    echo "$d numa=$(cat /sys/bus/pci/devices/0000:$d/numa_node)"
done

Intel X710 devices show PCI ID 8086:1572 (SFP+). All eight ports should report the same NUMA node (or -1 on a single-socket system).

8.4 TRex installation

mkdir -p /data/trex /opt/trex
cd /data/trex
# the TRex download server uses a certificate chain that some systems do not trust;
# if --no-check-certificate is needed, verify the archive against the checksum on the release page
wget --no-check-certificate https://trex-tgn.cisco.com/trex/release/v3.08.tar.gz
tar xzf v3.08.tar.gz
ln -sfn /data/trex/v3.08 /opt/trex/current
cd /opt/trex/current
./t-rex-64 --help | head -5          # must print the usage text
./dpdk_setup_ports.py -s             # shows NICs, drivers, NUMA, MAC addresses
Known issue: GLIBCXX / libstdc++ mismatch TRex 3.06 and later ship their own libstdc++.so.6. On some distributions the system libicu/libarchive require a newer symbol (GLIBCXX_3.4.30) and _t-rex-64 aborts at start. Work-around confirmed by the TRex community: point TRex to the system library: mv so/x86_64/libstdc++.so.6 so/x86_64/libstdc++.so.6.trex && ln -s /usr/lib64/libstdc++.so.6 so/x86_64/libstdc++.so.6. Re-test with ./t-rex-64 --help.

8.4.1 Binding the X710 ports to DPDK

Run the interactive generator once to let TRex detect the NICs and create a baseline configuration, then split it into the two instance files of section 8.5. Select all eight X710 ports (IDs from the table), keep the default IP suggestions (they are not used in stateless mode), and let the script save to /etc/trex_cfg.yaml.

./dpdk_setup_ports.py -i
# ... choose the 8 X710 interfaces, accept defaults, save to /etc/trex_cfg.yaml
cat /etc/trex_cfg.yaml                # baseline: interfaces list and platform/thread layout
./dpdk_setup_ports.py -s              # X710 ports must now show driver vfio-pci (or igb_uio)

With IOMMU enabled the script binds the ports to vfio-pci; without IOMMU it compiles and loads igb_uio from ko/src (needs kernel-devel, fails with Secure Boot). The binding is re-applied automatically by t-rex-64 at every start.

8.5 TRex configuration files for the two instances

Replace the PCI addresses with the values from dpdk_setup_ports.py -s (NIC1 = four consecutive functions .0-.3 of the first X710, NIC2 = the second X710). Thread numbers assume a 16-core / 32-thread single socket; threads 0-5 and 16-27 remain for the OS, InfluxDB, Grafana and trexctl (c = data-plane threads per port pair; the threads list of each dual_if entry must contain at least c entries).

### /etc/trex/trex_mon.yaml - monitoring instance (NIC1, software mode, EMU)
- version: 2
  interfaces: ['31:00.0', '31:00.1', '31:00.2', '31:00.3']
  port_limit: 4
  prefix: mon
  zmq_pub_port: 4500
  zmq_rpc_port: 4501
  limit_memory: 3072
  port_bandwidth_gb: 10
  c: 2
  services_core: 5
  port_info:
    - ip: 1.1.1.1
      default_gw: 1.1.1.2
    - ip: 1.1.1.2
      default_gw: 1.1.1.1
    - ip: 1.1.2.1
      default_gw: 1.1.2.2
    - ip: 1.1.2.2
      default_gw: 1.1.2.1
  platform:
    master_thread_id: 4
    latency_thread_id: 5
    dual_if:
      - socket: 0
        threads: [6, 7]
      - socket: 0
        threads: [8, 9]
### /etc/trex/trex_lab.yaml - lab instance (NIC2, hardware mode or ASTF)
- version: 2
  interfaces: ['98:00.0', '98:00.1', '98:00.2', '98:00.3']
  port_limit: 4
  prefix: lab
  zmq_pub_port: 4600
  zmq_rpc_port: 4601
  limit_memory: 3072
  port_bandwidth_gb: 10
  c: 4
  port_info:
    - ip: 2.1.1.1
      default_gw: 2.1.1.2
    - ip: 2.1.1.2
      default_gw: 2.1.1.1
    - ip: 2.1.2.1
      default_gw: 2.1.2.2
    - ip: 2.1.2.2
      default_gw: 2.1.2.1
  platform:
    master_thread_id: 10
    latency_thread_id: 11
    dual_if:
      - socket: 0
        threads: [12, 13, 28, 29]
      - socket: 0
        threads: [14, 15, 30, 31]

The port_info entries are placeholders: in stateless mode the real client addresses are configured by EMU (monitoring) or by the trexctl test runner (lab); in ASTF mode the lab entries are overwritten by the ASTF profile run (section 11.7). Keys prefix, zmq_pub_port, zmq_rpc_port, limit_memory, services_core, c and the platform section are documented in the TRex manual (chapter "Platform configuration"). VALIDATED

8.6 systemd units

mkdir -p /etc/trex /var/log/trex
cat >/etc/systemd/system/trex-mon.service <<'EOF'
[Unit]
Description=TRex monitoring instance (stateless, software mode, EMU)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/trex/current
ExecStart=/opt/trex/current/t-rex-64 -i --software --emu --cfg /etc/trex/trex_mon.yaml --iom 0
Restart=on-failure
RestartSec=15
LimitMEMLOCK=infinity
LimitNOFILE=65536
StandardOutput=append:/var/log/trex/trex-mon.log
StandardError=append:/var/log/trex/trex-mon.log

[Install]
WantedBy=multi-user.target
EOF

cat >/etc/systemd/system/trex-lab.service <<'EOF'
[Unit]
Description=TRex lab instance (stateless, hardware flow statistics)
After=network-online.target
Conflicts=trex-lab-astf.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/trex/current
ExecStart=/opt/trex/current/t-rex-64 -i --cfg /etc/trex/trex_lab.yaml --iom 0
Restart=no
LimitMEMLOCK=infinity
StandardOutput=append:/var/log/trex/trex-lab.log
StandardError=append:/var/log/trex/trex-lab.log
EOF

cat >/etc/systemd/system/trex-lab-astf.service <<'EOF'
[Unit]
Description=TRex lab instance (advanced stateful, ASTF)
After=network-online.target
Conflicts=trex-lab.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/trex/current
ExecStart=/opt/trex/current/t-rex-64 -i --astf --cfg /etc/trex/trex_lab.yaml --iom 0
Restart=no
LimitMEMLOCK=infinity
StandardOutput=append:/var/log/trex/trex-lab.log
StandardError=append:/var/log/trex/trex-lab.log
EOF

systemctl daemon-reload
systemctl enable --now trex-mon.service
sleep 20 && tail -n 30 /var/log/trex/trex-mon.log

The lab units are started on demand (systemctl start trex-lab or trex-lab-astf); Conflicts= guarantees that only one of them owns NIC2. t-rex-64 is a wrapper script that prepares hugepages and DPDK binding before launching _t-rex-64; the --iom 0 flag suppresses the interactive text UI output in the log.

8.7 Python environment for trexctl and the console

python3.12 -m venv /opt/trexctl/venv
/opt/trexctl/venv/bin/pip install --upgrade pip
/opt/trexctl/venv/bin/pip install pyyaml scapy influxdb-client rich jsonschema pyzmq simplejson
# make the TRex client libraries importable (STL, EMU, ASTF APIs ship with the TRex release)
echo "/opt/trex/current/automation/trex_control_plane/interactive" \
   > /opt/trexctl/venv/lib/python3.12/site-packages/trex.pth
/opt/trexctl/venv/bin/python -c "from trex.stl.api import STLClient; from trex.emu.api import EMUClient; print('ok')"

TRex v3.08 added Python 3.12 support on the client side and notes that older Python versions may not work with that release; hence the dedicated 3.12 environment. Console access: cd /opt/trex/current && ./trex-console -p 4501 --async_port 4500 --emu (monitoring) or -p 4601 --async_port 4600 (lab).

8.8 Initial self-test (before connecting to the TX switch)

  1. Connect NIC1 port 2 and port 3 (p2, p3) with a DAC (loopback). Start trex-mon, open the console and run a short stateless test:
    cd /opt/trex/current && ./trex-console -p 4501 --async_port 4500
    trex> portattr -a --prom on
    trex> start -f stl/udp_1pkt_simple.py -m 1kpps --port 2
    trex> tui            # RX on port 3 must equal TX on port 2; q to quit
    trex> stop -a
  2. Repeat with the latency example stl/flow_stats_latency.py and check stats --ls: latency in the single-digit microsecond range confirms the server-side baseline (DPDK, no switch).
  3. Start trex-lab with NIC2 p6-p7 looped and run start -f stl/imix.py -m 100% for 60 s: no drops and no "queue full" counters confirm hardware mode line rate.
  4. Record the results in the acceptance protocol (section 12.3).

8.9 Installation troubleshooting

SymptomCauseAction
_t-rex-64: GLIBCXX_3.4.30 not foundBundled libstdc++ older than the system librariesSymlink the system libstdc++ (8.4)
Ports missing in dpdk_setup_ports.py -s or "unsupported SFP"X710 firmware rejects non-Intel opticsUse passive DAC or Intel-coded SR modules; check dmesg | grep i40e while the kernel driver is still bound
"Not enough hugepages" / EAL init failureHugepages not reserved or fragmented; two instances exceed the poolVerify /proc/meminfo; raise hugepages=; keep limit_memory sum below the pool
Second instance fails with "address already in use"Same ZMQ ports or prefixCheck zmq_pub_port/zmq_rpc_port/prefix differ
Low performance, high CPUNIC and threads on different NUMA nodes, C-states enabled, isolcpus missingCheck numa_node, BIOS profile, tuned-adm active
vfio-pci not loadedIOMMU disabledBIOS VT-d + intel_iommu=on; fall back to igb_uio only with Secure Boot off
EMU clients not resolving the gatewayPort not promiscuous, wrong tags, firewall/gateway not answering ARPportattr -a --prom on; emu_show_all; capture with capture monitor start --rx 0 in the console

9. Orchestration tooling: trexctl specification

trexctl is a project deliverable: a Python 3.12 command-line tool and a small daemon that turn a declarative description of the environment (inventory) and of the wanted traffic (profiles) into TRex streams and EMU clients, run them, and export statistics to InfluxDB. It replaces the proprietary trex_client.py of the reference design. This section is its functional specification; implementation effort is estimated in section 12.

9.1 Architecture

ModuleResponsibility
trexctl.inventoryLoads and validates inventory.yaml (APs, S-VLANs, TRex ports, VLANs under test, pools, gateways, firewall zone); derives client IP/MAC per AP and VLAN (section 4.6.3); renders Comware configuration snippets for Leaf/BL ports.
trexctl.profileLoads profiles/*.yaml; expands stream groups (class, source APs/VLANs, destination APs/VLANs, rate, size, TOS, bidirectional flag) into concrete unidirectional stream definitions; validates against the packet budget.
trexctl.emuBuilds the EMU profile (one namespace per TRex port + S-VLAN + C-VLAN, one client per IP), loads it into the monitoring instance, waits for gateway resolution and returns resolved MACs.
trexctl.streamsBuilds Scapy packets (Ether/Dot1Q/Dot1Q/IP/UDP/payload), assigns stable pg_ids, creates STLStream objects with STLFlowLatencyStats, pushes them to the right TRex port, starts/stops/updates traffic.
trexctl.exporterDaemon: polls get_pgid_stats(), port stats and global stats every N seconds, computes interval deltas, writes InfluxDB line protocol with the stream's tags; keeps a local state file so that restarts do not produce false drops.
trexctl.testsTest runners for the lab instance: throughput (binary search for no-drop rate), soak (fixed load for a duration), convergence (high-rate loss timing), astf (stateful profile runner), each producing a JSON/Markdown report and InfluxDB annotations.
trexctl.cliCommand-line front end (section 9.6), rich-based status tables.

9.2 Repository and file layout

/opt/trexctl/                         # git checkout (LVR internal repository)
  venv/                               # Python 3.12 virtual environment (8.7)
  trexctl/                            # package: cli.py inventory.py profile.py emu.py streams.py exporter.py tests/
  schemas/inventory.schema.json       # JSON schema for validation
  schemas/profile.schema.json
  dashboards/*.json                   # Grafana dashboards (provisioned)
  alerts/*.yaml                       # Grafana alert rules (provisioned)
/etc/trexctl/
  inventory.yaml                      # environment description (single source of truth)
  profiles/monitoring-default.yaml    # permanent profile
  profiles/dscp-check.yaml
  profiles/lab-*.yaml                 # lab test definitions
  trexctl.yaml                        # tool settings: TRex endpoints, InfluxDB URL/token, sampling interval, budget
  pgid-map.json                       # persisted pg_id allocation (auto-managed)
  secrets.env                         # INFLUX_TOKEN (mode 0600)
/data/trexctl/
  reports/                            # test reports (JSON + Markdown)
  archive/                            # switch config snapshots, pcaps
  state/                              # exporter state
/var/log/trexctl/

9.3 Inventory (inventory.yaml)

version: 1
site:
  name: LVR RZK/RZC
  mac_oui: "02:54:52"            # locally administered prefix for TRex clients
trex:
  mon:  { server: 127.0.0.1, rpc_port: 4501, pub_port: 4500, emu_port: 4510, mode: stl-software-emu }
  lab:  { server: 127.0.0.1, rpc_port: 4601, pub_port: 4600, mode: stl-hw }
ports:                                 # TRex port roles
  mon:
    0: { type: multiplexed, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/21, default_for: [rzk, fw] }
    1: { type: multiplexed, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/22, default_for: [rzc] }
  lab:
    4: { type: pinned, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/9,  ap: K-L11 }
    5: { type: pinned, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/10, ap: K-BL }
    6: { type: pinned, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/11, ap: FW }
    7: { type: pinned, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/12, ap: C-L21 }
aps:
  K-L11: { index: 1,  dc: rzk, device: sw-rzk-L11, device_port: Ten-GigabitEthernet1/3/1, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/1, svlan: 3101, vlans: [1314, 1315] }
  K-L12: { index: 2,  dc: rzk, device: sw-rzk-L12, device_port: TBD, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/2, svlan: 3102, vlans: [1314, 1315] }
  K-L21: { index: 3,  dc: rzk, device: sw-rzk-L21, device_port: TBD, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/3, svlan: 3103, vlans: [1314, 1315] }
  K-L31: { index: 4,  dc: rzk, device: sw-rzk-L31, device_port: TBD, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/4, svlan: 3104, vlans: [1314, 1315] }
  K-L41: { index: 5,  dc: rzk, device: sw-rzk-L41, device_port: TBD, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/5, svlan: 3105, vlans: [1314, 1315] }
  K-BL:  { index: 6,  dc: rzk, device: sw-rzk-BL,  device_port: Ten-GigabitEthernet1/3/6, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/6, svlan: 3110, vlans: [1314, 1315] }
  C-L11: { index: 7,  dc: rzc, device: sw-rzc-L11, device_port: TBD, tx_switch: sw-rzc-TX1, tx_port: XGE1/1/1, svlan: 3201, vlans: [1314, 1315] }
  C-L12: { index: 8,  dc: rzc, device: sw-rzc-L12, device_port: TBD, tx_switch: sw-rzc-TX1, tx_port: XGE1/1/2, svlan: 3202, vlans: [1314, 1315] }
  C-L13: { index: 9,  dc: rzc, device: sw-rzc-L13, device_port: TBD, tx_switch: sw-rzc-TX1, tx_port: XGE1/1/3, svlan: 3203, vlans: [1314, 1315] }
  C-L21: { index: 10, dc: rzc, device: SW-RZC-L21, device_port: Ten-GigabitEthernet1/4/4, tx_switch: sw-rzc-TX1, tx_port: XGE1/1/4, svlan: 3204, vlans: [1314, 1315] }
  C-L22: { index: 11, dc: rzc, device: sw-rzc-L22, device_port: TBD, tx_switch: sw-rzc-TX1, tx_port: XGE1/1/5, svlan: 3205, vlans: [1314, 1315] }
  C-L23: { index: 12, dc: rzc, device: sw-rzc-L23, device_port: TBD, tx_switch: sw-rzc-TX1, tx_port: XGE1/1/6, svlan: 3206, vlans: [1314, 1315] }
  C-BL:  { index: 13, dc: rzc, device: sw-rzc-BL,  device_port: Ten-GigabitEthernet1/3/14, tx_switch: sw-rzc-TX1, tx_port: XGE1/1/7, svlan: 3210, vlans: [1314, 1315] }
  FW:    { index: 14, dc: both, device: CPF-ZV01/ZV02, device_port: TBD, tx_switch: both, tx_port: XGE1/1/7+XGE1/1/8, svlan: 3300, vlans: [1420] }
vlans:
  1314: { vsi: VPN-1314, prefix: 10.3.14.0/24, gateway: 10.3.14.1, gateway_owner: sw-rzk-BL/VPN-CORE, pool_start: 10.3.14.101, vrf: VPN-CORE }
  1315: { vsi: VPN-1315, prefix: 10.3.15.0/24, gateway: 10.3.15.1, gateway_owner: sw-rzk-BL/VPN-CORE, pool_start: 10.3.15.101, vrf: VPN-CORE }
  1420: { prefix: 10.9.90.0/24, gateway: 10.9.90.1, gateway_owner: ENT-FW, pool_start: 10.9.90.101, vrf: FW-ZONE }
  <PROD-VLAN-A>: { vsi: VPN-A, prefix: <SUBNET-A>, gateway: <GW-A>, gateway_owner: DC-FW, pool_start: <POOL-A>, vrf: DC-FW }
budget: { max_streams: 600, max_pps: 50000, max_bps: 50000000, max_pps_per_fw_stream: 100 }

Rules enforced by the validator: S-VLANs unique; AP indexes unique and 1-49 (lab clients use index+50); every VLAN referenced by an AP exists; pool size (16) does not overlap the gateway; per VLAN the pool stays inside the prefix.

9.4 Profiles (profiles/*.yaml)

version: 1
name: monitoring-default
instance: mon
defaults: { pps: 200, size: 128, tos: 0, ttl: 64, latency: true, bidir: true, dport_base: 32000, sport_base: 40000 }
groups:
  - name: l2-intra-rzk
    class: L2                          # L2: same VLAN, dst MAC = remote client MAC
    vlans: [1314, 1315]
    pairs: [[K-L11, K-BL], [K-L12, K-BL], [K-L21, K-BL], [K-L31, K-BL], [K-L41, K-BL]]
  - name: l2-intra-rzc
    class: L2
    vlans: [1314, 1315]
    pairs: [[C-L11, C-BL], [C-L12, C-BL], [C-L13, C-BL], [C-L21, C-BL], [C-L22, C-BL], [C-L23, C-BL]]
  - name: l2-inter-dc
    class: L2
    vlans: [1314, 1315]
    pairs: [[K-L11, C-L11], [K-L12, C-L12], [K-L21, C-L21], [K-L31, C-L22], [K-L41, C-L23], [K-BL, C-BL]]
  - name: l3-bl
    class: L3                          # L3: dst MAC = resolved gateway MAC of the source VLAN
    src_vlan: 1314
    dst_vlan: 1315
    pairs: [[K-L11, K-L21], [K-L31, K-BL], [C-L21, C-L22], [C-L13, C-BL]]
  - name: l3-dcfw
    class: L3
    src_vlan: <PROD-VLAN-A>
    dst_vlan: <PROD-VLAN-B>
    pps: 50
    pairs: [[K-L11, K-L41], [K-L21, K-L31], [C-L12, C-L23], [C-L11, C-L22]]
  - name: l3-entfw
    class: L3
    src_vlan: 1314
    dst_vlan: 1420
    pps: 50
    pairs: [[K-L11, FW], [K-BL, FW], [C-L21, FW], [C-BL, FW]]
  - name: dscp-l2-interdc
    class: L2
    vlans: [1314]
    pps: 100
    size: 256
    tos_set: [0xB8, 0x88, 0x20]        # one stream per TOS value
    pairs: [[K-L11, C-L21]]
  - name: dscp-entfw
    class: L3
    src_vlan: 1314
    dst_vlan: 1420
    pps: 50
    size: 256
    tos_set: [0xB8, 0x88, 0x20]
    pairs: [[K-L11, FW]]
tags: { environment: prod, owner: netzwerk }

Expansion rules: each pair and each VLAN (or VLAN pair) and each TOS value produces one stream; bidir: true adds the reverse stream. Class L2 requires both APs to carry the VLAN; class L3 requires a gateway for the source VLAN and resolves it per source AP. The class name, DC pair (rzk-rzk, rzk-rzc, rzc-rzc, x-fw), VLANs, APs and TOS become InfluxDB tags.

9.5 Stream generation algorithm

  1. Load and validate inventory and profile (JSON schema + semantic rules); compute the stream list; abort if the budget is exceeded (unless --force).
  2. Allocate pg_ids: key = class|src_ap|src_vlan|dst_ap|dst_vlan|tos; look up in pgid-map.json, otherwise assign the lowest free id in 1-899 and persist. Stable ids keep Grafana history continuous.
  3. Provision EMU (monitoring instance): for every (TRex port, S-VLAN, C-VLAN) create a namespace with tci=[svlan, cvlan], tpid=[0x8100, 0x8100]; add one client per needed IP with its deterministic MAC, ipv4_dg = VLAN gateway and plugins arp, icmp. Set the TRex ports to promiscuous + multicast and service mode filtered for EMU. Wait until every client that needs a gateway reports dgw.resolve = true; retry three times, then report unresolved clients and continue with the resolvable streams only.
  4. Build packets: Ether(src=client_mac, dst=dst_mac)/Dot1Q(vlan=svlan)/Dot1Q(vlan=cvlan)/IP(src, dst, tos, ttl)/UDP(sport, dport)/Raw(pad), padded to size. For class L2 dst_mac is the remote TRex client MAC; for class L3 it is the resolved gateway MAC. Pinned lab ports omit the outer Dot1Q.
  5. Create streams: STLStream(packet=STLPktBuilder(pkt), mode=STLTXCont(pps=pps), flow_stats=STLFlowLatencyStats(pg_id=pg_id), name=key); group by TRex port; add_streams() per port; start(ports, force=True). Streams are added with c.add_streams() individually so that a single stream can be stopped/updated via its stream id without disturbing the others (TRex supports per-stream pause/update through profiles per port; trexctl uses one profile per class to allow partial restarts).
  6. Record the applied stream table (/data/trexctl/state/applied-<profile>.json) with pg_id, ports, addresses, tags - the exporter reads this file to tag the statistics.

9.6 Command-line interface

CommandPurpose
trexctl inventory validateSchema and semantic validation; prints the AP/VLAN/IP table
trexctl inventory render-leaf --ap K-L11Prints the Comware snippet for the Leaf AP port (section 7.3 template) from the inventory
trexctl inventory render-tx --switch sw-rzk-TX1Prints the TX switch QinQ port configuration
trexctl plan -p monitoring-defaultExpands the profile, shows every stream with pg_id, ports, addresses, rate; budget summary; no changes
trexctl apply -p monitoring-default [--force]Provisions EMU, builds and starts the streams on the monitoring instance (idempotent: re-apply replaces the profile)
trexctl status [--watch]Live table: per stream TX/RX pps, loss, latency avg/max/jitter; port and global counters; unresolved clients
trexctl stop [-p profile | --all]Stops streams (EMU clients stay)
trexctl update --group l2-inter-dc --pps 1000Changes the rate of a group live (e.g. before a maintenance window) without re-creating streams
trexctl emu show | resolve | clearEMU client table, forced re-resolution, removal
trexctl exporter runForeground exporter (normally run by systemd trexctl-exporter.service)
trexctl test throughput --src K-L11 --dst C-L21 --vlan 1314 --sizes 64,512,1518 --duration 60Lab: binary search for the no-drop rate per frame size, report
trexctl test soak --src K-L11 --dst FW --src-vlan 1314 --dst-vlan 1420 --rate 2gbps --duration 900Lab: fixed load, loss/latency over time
trexctl test convergence --group l2-inter-dc --pps 1000 --duration 1800Monitoring instance: temporarily raises the rate of a group and records outage durations per stream
trexctl test astf --profile lab-fw-http.yaml --mult 500 --duration 300Lab: ASTF run with CPS/flows/goodput report
trexctl annotate "IRF reboot sw-rzk-L21 member 2"Writes a Grafana annotation (via InfluxDB measurement trex_event)
trexctl report --test <id> --format md|json|htmlRenders a stored test report

9.7 Exporter and InfluxDB data model

Interval: 2 s by default (1 s possible for convergence tests, 5 s for long-term). Each poll calls get_pgid_stats() (flow and latency statistics), get_stats() (ports, global). TX/RX packet counters are converted to per-interval deltas; drops per interval = TX delta - RX delta (clamped at 0 and compensated for in-flight packets by using the TRex rx_delay convention); loss is also kept as cumulative counters for exact outage accounting.

MeasurementTagsFields
trex_streampg_id, name, class, src_ap, dst_ap, src_dc, dst_dc, dc_pair, src_vlan, dst_vlan, vrf, tos, dscp, instance, profile + profile tagstx_pps, rx_pps, tx_bps, rx_bps, tx_pkts, rx_pkts, drop_pkts, drop_pkts_total, lat_avg_us, lat_min_us, lat_max_us, lat_last_max_us, jitter_us, hist_100, hist_200, ... (histogram buckets), rx_ok(bool)
trex_portinstance, port, roletx_pps, rx_pps, tx_bps, rx_bps, ierrors, oerrors, tx_queue_full, link_up
trex_globalinstancecpu_util, rx_cpu_util, bw_per_core, rx_drop_bps, queue_full, active_streams, unresolved_clients, exporter_lag_ms
trex_testtest_id, type, src_ap, dst_ap, vlan, sizeoffered_bps, offered_pps, rx_bps, loss_pct, lat_avg_us, lat_max_us, ndr_bps
trex_eventkind (annotation, apply, stop, test)text

Series cardinality: about 180 streams x ~25 fields - trivial for InfluxDB. Writes use the v2 HTTP API with a write token scoped to the trex bucket; batched every interval; on InfluxDB unavailability the exporter buffers up to 10 minutes in memory and logs a warning.

9.8 Test runners

9.9 Reference implementation sketches

The following excerpts illustrate the TRex API usage the implementation relies on. They follow the TRex STL and EMU API documentation (v3.x).

# EMU profile: one namespace per (port, S-VLAN, C-VLAN), one client per TRex IP
from trex.emu.api import *

def build_emu_profile(clients):
    ns_by_key = {}
    for c in clients:                                   # c: port, svlan, cvlan, mac, ip, gw
        key = (c.port, c.svlan, c.cvlan)
        if key not in ns_by_key:
            tci  = [c.svlan, c.cvlan] if c.svlan else [c.cvlan, 0]
            tpid = [0x8100, 0x8100] if c.svlan else [0x8100, 0]
            ns_key = EMUNamespaceKey(vport=c.port, tci=tci, tpid=tpid)
            ns_by_key[key] = EMUNamespaceObj(ns_key=ns_key,
                                             def_c_plugs={'arp': {'enable': True}, 'icmp': {}})
        ns_by_key[key].add_clients(EMUClientObj(mac=Mac(c.mac).V(),
                                                ipv4=Ipv4(c.ip).V(),
                                                ipv4_dg=Ipv4(c.gw).V()))
    return EMUProfile(ns=list(ns_by_key.values()), def_ns_plugs=None)

emu = EMUClient(server='127.0.0.1', sync_port=4510)
emu.connect()
emu.load_profile(profile=build_emu_profile(clients), max_rate=512, tunables=[])
# then poll emu.get_info_clients(...) until dgw.resolve is True and read dgw.rmac
# stateless streams with latency statistics, double-tagged for multiplexed ports
from trex.stl.api import *
from scapy.layers.l2 import Ether, Dot1Q
from scapy.layers.inet import IP, UDP

def build_stream(s):                                     # s: stream definition (dataclass)
    pkt = Ether(src=s.src_mac, dst=s.dst_mac)
    if s.svlan:
        pkt = pkt / Dot1Q(vlan=s.svlan)
    pkt = pkt / Dot1Q(vlan=s.cvlan) / IP(src=s.src_ip, dst=s.dst_ip, tos=s.tos, ttl=s.ttl) \
              / UDP(sport=s.sport, dport=s.dport)
    pad = max(0, s.size - len(pkt)) * b'\x00'
    return STLStream(name=s.key,
                     packet=STLPktBuilder(pkt=pkt / pad),
                     mode=STLTXCont(pps=s.pps),
                     flow_stats=STLFlowLatencyStats(pg_id=s.pg_id))

c = STLClient(server='127.0.0.1', sync_port=4501, async_port=4500)
c.connect()
c.acquire(ports=[0, 1], force=True)
c.set_port_attr(ports=[0, 1], promiscuous=True, multicast=True)
# punt only EMU protocols to the RX core (console equivalent: service --emu)
c.set_service_mode(ports=[0, 1], enabled=False, filtered=True, mask=EMU_MASK)
for port, streams in streams_by_port.items():
    c.add_streams([build_stream(s) for s in streams], ports=[port])
c.start(ports=list(streams_by_port), force=True)
# exporter poll loop (simplified)
import time
from influxdb_client import InfluxDBClient, Point, WritePrecision

influx = InfluxDBClient(url="http://127.0.0.1:8086", token=TOKEN, org="lvr")
write  = influx.write_api()
prev = {}
while True:
    st  = c.get_pgid_stats()                            # {'flow_stats': {...}, 'latency': {...}}
    now = time.time_ns()
    points = []
    for pg_id, meta in applied.items():                 # meta = tags from the applied stream table
        fs  = st['flow_stats'].get(pg_id, {})
        lat = st['latency'].get(pg_id, {}).get('latency', {})
        tx  = sum(fs.get('tx_pkts', {}).values())
        rx  = sum(fs.get('rx_pkts', {}).values())
        dtx = tx - prev.get((pg_id, 'tx'), tx)
        drx = rx - prev.get((pg_id, 'rx'), rx)
        prev[(pg_id, 'tx')] = tx
        prev[(pg_id, 'rx')] = rx
        p = Point("trex_stream").time(now, WritePrecision.NS)
        for k, v in meta.tags.items(): p = p.tag(k, v)
        p = (p.field("tx_pkts", tx).field("rx_pkts", rx)
               .field("drop_pkts", max(0, dtx - drx))
               .field("drop_pkts_total", max(0, tx - rx))
               .field("tx_pps", dtx / INTERVAL).field("rx_pps", drx / INTERVAL)
               .field("lat_avg_us", lat.get('average', 0.0))
               .field("lat_max_us", lat.get('total_max', 0))
               .field("lat_last_max_us", lat.get('last_max', 0))
               .field("lat_min_us", lat.get('total_min', 0))
               .field("jitter_us", lat.get('jitter', 0)))
        points.append(p)
    write.write(bucket="trex", record=points)
    time.sleep(INTERVAL)

Latency dictionary keys (average, total_max, total_min, last_max, jitter, histogram) are documented in the TRex STL Python API (get_pgid_stats). VALIDATED

9.10 Service integration, permissions and logging

cat >/etc/systemd/system/trexctl-exporter.service <<'EOF'
[Unit]
Description=trexctl statistics exporter (TRex -> InfluxDB)
After=trex-mon.service influxdb.service
Requires=trex-mon.service

[Service]
Type=simple
User=trexctl
Group=trexctl
EnvironmentFile=/etc/trexctl/secrets.env
ExecStart=/opt/trexctl/venv/bin/trexctl exporter run
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF
useradd -r -s /sbin/nologin -d /data/trexctl trexctl
# trexctl needs to start/stop the lab units for ASTF tests:
cat >/etc/sudoers.d/trexctl <<'EOF'
trexctl ALL=(root) NOPASSWD: /usr/bin/systemctl start trex-lab.service, \
    /usr/bin/systemctl stop trex-lab.service, \
    /usr/bin/systemctl start trex-lab-astf.service, \
    /usr/bin/systemctl stop trex-lab-astf.service
EOF
chmod 440 /etc/sudoers.d/trexctl
systemctl daemon-reload && systemctl enable --now trexctl-exporter.service

9.11 Development and acceptance of trexctl

10. InfluxDB and Grafana

10.1 InfluxDB OSS 2.x installation

cat >/etc/yum.repos.d/influxdata.repo <<'EOF'
[influxdata]
name = InfluxData Repository - Stable
baseurl = https://repos.influxdata.com/stable/x86_64/main
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdata-archive.key
EOF
dnf -y install influxdb2 influxdb2-cli
# keep the data on /data
mkdir -p /data/influxdb && chown influxdb:influxdb /data/influxdb
cat >/etc/influxdb/config.toml <<'EOF'
bolt-path = "/data/influxdb/influxd.bolt"
engine-path = "/data/influxdb/engine"
http-bind-address = "127.0.0.1:8086"
query-memory-bytes = 2147483648
storage-cache-max-memory-size = 2147483648
EOF
systemctl enable --now influxdb
# initial setup: organisation lvr, bucket trex with 90-day retention;
# the admin token is printed once - store it in the password safe
influx setup --org lvr --bucket trex --retention 90d --username influxadmin \
    --password '<STRONG-PASSWORD>' --force
influx bucket create --org lvr --name trex_longterm --retention 730d
# scoped tokens (bucket IDs from 'influx bucket list')
TREX_ID=$(influx bucket list --org lvr --name trex --hide-headers | awk '{print $1}')
LT_ID=$(influx bucket list --org lvr --name trex_longterm --hide-headers | awk '{print $1}')
influx auth create --org lvr --description "trexctl exporter (write trex)" --write-bucket "$TREX_ID"
influx auth create --org lvr --description "grafana (read)" --read-bucket "$TREX_ID" --read-bucket "$LT_ID"

Pin the package version in the repository configuration (e.g. influxdb2-2.9.x) - InfluxData moved its "latest" tags to InfluxDB 3 Core in September 2026, which has a different storage engine and API. InfluxDB 2.x is still maintained (2.9.1 at the time of writing) and remains the recommended version for this deployment; a later migration to InfluxDB 3 Enterprise/Core is possible but out of scope.

10.2 Downsampling task

Raw 2-second data is kept for 90 days in trex. A Flux task writes 1-minute aggregates (mean/max/sum per stream) into trex_longterm for two years:

option task = {name: "trex_downsample_1m", every: 10m, offset: 1m}

from(bucket: "trex")
  |> range(start: -20m)
  |> filter(fn: (r) => r._measurement == "trex_stream")
  |> filter(fn: (r) => r._field == "lat_avg_us" or r._field == "jitter_us"
                       or r._field == "rx_pps" or r._field == "tx_pps")
  |> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
  |> to(bucket: "trex_longterm", org: "lvr")

from(bucket: "trex")
  |> range(start: -20m)
  |> filter(fn: (r) => r._measurement == "trex_stream")
  |> filter(fn: (r) => r._field == "lat_max_us" or r._field == "lat_last_max_us")
  |> aggregateWindow(every: 1m, fn: max, createEmpty: false)
  |> to(bucket: "trex_longterm", org: "lvr")

from(bucket: "trex")
  |> range(start: -20m)
  |> filter(fn: (r) => r._measurement == "trex_stream" and r._field == "drop_pkts")
  |> aggregateWindow(every: 1m, fn: sum, createEmpty: false)
  |> to(bucket: "trex_longterm", org: "lvr")

Create it with influx task create --org lvr -f /opt/trexctl/influx/downsample.flux. Disk estimate: 180 streams x 25 fields x 0.5 points/s is about 2 250 points/s raw; with InfluxDB compression this is in the order of 1-2 GB per month, so 90 days of raw data need well under 10 GB.

10.3 Grafana installation

cat >/etc/yum.repos.d/grafana.repo <<'EOF'
[grafana]
name=grafana
baseurl=https://rpm.grafana.com
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://rpm.grafana.com/gpg.key
EOF
dnf -y install grafana            # pin a version if required by LVR policy, e.g. grafana-12.4.x
# TLS: certificate from the LVR PKI (CN trex-rzk-01.<domain>)
install -o root -g grafana -m 640 /path/trex-rzk-01.crt /etc/grafana/tls.crt
install -o root -g grafana -m 640 /path/trex-rzk-01.key /etc/grafana/tls.key
# grafana.ini changes
sed -i -e 's/^;protocol = http/protocol = https/' \
       -e 's/^;http_port = 3000/http_port = 443/' \
       -e 's#^;cert_file =#cert_file = /etc/grafana/tls.crt#' \
       -e 's#^;cert_key =#cert_key = /etc/grafana/tls.key#' \
       -e 's/^;root_url = .*/root_url = https:\/\/trex-rzk-01.<DOMAIN>\//' \
       -e 's/^;min_refresh_interval = 5s/min_refresh_interval = 1s/' /etc/grafana/grafana.ini
# allow the grafana service user to bind port 443 (systemd drop-in survives package upgrades)
mkdir -p /etc/systemd/system/grafana-server.service.d
cat >/etc/systemd/system/grafana-server.service.d/bind443.conf <<'EOF'
[Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
EOF
systemctl daemon-reload
systemctl enable --now grafana-server

Data sources (provisioned)

# /etc/grafana/provisioning/datasources/influx.yaml
apiVersion: 1
datasources:
  - name: InfluxDB-trex
    type: influxdb
    access: proxy
    url: http://127.0.0.1:8086
    isDefault: true
    jsonData: { version: Flux, organization: lvr, defaultBucket: trex, tlsSkipVerify: true }
    secureJsonData: { token: "<GRAFANA-READ-TOKEN>" }
  - name: InfluxDB-trex-longterm
    type: influxdb
    access: proxy
    url: http://127.0.0.1:8086
    jsonData: { version: Flux, organization: lvr, defaultBucket: trex_longterm }
    secureJsonData: { token: "<GRAFANA-READ-TOKEN>" }

Authentication

Local admin plus Active Directory via LDAP ([auth.ldap] enabled = true, config_file = /etc/grafana/ldap.toml with the LVR domain controllers, group mapping: network team = Editor, others = Viewer). Anonymous access disabled. Dashboards and alert rules are provisioned from /opt/trexctl/dashboards and /opt/trexctl/alerts so that the installation is reproducible.

10.4 Dashboards

DashboardPanelsVariables
TRex - OverviewInstance state (up/down, TRex CPU, RX CPU), total TX/RX pps, number of dropping streams (last 5 min), number of streams without RX ("path down"), worst latency per class (stat panels), event/annotation list-
TRex - Latency matrixTable/heatmap: average and maximum one-way latency per source AP x destination AP for the selected class, VLAN and time range; sparkline per cellclass, vlan, dscp
TRex - Loss and outagesDrops per stream over time (bar), cumulative drops per stream (table sorted descending), outage duration table (drops / pps), per-DC-pair drops, per-class dropsclass, dc_pair, src_ap, dst_ap
TRex - Class detailFor one class: latency avg/max/jitter per stream, RX pps per stream, histogram buckets (heatmap)class, src_ap, dst_ap, vlan
TRex - DSCPLatency and loss grouped by DSCP for the same AP pair, side by sidepair
TRex - Ports and serverPer TRex port TX/RX bps (RX mirrored negative), errors, queue full; exporter lag; InfluxDB write errorsinstance
TRex - Lab testsOffered load vs. RX, loss %, latency for a selected test id; NDR summary table per frame sizetest_id
TRex - ASTFActive/established flows, CPS, TCP errors, goodput client/server, latency histogramtest_id

Example Flux queries

// Latency matrix cell: mean latency per src/dst AP for one class
from(bucket: "trex")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r._measurement == "trex_stream" and r._field == "lat_avg_us")
  |> filter(fn: (r) => r.class == "${class}" and r.src_vlan == "${vlan}")
  |> group(columns: ["src_ap", "dst_ap"])
  |> mean()
  |> pivot(rowKey: ["src_ap"], columnKey: ["dst_ap"], valueColumn: "_value")

// Drops per stream over time
from(bucket: "trex")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r._measurement == "trex_stream" and r._field == "drop_pkts")
  |> filter(fn: (r) => r.dc_pair =~ /${dc_pair:regex}/)
  |> aggregateWindow(every: v.windowPeriod, fn: sum, createEmpty: false)

// Number of streams currently dropping (last 2 intervals)
from(bucket: "trex")
  |> range(start: -10s)
  |> filter(fn: (r) => r._measurement == "trex_stream" and r._field == "drop_pkts" and r._value > 0)
  |> group(columns: ["pg_id"]) |> count() |> group() |> count()

// Outage table: drops / pps = outage seconds per stream in the selected range
drops = from(bucket: "trex") |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r._measurement == "trex_stream" and r._field == "drop_pkts")
  |> group(columns: ["name", "src_ap", "dst_ap", "class"]) |> sum() |> rename(columns: {_value: "drops"})
pps = from(bucket: "trex") |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r._measurement == "trex_stream" and r._field == "tx_pps")
  |> group(columns: ["name", "src_ap", "dst_ap", "class"]) |> mean() |> rename(columns: {_value: "pps"})
join(tables: {d: drops, p: pps}, on: ["name", "src_ap", "dst_ap", "class"])
  |> map(fn: (r) => ({r with outage_s: float(v: r.drops) / r.pps}))
  |> sort(columns: ["outage_s"], desc: true)

Usage hints carried over from the reference design: keep the auto-refresh at 1-5 s and the time window at 5-30 minutes for live observation; disable auto-refresh when zooming or hovering; prefer "all streams" and filter by tags (class, DC pair, AP) rather than by individual stream ids; use the long-term data source for windows above 24 hours.

10.5 Alert rules (Grafana unified alerting)

RuleConditionSeverityNote
Stream losssum(drop_pkts) over 30 s > 0 for a stream, pending 30 swarningGrouped by class and dc_pair to avoid alert storms; one notification per group
Path downrx_pps == 0 while tx_pps > 0 for 30 scriticalIndicates AP link, VLAN mapping or firewall rule problem
Latency degradationlat_avg_us > 3 x 7-day baseline (or fixed thresholds per class once measured) for 2 minwarningThresholds set after the baseline phase (section 11.2)
Jitterjitter_us > 10 x baseline for 2 mininfo
TRex instance / exporter downNo trex_global points for 60 scriticalAlso covered by systemd restart
Unresolved clientsunresolved_clients > 0 for 5 minwarningGateway not answering ARP (VLAN missing on AP port, FW interface down)
Budgetactive_streams > 600 or total tx_pps > 50 000warningGuard against accidental high-rate profiles

Notification channels: e-mail to the network team distribution list; optionally the existing monitoring system (IMC/syslog webhook). Maintenance windows are modelled with Grafana mute timings plus trexctl annotate events.

10.6 Backup and housekeeping

11. Operations and test procedures

11.1 Roles and daily operation

RoleTasksAccess
Network operatorWatches the Overview dashboard, reacts to alerts, correlates outages with change tickets, runs predefined testsGrafana Viewer/Editor (AD group), SSH to trex-rzk-01 (group trex), trexctl read/test commands
Platform administratorMaintains inventory/profiles, adds VLANs/APs, upgrades TRex/InfluxDB/Grafana, manages tokens and backupssudo on trex-rzk-01, switch configuration rights for AP ports
Firewall administratorMaintains TRex objects and rules, zone interfaceSmartConsole

Daily: check the Overview dashboard (no path-down streams, no dropping streams, latency within baseline, TRex CPU < 50%); review alert history. Weekly: check /data usage, exporter log for InfluxDB write errors, unresolved EMU clients. Monthly: review baseline thresholds and the monitoring matrix.

11.2 Permanent delay monitoring: bring-up and baseline

  1. Prerequisites complete: TX switches configured (7.1/7.2), Leaf/BL AP ports configured for VLAN 1314/1315 (7.3/7.4), firewall zone and rules active (7.5), TRex server installed with trex-mon running (8), InfluxDB and Grafana running (10), inventory validated (trexctl inventory validate).
  2. Dry run: trexctl plan -p monitoring-default - review the stream table, pg_ids and budget.
  3. Apply: trexctl apply -p monitoring-default. Expected output: EMU clients created (e.g. 14 APs x 2 VLANs = 28 clients + FW zone), gateways resolved for all L3 streams, N streams started on ports 0 and 1.
  4. Verify on TRex: trexctl status shows RX pps = TX pps for every stream after a few seconds; latency values plausible (intra-DC fabric tens of microseconds, inter-DC 100-300 us depending on fibre length, firewall paths 50-500 us).
  5. Verify on the network: display l2vpn mac-address vsi VPN-1314 on a Leaf shows the local TRex MAC on the AP port and the remote TRex MACs via VXLAN tunnels; display arp vpn-instance VPN-CORE on sw-rzk-BL shows the TRex IPs; display mac-address vlan 3101 on sw-rzk-TX1 shows MACs on both the AP port and the TRex trunk port.
  6. Verify Grafana: Overview shows all streams, no drops; Latency matrix populated.
  7. Baseline phase (7 days): let the system run; then derive per-class latency thresholds (e.g. p99 of the 7-day average x 1.5) and set the alert rules (10.5). Document the baseline table in the operations handbook (template below).
  8. Enable alert notifications.
Class / pair typeExpected one-way latency (to be replaced by measured baseline)Alert threshold
L2 intra-DC (Leaf-Spine-Leaf/BL)15-40 us (two or three 5950 hops, VXLAN encapsulation, TX switch hops)baseline x 3
L2 inter-DCintra-DC + 2 x DCI + fibre (~5 us/km) + TX fibre; typically 100-300 usbaseline x 2
L3-BLintra-DC + one routing hop on sw-rzk-BL; RZC sources add two DCI crossingsbaseline x 3
L3-DCFW / L3-ENTFW50-500 us depending on firewall load and active member locationbaseline x 3, and absolute 2 ms

11.3 Generic test procedure (applies to 11.4-11.10)

  1. Define: purpose, class, APs, VLANs, rate, duration, expected result; create a change/test ticket if production VLANs or firewalls are involved.
  2. Pre-checks: trexctl status (monitoring healthy), target AP links up (display interface brief on TX switch), firewall rules in place, no concurrent maintenance.
  3. Annotate: trexctl annotate "TEST <id>: <description> start".
  4. Execute with trexctl test ... (or raw TRex console for ad-hoc cases).
  5. Observe in Grafana (Lab tests / Loss dashboards) and in the switch counters (display counters rate inbound interface on TX switch and AP ports).
  6. Post-checks: lab streams stopped (trexctl test stops automatically; verify with the console stats), monitoring unaffected, firewall sessions cleared.
  7. Report: trexctl report --test <id> --format md; attach to the ticket; annotate "end".

11.4 Test: Layer 2 inside one VLAN

Goal: loss and delay between two APs in the same VLAN (e.g. VLAN 1314, K-L11 to C-L21, inter-DC). Where: monitoring instance (already running permanently); for a dedicated high-rate run use the lab instance.

  1. Permanent view: Grafana "Class detail", class L2, src_ap K-L11, dst_ap C-L21 - read latency/jitter/loss for the time range.
  2. Higher resolution for a limited time: trexctl update --group l2-inter-dc --pps 1000 (1 ms resolution; budget check applies); revert with --pps 200.
  3. Line-rate variant: pin lab ports p4 to K-L11 and p7 to C-L21 (already the default pins), then trexctl test throughput --src K-L11 --dst C-L21 --vlan 1314 --sizes 128,512,1518 --duration 60 --bidir. The runner creates lab EMU-less clients (index+50 addresses), resolves nothing (L2: destination MAC = remote lab client MAC), runs the binary search and reports the NDR per frame size plus latency at NDR. Note that the inter-DC TX fibre carries 10G in each direction in this test; with a 10G inter-DC TX link, bidirectional line rate is the maximum.

Raw TRex alternative (console on the lab instance, ports p4/p7 pinned, single-tagged):

cd /opt/trex/current && ./trex-console -p 4601 --async_port 4600
trex> portattr -a --prom on
trex> start -f /opt/trexctl/profiles/raw/udp_vlan_latency.py --port 4 -t cvlan=1314,smac=02:54:52:33:05:22,dmac=02:54:52:3c:05:22,sip=10.3.14.151,dip=10.3.14.160,pps=1000
trex> start -f /opt/trexctl/profiles/raw/udp_vlan_latency.py --port 7 -t cvlan=1314,smac=02:54:52:3c:05:22,dmac=02:54:52:33:05:22,sip=10.3.14.160,dip=10.3.14.151,pps=1000,pg=901
trex> stats --ls          # latency per pg_id
trex> tui                 # live view, 'l' for latency; q to quit
trex> stop -a
# /opt/trexctl/profiles/raw/udp_vlan_latency.py - minimal single/double-tagged UDP latency stream with tunables
from trex.stl.api import *

class STLS1(object):
    def get_streams(self, direction=0, svlan=0, cvlan=1314, smac='02:54:52:33:05:22', dmac='02:54:52:3c:05:22',
                    sip='10.3.14.151', dip='10.3.14.160', pps=200, size=128, tos=0, pg=900, **kwargs):
        pkt = Ether(src=smac, dst=dmac)
        if int(svlan):
            pkt = pkt / Dot1Q(vlan=int(svlan))
        pkt = pkt / Dot1Q(vlan=int(cvlan)) / IP(src=sip, dst=dip, tos=int(tos), ttl=64) / UDP(sport=40000 + int(pg), dport=32009)
        pad = max(0, int(size) - len(pkt)) * 'x'
        return [STLStream(packet=STLPktBuilder(pkt=pkt / pad),
                          mode=STLTXCont(pps=int(pps)),
                          flow_stats=STLFlowLatencyStats(pg_id=int(pg)))]

def register():
    return STLS1()

For L2 streams no ARP is needed, but the remote switch must have learned the destination MAC: the reverse stream (or a gratuitous ARP from the lab client via service mode arp) takes care of that; otherwise the first packets are flooded in the VSI (still delivered).

11.5 Test: Layer 3 within VPN-CORE (Border Leaf routing)

Goal: delay added by the centralised gateway, asymmetry RZK vs RZC. Pairs: VLAN 1314 at AP X to VLAN 1315 at AP Y.

  1. Permanent: class L3-BL in Grafana (K-L11 to K-L21 and C-L21 to C-L22). Compare RZC-sourced vs RZK-sourced latency: the difference is the double DCI crossing to the gateway in Kalk.
  2. Ad-hoc with the monitoring instance: add a temporary group with a new profile file (copy monitoring-default.yaml, keep only an l3-bl group with the wanted pairs) and trexctl apply -p l3bl-adhoc; EMU resolves 10.3.14.1 / 10.3.15.1 for each source AP; verify with trexctl emu show (resolved MAC = sw-rzk-BL Vsi-interface MAC). Remove with trexctl stop -p l3bl-adhoc.
  3. Line-rate: pin p4 to K-L11 (VLAN 1314 side) and p5 to K-BL (VLAN 1315 side): trexctl test throughput --src K-L11 --src-vlan 1314 --dst K-BL --dst-vlan 1315 --sizes 512,1518 --duration 60. The runner puts the lab ports in L3 service mode (set_l3_mode with VLAN) to resolve the gateways, then builds streams with the gateway MACs. Expect line rate on the 5950 (hardware routing); any loss points to the single 10G AP link being the bottleneck (both directions share it in bidirectional mode).

Switch-side checks during the test: display counters rate inbound interface Ten-GigabitEthernet1/3/1 on sw-rzk-L11; display arp vpn-instance VPN-CORE on sw-rzk-BL; display interface Vsi-interface914 and Vsi-interface915 for packet counters. VALIDATED

11.6 Test: Layer 3 through the DC firewall (production VLANs)

Goal: inter-VLAN latency and loss through CPF-ZV05/06 between two production VLANs whose gateway is the DC firewall. Prerequisites: TRex pools reserved in both VLANs, Leaf AP ports carry both VLANs, DC-FW rule (7.5.2) active.

  1. Permanent: group l3-dcfw (50 pps). Grafana "Class detail", class L3-DCFW. A step change in latency usually indicates a cluster failover (active member moved to the other DC); confirm in the firewall logs and annotate.
  2. Ad-hoc profile: as in 11.5 with class: L3, src_vlan: <A>, dst_vlan: <B>; keep pps <= 100 per stream through firewalls (budget rule).
  3. Load test (coordinate with the firewall team): pin two lab ports to two APs that carry VLAN A and B, trexctl test soak --src K-L11 --src-vlan <A> --dst K-L41 --dst-vlan <B> --rate 1gbps --duration 600. Watch firewall CPU and connection table in SmartView at the same time. Increase the rate stepwise; stop when loss appears or the firewall team requests it.

11.7 Test: VPN-CORE through the Enterprise firewall (firewall zone) and stateful tests

Goal: inter-VRF/firewall path latency (stateless) and firewall performance (stateful).

Stateless (monitoring and lab)

  1. Permanent: group l3-entfw (VLAN 1314 at four APs to the FW zone, 50 pps). The FW-zone client (10.9.90.101 on p0) resolves the VIP 10.9.90.1 via EMU; the inside clients resolve 10.3.14.1 on sw-rzk-BL. Verify the OSPF route for 10.9.90.0/24 on both Border Leafs first (display ip routing-table vpn-instance VPN-CORE 10.9.90.0 24).
  2. Load test: pin p4 to K-L11 (VLAN 1314) and p6 to FW (VLAN 1420): trexctl test throughput --src K-L11 --src-vlan 1314 --dst FW --dst-vlan 1420 --sizes 512,1518 --duration 60. Stateless UDP through a Check Point gateway creates one session per 5-tuple; the runner uses a small number of 5-tuples (default 16 per direction) so the test measures forwarding, not session setup.

Stateful (ASTF) - option A: port addresses only (no routing changes)

  1. trexctl test astf --profile lab-fw-http.yaml --mult 200 --duration 300. The runner stops trex-lab, starts trex-lab-astf, loads an ASTF profile where the client range is the single lab client IP 10.3.14.151 (p4, VLAN 1314 via ASTF topology VIF with vlan=1314) and the server range the single IP 10.9.90.151 (p6, VLAN 1420). Gateways are resolved from trex_cfg port_info (default_gw 10.3.14.1 / 10.9.90.1) - the runner writes a temporary lab configuration with these values. With one client IP the connection rate is limited by source-port reuse (~60 000 concurrent flows); sufficient for throughput and latency, not for CPS scalability.

Stateful (ASTF) - option B: routed ranges (scalable)

  1. Switch team: ip route-static vpn-instance VPN-CORE 10.9.92.0 24 10.3.14.151 description TRex-ASTF-clients on sw-rzk-BL (7.4.3). Firewall team: static route 10.9.93.0/24 via 10.9.90.151 on the Enterprise firewall and rule TRX-astf-clients to TRX-astf-servers TCP 80/443.
  2. Profile lab-fw-http-routed.yaml: client range 10.9.92.1-10.9.92.254, server range 10.9.93.1-10.9.93.254, templates http_simple/http_https (TRex astf/ examples) or a pcap-based L7 profile; --mult scales connections per second.
  3. Run as in option A; read CPS, established flows, TCP retransmissions and goodput from the ASTF dashboard; correlate with firewall CPU. Remove the static route afterwards.
# ASTF profile skeleton used by trexctl (derived from the TRex astf/http_simple.py example)
from trex.astf.api import *

class Prof1():
    def get_profile(self, tunables, **kwargs):
        ip_gen_c = ASTFIPGenDist(ip_range=["10.9.92.1", "10.9.92.254"], distribution="seq")
        ip_gen_s = ASTFIPGenDist(ip_range=["10.9.93.1", "10.9.93.254"], distribution="seq")
        ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset="1.0.0.0"), dist_client=ip_gen_c, dist_server=ip_gen_s)
        return ASTFProfile(default_ip_gen=ip_gen,
                           cap_list=[ASTFCapInfo(file="../avl/delay_10_http_browsing_0.pcap", cps=10)])

def register():
    return Prof1()

ASTF VLAN handling: the client side uses an ASTF topology VIF with the VLAN tag; the server side learns VLAN and MAC from the incoming SYN (TRex ASTF guide, "Topology"). Because the lab ports are pinned (single-tagged), no QinQ is involved in ASTF tests.

11.8 Test: DSCP / QoS verification

  1. Permanent: groups dscp-l2-interdc and dscp-entfw; Grafana "DSCP" dashboard compares EF/AF41/CS1/BE side by side for the same pair. In an unloaded fabric all four must be identical within jitter.
  2. Under load: run a lab soak at 8-9 Gbit/s on the same AP pair with TOS 0 while the DSCP monitoring streams keep running; a divergence between EF and BE latency/loss shows whether any device in the path differentiates (fabric: expected no; firewall: depends on configuration).
  3. Mark verification: trexctl capture --port 1 --filter "vlan 1314 and udp port 32005" --count 20 (wrapper around the TRex capture API) and inspect the TOS byte at the receiving end to detect remarking.

11.9 Test: throughput / performance (stateless, lab instance)

  1. Pin the two lab ports to the wanted APs (7.1.4), update inventory.yaml ports.lab, run trexctl inventory validate.
  2. Decide frame sizes (64, 128, 256, 512, 1024, 1518, 9000 or IMIX) and whether bidirectional.
  3. trexctl test throughput --src <AP> --dst <AP> --vlan <V> [--src-vlan/--dst-vlan for L3] --sizes 64,512,1518 --duration 60 [--bidir] [--max-rate 9gbps].
  4. Result: table NDR (Mbit/s, pps) per frame size, latency avg/max at NDR and at 50%, drops at line rate; stored under /data/trexctl/reports/ and in trex_test.
  5. Interpretation: the 5950 forwards at line rate for all sizes; loss at 64-byte line rate (14.88 Mpps) usually means the TRex RX side (software counters) or the X710 at small frames - check trex_port.ierrors and queue_full; use 128 bytes as the smallest meaningful size unless hardware flow statistics are confirmed to keep up.

11.10 Test: convergence during planned maintenance

  1. Before the window: trexctl test convergence --group l2-inter-dc,l3-bl --pps 1000 --duration 3600 raises the selected groups to 1000 pps (1 ms resolution) and starts recording.
  2. trexctl annotate "Maintenance: sw-rzk-L21 IRF member 2 reboot".
  3. Perform the maintenance (IRF member reboot, link failover, ISSU, firewall failover ...).
  4. After the window the runner restores the rates and prints the outage table: per stream and per AP pair the number of lost packets and the derived outage (drops/pps) plus the time of first and last loss. Streams through the rebooted member's AP show the full downtime (expected); other streams reveal fabric convergence time (EVPN/VXLAN re-route, LACP on servers is not covered because APs use single links).
  5. Grafana "Loss and outages" with the annotation marks the event for later review.

11.11 Change procedure: adding a VLAN under test or an attachment point

  1. IP address management reserves 16 addresses in the VLAN; firewall team adds the pool object to the TRex rules (if the VLAN's gateway is a firewall or if L3 classes will use it).
  2. Edit /etc/trexctl/inventory.yaml: add the VLAN (vsi, prefix, gateway, pool_start, vrf) and append it to the vlans list of the APs that should carry it; trexctl inventory validate.
  3. Render and apply the Leaf/BL configuration: trexctl inventory render-leaf --ap K-L11 prints port trunk permit vlan ... and the service-instance/xconnect vsi block; apply on the switch, save force.
  4. Extend the profile (new groups or VLAN list), trexctl plan, trexctl apply.
  5. Verify RX = TX for the new streams; EMU clients resolved; Grafana shows the new VLAN tag.
  6. New AP: additionally patch the fibre, configure the TX switch AP port (QinQ access, new S-VLAN; add the S-VLAN to the trunk permit lists and, for RZC, to the inter-DC trunk), configure the device port, add the AP to the inventory with the next free index.
  7. Commit inventory/profile changes to git with the ticket number.

11.12 Maintenance of the platform

11.13 Troubleshooting matrix

SymptomLikely causeChecks
Stream RX = 0, TX > 0 for all streams of one APAP link down, QinQ port misconfigured, Leaf port missing VLANTX switch display interface brief, display qinq, display vlan <svlan>; Leaf display interface <port>, display current-configuration interface <port>
RX = 0 for L3 streams onlyGateway not resolved or firewall rule missingtrexctl emu show (dgw.resolve), display arp vpn-instance VPN-CORE on sw-rzk-BL, firewall logs for drops on TRX rules
RX = 0 for one direction of a pairRemote MAC not learned / asymmetric firewall ruledisplay l2vpn mac-address vsi VPN-<vlan> on the destination Leaf; firewall rule for the reverse direction
Constant small loss (0.01%)TRex software-mode RX overload, duplicate addresses, ECMP polarisation to a congested linktrex_global.rx_cpu_util, queue_full; display mac-address mac-move on Leafs; interface error counters along the path
Latency step change on firewall classesCluster failover (active member in the other DC)Firewall cluster state; correlate with annotation; expected behaviour
Latency spikes on all RZC streamsInter-DC TX fibre or DWDM issue (return path)TX switch inter-DC interface errors/optical levels (display transceiver diagnosis interface), compare with RZC-internal streams
MAC flapping alarms on a LeafTwo TRex clients with the same MAC, or the same client sent from two TRex portsInventory index uniqueness; trexctl inventory validate
Grafana shows gapsExporter stalled, InfluxDB full or slowsystemctl status trexctl-exporter, exporter log, df -h /data, InfluxDB logs
trex-mon restarts in a loopHugepages, NIC binding, configuration error/var/log/trex/trex-mon.log, section 8.9

12. Implementation plan

12.1 Phases and work packages

#PhaseWork packagesResponsibleExit criterion
0Decisions and procurementConfirm open items (12.5); order server, NICs, optics/DACs; reserve IP pools and VLAN 1420 / subnets; order or allocate the inter-DC fibre/DWDM channel; approve firewall changes; identify spare 5950 chassis/modules and free Leaf/BL/FW portsLVR network team, Secured NetworksBoM ordered, all TBD items closed
1Server build (lab bench)BIOS/OS/TRex/InfluxDB/Grafana installation (8, 10); loopback self-tests; trexctl installed; TX switch sw-rzk-TX1 staged on the bench with the server; QinQ bring-up with two bench VLANsSecured Networks / LVR Linux teamSection 8.8 self-test passed; trexctl loopback acceptance (9.11)
2trexctl developmentInventory/profile engine, EMU provisioning, stream builder, exporter, dashboards, alert rules, test runners (throughput, soak, convergence, ASTF), documentation; tested against the bench setupSecured Networks (or LVR development)Acceptance tests 9.11 green
3TX switches and cabling in the DCsRack sw-rzk-TX1 and sw-rzc-TX1; configure (7.1/7.2); inter-DC link up; patch AP links; Leaf/BL AP ports configured for VLAN 1314/1315 (7.3/7.4), one Leaf per DC firstLVR network teamQinQ path verified end to end for K-L11 and C-L21 (7.6)
4Firewall zoneZone interface, VIP, OSPF advertisement, objects and rules (7.5); DC-FW rules for the selected production VLANsLVR firewall teamRoute 10.9.90.0/24 visible on both BLs; ping from TRex FW-zone client to inside client works
5Monitoring go-liveRemaining AP ports; production VLAN pools; monitoring-default applied; 7-day baseline; thresholds and alerts; operations handbook completedLVR network team, Secured NetworksAll streams RX = TX; alerts enabled
6Lab tests and handoverExecute one test of each type (11.4-11.10) with the team; ASTF option A; knowledge transfer; final documentation v1.0 (PDF)Secured Networks, LVRTest reports archived; sign-off

12.2 Indicative effort

Work packageEffort (person-days)Comment
Server build, OS, TRex, InfluxDB, Grafana3-4Including bench self-tests
trexctl core (inventory, profiles, EMU, streams, exporter)10-12Python, unit tests, bench integration
trexctl test runners (throughput, soak, convergence, ASTF)5-6
Grafana dashboards and alert rules3Eight dashboards, seven rules
TX switch configuration, cabling supervision, AP ports3Both DCs, excluding physical installation
Firewall zone and rules1-2Firewall team
Baseline, tuning, test execution, handover, documentation v1.05
Total30-35Excluding procurement lead times and fibre provisioning

12.3 Acceptance criteria

  1. Server self-test: loopback latency < 20 us average, 0 drops at 1 kpps; lab instance 0 drops at 1518-byte line rate for 60 s in loopback.
  2. QinQ path: for every AP, a stream from the monitoring instance to a client at that AP shows RX = TX for 10 minutes; display mac-address vlan <svlan> on the TX switch shows exactly the expected MACs.
  3. Monitoring profile: all planned streams started, all L3 gateways resolved, exporter writing, Grafana Overview without path-down streams, 24 h without false alerts after baseline tuning.
  4. Firewall classes: L3-DCFW and L3-ENTFW streams RX = TX; a firewall cluster failover is visible as a latency step and logged by an annotation; no loss beyond the failover window.
  5. Test runners: throughput report for K-L11 to C-L21 (VLAN 1314) at 512 and 1518 bytes; convergence report from one maintenance event; ASTF option A report with established flows > 0 and zero TCP errors at the chosen rate.
  6. Operations: handbook (this document v1.0) with the baseline table; runbook procedures 11.2-11.12 executed once by the LVR team.

12.4 Risks and mitigations

RiskImpactMitigation
X710 refuses optics or DACsDelay in phase 1Order passive DACs from the HPE list plus two Intel-coded SR modules as fallback; test on the bench first
TRex software mode cannot sustain the planned rateLower stream countBudget is 1000x below TRex limits; monitor rx_cpu_util; split ports if needed
QinQ BPDU/LLDP behaviour on the TX switch differs from expectationLeaf port state or noiseValidate in phase 3 with one Leaf; add bpdu-drop any on AP ports if BPDUs are tunnelled
Firewall change approval takes longClasses L3-DCFW/L3-ENTFW delayedStart with L2 and L3-BL (no firewall involvement); firewall classes added later without redesign
IP pool reservation in production VLANs refusedReduced production coverageMonitoring works fully on VLAN 1314/1315; production VLANs are optional per VLAN
Spare 5950 modules do not provide enough SFP+ portsFewer APsUse breakout cables on QSFP28 ports (7.1.6) or add a second SFP+ module
5950 EoSLNo vendor support for TX switchesAcceptable for a test tool; keep a cold spare; replacement by a current model (e.g. HPE 5945) later requires only re-entering the same configuration
TRex release regressions (e.g. libstdc++)Startup failure after upgradeKeep previous release; test on the bench configuration first (11.12)
InfluxDB 2.x end of maintenance in the futureMigration effortExporter abstracts the write path; Grafana queries isolated in dashboards; migration to InfluxDB 3 or VictoriaMetrics possible later

12.5 Open items

#ItemOwnerNeeded for
1Exact model and module layout of the two spare 5950s (JH404A modules or JH321A); interface namesLVR network7.1, 7.2
2Free SFP+ ports on sw-rzk-L12/L21/L31/L41 and sw-rzc-L11/L12/L13/L22/L23 (no diag files available); re-verification of the proposed ports on L11, RZC-L21, both BLsLVR network4.6.1, 6.x, 7.3
3Free 10G interfaces on CPF-ZV01 and CPF-ZV02; confirmation that they form one ClusterXLLVR firewall4.3.5, 7.5
4Inter-DC fibre/DWDM details: distance, connector, optics type, available bandwidthLVR network5.2, 7.1.5
5Production VLANs to monitor (2-4), their subnets, gateways and reserved poolsLVR network / IPAM4.6.2, 9.3
6Approval of VLAN 1420 and subnets 10.9.90.0/24 (zone), 10.9.92.0/24 and 10.9.93.0/24 (ASTF) or alternativesLVR IPAM4.6.2, 7.5
7Server management network, DNS name, certificate authority, AD/LDAP group names for GrafanaLVR Linux / AD8.2, 10.3
8Confirmation of the TRex pools in VLAN 1314/1315 (.101-.116) - DHCP relay is configured on Vsi914/915; make sure the DHCP scopes exclude the poolLVR network4.6.2
9Decision whether Threat Prevention inspects TRex traffic on the Enterprise firewallLVR firewall7.5.1
10Hosting of the trexctl git repository and ownership of further developmentLVR9.2

Appendix A - Validated command reference and citations

Command / factSource
QinQ concept, qinq enable, PVID tagging behaviour, MTU note, trunk/pvid exampleHPE FlexFabric 5950 Switch Series Layer 2 - LAN Switching Configuration Guide, Release 630x: "Configuring QinQ", PDF pp. 219-229 (printed 207-217)
display qinq, qinq enable, qinq ethernet-type, qinq transparent-vlanHPE FlexFabric 5950 Layer 2 - LAN Switching Command Reference, Release 630x: "QinQ commands", PDF pp. 277-281
Jumbo frames default 9416 bytes (jumboframe enable [size])Layer 2 Configuration Guide, PDF p. 41
using tengige breakout of 40G/100G interfacesLayer 2 Configuration Guide, PDF pp. 36-38
stp edged-portLayer 2 Configuration Guide, PDF p. 294
undo stp global enable (default state with initial settings)Layer 2 Configuration Guide, PDF p. 306
stp bpdu-protection (not used; reference only)Layer 2 Configuration Guide, PDF p. 308
lldp global enableLayer 2 Configuration Guide, PDF p. 334
display l2vpn mac-address [vsi name]HPE FlexFabric 5950 VXLAN Command Reference, Release 630x, PDF p. 13
display ip routing-table [vpn-instance X] ip-address mask-lengthHPE FlexFabric 5950 Layer 3 - IP Routing Command Reference, Release 630x, PDF p. 26
display arp vpn-instance XHPE FlexFabric 5950 Layer 3 - IP Services Command Reference, Release 630x, PDF p. 33
Access pattern service-instance / encapsulation s-vid / xconnect vsi; ip route-static vpn-instance VPN-CORE ...; mgmt/NTP/VPN MGMT pattern; display evpn route mac, display counters rate inbound interface, display mac-address mac-move, display ospf peerRunning configurations and command outputs in diag_sw-rzk-L11, diag_sw-rzk-BL, diag_sw-rzc-BL, diag_SW-RZC-L21 (2025-02-17/18)
TRex: QinQ flow statistics require --software; X710 127 pg_ids (HW) / 1023 (software); no RX byte counters on X710 in HW mode; latency streams software processed, total below 5 MppsTRex Stateless support guide, "Flow statistics" and "Latency" sections (Table 14), trex-tgn.cisco.com/trex/doc/trex_stateless.html
TRex: EMU namespace key {vport, tci[2], tpid[2]}, client fields ipv4_dg, plugins arp/icmp, --emu, console emu_load_profile/emu_show_all, promiscuous requirementTRex EMU guide, trex-tgn.cisco.com/trex/doc/trex_emu.html
TRex: set_vlan with two tags, set_l3_mode(vlan=), get_pgid_stats latency keys, set_port_attr(promiscuous=), set_service_mode(filtered, mask)TRex STL Python API reference, cp_stl_docs/api/client_code.html
TRex: configuration keys prefix, zmq_pub_port, zmq_rpc_port, limit_memory, services_core, c, platform/dual_if; supported NICs; X710 optics restrictionTRex manual, "Platform configuration" and "Hardware recommendations", trex-tgn.cisco.com/trex/doc/trex_manual.html
TRex: ASTF profiles, topology VIF with VLAN, batch vs interactive modeTRex ASTF guide, trex-tgn.cisco.com/trex/doc/trex_astf.html
TRex releases: v3.08 (Python 3.12 client), v3.07 (DPDK 25.07, E810 hardware mode), v3.06 libstdc++ issue and work-aroundTRex release notes; trex-tgn Google group thread "trex v3.06" (Sept 2024 - Mar 2025)
Console options -p, --async_port, --emu, --emu-server-porttrex-core trex_console.py argument parser
InfluxDB OSS 2.x current release 2.9.1; InfluxDB 3 Core 3.11.x; Grafana 13.2.3 / 12.4.xGitHub release lists (influxdata/influxdb, grafana/grafana), October 2026

Appendix B - Source documents

Appendix C - Glossary

APAttachment point: a 10G link from a TX switch into a Leaf, Border Leaf or firewall member
ASTFTRex Advanced Stateful mode: real TCP/UDP stacks for client/server emulation
BLBorder Leaf (sw-rzk-BL, sw-rzc-BL): EVPN gateway, VRF owner, DCI, firewall attachment
C-VLAN / S-VLANInner (customer) and outer (service) 802.1Q tag in QinQ; here: production VLAN and attachment point id
DCIData-centre interconnect (RAGG1 between the Border Leafs, 2 x 40G with MACsec)
EMUTRex emulation server: ARP/ICMP/DHCP/IGMP client emulation in Go, per namespace (port, VLAN tags)
Flow statistics / pg_idTRex per-stream TX/RX counting identified by a packet group id carried in the IPv4 identification field
Latency streamStream with STLFlowLatencyStats: RX timestamps give one-way latency, jitter and histogram
NDRNo-drop rate (RFC 2544 throughput)
QinQIEEE 802.1ad provider bridging (802.1Q-in-802.1Q); Comware feature qinq enable
STLTRex stateless mode
TX switchDedicated TRex distribution switch (sw-rzk-TX1, sw-rzc-TX1)
VSIComware virtual switch instance = Layer 2 broadcast domain mapped to a VXLAN VNI (here VPN-<vlan>)