3. Test environment

3.1 Platform under test — hardware

Server 2-socket Intel Xeon E5-2640 v2 @ 2.00 GHz
Cores / threads 16 cores (2 × 8), 1 thread per core — SMT disabled
Cache / NUMA 40 MiB L3 (2 instances), 2 NUMA nodes
Memory 31 GiB, with 8 × 1 GiB hugepages (all allocated to the dataplane)
Dataplane NICs 2 × Intel XL710 40GbE backplane, [8086:1580] rev 01
NIC driver vfio-pci, both devices on NUMA node 0
OS / kernel Ubuntu 24.04.4 LTS, kernel 6.8.0-146-generic

Full network controller inventory, read from dpdk-devbind --status on the
box under test. The XL710s are the only ports that carry subscriber traffic;
the rest are management and are listed so the inventory is complete:

PCI Controller chip Interface Driver Role
0000:01:00.0 Intel XL710 40GbE backplane [8086:1580] FortyGigabitEthernet1/0/0 vfio-pci Access — subscriber side
0000:47:00.0 Intel XL710 40GbE backplane [8086:1580] FortyGigabitEthernet47/0/0 vfio-pci Uplink — core side
0000:04:00.1 Intel DH8900CC Gigabit backplane [8086:043c] enp4s0f1 igb Management / harness SSH (the only active 1G port)
0000:04:00.2-4 Intel DH8900CC Gigabit backplane [8086:043c] enp4s0f2-4 igb Unused
0000:4a:00.0 Intel I350 Gigabit [8086:1521] enp74s0f0 igb Unused on this box
0000:4a:00.1 Intel I350 Gigabit [8086:1521] enp74s0f1 igb Unused
0000:04:00.0 Intel DH89XXCC QAT [8086:0434] — — Crypto accelerator, unused

Both XL710 ports are backplane variants — this is a blade chassis, not a
box with pluggable optics. Neither the QAT accelerator nor any offload beyond
RSS is used on the forwarding path; no-tx-checksum-offload is set in §3.3, so
the per-packet cost in §5.7 is software forwarding cost.

What this hardware means for the numbers

The processor launched in 2013. The E5-2640 v2 is a 2.0 GHz Ivy Bridge-EP
part — two generations before DDR4, and roughly a decade behind anything a
customer would deploy new today. We state the platform prominently because it is
the most important context for every forwarding figure here: these are floors
measured on old silicon
. A reader deploying current hardware can reason
upward from them.

Symmetric multithreading is disabled (1 thread per core), so each dataplane
worker is a physical core with no sibling contention — and equally no benefit
from SMT.

Core isolation is applied. The boot command line is:

default_hugepagesz=1G hugepagesz=1G hugepages=8 irqaffinity=0-1
isolcpus=2-6 nohz_full=2-6 rcu_nocbs=2-6
intel_pstate=disable processor.max_cstate=1 intel_idle.max_cstate=0 idle=poll
numa_balancing=disable hpet=disable mce=off tsc=reliable nmi_watchdog=0
intel_iommu=on iommu=pt

The kernel confirms it: /sys/devices/system/cpu/isolated reads 2-6, and all
five VPP workers sit on exactly that set with interrupts confined to cores 0–1.

An honest note on what isolation bought. We measured this platform both
without and with core isolation. It produced no throughput improvement. The
two isolated runs reproduce each other to within 0.2% on the single-worker
cells, and both sit 2.5–3.9% below the single un-isolated run; the two-worker
cells agree within 1.1% across all three. We are not claiming isolation harms
forwarding — the un-isolated condition was measured once, and nohz_full /
rcu_nocbs carry their own overheads we did not isolate. The honest conclusion
is that on a box where nothing else contends for the worker cores, isolation
removes contention that was not there. It remains correct practice because it
protects against future contention, not because it raised these figures.

NUMA locality is correct. The dataplane uses main-core 1 with
corelist-workers 2-6, and CPUs 0–6 all sit on NUMA node 0 — the same node as
both NICs. No cross-socket traffic on the forwarding path.

3.2 Platform under test — software

Installer bundle quantumtouch-installer-1.4.0-13
BNG plugin 0.10.36, commit 9a12835, clean tree
Controller quantum-bng-controller:1.4.0 (container)
quantum_core v1.6.0
VPP v25.10.0-23~g744d3c715
CPESIM 0.4.17
Metrics Prometheus (container)

3.3 Dataplane configuration

Taken verbatim from the running /etc/vpp/startup.conf:

cpu     { main-core 1   corelist-workers 2-6 }
memory  { main-heap-size 2G }
buffers { buffers-per-numa 1048576   default data-size 2048 }
statseg { size 1024M }
dpdk    { uio-driver vfio-pci   no-multi-seg   no-tx-checksum-offload
          dev 0000:01:00.0 { num-rx-queues 5  num-tx-queues 6
                             num-rx-desc 4096 num-tx-desc 4096
                             rss { ipv4 ipv4-udp ipv4-tcp } }
          dev 0000:47:00.0 { ... same ... } }

Receive-queue placement — one queue per worker, both interfaces, no sharing:

Worker lcore Access queue Uplink queue
vpp_wk_0 2 0 0
vpp_wk_1 3 1 1
vpp_wk_2 4 2 2
vpp_wk_3 5 3 3
vpp_wk_4 6 4 4

The statistics segment is sized to 1024 MB. VPP's 32 MB default is exhausted
well before this scale, because the BNG allocates a forwarding entry and
per-session counters for every subscriber.

3.4 Service configuration

Subscriber pool 100.64.0.0/17 (32,766 usable)
Access interface FortyGigabitEthernet1/0/0
Uplink interface FortyGigabitEthernet47/0/0
AAA mode open admission (local AAA measured separately in §5.8)
Captive portal 100.64.0.1
Plan under test Bronze — 20/25 Mbps down (CIR/PIR), 10/12 Mbps up
DHCP relay giaddr block of 64, 100.64.127.1 upward

3.5 Licence state, verified at launch

The session cap is a property of the licence, not the platform, so the gate
records it before the run starts:

licence VALID        grant bng.max_sessions = 25000
cap 25000            0 sessions resident

A reader may notice the platform reports max_source: free_baseline even when
fully licensed. The number is correct; that provenance label is wrong
upstream
and is being tracked. The cap in force during this run was 25,000,
and the working set was 5,000 — so no result here is cap-constrained.

3.6 Load generation

Generators 2 hosts (bluedot2, bluedot3)
Simulator CPESIM 0.4.17

Both generator hosts are wired symmetrically with a port on each side of the
BNG, and each carries two roles:

Host Role Interface PCI bus Address
bluedot2 CPE generator (access side) enp1s0f0 01:00.0 L2 only, no address
bluedot2 Uplink origin (core side) enp71s0f0 47:00.0 10.0.0.3/24
bluedot3 CPE generator (access side) enp1s0f0 01:00.0 L2 only, no address
bluedot3 Uplink origin (core side) enp71s0f0 47:00.0 10.0.0.2/24

Both origins hold a return route 100.64.0.0/17 via 10.0.0.1 so downstream
traffic reaches the subscriber pool. This run used both hosts for CPE
generation, with bluedot3 as the active uplink origin (10.0.0.2).

The access-side interfaces carry no IP address: the simulator drives raw frames
on them, relaying DHCP with a source giaddr, so there is nothing for the host
kernel to address. The PCI buses above are derived from the predictable
interface names (enp71s0f0 → bus 0x47) and place the generator ports in the
same slots as the platform's own, these being identically-specified chassis.

On the generator NIC chips. The generators were not read with
dpdk-devbind during this run, so their controllers are not confirmed
first-hand here. The evidence that they match the platform is strong but
indirect: all three chassis enumerate the same PCI topology — a 40GbE port at
bus 01:00.0, a second at 0x47, and an Intel I350 pair at bus 0x4a (idle on
the box under test, and the management port on bluedot3). Identical
slot-for-slot enumeration across three machines indicates identically-specified
chassis,
which would put Intel XL710 backplane controllers in the generators too.
Treated as inference, not measurement, and flagged for first-hand confirmation
on the next rig session.

It does not weaken the report, because generator capability here is established
by measurement rather than part number: the ceilings in §5.7 are ~20 Gbps
aggregate, 15.2 Mpps at 128B and 21.93 Mpps at 64B
, each held byte-identical
across five different platform configurations. A part number would explain those
ceilings; it would not change them, and it is the measured ceiling that makes
the generator-limited cells floors.

The generators bound most forwarding cells, but not all in the same way.
Of the 20 UDP cells, 4 found a platform ceiling, 13 reached line rate with zero
loss, and 3 are floors where the rig under-offered. The distinction matters:
only the floors understate the platform. §5.7 separates them, and the rig's
~20 Gbps aggregate ceiling is what makes the large-frame cells wire-speed
results rather than shortfalls.