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.91 for review - review round 1 incorporated (content to be ironed out before PDF release)
Date
13 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.9.x, Grafana 12.4.x / 13.x
Author
Secured Networks
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.
0.912026-10-13Secured NetworksReview round 1 incorporated after independent re-verification of every finding (Appendix D): 128-latency-stream limit and split profile, ONE_QUE / c: 1, firewall-zone option B (VSI 4003) and ClusterXL risk, member-MAC behaviour and stream rebuild, nftables host protection, ASTF two-port configuration, commissioning checks for centralised-gateway ARP, TRex packet marking facts (TOS bit 0, IP ID, UDP checksum 0), exporter corrections, addressing and citation fixes.
1.0tbdClose 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

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 about 21 kpps and 25 Mbit/s in total (176 streams: 74 latency streams at 50-200 pps and 102 loss-only streams at 100 pps, 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. The zone is either a new FW interface cabled to the TX switches (option A) or the existing, unused transfer VSI 4003 that is already trunked to both cluster members (option B, recommended; section 4.3.5). 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 zone. Review finding: a direct link becomes a ClusterXL-monitored interface and can trigger a production failover; option B (existing transfer VSI 4003) avoids this. Re-decision requested (section 4.3.5, open item 11).RE-DECIDE
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. Attached via BAGG10 "--> Channel to ENT-FW ZV01/ZV02 inside" on each BL, trunk VLANs 4000 to 4003; VSI VPN-4003 "Transfer ENTFW *frei*" is unused (no gateway, no MACs learned). VPN-CORE carries a default route 0.0.0.0/0 O_ASE1 via 10.9.0.22.
CPF-ZV05 / ZV06DC FW RZK / RZCCheck Point---Default gateway of most server VLANs (BAGG31 "--> Channel to DC-FW Vlan-all": VLANs 32 ... 1000-1399, 4033, i.e. including 1314/1315); the VPN-CORE transfer VSI 4004 (10.9.0.33/.34, FW 10.9.0.35) runs on BAGG30 "--> Channel to DC-FW inside"

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 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.9.x (Flux/InfluxQL), Grafana 12.4.x or 13.x, 2-second sampling by default with interval maxima derived from the TRex latency histogram, downsampling task for long-term retention.
1000 pps per stream = 1 ms outage resolutionPer class200 pps for fabric latency streams (5 ms resolution), 100 pps for loss-only streams (10 ms), 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, option A) 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 opt. A, S-VLAN 3300 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, option A) 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 opt. A, S-VLAN 3300 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. The direct firewall links are option A of the firewall zone (section 4.3.5); with option B they are omitted.
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: up to 128 latency streams (latency/jitter/loss per stream) plus up to 1023 loss-only streams, QinQ frames, EMU for ARP/ICMPTRex STL, --software --emu, one data-plane thread per port pair (c: 1, ONE_QUE), 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, gateway-MAC tracking, start/stop, test runners, statistics exportPython 3.12, 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 12.4.x or 13.x (Grafana has no official LTS label)

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); 128 latency + 1023 loss-only streams per instance; 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). The destination MAC of these streams is the MAC of the active cluster member (section 2.4): after a failover the stream keeps sending to the old MAC until trexctl detects the new gateway MAC and rebuilds the stream (section 9.5); the gap seen in Grafana therefore includes the rebuild time, which must be considered when failover times are read from these streams.

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 a new TRex firewall zone (subnet 10.9.90.0/24, VIP 10.9.90.1, proposal) which is an interface of the Enterprise-FW cluster. Two ways to build the zone are described in 4.3.5: option A - a new physical interface per cluster member cabled to the TX switches (AP "FW", S-VLAN 3300 stretched over both TX switches, FW VLAN 1420); option B - the existing, unused transfer VSI 4003 that is already trunked to both cluster members on BAGG10, reached by TRex through the Border Leaf APs like any other VLAN. Path (option B): Leaf - fabric - sw-rzk-BL (VPN-CORE) - Vsi40 transfer (10.9.0.16/29) - ENT-FW active member - VLAN 4003 interface - BAGG10 - sw-rzk-BL or sw-rzc-BL VSI VPN-4003 - fabric - BL AP (K-BL or C-BL) - TX switch - TRex. VPN-CORE already carries a default route to the firewall (10.9.0.22), so the zone is reachable without switch changes; the firewall should nevertheless advertise 10.9.90.0/24 into OSPF 1 explicitly. The zone-side streams (zone client to inside) have the firewall MAC as destination and are subject to the rebuild-after-failover rule of 4.3.3. 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 TX switchA: AP FW, S 3300B: BL AP, VSI 4003 TRex p0/p1A: .114 [S 3300][C 1420]B: .106 [S 3110][C 4003] 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 (zone-side frame format for option A / option B).

4.3.5 Firewall zone design options

Review finding - the direct firewall link can affect production In Check Point ClusterXL every cluster interface (an interface with a cluster VIP) is monitored; if the link of the active member fails while the standby member's link is up, the cluster fails over. With option A the TRex zone interface depends on a non-redundant test path (TX switch, TX-to-TX fibre, optics, TRex port). A TX switch reboot, a fibre cut or an unplugged optic could therefore cause a production firewall failover or a loss of redundancy. The sentence "a TX switch failure never affects production" (4.8) only holds for option A if the firewall team can configure the interface as non-critical for failover in a supported way for their Check Point version, or if the risk is formally accepted. Option B has no such dependency. DECISION
OptionPhysical / L2 designFirewall designAssessment
A - direct links (customer's original wish)One free 10G port per cluster member cabled to sw-rzk-TX1 XGE1/1/7 (ZV01) and sw-rzc-TX1 XGE1/1/8 (ZV02); QinQ access ports with PVID 3300; S-VLAN 3300 also on the TX-to-TX trunk so that both members share one Layer 2 domain. AP index 14; zone client 10.9.90.114 (lab client .164).New cluster VLAN interface (e.g. eth1-05.1420) with VIP 10.9.90.1, member IPs .2/.3; anti-spoofing "internal, this network". If the members turn out to be independent clusters: two local S-VLANs (3300 RZK, 3310 RZC) and two subnets.Matches "physical connection from the dedicated switch to the FW". Needs two new firewall ports and transceivers. Production risk through ClusterXL interface monitoring (see box). Zone traffic bypasses the fabric, so the measurement isolates the firewall hop best.
B - existing transfer VSI 4003 (recommended)No new cabling. VSI VPN-4003 "Transfer ENTFW *frei*" exists on both Border Leafs and is already a member of the LACP bundles BAGG10 to CPF-ZV01 and CPF-ZV02 (port trunk permit vlan 4000 to 4003, no MACs learned in February 2025). TRex reaches it through the Border Leaf APs: service instance 4003 on sw-rzk-BL XGE1/3/6 (AP K-BL, index 6, zone client 10.9.90.106, lab client .156) and on sw-rzc-BL XGE1/3/14 (AP C-BL, index 13, zone client .113).New VLAN 4003 sub-interface on the existing inside bond of both members, VIP 10.9.90.1, member IPs .2/.3; same objects and rules as option A.Uses the existing redundant firewall attachment; no dependency of the cluster on the TX switches; no new firewall ports. The zone traffic crosses the fabric once more (BL to BL AP), which adds a few tens of microseconds but is identical for all zone streams. Does not provide a "direct" TX-switch-to-firewall link; the TX switch ports XGE1/1/7 (RZK) and XGE1/1/8 (RZC) remain free for later use.

Both options use the same subnet, the same TRex clients (addressed by the AP-index formula of 4.6.3), the same firewall objects and rules, and the same trexctl profile group (l3-entfw); only the inventory entry of the zone differs. The remainder of this document describes option B as the default and marks the option-A specifics where they occur.

4.3.6 Class DSCP - QoS verification

Selected L2 and L3 pairs are duplicated with four TOS bytes on the same pair, size and rate: BE = 0x00 as the reference, EF = 0xB8, AF41 = 0x88 and CS1 = 0x20. The BE copy is essential: each class is compared with a stream that is identical except for the TOS byte. 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. Two TRex properties must be known when captures are inspected: TRex sets bit 0 of the TOS byte on every flow-statistics and latency packet (TOS_GO_TO_CPU 0x1 in src/bp_sim.h, applied in src/stx/stl/trex_stl_fs.cpp), so the streams leave with 0x01 / 0xB9 / 0x89 / 0x21 - the DSCP (upper six bits) is unchanged, the ECN field reads 01; and the IPv4 identification field is rewritten (4.4). 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

The profile is split into latency streams (limit 128 per instance) for the pairs where delay and jitter matter, and loss-only streams (flow statistics, limit 1023) that extend the coverage to further VLANs. Both kinds report TX/RX counters and therefore loss and outage duration.

KindClassPairs (default profile)Streamspps / streamSizeTotal ppsLoss resolution
latencyL2 intra-DCVLAN 1314: each Leaf AP <-> BL AP of its DC (5 RZK + 6 RZC pairs, 2 directions)22200128 B4 4005 ms
latencyL2 inter-DCVLAN 1314: K-L11<->C-L11, K-L12<->C-L12, K-L21<->C-L21, K-L31<->C-L22, K-L41<->C-L23, K-BL<->C-BL12200128 B2 4005 ms
latencyL3-BLVLAN 1314 <-> 1315: K-L11<->K-L21, K-L31<->K-BL, C-L21<->C-L22, C-L13<->C-BL8200128 B1 6005 ms
latencyL3-DCFWProduction VLAN A <-> B: K-L11<->K-L41, K-L21<->K-L31, C-L12<->C-L23, C-L11<->C-L22850128 B40020 ms
latencyL3-ENTFWVLAN 1314 at K-L11, K-BL, C-L21, C-BL <-> FW zone850128 B40020 ms
latencyDSCPK-L11<->C-L21 (L2, 100 pps) and K-L11<->FW zone (L3-ENTFW, 50 pps), each with BE/EF/AF41/CS1, both directions16100 / 50256 B1 20010 / 20 ms
Latency streams (limit 128, guard rail 120)7410 400
loss-onlyL2 intra + inter-DCVLAN 1315: the same 11 + 6 pairs, 2 directions34100128 B3 40010 ms
loss-onlyL2 intra + inter-DCPer production VLAN (2 assumed): the same 17 pairs, 2 directions68100128 B6 80010 ms
Loss-only streams (limit 1023, guard rail 600)10210 200
Total with 4 monitored VLANs (1314, 1315 + 2 production VLANs)176~20 600 pps, ~22 Mbit/s L2 (~26 Mbit/s on the wire)

Guard rails enforced by trexctl for the permanent profile: at most 120 latency streams (hard limit 128), at most 600 loss-only streams (hard limit 1023), at most 50 kpps and 50 Mbit/s in total, at most 100 pps per stream through a firewall. About 50 latency streams remain free for ad-hoc latency measurements. The profile is a YAML file (section 9.4), so pairs, kinds and rates are adjusted without code changes. If more than ~120 latency streams are ever needed, a second monitoring instance (own 128 latency streams) on p2/p3 is the way forward; it needs bench validation because the EMU helper process is shared per host (section 11.12).

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 (option A, 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 (option A, member ZV02)RZCCPF-ZV02TBD free 10G portsw-rzc-TX1 XGE1/1/8330014
FW zone (option B)bothVSI VPN-4003 via K-BL and C-BLservice instance 4003 on sw-rzk-BL XGE1/3/6 and sw-rzc-BL XGE1/3/14(uses the K-BL / C-BL ports)3110 / 32106 / 13

AP indexes 1-49 are reserved for attachment points; lab clients use index + 50 (4.6.3).

4.6.2 VLANs under test and TRex address pools

VLANVSISubnetGatewayGateway ownerTRex pools (monitoring .101-.116, lab .151-.166)Purpose
1314VPN-131410.3.14.0/2410.3.14.1sw-rzk-BL, VPN-CORE10.3.14.101-116 (AP index 1-14 => .101-.114) and 10.3.14.151-166 (lab clients, index + 50) DECISIONPrimary monitoring carrier, L3-BL, L3-ENTFW, lab
1315VPN-131510.3.15.0/2410.3.15.1sw-rzk-BL, VPN-CORE10.3.15.101-116 and .151-.166Second carrier (loss-only L2), L3-BL
<PROD-VLAN-A>VPN-A<SUBNET-A><GW-A>DC-FW CPF-ZV05/06<POOL-A> e.g. .236-.251 (plus a lab pool only if lab tests use this VLAN)L2 production (loss-only), L3-DCFW
<PROD-VLAN-B>VPN-B<SUBNET-B><GW-B>DC-FW CPF-ZV05/06<POOL-B>L2 production (loss-only), L3-DCFW
FW zone: 4003 (option B, existing VSI VPN-4003) or 1420 (option A, new)VPN-4003 / -10.9.90.0/24 DECISION10.9.90.1 (VIP), members .2/.3ENT-FW cluster, zone "TRex"10.9.90.101-116 and .151-.166; by the formula: option B zone clients .106 (K-BL) and .113 (C-BL), lab .156; option A zone client .114, lab .164L3-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; note that VPN-171 and VPN-724 do not exist on SW-RZC-L21 (3.2). TBD Every pool (monitoring and lab) needs an IPAM reservation and, where DHCP relay exists (Vsi914/915), a DHCP scope exclusion.

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 + 50, i.e. the lab pool .151-.166 and MACs 02:54:52:33.. onwards, so that monitoring and lab clients never collide. Examples: lab client at K-L11 in VLAN 1314 = 10.3.14.151 / 02:54:52:33:05:22; at K-BL = 10.3.14.156 / 02:54:52:38:05:22; at C-L21 = 10.3.14.160 / 02:54:52:3c:05:22; zone lab client option B (K-BL, VLAN 4003 = 0x0FA3) = 10.9.90.156 / 02:54:52:38:0f:a3, option A (index 64, VLAN 1420 = 0x058C) = 10.9.90.164 / 02:54:52:40:05:8c.

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 latency streams 1-127, trex-mon loss-only streams 1000-1999, trex-lab 2000 upwards; allocated by trexctl and persisted in /etc/trexctl/pgid-map.json so that ids stay stable (pg_ids are 32-bit user values; the IPv4 identification carries an internal id, not the pg_id)
TOS byte0x00 default; DSCP class uses 0x00 (BE reference), 0xB8 (EF), 0x88 (AF41), 0x20 (CS1); on the wire TRex sets bit 0 (0x01 / 0xB9 / 0x89 / 0x21)
UDP checksum0 (disabled) for latency streams, because TRex rewrites the payload per packet; computed normally for loss-only streams
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; the ASTF unit uses its own two-port configuration [p4, p6] (client, server)
TRex modeSTL interactive, --software --emu, c: 1. In software mode TRex selects the queue mode from c: one data-plane thread per port pair gives ONE_QUE (the RX core reads the port queue directly, accurate latency); two or more give MULTI_QUE, for which the source states "latency won't be accurate in this mode" (src/trex_modes.h, choose_mode() in src/trex_modes.cpp). The start-up log must show set dpdk queues mode to ONE_QUE.STL interactive hardware mode (default, DROP_QUE_FILTER, c: 4) 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 128 latency + 1023 loss-only streams127 hardware flow-stat streams (plus up to 128 latency streams), line rate
Port numberingp0-p7 are server-wide labels. Inside each instance ports are numbered from 0 in the order of its interfaces list: trex-mon ports 0-3 = p0-p3; trex-lab ports 0-3 = p4-p7; trex-lab-astf port 0 = p4 (client side), port 1 = p6 (server side). Console and API commands always use the instance-local number. ASTF port roles are fixed: even ports are client side, odd ports server side.
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
Shared helpersThe EMU server (port 4510) and the Scapy server (port 4507) are single named daemons per host: an instance started with --emu restarts EMU, an interactive STL instance restarts the Scapy server. The lab units therefore run with --no-scapy-server and never with --emu.

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 or 13.x; Python 3.12 (AppStream) for the TRex client libraries and trexctlAll 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: 6 (5 Leafs, BL) + 1 FW member with option A; RZC: 7 (6 Leafs, BL) + 1 with option AHPE 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) - option A onlyCheck Point certified SFP+ SR; not needed with option B
Inter-DC link optics2Choose after the real distance and attenuation are known: the existing DCI uses 40G_BASE_ER4_QSFP_PLUS (40 km class) optics, which suggests a path longer than the 10 km reach of LR/LR4 parts. Candidates: 10G ER (40 km, JG234A), 40G ER4 (as on the DCI), or DWDM transponder client ports. 40G/100G recommended if RZC performance tests above 10 Gbit/s aggregate are wanted; the link is shared by all RZC monitoring and lab traffic
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 (option A only, member ZV01)CPF-ZV01 <FW-PORT>3300, QinQ access (shutdown with option B)SR
XGE1/1/8, XGE1/1/13-20spare-shutdown
XGE1/1/21TRex p0 (trex-mon port 0)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 port 0; ASTF client port 0)NIC2 port 0QinQ access, PVID = pinned AP (default 3101 = K-L11)DAC
XGE1/1/10TRex p5 (trex-lab port 1)NIC2 port 1QinQ access, PVID = pinned AP (default 3110 = K-BL)DAC
XGE1/1/11TRex p6 (trex-lab port 2; ASTF server port 1)NIC2 port 2QinQ access, PVID = pinned AP (default: FW zone - 3110 with option B, 3300 with option A)DAC
XGE1/1/12TRex p7 (trex-lab port 3)NIC2 port 3QinQ access, PVID = pinned AP (default 3204 = C-L21)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 (option A only, member ZV02)CPF-ZV02 <FW-PORT>3300, QinQ access (shutdown with option B)SR
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 vpn-instance MGMT 10.0.61.10
# 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); info-center loghost [ vpn-instance name ] ip: Network Management and Monitoring Command Reference R630x, PDF p. 440 (the production switches log in the public instance: info-center loghost 10.0.61.10); ip binding vpn-instance MGMT on M-GigabitEthernet0/0/0 and the NTP/VPN pattern as on sw-rzk-BL and sw-rzc-BL (sw-rzk-L11 uses ip address dhcp-alloc without a VPN binding on its management port). 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; not every VSI exists on every Leaf, e.g. VPN-724 and VPN-171 are missing on SW-RZC-L21) 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 4003
 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
 #
# firewall zone option B: the existing transfer VSI 4003 ("Transfer ENTFW *frei*") becomes the TRex zone
 service-instance 4003
  encapsulation s-vid 4003
  xconnect vsi VPN-4003
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 4003
 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 4003
  encapsulation s-vid 4003
  xconnect vsi VPN-4003
quit

VSI VPN-4003 exists on both Border Leafs (vxlan 4003, no gateway interface) and is already a service instance on BAGG10 towards each Enterprise-firewall member. With option A the 4003 entries are omitted.

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

ItemOption B - existing transfer VSI 4003 (recommended)Option A - direct links to the TX switches
Physical interfaceNone new: the inside bond of each member (BL BAGG10, trunk VLANs 4000-4003) already carries VLAN 4003One 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 4003 sub-interface on the existing inside bond of both membersVLAN 1420 sub-interface on the new port of 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
Cluster monitoringThe interface shares the existing redundant bond; no new failover dependencyThe interface depends on a non-redundant test path. The firewall team must configure it so that a link failure on this interface does not cause a failover (or accept the risk). DECISION
MAC behaviourThe cluster currently answers ARP with the active member's MAC (2.4). Either enable a ClusterXL virtual MAC for the cluster, or accept that trexctl rebuilds the zone-side streams after a failover (9.5). DECISION
Topology / anti-spoofingInternal, "network defined by the interface IP and net mask"; anti-spoofing enabled (prevent + log)
RoutingVPN-CORE already carries a default route 0.0.0.0/0 O_ASE1 via 10.9.0.22, so the zone is reachable without switch changes. Recommended anyway: advertise 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); 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, which carry preference 70 on sw-rzc-BL; import-route static into OSPF 1 is already configured)
Host objectsTRX-mon-1314 (10.3.14.101-116), TRX-lab-1314 (10.3.14.151-166), TRX-mon-1315, TRX-mon-<VLAN> per production VLAN pool, TRX-fwzone (10.9.90.101-116) and TRX-fwzone-lab (10.9.90.151-166); groups TRX-inside and TRX-zone
ServicesTRX-udp = UDP 32000-32099; TRX-tcp = TCP 80, 443, 8080 (ASTF); ICMP echo
Access rules1) TRX-inside -> TRX-zone: TRX-udp, icmp - Accept, Log. 2) TRX-zone -> TRX-inside: TRX-udp, icmp - Accept, Log. 3) (ASTF) TRX-astf-clients (10.9.92.0/24 or the lab client 10.3.14.151) -> TRX-astf-servers (10.9.93.0/24 or the zone lab client 10.9.90.156 / .164): 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. Latency streams carry UDP checksum 0 and TOS bit 0 set (4.4); confirm that no inspection feature drops them. DECISION
TimeoutsThe UDP virtual session timeout (Check Point default 40 s CONFIRM) is not reached by continuous streams at 50 pps; for ASTF increase the 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)
Leaf / BLdisplay l2vpn vsi name VPN-4003 verbose, display l2vpn mac-address vsi VPN-4003Option B: VSI up; firewall member MACs (001c-7f65-...) and the TRex zone client MACs visibleVALIDATED VXLAN CR PDF p. 13
RZC Leaf (e.g. SW-RZC-L21)display evpn route mac (filter for ec9b-8b67-37b8)Commissioning check: the sw-rzk-BL gateway MAC should be present in VSI VPN-1314/1315 once routed streams run; if it never appears, routed traffic from RZC APs is flooded as unknown unicast (3.2)CONFIRM
TRex (monitoring)trexctl emu showCommissioning check: an EMU client behind a Leaf AP (e.g. K-L11, C-L21) resolves 10.3.14.1 (centralised-gateway ARP through VXLAN, 3.2); if not, source the L3 classes from the BL APs or ask for ARP suppression in the VSIsCONFIRM
TRextrex-console -p 4501 --async_port 4500 --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 profileCustom with the settings below. Do not select the predefined "Low Latency" profile: on HPE Gen11 servers it sets Intel VT-d and VT-x to Disabled (HPE UEFI System Utilities User Guide for ProLiant Gen11, Table 1 "Workload profiles"), which breaks the vfio-pci DPDK driverDeterministic DPDK polling with IOMMU available
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-ThreadingEnabledFine for TRex; the hyper-thread siblings of the TRex threads are kept free of other work by isolcpus (8.3). Verify the sibling numbering with lscpu -e
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 nftables 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

# host firewall: nftables, NOT firewalld. TRex's start script (scripts/trex-cfg) runs
# "systemctl stop firewalld.service" on Red Hat-family systems at every start, and the TRex
# control ports (4500/4501, 4600/4601, 4507, 4510) have no authentication.
systemctl disable --now firewalld 2>/dev/null; dnf -y remove firewalld
cat >/etc/sysconfig/nftables.conf <<'EOF'
flush ruleset
table inet filter {
  set mgmt_hosts {
    type ipv4_addr; flags interval
    elements = { <MGMT-PREFIX>, <JUMPHOST-IP> }
  }
  chain input {
    type filter hook input priority 0; policy drop;
    iif lo accept
    ct state established,related accept
    ct state invalid drop
    ip protocol icmp accept
    # SSH and Grafana from the management hosts only
    ip saddr @mgmt_hosts tcp dport { 22, 443 } accept
    # TRex control channels (RPC, publisher, EMU, Scapy) only from the management hosts
    ip saddr @mgmt_hosts tcp dport { 4500, 4501, 4507, 4510, 4600, 4601 } accept
    # InfluxDB listens on 127.0.0.1 only (10.1); nothing to open here
    counter drop
  }
  chain forward { type filter hook forward priority 0; policy drop; }
  chain output  { type filter hook output  priority 0; policy accept; }
}
EOF
systemctl enable --now nftables
nft list ruleset | head -30

# 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"
# CPU isolation: keep the OS, InfluxDB, Grafana and trexctl on cores 0-3 (threads 0-3 and 16-19);
# TRex threads 4-15 and their hyper-thread siblings 20-31 are isolated (layout of 8.5; verify siblings with lscpu -e)
grubby --update-kernel=ALL --args="isolcpus=4-15,20-31 nohz_full=4-15,20-31 rcu_nocbs=4-15,20-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)

dpdk_setup_ports.py -i only generates the configuration file. The ports are bound to the DPDK driver when TRex starts (t-rex-64 calls trex-cfg, which runs dpdk_setup_ports.py --parent ... with the configuration file) or manually with ./dpdk_setup_ports.py --cfg /etc/trex/trex_mon.yaml. With IOMMU enabled vfio-pci is used; without IOMMU the script compiles and loads igb_uio from ko/src (needs kernel-devel, fails with Secure Boot).

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 with siblings N and N+16 (verify with lscpu -e); threads 0-3 and 16-19 remain for the OS, InfluxDB, Grafana and trexctl. c is the number of data-plane threads per port pair and each dual_if threads list must contain at least c entries.

trex-mon must run with c: 1 In stateless software mode TRex derives its queue mode from c (choose_mode() in src/trex_modes.cpp): with one data-plane thread per port pair it selects ONE_QUE, in which the RX core reads the port queue directly and latency is accurate; with two or more it selects MULTI_QUE, documented in src/trex_modes.h as "latency won't be accurate in this mode - both latency Tx and Rx are indirect". The monitoring load (~21 kpps) needs a small fraction of one core. The start-up log must contain set dpdk queues mode to ONE_QUE; this is an acceptance criterion (12.3). services_core (the core for the EMU and Scapy helpers) is the master thread, which is also the TRex default; the latency thread (5) must not be used for it.
### /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: 1
  services_core: 4
  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]
      - socket: 0
        threads: [8]
### /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]
### /etc/trex/trex_lab_astf.yaml - lab instance in ASTF mode: two ports only.
### ASTF port roles are fixed: even ports = client side, odd ports = server side.
### port 0 = p4 (client, pinned to a VPN-CORE VLAN AP), port 1 = p6 (server, pinned to the FW zone)
- version: 2
  interfaces: ['98:00.0', '98:00.2']
  port_limit: 2
  prefix: lab
  zmq_pub_port: 4600
  zmq_rpc_port: 4601
  limit_memory: 3072
  port_bandwidth_gb: 10
  c: 4
  port_info:
    - ip: 10.3.14.151
      default_gw: 10.3.14.1
      vlan: 1314
    - ip: 10.9.90.156
      default_gw: 10.9.90.1
      vlan: 4003
  platform:
    master_thread_id: 10
    latency_thread_id: 11
    dual_if:
      - socket: 0
        threads: [12, 13, 28, 29]

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 port_info of trex_lab_astf.yaml is real (port address, default gateway and VLAN per port; trexctl test astf rewrites it for the chosen pins, section 11.7; the zone values shown are for option B - option A uses VLAN 1420 and 10.9.90.164). Keys prefix, zmq_pub_port, zmq_rpc_port, limit_memory, services_core, c, port_info (ip, default_gw, vlan) and the platform section are documented in the TRex manual (chapter "Platform configuration"). VALIDATED Because the ASTF configuration uses two of the four ports of NIC2, TRex (i40e) needs --unbind-unused-ports at start, otherwise it exits with an error about bound but unused ports of the same NIC (main_dpdk.cpp option list) CONFIRM on the bench.

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 --no-scapy-server
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_astf.yaml --iom 0 --no-scapy-server --unbind-unused-ports
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 runs trex-cfg (hugepages, DPDK binding, helper daemons) before launching _t-rex-64; the --iom 0 flag suppresses the interactive text UI output in the log. --no-scapy-server on the lab units prevents them from restarting the Scapy helper daemon (a single named daemon per host, started by any interactive STL instance) under trex-mon; the lab units never use --emu, because a second --emu start would restart trex-mon's EMU server as well. After the first start verify in /var/log/trex/trex-mon.log: set dpdk queues mode to ONE_QUE.

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 -l and stats --lh (the console shows at most 4-5 pg_ids; use the API for more): latency in the single-digit microsecond range confirms the server-side baseline (DPDK, no switch). Confirm set dpdk queues mode to ONE_QUE in the trex-mon log.
  3. Start trex-lab with NIC2 p6-p7 looped (lab ports 2 and 3) and run start -f stl/imix.py -m 100% --port 2 for 60 s: no drops and no "queue full" counters confirm hardware mode line rate. Never run the bundled ./ndr tool on this server: it connects to the default RPC port 4501 (trex-mon) and resets all ports.
  4. Capture a few latency packets on the looped ports (capture record start --rx 3 --limit 50, capture record stop --id 1 -o /tmp/lat.pcap) and confirm in Wireshark: IP ID 0xFFFF, TOS bit 0 set (e.g. 0x01), UDP checksum 0 - the expected signature of TRex latency streams (4.4).
  5. 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 ARP (centralised-gateway caveat, 3.2)portattr -a --prom on; emu_show_all; capture with capture monitor start --rx 0 in the console; test the same client behind a BL AP
Management access lost after TRex startA firewalld-based ruleset was in use; trex-cfg stopped firewalldUse the nftables service (8.3); never re-enable firewalld on this host
trex-mon log shows MULTI_QUEc > 1 in trex_mon.yamlSet c: 1; latency is only accurate in ONE_QUE (8.5)
ASTF start fails with an error about bound unused portsTwo-port ASTF configuration on a four-port X710Add --unbind-unused-ports (already in the unit) or list all four ports and pin accordingly

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 once, applies later changes incrementally (add_ns/add_clients/remove_clients), waits for gateway resolution, returns resolved MACs and keeps watching them (gateway-MAC tracker).
trexctl.streamsBuilds Scapy packets (Ether/Dot1Q/Dot1Q/IP/UDP/payload), assigns stable pg_ids, creates STLStream objects with STLFlowLatencyStats (kind latency) or STLFlowStats (kind flowstat), pushes them to the right TRex port as one profile per group, starts/stops traffic and rebuilds streams whose destination MAC changed.
trexctl.exporterDaemon: polls get_pgid_stats(), port stats and global stats every N seconds with a read-only client (never acquires ports, disconnects with stop_traffic=False), computes interval deltas and histogram-based interval maxima, 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:                                 # keys = instance-local port numbers of trex-lab; label = server-wide name
    0: { label: p4, type: pinned, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/9,  ap: K-L11, astf_role: client }
    1: { label: p5, type: pinned, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/10, ap: K-BL }
    2: { label: p6, type: pinned, tx_switch: sw-rzk-TX1, tx_port: XGE1/1/11, ap: FWZ,   astf_role: server }
    3: { label: p7, 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, 4003] }
  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, 4003] }
  # firewall zone, option B (default): VSI 4003 reached through the BL APs -> no AP of its own;
  # K-BL and C-BL simply carry VLAN 4003 (added above). FWZ is an alias used by the lab pins.
  FWZ:   { alias_of: K-BL, vlan: 4003 }
  # firewall zone, option A (alternative): direct links, own AP index 14
  # 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, lab_pool_start: 10.3.14.151, 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, lab_pool_start: 10.3.15.151, vrf: VPN-CORE }
  4003: { vsi: VPN-4003, prefix: 10.9.90.0/24, gateway: 10.9.90.1, gateway_owner: ENT-FW, pool_start: 10.9.90.101, lab_pool_start: 10.9.90.151, vrf: FW-ZONE, gateway_mac_tracking: true }
  # 1420: { prefix: 10.9.90.0/24, gateway: 10.9.90.1, gateway_owner: ENT-FW, pool_start: 10.9.90.101, lab_pool_start: 10.9.90.151, vrf: FW-ZONE, gateway_mac_tracking: true }   # option A
  <PROD-VLAN-A>: { vsi: VPN-A, prefix: <SUBNET-A>, gateway: <GW-A>, gateway_owner: DC-FW, pool_start: <POOL-A>, vrf: DC-FW, gateway_mac_tracking: true }
budget: { max_latency_streams: 120, max_flowstat_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; the monitoring pool (16 addresses) and the lab pool (16 addresses) do not overlap each other or the gateway and stay inside the prefix; gateway_mac_tracking is set for every VLAN whose gateway is a firewall cluster (the MAC of the active member changes on failover, 2.4). trexctl inventory render-leaf and the acceptance checks also verify that the VSI of every listed VLAN exists on the Leaf (3.2).

9.4 Profiles (profiles/*.yaml)

version: 1
name: monitoring-default
instance: mon
defaults: { kind: latency, pps: 200, size: 128, tos: 0, ttl: 64, bidir: true, dport_base: 32000, sport_base: 40000 }
# kind: latency = STLFlowLatencyStats (max 128 per instance); flowstat = STLFlowStats, loss only (max 1023)
groups:
  - name: l2-intra-rzk
    class: L2                          # L2: same VLAN, dst MAC = remote client MAC
    vlans: [1314]
    pairs: &rzk_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]
    pairs: &rzc_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]
    pairs: &dc_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: l2-coverage-1315          # loss-only copies of the three L2 groups on the second carrier VLAN
    class: L2
    kind: flowstat
    pps: 100
    vlans: [1315]
    pairs_from: [l2-intra-rzk, l2-intra-rzc, l2-inter-dc]
  - name: l2-coverage-prod          # loss-only copies on the production VLANs
    class: L2
    kind: flowstat
    pps: 100
    vlans: [<PROD-VLAN-A>, <PROD-VLAN-B>]
    pairs_from: [l2-intra-rzk, l2-intra-rzc, l2-inter-dc]
  - 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: 4003                     # firewall zone option B (option A: 1420 at AP FW)
    pps: 50
    pairs: [[K-L11, K-BL], [K-BL, K-BL], [C-L21, C-BL], [C-BL, C-BL]]   # zone client sits at the BL AP of the same DC
  - name: dscp-l2-interdc
    class: L2
    vlans: [1314]
    pps: 100
    size: 256
    tos_set: [0x00, 0xB8, 0x88, 0x20]  # one stream per TOS value; 0x00 = best-effort reference
    pairs: [[K-L11, C-L21]]
  - name: dscp-entfw
    class: L3
    src_vlan: 1314
    dst_vlan: 4003
    pps: 50
    size: 256
    tos_set: [0x00, 0xB8, 0x88, 0x20]
    pairs: [[K-L11, K-BL]]
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; pairs_from re-uses the pair lists of other groups. Class L2 requires both APs to carry the VLAN; class L3 requires a gateway for the source VLAN and resolves it per source AP; for class L3 the destination is the client of dst_vlan at the second AP of the pair. kind selects STLFlowLatencyStats (latency, counted against the limit of 128) or STLFlowStats (loss only). The expanded default profile yields 74 latency and 102 loss-only streams (4.5). The class name, kind, 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 a budget guard rail is exceeded (latency streams > 120, loss-only streams > 600, pps/bps, firewall pps) unless --force (the hard TRex limits 128/1023 are never overridable).
  2. Allocate pg_ids: key = class|kind|src_ap|src_vlan|dst_ap|dst_vlan|tos; look up in pgid-map.json, otherwise assign the lowest free id (latency 1-127, loss-only 1000-1999) 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] (tci[0] is the outer tag); add one client per needed IP with its deterministic MAC, ipv4_dg = VLAN gateway and plugins arp, icmp. EMUClient.load_profile() first calls remove_profile() and deletes all namespaces and clients, so it is used only for the initial load; every later change is incremental (add_ns, add_clients, remove_clients, remove_ns) so that running streams keep their emulated hosts. Set the TRex ports to promiscuous + multicast and to filtered service mode with the mask the console uses for service --emu (NO_TCP_UDP_MASK | DHCP_MASK | MDNS_MASK | TRANSPORT_MASK; NO_TCP_UDP_MASK alone covers ARP/ICMP - confirm on the bench that the statistics UDP streams are counted unchanged). 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, chksum=0 for latency streams)/Raw(pad), padded to size (at least 16 bytes of payload for the latency signature). 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) or STLFlowStats(pg_id), name=key); one TRex profile per group and port (port_id.profile_id syntax, e.g. 0.l2-inter-dc) so that a group can be stopped, removed and re-added without disturbing the others; start(ports=[...profiles...], force=True). Rate changes are implemented as remove + re-add of the group (latency streams ignore the multiplier, so update(mult=) cannot change them; counters restart, the exporter handles the discontinuity).
  6. Track gateway MACs: for every VLAN with gateway_mac_tracking the tracker polls the EMU client information (dgw.rmac) every 10 s and additionally forces a re-resolution every 60 s; when the resolved MAC differs from the MAC baked into the running streams, the affected streams (all L3 streams sourced in that VLAN at that AP) are rebuilt and an event gateway_mac_changed is written to trex_event. Until then the streams show loss - the gap measured on firewall classes therefore includes the detection time (worst case ~10 s + rebuild).
  7. 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 (e.g. before a maintenance window) by removing and re-adding its streams; the pg_ids stay the same, the TRex counters restart (latency streams cannot be re-rated in place)
trexctl emu show | resolve | clearEMU client table with resolved gateway MACs, forced re-resolution, removal (incremental; never reloads the whole profile while streams run)
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 FWZ --src-vlan 1314 --dst-vlan 4003 --rate 2gbps --duration 900Lab: fixed load, loss/latency over time (FWZ = firewall-zone alias of the inventory)
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) and get_stats() (ports, global) through a read-only client: the exporter never acquires the monitoring ports and disconnects with disconnect(stop_traffic=False), because the default disconnect() stops traffic on owned ports. Counters are read from the 'total' entry of the per-port dictionaries (summing all values would double-count). 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. Latency: average is exported as reported (low-pass filtered by TRex); the interval maximum is derived from the delta of the cumulative histogram (upper edge of the highest bucket that grew in the interval), because last_max only covers the last 0.5-second server window; total_max/total_min are exported as lifetime values; no latency fields are written for an interval in which the stream received no packets (TRex freezes average in that case).

MeasurementTagsFields
trex_streampg_id, name, class, kind (latency|flowstat), src_ap, dst_ap, src_dc, dst_dc, dc_pair, src_vlan, dst_vlan, vrf, tos, dscp, instance, profile + profile tagsall kinds: tx_pps, rx_pps, tx_bps, rx_bps, tx_pkts, rx_pkts, drop_pkts, drop_pkts_total, rx_ok(bool); latency kind only: lat_avg_us, lat_min_us, lat_max_us (interval maximum from histogram deltas), lat_last_max_us, lat_total_max_us, jitter_us, seq_dropped, seq_ooo, seq_dup, hist_<bucket> (per-interval counts)
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 up to ~30 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()
if first_apply:                                         # load_profile() removes ALL existing namespaces/clients first
    emu.load_profile(profile=build_emu_profile(clients), max_rate=512, tunables=[])
else:                                                   # incremental changes keep the running streams' hosts intact
    emu.add_ns(new_namespaces); emu.add_clients(ns_key, new_clients); emu.remove_clients(ns_key, gone_clients)
# then poll emu.get_info_clients(...) until dgw.resolve is True and read dgw.rmac;
# the gateway-MAC tracker keeps polling dgw.rmac and triggers a stream rebuild when it changes
# 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)
    if s.kind == 'latency':
        pkt = pkt / UDP(sport=s.sport, dport=s.dport, chksum=0)   # TRex rewrites the payload per packet without fixing the UDP checksum
    else:
        pkt = pkt / UDP(sport=s.sport, dport=s.dport)
    pad = max(16, s.size - len(pkt)) * b'\x00'                 # >= 16 bytes payload for the latency signature
    fs = STLFlowLatencyStats(pg_id=s.pg_id) if s.kind == 'latency' else STLFlowStats(pg_id=s.pg_id)
    return STLStream(name=s.key, packet=STLPktBuilder(pkt=pkt / pad), mode=STLTXCont(pps=s.pps), flow_stats=fs)

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)
# filtered service mode with the mask the console uses for "service --emu"
from trex.common.trex_client import NO_TCP_UDP_MASK, DHCP_MASK, MDNS_MASK, TRANSPORT_MASK
EMU_SERVICE_MASK = NO_TCP_UDP_MASK | DHCP_MASK | MDNS_MASK | TRANSPORT_MASK
c.set_service_mode(ports=[0, 1], enabled=False, filtered=True, mask=EMU_SERVICE_MASK)
for (port, group), streams in streams_by_port_group.items():
    profile = f"{port}.{group}"                              # one TRex profile per group and port
    c.add_streams([build_stream(s) for s in streams], ports=[profile])
c.start(ports=[f"{p}.{g}" for (p, g) in streams_by_port_group], 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()
c = STLClient(server='127.0.0.1', sync_port=4501, async_port=4500)
c.connect()                                             # read-only: no acquire(); at exit c.disconnect(stop_traffic=False)
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  = fs.get('tx_pkts', {}).get('total', 0)             # per-port dict also contains the key 'total'
        rx  = fs.get('rx_pkts', {}).get('total', 0)
        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))
        if meta.kind == 'latency' and drx > 0:                  # no latency fields for intervals without RX
            hist = lat.get('histogram', {})                      # cumulative counts per logarithmic bucket
            dh = {b: hist[b] - prev.get((pg_id, 'h', b), 0) for b in hist}
            for b in hist: prev[(pg_id, 'h', b)] = hist[b]
            grown = [int(b) for b, v in dh.items() if v > 0]
            interval_max = bucket_upper_edge(max(grown)) if grown else lat.get('last_max', 0)
            p = (p.field("lat_avg_us", lat.get('average', 0.0))
                   .field("lat_max_us", interval_max)              # interval maximum at bucket resolution
                   .field("lat_last_max_us", lat.get('last_max', 0))   # last 0.5 s window only
                   .field("lat_total_max_us", lat.get('total_max', 0))
                   .field("lat_min_us", lat.get('total_min', 0))
                   .field("jitter_us", lat.get('jitter', 0)))
            for b, v in dh.items(): p = p.field(f"hist_{b}", v)
        points.append(p)
    write.write(bucket="trex", record=points)
    time.sleep(INTERVAL)

Latency dictionary keys (average, total_max, total_min, last_max, jitter, histogram, err_cntrs) and the 'total' key of the per-port counter dictionaries are documented in the TRex STL Python API (get_pgid_stats) and in trex_stl_stats.py; the service-mode masks are defined in trex/common/trex_client.py. 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): InfluxDB 3 (Core/Enterprise) is now InfluxData's primary product line and has a different storage engine and API, and InfluxData has announced that its "latest" container tags move to InfluxDB 3 Core (announcement date to be re-checked at installation time CONFIRM). InfluxDB 2.x is still maintained (2.9.1, released 2026-05-12, at the time of writing) and remains the recommended version for this deployment; a later migration to InfluxDB 3 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 (latency kind), RX pps and loss per stream (both kinds), histogram buckets (heatmap); the kind tag distinguishes latency streams from loss-only streamsclass, kind, src_ap, dst_ap, vlan
TRex - DSCPLatency and loss grouped by DSCP (BE reference, EF, AF41, CS1) for the same AP pair, side by side; panels show the difference to the BE referencepair
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.kind == "latency" and 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 baseline (or fixed thresholds per class once measured) for 2 min; latency kind onlywarningThresholds set after the baseline phase (section 11.2). How the per-stream baseline is stored (Grafana recording rule, InfluxDB task writing a trex_baseline measurement, or static thresholds in the alert rule) is an open decision (12.5)
Gateway MAC changedtrex_event with kind=gateway_mac_changedinfoFirewall cluster failover detected by the trexctl tracker; streams were rebuilt
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 (13 APs x 2-4 VLANs + 2 zone clients), gateways resolved for all L3 streams, 74 latency + 102 loss-only streams started on ports 0 and 1. Commissioning checks (3.2): the EMU clients behind the Leaf APs (not only behind the BL APs) must resolve 10.3.14.1 / 10.3.15.1 - this proves that the centralised gateway answers ARP arriving through VXLAN; and on an RZC Leaf (display evpn route mac) the sw-rzk-BL gateway MAC ec9b-8b67-37b8 should be present in VSI VPN-1314/1315 once the routed streams run. If either check fails, source the L3 classes from the BL APs until the fabric team has decided on ARP suppression.
  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 plus the DCI and TX fibre delays, firewall paths 50-500 us); /var/log/trex/trex-mon.log contains set dpdk queues mode to ONE_QUE.
  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 + one DCI crossing (fibre ~5 us/km, 40 km class optics in use) + one TX-fibre crossing; intra-RZC streams carry two TX-fibre crossings insteadbaseline x 2
L3-BLintra-DC + one routing hop on sw-rzk-BL (service-loopback group); an RZC-to-RZC routed stream crosses the DCI twicebaseline 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; the group's streams are re-added, so their counters restart); 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; p4 and p7 are lab ports 0 and 3, 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 0 -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 3 -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=2001
trex> stats -l            # latency per pg_id (console shows the first 5); stats --lh = histogram
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=2000, **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, chksum=0)   # checksum 0: TRex rewrites the latency payload
        pad = max(16, int(size) - len(pkt)) * 'x'                        # >= 16 bytes for the latency signature
        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 fabric must have learned the destination MAC before a high-rate run: start the reverse stream (or send a gratuitous ARP from the lab client via service mode arp) at a low rate first and check display l2vpn mac-address vsi VPN-1314 on the destination Leaf. Otherwise the stream is flooded as unknown unicast into every port of the VSI (including the DC-firewall channel for VLAN 1314/1315) and into the trex-mon ports - at line rate this is a production incident, not a test. On the wire the packets carry TOS bit 0 and IP ID 0xFFFF (4.4).

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. Because the cluster answers ARP with the active member's MAC, a failover also produces a short loss gap on these streams until the trexctl tracker has rebuilt them with the new MAC (trex_event gateway_mac_changed); this gap is a property of the measurement, not of the firewall.
  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 zone clients (option B: 10.9.90.106 at K-BL on p0 and 10.9.90.113 at C-BL on p1, VLAN 4003; option A: 10.9.90.114 at AP FW) resolve the VIP 10.9.90.1 via EMU; the inside clients resolve 10.3.14.1 on sw-rzk-BL. Verify the 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; without an explicit advertisement the default route via 10.9.0.22 applies). The zone-side streams are subject to the MAC rebuild after a failover (11.6).
  2. Load test: pin p4 (lab port 0) to K-L11 (VLAN 1314) and p6 (lab port 2) to the zone (FWZ: option B = K-BL with VLAN 4003, option A = AP FW with VLAN 1420): trexctl test throughput --src K-L11 --src-vlan 1314 --dst FWZ --dst-vlan 4003 --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. Learn the zone client MAC before ramping (11.4).

Stateful (ASTF) - variant 1: port addresses only (no routing changes)

ASTF port roles are fixed in TRex: even ports are client side, odd ports server side. The ASTF unit therefore uses its own two-port configuration /etc/trex/trex_lab_astf.yaml with the interface list [p4, p6]: ASTF port 0 = p4 (client, pinned to a VPN-CORE VLAN AP), ASTF port 1 = p6 (server, pinned to the zone). The pins of p5/p7 are irrelevant during an ASTF run.

  1. trexctl test astf --profile lab-fw-http.yaml --mult 200 --duration 300. The runner writes trex_lab_astf.yaml (port 0: 10.3.14.151, gateway 10.3.14.1, VLAN 1314; port 1: zone lab client 10.9.90.156 for option B / .164 for option A, gateway 10.9.90.1, VLAN 4003 / 1420), stops trex-lab, starts trex-lab-astf (with --unbind-unused-ports because only two of the four NIC2 ports are used), loads an ASTF profile whose client range is the single port address and whose server range is the single zone address. 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) - variant 2: 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 the zone lab client (10.9.90.156 / .164) 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 variant 1; 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 per-port VLAN and default gateway come from port_info in trex_lab_astf.yaml (or from an ASTF topology VIF for finer control); 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. ASTF -m is a plain multiplier of the profile's connections per second, not a rate like in stateless mode.

11.8 Test: DSCP / QoS verification

  1. Permanent: groups dscp-l2-interdc and dscp-entfw (BE reference + EF/AF41/CS1); Grafana "DSCP" dashboard compares the four 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. Expected values on the wire are 0x01 / 0xB9 / 0x89 / 0x21, because TRex sets TOS bit 0 on statistics packets (4.3.6); any other value means the path remarked the packet.

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.
  6. Flooding safeguards (mandatory for line-rate runs): the runner first sends the reverse stream and a gratuitous ARP at low rate and verifies on the destination device that the lab-client MAC is learned (display l2vpn mac-address vsi VPN-<vlan>); it ramps the rate in steps (10% / 50% / 100%); it aborts when the RX counters of trex-mon ports show unexpected traffic (flooding into the monitoring ports); prefer the test VLANs 1314/1315 for line-rate tests. Optionally add static MAC entries for the deterministic lab-client MACs on the TX switch lab ports (mac-address static <H-H-H> interface Ten-GigabitEthernet1/1/9 vlan 3101, L2 CR R630x PDF p. 16 - verify the exact syntax with ? on the device CONFIRM). Never run the bundled ./ndr tool on this server (it targets port 4501 = trex-mon and resets all ports); NDR searches use trexctl test throughput on port 4601.

11.10 Test: convergence during planned maintenance

  1. Before the window: trexctl test convergence --group l2-inter-dc,l3-bl --pps 1000 --duration 3600 re-adds the selected groups at 1000 pps (1 ms resolution; counters restart) 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). For a firewall failover the L3-DCFW and zone-side L3-ENTFW streams additionally contain the gateway-MAC detection and rebuild time of trexctl (9.5); read the pure failover time from the inside-to-zone direction, whose destination MAC (sw-rzk-BL) does not change.
  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 and with gateway_mac_changed events; expected behaviour
Firewall-class streams stay at RX = 0 after a failoverGateway-MAC tracker did not rebuild (EMU still caches the old MAC, tracker stopped)trexctl emu resolve, trexctl emu show (dgw.rmac must equal the new active member MAC), then trexctl apply; consider a ClusterXL virtual MAC
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
All monitoring streams stopped after someone used the consoleConsole disconnect/reset on the trex-mon ports, or the bundled ./ndr tool was runOperators connect read-only (trex-console -r) unless they intend to change streams; trexctl apply restores the profile
Latency values implausibly high or noisytrex-mon running in MULTI_QUE (c > 1), OS work on TRex threadsCheck the log for ONE_QUE, c: 1, isolcpus, tuned-adm active

12. Implementation plan

12.1 Phases and work packages

#PhaseWork packagesResponsibleExit criterion
0Decisions and procurementConfirm open items (12.5), in particular firewall-zone option A/B and the ClusterXL virtual-MAC question; order server, NICs, optics/DACs (TX-to-TX optics after the distance is known); reserve IP pools (monitoring and lab) and the zone subnet; order or allocate the inter-DC fibre/DWDM channel; approve firewall changes; identify spare 5950 chassis/modules and free Leaf/BL ports (and FW ports for option A)LVR 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 first; commissioning checks: gateway ARP from a Leaf AP, RZC gateway-MAC route, BPDU behaviour on the QinQ ports (3.2, 7.6)LVR network teamQinQ path verified end to end for K-L11 and C-L21 (7.6); L3 checks passed or fallback decided
4Firewall zoneZone interface (option B: VLAN 4003 on the inside bond; option A: new ports), VIP, OSPF advertisement, objects and rules (7.5); virtual-MAC decision; DC-FW rules for the selected production VLANs; planned failover test to observe the gateway-MAC rebuildLVR firewall teamRoute 10.9.90.0/24 visible on both BLs; ping from TRex FW-zone client to inside client works; failover test documented
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: trex-mon log shows set dpdk queues mode to ONE_QUE; loopback latency < 20 us average, 0 drops at 1 kpps; a captured latency packet shows IP ID 0xFFFF, TOS bit 0 and UDP checksum 0; lab instance 0 drops at 1518-byte line rate for 60 s in loopback; management access survives a TRex restart (nftables, not firewalld).
  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: 74 latency and 102 loss-only streams started, all L3 gateways resolved (including from Leaf APs), exporter writing without stopping traffic on reconnect, 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 planned firewall cluster failover is visible as a latency step and logged by an annotation; the streams towards the firewall MAC are rebuilt automatically (gateway_mac_changed event) and recover within 15 s of the failover (or immediately if a virtual MAC is used); the inside-to-zone direction shows no loss beyond the failover window.
  5. Test runners: throughput report for K-L11 to C-L21 (VLAN 1314) at 512 and 1518 bytes with the flooding safeguards active; convergence report from one maintenance event; ASTF variant-1 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 far below TRex limits; monitor rx_cpu_util; split ports if needed
Firewall-zone option A: ClusterXL monitors the TRex zone interfaceProduction firewall failover or loss of redundancy caused by the test infrastructurePrefer option B (existing VSI 4003); if option A is chosen, the firewall team must make the interface non-critical or formally accept the risk (4.3.5)
Firewall cluster answers ARP with member MACsFirewall-class streams lose packets after a failover until rebuilttrexctl gateway-MAC tracker (9.5); alternatively a ClusterXL virtual MAC; document the effect in the test reports
Centralised EVPN gateway does not answer ARP through VXLAN from the Leaf APsL3 classes cannot be sourced from Leaf APsCommissioning check in phase 3; fallback: source L3 classes from the BL APs or enable ARP suppression in the VSIs (production change)
Unknown-unicast flooding by line-rate lab testsUp to 10 Gbit/s flooded into production VSIs and into trex-monMandatory pre-learning, rate ramps, static MACs on the TX switch lab ports, test VLANs only (11.9)
Unauthenticated TRex control ports; trex-cfg stops firewalldAnyone reaching the management network could start trafficnftables allow-list (8.3), management-network ACLs, read-only console use; re-check after every TRex upgrade
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
11Firewall zone: option B (existing transfer VSI 4003 on the inside bond, recommended) or option A (new direct 10G links from the TX switches, ClusterXL monitoring risk to be solved or accepted)LVR network + firewall4.3.5, 7.5.1
12ClusterXL virtual MAC for the Enterprise and DC clusters versus stream rebuild by trexctl after a failoverLVR firewall2.4, 9.5
13Host protection of the TRex server: nftables allow-list (proposed), management-network ACLs, list of management hostsLVR Linux / security4.8, 8.3
14IPAM reservations for the lab pools (.151-.166) in every VLAN used for lab tests, in addition to the monitoring pools; DHCP exclusions on Vsi914/915LVR IPAM4.6.2
15TX-to-TX link speed and optics once the fibre distance and attenuation are known (DCI uses 40 km class ER4 optics)LVR network5.2, 7.1.5
16Storage of the per-stream latency baseline for alerting (InfluxDB task / Grafana recording rule / static thresholds)Secured Networks / LVR10.5, 11.2
17Second monitoring instance (EMU helper conflict) if more than ~120 latency streams are ever required - bench validationSecured Networks4.5, 11.12
18Bench confirmations: ONE_QUE log line, TOS bit 0 and UDP checksum 0 through the firewalls, service-mode mask versus stream counters, BPDU handling on QinQ ports, --unbind-unused-ports for the two-port ASTF configuration, X710 optics/DACsSecured Networks8.8, 9.5, 12.3

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
Centralised EVPN gateway requires ARP/ND flood suppression on the VTEPs (gateway does not answer ARP arriving through VXLAN tunnels when remote ARP learning is disabled)HPE FlexFabric 5950 EVPN Configuration Guide, Release 630x, "Configuring a centralized EVPN gateway - Restrictions and guidelines", PDF p. 28; arp suppression enable: VXLAN Command Reference R630x, PDF pp. 5-6
info-center loghost [ vpn-instance name ] ip-addressHPE FlexFabric 5950 Network Management and Monitoring Command Reference, Release 630x, PDF p. 440
bpdu-drop any; mac-address static in interface viewLayer 2 - LAN Switching Command Reference R630x, PDF p. 292 and p. 16
HPE "Low Latency" workload profile disables VT-d and VT-xHPE UEFI System Utilities User Guide for ProLiant Gen11 servers, "Workload profile dependencies", Table 1 "Workload profiles: General power efficient compute - Low latency"
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 peer; BAGG10 trunk 4000-4003 and VSI VPN-4003 on both BLs; BAGG31 service instances 1314/1315; ARP of 10.9.0.22/10.9.0.35 to member MACs and ARP_DUPLICATE_IPADDR_DETECT log entries; VPN-CORE default route via 10.9.0.22; DCI transceivers 40G_BASE_ER4; ARP entries via Tunnel5 only; no gateway-flagged MAC routes on SW-RZC-L21Running 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: maximum 128 per instance "in addition to the streams which collect per stream statistics", software processed, total below 5 Mpps, multiplier does not apply, at least 16 bytes payloadTRex Stateless support guide, "Flow statistics" (Table 14) and "Per stream latency/jitter/packet errors" sections, trex-tgn.cisco.com/trex/doc/trex_stateless.html; trex-core src/trex_defs.h (MAX_FLOW_STATS 1023, MAX_FLOW_STATS_X710 127, MAX_FLOW_STATS_PAYLOAD 128)
TRex queue modes: stateless + --software with c = 1 selects ONE_QUE, with c > 1 MULTI_QUE ("latency won't be accurate in this mode"); hardware mode on X710 selects DROP_QUE_FILTER; start-up log line set dpdk queues mode to ...trex-core src/trex_modes.h (mode descriptions), src/trex_modes.cpp (choose_mode(), get_cap_for_mode())
TRex marks statistics packets: TOS bit 0 set (TOS_GO_TO_CPU 0x1); IPv4 ID = IP_ID_RESERVE_BASE (0xffff - 1023) + hw_id for flow statistics, 0xFFFF for latency; latency signature written per packet without UDP checksum recalculationtrex-core src/bp_sim.h, src/flow_stat_parser.cpp (set_tos_to_cpu()), src/stx/stl/trex_stl_fs.h/.cpp, src/main_dpdk.cpp (update_fsp_head_lat(), update_node_flow_stat())
TRex start script stops firewalld on Red Hat-family systems; ports are bound at start; helper daemons (Scapy, EMU) are single named daemons per host; --no-scapy-server, --unbind-unused-portstrex-core scripts/trex-cfg, scripts/t-rex-64, scripts/dpdk_setup_ports.py (run_servers(), cleanup_servers()), src/main_dpdk.cpp option table
TRex Python API: service-mode masks (NO_TCP_UDP_MASK ... ALL_MASK; no EMU_MASK), disconnect(stop_traffic=True) default, per-port counter dictionaries with a 'total' key, console stats -s/-l/--lh limited to 4-5 pg_ids, EMUClient.load_profile() removes all namespaces first, NDR tool uses the default RPC port and resetstrex-core trex/common/trex_client.py, trex/stl/trex_stl_client.py, trex/stl/trex_stl_stats.py, trex/utils/parsing_opts.py, trex/emu/trex_emu_client.py, trex/examples/stl/stl_ndr_bench_tool.py
ASTF port roles: even ports client side, odd ports server side (--astf-server-only, --astf-client-mask)TRex ASTF guide, "Client/Server mode" (batch CLI options table)
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; at most 128 per TRex instance
Loss-only streamStream with STLFlowStats: TX/RX packet and byte counters per pg_id, no latency; up to 1023 per instance in software mode
ONE_QUE / MULTI_QUETRex DPDK queue modes in software mode, selected by the number of data-plane threads per port pair; only ONE_QUE gives accurate latency
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>)

Appendix D - Changes since draft v0.9 (review round 1)

A technical review of draft v0.9 (13 October 2026) raised 39 items. Each was re-verified against the trex-core source (master = v3.08), the TRex documentation, the diagnostic files and the HPE guides before the plan was changed. Items that could not be verified are marked CONFIRM in the text. Rejected items: none; two items were softened (InfluxDB "latest" tag date, Check Point UDP timeout) because they could not be verified from primary sources.

#ChangeSectionsEvidence
1Latency streams are limited to 128 per instance (1023 applies to loss-only flow statistics). The permanent profile is now 74 latency + 102 loss-only streams (~21 kpps); profiles carry a kind attribute; budget guard rails 120 / 600.1, 4.1, 4.2, 4.4, 4.5, 4.7, 9.4-9.7TRex stateless guide; src/trex_defs.h
2trex-mon runs with c: 1 (ONE_QUE); with c: 2 TRex selects MULTI_QUE where latency is not accurate. Thread layout, services_core (master thread) and isolcpus adjusted; ONE_QUE log line is an acceptance criterion.4.7, 8.3, 8.5, 8.8, 12.3src/trex_modes.h/.cpp
3Firewall zone: the direct-link design (option A) makes the TRex path a ClusterXL-monitored interface; option B (existing transfer VSI 4003 on the inside bond, BAGG10) added and recommended; decision reopened.2.3, 4.3.4, 4.3.5, 4.6, 7.4, 7.5.1, 12.5BL configurations (BAGG10, VSI VPN-4003)
4Both firewall clusters answer ARP with the active member's MAC; streams towards a firewall MAC must be rebuilt after a failover (trexctl gateway-MAC tracker) or a virtual MAC enabled.2.4, 4.3.3, 4.3.4, 9.5, 11.6, 11.10sw-rzk-BL ARP table and ARP_DUPLICATE_IPADDR_DETECT logs
5TRex stops firewalld at every start and its control ports are unauthenticated: host protection moved to nftables with an allow-list.4.8, 8.3, 12.4scripts/trex-cfg
6ASTF needs its own two-port configuration (even = client, odd = server); all console/API examples use instance-local port numbers; --unbind-unused-ports, --no-scapy-server on the lab units.4.7, 8.5, 8.6, 9.3, 11.4, 11.7TRex ASTF guide; main_dpdk.cpp; dpdk_setup_ports.py
7Centralised-gateway ARP through VXLAN and the missing gateway MAC route on the RZC Leaf are commissioning checks with defined fallbacks.3.2, 7.6, 11.2, 12.1EVPN CG PDF p. 28; diag files
8VLAN 1314/1315 are also mapped to the DC-firewall channel (BAGG31) on both BLs; VLAN names corrected; confirmation item added.3.2, 4.6.2BL configurations
9DSCP group includes a BE reference stream; TRex sets TOS bit 0 on statistics packets; IP ID reservation corrected (0xFC00 base, 0xFFFF for latency); latency streams use UDP checksum 0.4.3.6, 4.4, 4.6.4, 9.5, 9.9, 11.4, 11.8trex-core source
10Exporter: use the 'total' counter key, derive interval maxima from histogram deltas, no latency fields without RX, read-only client with disconnect(stop_traffic=False), EMU changes incremental, correct service-mode mask constants, one TRex profile per group.9.1, 9.5, 9.7, 9.9TRex Python client source and API documentation
11Fibre offsets corrected (one TX-fibre crossing for RZK-RZC streams, two for RZC-RZC; one DCI crossing per direction); DCI uses 40 km class ER4 optics, TX-to-TX optics to be chosen after measuring the distance.3.2, 4.4, 5.2, 11.2sw-rzk-BL transceiver information
12Addressing: lab clients (.151-.166) get their own reservations; zone clients follow the AP-index formula (.106/.113 for option B, .114 for option A); pg_id ranges per kind.4.6.2-4.6.4, 7.5.1consistency
13BIOS: Custom profile instead of "Low Latency" (which disables VT-d); dpdk_setup_ports.py -i only generates the configuration.8.1, 8.4.1HPE Gen11 UEFI guide Table 1; trex-cfg
14Minor corrections: stats -l/--lh instead of the non-existent stats --ls; rate changes re-add streams; NDR tool hazard; flooding safeguards for lab tests; info-center loghost vpn-instance syntax; management-port pattern cited from the BLs; VPN-CORE default route; VSI 4004 on BAGG30; iperf-counting locations; VSI coverage per Leaf; SW-RZC-L21 XGE1/4/4 transceiver; Grafana "LTS" wording; VPN-CORE default route makes the zone reachable without switch changes.variousvarious